This commit is contained in:
Rachael Alexanderson 2017-04-21 18:15:48 -04:00
commit b2ba7a4e18
8 changed files with 115 additions and 90 deletions

View file

@ -1088,23 +1088,35 @@ static void DrawPowerups(player_t *CPlayer)
for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory) for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory)
{ {
IFVIRTUALPTR(item, AInventory, GetPowerupIcon) if (item->IsKindOf(NAME_Powerup))
{ {
VMValue param[] = { item }; IFVIRTUALPTRNAME(item, NAME_Powerup, GetPowerupIcon)
int rv;
VMReturn ret(&rv);
VMCall(func, param, 1, &ret, 1);
auto tex = FSetTextureID(rv);
if (!tex.isValid()) continue;
auto texture = TexMan(tex);
screen->DrawTexture(texture, x, y, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_CenterBottomOffset, true, TAG_DONE);
x -= POWERUPICONSIZE;
if (x < -hudwidth / 2)
{ {
x = -20; VMValue param[] = { item };
y += POWERUPICONSIZE * 3 / 2; int rv;
VMReturn ret(&rv);
VMCall(func, param, 1, &ret, 1);
auto tex = FSetTextureID(rv);
if (!tex.isValid()) continue;
auto texture = TexMan(tex);
IFVIRTUALPTRNAME(item, NAME_Powerup, IsBlinking)
{
// Reuse the parameters from GetPowerupIcon
VMCall(func, param, 1, &ret, 1);
if (!rv)
{
screen->DrawTexture(texture, x, y, DTA_KeepRatio, true, DTA_VirtualWidth, hudwidth, DTA_VirtualHeight, hudheight, DTA_CenterBottomOffset, true, TAG_DONE);
x -= POWERUPICONSIZE;
if (x < -hudwidth / 2)
{
x = -20;
y += POWERUPICONSIZE * 3 / 2;
}
}
}
} }
} }
} }

View file

@ -659,33 +659,47 @@ void CALLBACK WinMIDIDevice::CallbackFunc(HMIDIOUT hOut, UINT uMsg, DWORD_PTR dw
static bool IgnoreMIDIVolume(UINT id) static bool IgnoreMIDIVolume(UINT id)
{ {
#ifndef __GNUC__
MIDIOUTCAPS caps; MIDIOUTCAPS caps;
bool mustcheck = false;
if (MMSYSERR_NOERROR == midiOutGetDevCaps(id, &caps, sizeof(caps))) if (MMSYSERR_NOERROR == midiOutGetDevCaps(id, &caps, sizeof(caps)))
{ {
if (caps.wTechnology == MIDIDEV_MAPPER)
{
// We cannot determine what this is so we have to assume the worst, as the default
// devive's volume control is irreparably broken.
mustcheck = true;
}
// The Microsoft GS Wavetable Synth advertises itself as MIDIDEV_SWSYNTH with a VOLUME control. // The Microsoft GS Wavetable Synth advertises itself as MIDIDEV_SWSYNTH with a VOLUME control.
// If the one we're using doesn't match that, we don't need to bother checking the name. // If the one we're using doesn't match that, we don't need to bother checking the name.
if (caps.wTechnology == MIDIDEV_SWSYNTH && (caps.dwSupport & MIDICAPS_VOLUME)) if (caps.wTechnology == MIDIDEV_SWSYNTH && (caps.dwSupport & MIDICAPS_VOLUME))
{ {
if (strncmp(caps.szPname, "Microsoft GS", 12) == 0) if (strncmp(caps.szPname, "Microsoft GS", 12) == 0)
{ {
IMMDeviceEnumerator *enumerator; mustcheck = true;
// Now try to create an IMMDeviceEnumerator interface. If it succeeds,
// we know we're using the new audio stack introduced with Vista and
// should ignore this MIDI device's volume control.
if (SUCCEEDED(CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator), (void**)&enumerator))
&& enumerator != nullptr)
{
enumerator->Release();
return true;
}
} }
} }
} if (mustcheck)
{
#ifndef __GNUC__
IMMDeviceEnumerator *enumerator;
// Now try to create an IMMDeviceEnumerator interface. If it succeeds,
// we know we're using the new audio stack introduced with Vista and
// should ignore this MIDI device's volume control.
if (SUCCEEDED(CoCreateInstance(__uuidof(MMDeviceEnumerator), nullptr, CLSCTX_ALL,
__uuidof(IMMDeviceEnumerator), (void**)&enumerator))
&& enumerator != nullptr)
{
enumerator->Release();
return true;
}
#else
// assume the worst and consider volume control broken.
return true;
#endif #endif
}
}
return false; return false;
} }

