diff --git a/src/g_shared/shared_hud.cpp b/src/g_shared/shared_hud.cpp index 8ac35da248..b3e9532d8d 100644 --- a/src/g_shared/shared_hud.cpp +++ b/src/g_shared/shared_hud.cpp @@ -1088,23 +1088,35 @@ static void DrawPowerups(player_t *CPlayer) for (item = CPlayer->mo->Inventory; item != NULL; item = item->Inventory) { - IFVIRTUALPTR(item, AInventory, GetPowerupIcon) + if (item->IsKindOf(NAME_Powerup)) { - VMValue param[] = { item }; - 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) + IFVIRTUALPTRNAME(item, NAME_Powerup, GetPowerupIcon) { - x = -20; - y += POWERUPICONSIZE * 3 / 2; + VMValue param[] = { item }; + 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; + } + } + } } } } diff --git a/src/sound/mididevices/music_win_mididevice.cpp b/src/sound/mididevices/music_win_mididevice.cpp index 5682d71acf..d794c7df38 100644 --- a/src/sound/mididevices/music_win_mididevice.cpp +++ b/src/sound/mididevices/music_win_mididevice.cpp @@ -659,33 +659,47 @@ void CALLBACK WinMIDIDevice::CallbackFunc(HMIDIOUT hOut, UINT uMsg, DWORD_PTR dw static bool IgnoreMIDIVolume(UINT id) { -#ifndef __GNUC__ MIDIOUTCAPS caps; + bool mustcheck = false; 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. // 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 (strncmp(caps.szPname, "Microsoft GS", 12) == 0) { - 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; - } + mustcheck = 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 + } + } return false; } diff --git a/src/sound/musicformats/music_libsndfile.cpp b/src/sound/musicformats/music_libsndfile.cpp index a338d344f2..fc159314f0 100644 --- a/src/sound/musicformats/music_libsndfile.cpp +++ b/src/sound/musicformats/music_libsndfile.cpp @@ -120,15 +120,15 @@ void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end continue; } c -= 3; - int len = LittleLong(*(int*)c); - if (len > 1000000 || len <= (eqp - c + 1)) + int len = c[0] + 256*c[1] + 65536*c[2]; + if (c[3] || len > 1000000 || len <= (eqp - c + 1)) { // length looks fishy so retry with the next '=' continue; } c -= 4; - count = LittleLong(*(int*)c); - if (count <= 0 || count > 1000) + count = c[0] + 256 * c[1]; + if (c[2] || c[3] || count <= 0 || count > 1000) { // very unlikely to have 1000 tags continue; diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 0dfa479b98..b697282bb7 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -1195,6 +1195,8 @@ std::pair OpenALSoundRenderer::LoadSoundRaw(uint8_t *sfxdata, return std::make_pair(retval, channels==1); } +void FindLoopTags(FileReader *fr, uint32_t *start, bool *startass, uint32_t *end, bool *endass); + std::pair OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int length, bool monoize) { SoundHandle retval = { NULL }; @@ -1203,6 +1205,14 @@ std::pair OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int ChannelConfig chans; SampleType type; 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 decoder(CreateDecoder(&reader)); if(!decoder) return std::make_pair(retval, true); @@ -1269,6 +1279,19 @@ std::pair OpenALSoundRenderer::LoadSound(uint8_t *sfxdata, int 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(loop_start), static_cast(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); return std::make_pair(retval, (chans == ChannelConfig_Mono || monoize)); } diff --git a/src/sound/oplsynth/fmopl.cpp b/src/sound/oplsynth/fmopl.cpp index 1bbd74dc48..d50c0f329e 100644 --- a/src/sound/oplsynth/fmopl.cpp +++ b/src/sound/oplsynth/fmopl.cpp @@ -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 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 voices are playing, it's not much difference, but it does offer a big 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 ** types OPL and OPL2 ** -** Copyright (C) 2002,2003 Jarek Burczynski (bujar at mame dot net) -** Copyright (C) 1999,2000 Tatsuyuki Satoh , MultiArcadeMachineEmulator development +** Copyright Jarek Burczynski (bujar at mame dot net) +** Copyright Tatsuyuki Satoh , MultiArcadeMachineEmulator development ** ** Version 0.72 ** @@ -49,12 +34,12 @@ Revision History: 14-06-2003 Jarek Burczynski: - 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 08-10-2002 Jarek Burczynski (thanks to Dox for the YM3526 chip) - - corrected YM3526Read() to always set bit 2 and bit 1 - to HIGH state - identical to YM3812Read (verified on real YM3526) + - corrected ym3526_read() to always set bit 2 and bit 1 + to HIGH state - identical to ym3812_read (verified on real YM3526) 04-28-2002 Jarek Burczynski: - 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 - modified interface functions (they no longer return pointer - 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) - enabled waveform usage (credit goes to Vlad Romascanu and zazzal22) - speeded up noise generator calculations (Nicola Salmoria) @@ -89,9 +74,9 @@ Revision History: - fixed subscription range of attack/decay tables - To do: - add delay before key off in CSM mode (see CSMKeyControll) - verify volume of the FM part on the Y8950 + To do: + add delay before key off in CSM mode (see CSMKeyControll) + verify volume of the FM part on the Y8950 */ #include @@ -199,7 +184,7 @@ struct OPL_SLOT uint8_t vib; /* LFO Phase Modulation enable flag (active high)*/ /* waveform select */ - unsigned int wavetable; + uint16_t wavetable; }; struct OPL_CH diff --git a/wadsrc/static/zscript/inventory/inventory.txt b/wadsrc/static/zscript/inventory/inventory.txt index 43de6b527a..750296565e 100644 --- a/wadsrc/static/zscript/inventory/inventory.txt +++ b/wadsrc/static/zscript/inventory/inventory.txt @@ -858,21 +858,6 @@ class Inventory : Actor native 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 diff --git a/wadsrc/static/zscript/inventory/powerups.txt b/wadsrc/static/zscript/inventory/powerups.txt index 8402588c57..078647a231 100644 --- a/wadsrc/static/zscript/inventory/powerups.txt +++ b/wadsrc/static/zscript/inventory/powerups.txt @@ -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; } diff --git a/wadsrc/static/zscript/statusbar/statusbar.txt b/wadsrc/static/zscript/statusbar/statusbar.txt index 62bfa7fb3d..c5fd4a9caa 100644 --- a/wadsrc/static/zscript/statusbar/statusbar.txt +++ b/wadsrc/static/zscript/statusbar/statusbar.txt @@ -769,7 +769,7 @@ class BaseStatusBar native ui // Draw item count 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. Vector2 pos = (-20, POWERUPICONSIZE * 5 / 4); 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(); - if (icon.IsValid()) + let item = Powerup(iitem); + if (item != null) { - // Each icon gets a 32x32 block. - DrawTexture(icon, pos, DI_SCREEN_RIGHT_TOP, 1.0, (POWERUPICONSIZE, POWERUPICONSIZE)); - pos.x -= POWERUPICONSIZE; - if (pos.x < -maxpos) + let icon = item.GetPowerupIcon(); + if (icon.IsValid() && !item.IsBlinking()) { - pos.x = -20; - pos.y += POWERUPICONSIZE * 3 / 2; + // Each icon gets a 32x32 block. + 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); if (!ontex.IsValid()) return;