View file

@ -120,15 +120,15 @@ void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end
continue; continue;
} }
c -= 3; c -= 3;
int len = LittleLong(*(int*)c); int len = c[0] + 256*c[1] + 65536*c[2];
if (len > 1000000 || len <= (eqp - c + 1)) if (c[3] || len > 1000000 || len <= (eqp - c + 1))
{ {
// length looks fishy so retry with the next '=' // length looks fishy so retry with the next '='
continue; continue;
} }
c -= 4; c -= 4;
count = LittleLong(*(int*)c); count = c[0] + 256 * c[1];
if (count <= 0 || count > 1000) if (c[2] || c[3] || count <= 0 || count > 1000)
{ {
// very unlikely to have 1000 tags // very unlikely to have 1000 tags
continue; continue;

View file

@ -1195,6 +1195,8 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata,
return std::make_pair(retval, channels==1); return std::make_pair(retval, channels==1);
} }
void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end, bool *endass);
std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length, bool monoize) std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length, bool monoize)
{ {
SoundHandle retval = { NULL }; SoundHandle retval = { NULL };
@ -1203,6 +1205,14 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int
ChannelConfig chans; ChannelConfig chans;
SampleType type; SampleType type;
int srate; int srate;
uint32_t loop_start = 0, loop_end = 0;
bool startass = false, endass = false;
if (!memcmp(sfxdata, "OggS", 4) || !memcmp(sfxdata, "FLAC", 4))
{
MemoryReader mr((char*)sfxdata, length);
FindLoopTags(&mr, &loop_start, &startass, &loop_end, &endass);
}
std::unique_ptr<SoundDecoder> decoder(CreateDecoder(&reader)); std::unique_ptr<SoundDecoder> decoder(CreateDecoder(&reader));
if(!decoder) return std::make_pair(retval, true); if(!decoder) return std::make_pair(retval, true);
@ -1269,6 +1279,19 @@ std::pair<SoundHandle,bool> OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int
return std::make_pair(retval, true); return std::make_pair(retval, true);
} }
if (!startass) loop_start = Scale(loop_start, srate, 1000);
if (!endass) loop_end = Scale(loop_end, srate, 1000);
if (loop_start < 0) loop_start = 0;
if ((loop_start > 0 || loop_end > 0) && loop_end > loop_start && AL.SOFT_loop_points)
{
ALint loops[2] = { static_cast<ALint>(loop_start), static_cast<ALint>(loop_end) };
DPrintf(DMSG_NOTIFY, "Setting loop points %d -> %d\n", loops[0], loops[1]);
alBufferiv(buffer, AL_LOOP_POINTS_SOFT, loops);
getALError();
}
retval.data = MAKE_PTRID(buffer); retval.data = MAKE_PTRID(buffer);
return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize)); return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize));
} }

View file

@ -1,37 +1,22 @@
/* // license:GPL-2.0+
// copyright-holders:Jarek Burczynski,Tatsuyuki Satoh
/*
This file is based on fmopl.c from MAME 0.95. The non-YM3816 parts have been This file is based on fmopl.c from MAME. The non-YM3816 parts have been
ripped out in the interest of making this simpler, since Doom music doesn't ripped out in the interest of making this simpler, since Doom music doesn't
need them. I also made it render the sound a voice at a time instead of a need them. I also made it render the sound a voice at a time instead of a
sample at a time, so unused voices don't waste time being calculated. If all sample at a time, so unused voices don't waste time being calculated. If all
voices are playing, it's not much difference, but it does offer a big voices are playing, it's not much difference, but it does offer a big
improvement when only a few voices are playing. improvement when only a few voices are playing.
Here is the appropriate section from mame.txt:
VI. Reuse of Source Code
--------------------------
This chapter might not apply to specific portions of MAME (e.g. CPU
emulators) which bear different copyright notices.
The source code cannot be used in a commercial product without the written
authorization of the authors. Use in non-commercial products is allowed, and
indeed encouraged. If you use portions of the MAME source code in your
program, however, you must make the full source code freely available as
well.
Usage of the _information_ contained in the source code is free for any use.
However, given the amount of time and energy it took to collect this
information, if you find new information we would appreciate if you made it
freely available as well.
*/
/*
** **
** File: fmopl.c - software implementation of FM sound generator ** File: fmopl.c - software implementation of FM sound generator
** types OPL and OPL2 ** types OPL and OPL2
** **
** Copyright (C) 2002,2003 Jarek Burczynski (bujar at mame dot net) ** Copyright Jarek Burczynski (bujar at mame dot net)
** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development ** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development
** **
** Version 0.72 ** Version 0.72
** **
@ -49,12 +34,12 @@ Revision History:
14-06-2003 Jarek Burczynski: 14-06-2003 Jarek Burczynski:
- implemented all of the status register flags in Y8950 emulation - implemented all of the status register flags in Y8950 emulation
- renamed Y8950SetDeltaTMemory() parameters from _rom_ to _mem_ since - renamed y8950_set_delta_t_memory() parameters from _rom_ to _mem_ since
they can be either RAM or ROM they can be either RAM or ROM
08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip) 08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip)
- corrected YM3526Read() to always set bit 2 and bit 1 - corrected ym3526_read() to always set bit 2 and bit 1
to HIGH state - identical to YM3812Read (verified on real YM3526) to HIGH state - identical to ym3812_read (verified on real YM3526)
04-28-2002 Jarek Burczynski: 04-28-2002 Jarek Burczynski:
- binary exact Envelope Generator (verified on real YM3812); - binary exact Envelope Generator (verified on real YM3812);
@ -62,7 +47,7 @@ Revision History:
rates are 2 times slower and volume resolution is one bit less rates are 2 times slower and volume resolution is one bit less
- modified interface functions (they no longer return pointer - - modified interface functions (they no longer return pointer -
that's internal to the emulator now): that's internal to the emulator now):
- new wrapper functions for OPLCreate: YM3526Init(), YM3812Init() and Y8950Init() - new wrapper functions for OPLCreate: ym3526_init(), ym3812_init() and y8950_init()
- corrected 'off by one' error in feedback calculations (when feedback is off) - corrected 'off by one' error in feedback calculations (when feedback is off)
- enabled waveform usage (credit goes to Vlad Romascanu and zazzal22) - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22)
- speeded up noise generator calculations (Nicola Salmoria) - speeded up noise generator calculations (Nicola Salmoria)
@ -89,9 +74,9 @@ Revision History:
- fixed subscription range of attack/decay tables - fixed subscription range of attack/decay tables
To do: To do:
add delay before key off in CSM mode (see CSMKeyControll) add delay before key off in CSM mode (see CSMKeyControll)
verify volume of the FM part on the Y8950 verify volume of the FM part on the Y8950
*/ */
#include <stdio.h> #include <stdio.h>
@ -199,7 +184,7 @@ struct OPL_SLOT
uint8_t vib; /* LFO Phase Modulation enable flag (active high)*/ uint8_t vib; /* LFO Phase Modulation enable flag (active high)*/
/* waveform select */ /* waveform select */
unsigned int wavetable; uint16_t wavetable;
}; };
struct OPL_CH struct OPL_CH

View file

@ -858,21 +858,6 @@ class Inventory : Actor native
virtual ui version("2.4") bool DrawPowerup(int x, int y) { return false; } virtual ui version("2.4") bool DrawPowerup(int x, int y) { return false; }
//===========================================================================
//
// AInventory :: GetPowerupIcon
//
// Returns the icon that should be drawn for an active powerup.
//
//===========================================================================
virtual clearscope version("2.5") TextureID GetPowerupIcon() const
{
TextureID id;
id.SetInvalid();
return id;
}
//=========================================================================== //===========================================================================
// //
// AInventory :: AbsorbDamage // AInventory :: AbsorbDamage

View file

@ -269,11 +269,13 @@ class Powerup : Inventory
//=========================================================================== //===========================================================================
// //
// APowerup :: DrawPowerup // AInventory :: GetPowerupIcon
//
// Returns the icon that should be drawn for an active powerup.
// //
//=========================================================================== //===========================================================================
override TextureID GetPowerupIcon() virtual clearscope version("2.5") TextureID GetPowerupIcon() const
{ {
return Icon; return Icon;
} }

View file

@ -769,7 +769,7 @@ class BaseStatusBar native ui
// Draw item count // Draw item count
if (am_showitems) if (am_showitems)
{ {
DrawString(mSmallFont, String.Format("%s\34%c %d/%d", Stringtable.Localize("$AM_ITEMS"), crdefault+65, level.found_items, level.total_items), (1, y), 0, highlight); DrawString(mSmallFont, String.Format("%s\34%c %d/%d", Stringtable.Localize("$AM_ITEMS"), crdefault+65, level.found_items, level.total_items), (textdist, y), 0, highlight);
} }
} }
@ -813,18 +813,22 @@ class BaseStatusBar native ui
// that can obey AltHUD rules - which this cannot. // that can obey AltHUD rules - which this cannot.
Vector2 pos = (-20, POWERUPICONSIZE * 5 / 4); Vector2 pos = (-20, POWERUPICONSIZE * 5 / 4);
double maxpos = screen.GetWidth() / 2; double maxpos = screen.GetWidth() / 2;
for (let item = CPlayer.mo.Inv; item != NULL; item = item.Inv) for (let iitem = CPlayer.mo.Inv; iitem != NULL; iitem = iitem.Inv)
{ {
let icon = item.GetPowerupIcon(); let item = Powerup(iitem);
if (icon.IsValid()) if (item != null)
{ {
// Each icon gets a 32x32 block. let icon = item.GetPowerupIcon();
DrawTexture(icon, pos, DI_SCREEN_RIGHT_TOP, 1.0, (POWERUPICONSIZE, POWERUPICONSIZE)); if (icon.IsValid() && !item.IsBlinking())
pos.x -= POWERUPICONSIZE;
if (pos.x < -maxpos)
{ {
pos.x = -20; // Each icon gets a 32x32 block.
pos.y += POWERUPICONSIZE * 3 / 2; DrawTexture(icon, pos, DI_SCREEN_RIGHT_TOP, 1.0, (POWERUPICONSIZE, POWERUPICONSIZE));
pos.x -= POWERUPICONSIZE;
if (pos.x < -maxpos)
{
pos.x = -20;
pos.y += POWERUPICONSIZE * 3 / 2;
}
} }
} }
} }
@ -969,7 +973,7 @@ class BaseStatusBar native ui
// //
//============================================================================ //============================================================================
void DrawBar(String ongfx, String offgfx, double curval, double maxval, Vector2 position, int border, int vertical, int flags = 0, double alpha = 1.) void DrawBar(String ongfx, String offgfx, double curval, double maxval, Vector2 position, int border, int vertical, int flags = 0)
{ {
let ontex = TexMan.CheckForTexture(ongfx, TexMan.TYPE_MiscPatch); let ontex = TexMan.CheckForTexture(ongfx, TexMan.TYPE_MiscPatch);
if (!ontex.IsValid()) return; if (!ontex.IsValid()) return;