diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 71ac523d19..4a49b609e5 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -602,6 +602,7 @@ endif() # Start defining source files for ZDoom set( PLAT_WIN32_SOURCES win32/eaxedit.cpp + win32/critsec.cpp win32/fb_d3d9.cpp win32/fb_d3d9_wipe.cpp win32/fb_ddraw.cpp @@ -626,6 +627,7 @@ set( PLAT_POSIX_SOURCES posix/i_steam.cpp ) set( PLAT_SDL_SOURCES posix/sdl/crashcatcher.c + posix/sdl/critsec.cpp posix/sdl/hardware.cpp posix/sdl/i_gui.cpp posix/sdl/i_input.cpp diff --git a/src/basictypes.h b/src/basictypes.h index 3a9018b795..0e0e44cdb1 100644 --- a/src/basictypes.h +++ b/src/basictypes.h @@ -19,7 +19,7 @@ typedef int INTBOOL; #define GUID_DEFINED typedef struct _GUID { - DWORD Data1; + uint32_t Data1; uint16_t Data2; uint16_t Data3; uint8_t Data4[8]; @@ -46,7 +46,7 @@ union QWORD_UNION #define FRACUNIT (1< + +class FInternalCriticalSection +{ +public: + FInternalCriticalSection(); + ~FInternalCriticalSection(); + + void Enter(); + void Leave(); + +private: + pthread_mutex_t m_mutex; + +}; + // TODO: add error handling -FCriticalSection::FCriticalSection() +FInternalCriticalSection::FInternalCriticalSection() { pthread_mutexattr_t attributes; pthread_mutexattr_init(&attributes); @@ -46,17 +62,38 @@ FCriticalSection::FCriticalSection() pthread_mutexattr_destroy(&attributes); } -FCriticalSection::~FCriticalSection() +FInternalCriticalSection::~FInternalCriticalSection() { pthread_mutex_destroy(&m_mutex); } -void FCriticalSection::Enter() +void FInternalCriticalSection::Enter() { pthread_mutex_lock(&m_mutex); } -void FCriticalSection::Leave() +void FInternalCriticalSection::Leave() { pthread_mutex_unlock(&m_mutex); } + + +FInternalCriticalSection *CreateCriticalSection() +{ + return new FInternalCriticalSection(); +} + +void DeleteCriticalSection(FInternalCriticalSection *c) +{ + delete c; +} + +void EnterCriticalSection(FInternalCriticalSection *c) +{ + c->Enter(); +} + +void LeaveCriticalSection(FInternalCriticalSection *c) +{ + c->Leave(); +} diff --git a/src/posix/cocoa/critsec.h b/src/posix/cocoa/critsec.h deleted file mode 100644 index 7940dfe328..0000000000 --- a/src/posix/cocoa/critsec.h +++ /dev/null @@ -1,53 +0,0 @@ -/* - ** critsec.h - ** - **--------------------------------------------------------------------------- - ** Copyright 2014 Alexey Lysiuk - ** All rights reserved. - ** - ** Redistribution and use in source and binary forms, with or without - ** modification, are permitted provided that the following conditions - ** are met: - ** - ** 1. Redistributions of source code must retain the above copyright - ** notice, this list of conditions and the following disclaimer. - ** 2. Redistributions in binary form must reproduce the above copyright - ** notice, this list of conditions and the following disclaimer in the - ** documentation and/or other materials provided with the distribution. - ** 3. The name of the author may not be used to endorse or promote products - ** derived from this software without specific prior written permission. - ** - ** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR - ** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - ** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - ** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - ** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - ** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - ** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - ** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - ** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - ** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - **--------------------------------------------------------------------------- - ** - */ - -#ifndef CRITSEC_H -#define CRITSEC_H - -#include - -class FCriticalSection -{ -public: - FCriticalSection(); - ~FCriticalSection(); - - void Enter(); - void Leave(); - -private: - pthread_mutex_t m_mutex; - -}; - -#endif diff --git a/src/posix/sdl/critsec.h b/src/posix/sdl/critsec.cpp similarity index 65% rename from src/posix/sdl/critsec.h rename to src/posix/sdl/critsec.cpp index a3d6210af4..56bfef585b 100644 --- a/src/posix/sdl/critsec.h +++ b/src/posix/sdl/critsec.cpp @@ -2,17 +2,14 @@ // object similar to a mutex but optimized for access by threads belonging to // only one process, hence the class name.) -#ifndef CRITSEC_H -#define CRITSEC_H - #include "SDL.h" #include "SDL_thread.h" #include "i_system.h" -class FCriticalSection +class FInternalCriticalSection { public: - FCriticalSection() + FSDLCriticalSection() { CritSec = SDL_CreateMutex(); if (CritSec == NULL) @@ -20,7 +17,7 @@ public: I_FatalError("Failed to create a critical section mutex."); } } - ~FCriticalSection() + ~FSDLCriticalSection() { if (CritSec != NULL) { @@ -45,4 +42,22 @@ private: SDL_mutex *CritSec; }; -#endif +FInternalCriticalSection *CreateCriticalSection() +{ + return new FInternalCriticalSection(); +} + +void DeleteCriticalSection(FInternalCriticalSection *c) +{ + delete c; +} + +void EnterCriticalSection(FInternalCriticalSection *c) +{ + c->Enter(); +} + +void LeaveCriticalSection(FInternalCriticalSection *c) +{ + c->Leave(); +} diff --git a/src/sound/i_music.cpp b/src/sound/i_music.cpp index 54a78189be..9ad273eb9e 100644 --- a/src/sound/i_music.cpp +++ b/src/sound/i_music.cpp @@ -36,6 +36,7 @@ #define WIN32_LEAN_AND_MEAN #include #include +#define USE_WINDOWS_DWORD #else #include #include @@ -46,8 +47,6 @@ #include #include #include "mus2midi.h" -#define FALSE 0 -#define TRUE 1 extern void ChildSigHandler (int signum); #endif @@ -347,7 +346,7 @@ static MIDIStreamer *CreateMIDIStreamer(FileReader &reader, EMidiDevice devtype, // //========================================================================== -static EMIDIType IdentifyMIDIType(DWORD *id, int size) +static EMIDIType IdentifyMIDIType(uint32_t *id, int size) { // Check for MUS format // Tolerate sloppy wads by searching up to 32 bytes for the header @@ -400,7 +399,7 @@ MusInfo *I_RegisterSong (FileReader *reader, MidiDeviceSetting *device) { MusInfo *info = NULL; const char *fmt; - DWORD id[32/4]; + uint32_t id[32/4]; if (nomusic) { @@ -501,7 +500,7 @@ retry_as_sndsys: // Check for CDDA "format" if (id[0] == (('R')|(('I')<<8)|(('F')<<16)|(('F')<<24))) { - DWORD subid; + uint32_t subid; reader->Seek(8, SEEK_CUR); if (reader->Read (&subid, 4) != 4) @@ -628,7 +627,7 @@ static bool ungzip(uint8_t *data, int complen, TArray &newdata) } // Decompress - isize = LittleLong(*(DWORD *)(data + complen - 4)); + isize = LittleLong(*(uint32_t *)(data + complen - 4)); newdata.Resize(isize); stream.next_in = (Bytef *)compstart; diff --git a/src/sound/i_musicinterns.h b/src/sound/i_musicinterns.h index 7c66f89946..c658da61b9 100644 --- a/src/sound/i_musicinterns.h +++ b/src/sound/i_musicinterns.h @@ -1,24 +1,4 @@ -#ifdef _WIN32 -#define WIN32_LEAN_AND_MEAN -#define USE_WINDOWS_DWORD -#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0400 -#undef _WIN32_WINNT -#endif -#ifndef _WIN32_WINNT -#define _WIN32_WINNT 0x0400 -#endif -#ifndef USE_WINDOWS_DWORD -#define USE_WINDOWS_DWORD -#endif -#include -#include -#else -#define FALSE 0 -#define TRUE 1 -#endif -#ifdef __APPLE__ -#include -#endif // __APPLE__ + #include "tempfiles.h" #include "oplsynth/opl_mus_player.h" #include "c_cvars.h" @@ -105,83 +85,13 @@ public: virtual FString GetStats(); }; -// WinMM implementation of a MIDI output device ----------------------------- #ifdef _WIN32 -class WinMIDIDevice : public MIDIDevice -{ -public: - WinMIDIDevice(int dev_id); - ~WinMIDIDevice(); - int Open(MidiCallback, void *userdata); - void Close(); - bool IsOpen() const; - int GetTechnology() const; - int SetTempo(int tempo); - int SetTimeDiv(int timediv); - int StreamOut(MidiHeader *data); - int StreamOutSync(MidiHeader *data); - int Resume(); - void Stop(); - int PrepareHeader(MidiHeader *data); - int UnprepareHeader(MidiHeader *data); - bool FakeVolume(); - bool NeedThreadedCallback(); - bool Pause(bool paused); - void PrecacheInstruments(const uint16_t *instruments, int count); - -protected: - static void CALLBACK CallbackFunc(HMIDIOUT, UINT, DWORD_PTR, DWORD, DWORD); - - HMIDISTRM MidiOut; - UINT DeviceID; - DWORD SavedVolume; - MIDIHDR WinMidiHeaders[2]; - int HeaderIndex; - bool VolumeWorks; - - MidiCallback Callback; - void *CallbackData; -}; +MIDIDevice *CreateWinMIDIDevice(int mididevice); +#elif defined __APPLE__ +MIDIDevice *CreateAudioToolboxMIDIDevice(int mididevice); #endif - -// AudioToolbox implementation of a MIDI output device ---------------------- - -#ifdef __APPLE__ - -class AudioToolboxMIDIDevice : public MIDIDevice -{ -public: - virtual int Open(MidiCallback, void *userData) override; - virtual void Close() override; - virtual bool IsOpen() const override; - virtual int GetTechnology() const override; - virtual int SetTempo(int tempo) override; - virtual int SetTimeDiv(int timediv) override; - virtual int StreamOut(MidiHeader *data) override; - virtual int StreamOutSync(MidiHeader *data) override; - virtual int Resume() override; - virtual void Stop() override; - virtual int PrepareHeader(MidiHeader* data) override; - virtual bool FakeVolume() override { return true; } - virtual bool Pause(bool paused) override; - virtual bool Preprocess(MIDIStreamer *song, bool looping) override; - -private: - MusicPlayer m_player = nullptr; - MusicSequence m_sequence = nullptr; - AudioUnit m_audioUnit = nullptr; - CFRunLoopTimerRef m_timer = nullptr; - MusicTimeStamp m_length = 0; - - MidiCallback Callback; - Callback m_callback = nullptr; - void* m_userData = nullptr; - - static void TimerCallback(CFRunLoopTimerRef timer, void* info); -}; - -#endif // __APPLE__ +MIDIDevice *CreateTimidityPPMIDIDevice(const char *args); // Base class for pseudo-MIDI devices --------------------------------------- @@ -218,46 +128,6 @@ public: bool Preprocess(MIDIStreamer *song, bool looping); }; -// MIDI file played with TiMidity++ and possibly streamed through the Sound System - -class TimidityPPMIDIDevice : public PseudoMIDIDevice -{ -public: - TimidityPPMIDIDevice(const char *args); - ~TimidityPPMIDIDevice(); - - int Open(MidiCallback, void *userdata); - bool Preprocess(MIDIStreamer *song, bool looping); - bool IsOpen() const; - int Resume(); - - void Stop(); - bool IsOpen(); - void TimidityVolumeChanged(); - -protected: - bool LaunchTimidity(); - - FTempFileName DiskName; -#ifdef _WIN32 - HANDLE ReadWavePipe; - HANDLE WriteWavePipe; - HANDLE ChildProcess; - bool Validated; - bool ValidateTimidity(); -#else // _WIN32 - int WavePipe[2]; - pid_t ChildProcess; -#endif - FString CommandLine; - size_t LoopPos; - - static bool FillStream(SoundStream *stream, void *buff, int len, void *userdata); -#ifdef _WIN32 - static const char EventName[]; -#endif -}; - // Base class for software synthesizer MIDI output devices ------------------ class SoftSynthMIDIDevice : public MIDIDevice @@ -286,7 +156,7 @@ protected: double NextTickIn; MidiHeader *Events; bool Started; - DWORD Position; + uint32_t Position; int SampleRate; MidiCallback Callback; @@ -491,10 +361,11 @@ public: protected: MIDIStreamer(const char *dumpname, EMidiDevice type); - void OutputVolume (DWORD volume); - int FillBuffer(int buffer_num, int max_events, DWORD max_time); + bool CheckExitEvent(); + void OutputVolume (uint32_t volume); + int FillBuffer(int buffer_num, int max_events, uint32_t max_time); int FillStopBuffer(int buffer_num); - DWORD *WriteStopNotes(DWORD *events); + uint32_t *WriteStopNotes(uint32_t *events); int ServiceEvent(); int VolumeControllerChange(int channel, int volume); int ClampLoopCount(int loopcount); @@ -512,7 +383,7 @@ protected: virtual bool CheckDone() = 0; virtual void Precache(); virtual bool SetMIDISubsong(int subsong); - virtual DWORD *MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) = 0; + virtual uint32_t *MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time) = 0; enum { @@ -526,29 +397,20 @@ protected: SONG_ERROR }; -#ifdef _WIN32 - static DWORD WINAPI PlayerProc (LPVOID lpParameter); - DWORD PlayerLoop(); - - HANDLE PlayerThread; - HANDLE ExitEvent; - HANDLE BufferDoneEvent; -#endif - MIDIDevice *MIDI; - DWORD Events[2][MAX_EVENTS*3]; + uint32_t Events[2][MAX_EVENTS*3]; MidiHeader Buffer[2]; int BufferNum; int EndQueued; bool VolumeChanged; bool Restarting; bool InitialPlayback; - DWORD NewVolume; + uint32_t NewVolume; int Division; int Tempo; int InitialTempo; uint8_t ChannelVolumes[16]; - DWORD Volume; + uint32_t Volume; EMidiDevice DeviceType; bool CallbackIsThreaded; int LoopLimit; @@ -574,7 +436,7 @@ protected: void DoRestart(); bool CheckDone(); void Precache(); - DWORD *MakeEvents(DWORD *events, DWORD *max_events_p, DWORD max_time); + uint32_t *MakeEvents(uint32_t *events, uint32_t *max_events_p, uint32_t max_time); MUSHeader *MusHeader; uint8_t *MusBuffer; @@ -600,13 +462,13 @@ protected: void DoInitialSetup(); void DoRestart(); bool CheckDone(); - DWORD *MakeEvents(DWORD *events, DWORD *max_events_p, DWORD max_time); - void AdvanceTracks(DWORD time); + uint32_t *MakeEvents(uint32_t *events, uint32_t *max_events_p, uint32_t max_time); + void AdvanceTracks(uint32_t time); struct TrackInfo; void ProcessInitialMetaEvents (); - DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom); + uint32_t *SendCommand (uint32_t *event, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom); TrackInfo *FindNextDue (); uint8_t *MusHeader; @@ -622,15 +484,15 @@ protected: struct AutoNoteOff { - DWORD Delay; + uint32_t Delay; uint8_t Channel, Key; }; // Sorry, std::priority_queue, but I want to be able to modify the contents of the heap. class NoteOffQueue : public TArray { public: - void AddNoteOff(DWORD delay, uint8_t channel, uint8_t key); - void AdvanceTime(DWORD time); + void AddNoteOff(uint32_t delay, uint8_t channel, uint8_t key); + void AdvanceTime(uint32_t time); bool Pop(AutoNoteOff &item); protected: @@ -660,17 +522,17 @@ protected: void DoInitialSetup(); void DoRestart(); bool CheckDone(); - DWORD *MakeEvents(DWORD *events, DWORD *max_events_p, DWORD max_time); - void AdvanceTracks(DWORD time); + uint32_t *MakeEvents(uint32_t *events, uint32_t *max_events_p, uint32_t max_time); + void AdvanceTracks(uint32_t time); struct TrackInfo; void ProcessInitialMetaEvents (); - DWORD *SendCommand (DWORD *event, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom); + uint32_t *SendCommand (uint32_t *event, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom); TrackInfo *FindNextDue (); - static DWORD ReadVarLenHMI(TrackInfo *); - static DWORD ReadVarLenHMP(TrackInfo *); + static uint32_t ReadVarLenHMI(TrackInfo *); + static uint32_t ReadVarLenHMP(TrackInfo *); uint8_t *MusHeader; int SongLen; @@ -678,7 +540,7 @@ protected: TrackInfo *Tracks; TrackInfo *TrackDue; TrackInfo *FakeTrack; - DWORD (*ReadVarLen)(TrackInfo *); + uint32_t (*ReadVarLen)(TrackInfo *); NoteOffQueue NoteOffs; }; @@ -705,11 +567,11 @@ protected: void DoInitialSetup(); void DoRestart(); bool CheckDone(); - DWORD *MakeEvents(DWORD *events, DWORD *max_events_p, DWORD max_time); - void AdvanceSong(DWORD time); + uint32_t *MakeEvents(uint32_t *events, uint32_t *max_events_p, uint32_t max_time); + void AdvanceSong(uint32_t time); void ProcessInitialMetaEvents(); - DWORD *SendCommand (DWORD *event, EventSource track, DWORD delay, ptrdiff_t room, bool &sysex_noroom); + uint32_t *SendCommand (uint32_t *event, EventSource track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom); EventSource FindNextDue(); uint8_t *MusHeader; diff --git a/src/sound/i_sound.cpp b/src/sound/i_sound.cpp index bd43f4f192..672ada6385 100644 --- a/src/sound/i_sound.cpp +++ b/src/sound/i_sound.cpp @@ -40,9 +40,6 @@ extern HWND Window; extern HINSTANCE g_hInst; #define USE_WINDOWS_DWORD -#else -#define FALSE 0 -#define TRUE 1 #endif #include diff --git a/src/sound/music_audiotoolbox_mididevice.cpp b/src/sound/music_audiotoolbox_mididevice.cpp index 8ee9b66f80..979aeaff54 100644 --- a/src/sound/music_audiotoolbox_mididevice.cpp +++ b/src/sound/music_audiotoolbox_mididevice.cpp @@ -25,9 +25,46 @@ #ifdef __APPLE__ +#include #include "i_musicinterns.h" #include "templates.h" +// AudioToolbox implementation of a MIDI output device ---------------------- + +class AudioToolboxMIDIDevice : public MIDIDevice +{ +public: + virtual int Open(MidiCallback, void *userData) override; + virtual void Close() override; + virtual bool IsOpen() const override; + virtual int GetTechnology() const override; + virtual int SetTempo(int tempo) override; + virtual int SetTimeDiv(int timediv) override; + virtual int StreamOut(MidiHeader *data) override; + virtual int StreamOutSync(MidiHeader *data) override; + virtual int Resume() override; + virtual void Stop() override; + virtual int PrepareHeader(MidiHeader* data) override; + virtual bool FakeVolume() override { return true; } + virtual bool Pause(bool paused) override; + virtual bool Preprocess(MIDIStreamer *song, bool looping) override; + +private: + MusicPlayer m_player = nullptr; + MusicSequence m_sequence = nullptr; + AudioUnit m_audioUnit = nullptr; + CFRunLoopTimerRef m_timer = nullptr; + MusicTimeStamp m_length = 0; + + MidiCallback Callback; + Callback m_callback = nullptr; + void* m_userData = nullptr; + + static void TimerCallback(CFRunLoopTimerRef timer, void* info); +}; + + + #define AT_MIDI_CHECK_ERROR(CALL,...) \ { \ const OSStatus result = CALL; \ @@ -289,4 +326,9 @@ void AudioToolboxMIDIDevice::TimerCallback(CFRunLoopTimerRef timer, void* info) #undef AT_MIDI_CHECK_ERROR +MIDIDevice *CreateAudioToolboxMIDTDevice(int mididevice) +{ + return new AudioToolboxMIDIDevice(mididevice); +} + #endif // __APPLE__ diff --git a/src/sound/music_dumb.cpp b/src/sound/music_dumb.cpp index eccd5f7ff0..998dcdc56d 100644 --- a/src/sound/music_dumb.cpp +++ b/src/sound/music_dumb.cpp @@ -908,7 +908,7 @@ MusInfo *MOD_OpenSong(FileReader &reader) // safe. We'll restrict MOD loading to 31-instrument modules with known // signatures and let the sound system worry about 15-instrument ones. // (Assuming it even supports them) - duh = dumb_read_mod_quick(f, TRUE); + duh = dumb_read_mod_quick(f, true); } if (f != NULL) diff --git a/src/sound/music_fluidsynth_mididevice.cpp b/src/sound/music_fluidsynth_mididevice.cpp index 087a0ce3d3..551c0a10c3 100644 --- a/src/sound/music_fluidsynth_mididevice.cpp +++ b/src/sound/music_fluidsynth_mididevice.cpp @@ -35,6 +35,7 @@ #ifdef HAVE_FLUIDSYNTH // HEADER FILES ------------------------------------------------------------ +#include "i_midi_win32.h" #include "i_musicinterns.h" #include "templates.h" @@ -317,7 +318,7 @@ FluidSynthMIDIDevice::FluidSynthMIDIDevice(const char *args) #ifdef _WIN32 // On Windows, look for the 4 megabyte patch set installed by Creative's drivers as a default. char sysdir[MAX_PATH+sizeof("\\CT4MGM.SF2")]; - UINT filepart; + uint32_t filepart; if (0 != (filepart = GetSystemDirectoryA(sysdir, MAX_PATH))) { strcat(sysdir, "\\CT4MGM.SF2"); diff --git a/src/sound/music_hmi_midiout.cpp b/src/sound/music_hmi_midiout.cpp index cc0df0c8fd..c0dfa3bf7d 100644 --- a/src/sound/music_hmi_midiout.cpp +++ b/src/sound/music_hmi_midiout.cpp @@ -92,15 +92,15 @@ struct HMISong::TrackInfo const uint8_t *TrackBegin; size_t TrackP; size_t MaxTrackP; - DWORD Delay; - DWORD PlayedTime; + uint32_t Delay; + uint32_t PlayedTime; uint16_t Designation[NUM_HMI_DESIGNATIONS]; bool Enabled; bool Finished; uint8_t RunningStatus; - DWORD ReadVarLenHMI(); - DWORD ReadVarLenHMP(); + uint32_t ReadVarLenHMI(); + uint32_t ReadVarLenHMP(); }; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -131,12 +131,10 @@ extern char MIDI_CommonLengths[15]; HMISong::HMISong (FileReader &reader, EMidiDevice type, const char *args) : MIDIStreamer(type, args), MusHeader(0), Tracks(0) { -#ifdef _WIN32 - if (ExitEvent == NULL) + if (!CheckExitEvent()) { return; } -#endif int len = reader.GetLength(); if (len < 0x100) { // Way too small to be HMI. @@ -153,8 +151,8 @@ HMISong::HMISong (FileReader &reader, EMidiDevice type, const char *args) { SetupForHMI(len); } - else if (((DWORD *)MusHeader)[0] == MAKE_ID('H','M','I','M') && - ((DWORD *)MusHeader)[1] == MAKE_ID('I','D','I','P')) + else if (((uint32_t *)MusHeader)[0] == MAKE_ID('H','M','I','M') && + ((uint32_t *)MusHeader)[1] == MAKE_ID('I','D','I','P')) { SetupForHMP(len); } @@ -499,12 +497,12 @@ bool HMISong::CheckDone() // //========================================================================== -DWORD *HMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) +uint32_t *HMISong::MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time) { - DWORD *start_events; - DWORD tot_time = 0; - DWORD time = 0; - DWORD delay; + uint32_t *start_events; + uint32_t tot_time = 0; + uint32_t time = 0; + uint32_t delay; start_events = events; while (TrackDue && events < max_event_p && tot_time <= max_time) @@ -524,7 +522,7 @@ DWORD *HMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) do { bool sysex_noroom = false; - DWORD *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom); + uint32_t *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom); if (sysex_noroom) { return events; @@ -552,7 +550,7 @@ DWORD *HMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) // //========================================================================== -void HMISong::AdvanceTracks(DWORD time) +void HMISong::AdvanceTracks(uint32_t time) { for (int i = 0; i <= NumTracks; ++i) { @@ -573,9 +571,9 @@ void HMISong::AdvanceTracks(DWORD time) // //========================================================================== -DWORD *HMISong::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom) +uint32_t *HMISong::SendCommand (uint32_t *events, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom) { - DWORD len; + uint32_t len; uint8_t event, data1 = 0, data2 = 0; // If the next event comes from the fake track, pop an entry off the note-off queue. @@ -783,7 +781,7 @@ void HMISong::ProcessInitialMetaEvents () TrackInfo *track; int i; uint8_t event; - DWORD len; + uint32_t len; for (i = 0; i < NumTracks; ++i) { @@ -828,7 +826,7 @@ void HMISong::ProcessInitialMetaEvents () // //========================================================================== -DWORD HMISong::ReadVarLenHMI(TrackInfo *track) +uint32_t HMISong::ReadVarLenHMI(TrackInfo *track) { return track->ReadVarLenHMI(); } @@ -839,7 +837,7 @@ DWORD HMISong::ReadVarLenHMI(TrackInfo *track) // //========================================================================== -DWORD HMISong::ReadVarLenHMP(TrackInfo *track) +uint32_t HMISong::ReadVarLenHMP(TrackInfo *track) { return track->ReadVarLenHMP(); } @@ -852,9 +850,9 @@ DWORD HMISong::ReadVarLenHMP(TrackInfo *track) // //========================================================================== -DWORD HMISong::TrackInfo::ReadVarLenHMI() +uint32_t HMISong::TrackInfo::ReadVarLenHMI() { - DWORD time = 0, t = 0x80; + uint32_t time = 0, t = 0x80; while ((t & 0x80) && TrackP < MaxTrackP) { @@ -874,9 +872,9 @@ DWORD HMISong::TrackInfo::ReadVarLenHMI() // //========================================================================== -DWORD HMISong::TrackInfo::ReadVarLenHMP() +uint32_t HMISong::TrackInfo::ReadVarLenHMP() { - DWORD time = 0; + uint32_t time = 0; uint8_t t = 0; int off = 0; @@ -895,7 +893,7 @@ DWORD HMISong::TrackInfo::ReadVarLenHMP() // //========================================================================== -void NoteOffQueue::AddNoteOff(DWORD delay, uint8_t channel, uint8_t key) +void NoteOffQueue::AddNoteOff(uint32_t delay, uint8_t channel, uint8_t key) { unsigned int i = Reserve(1); while (i > 0 && (*this)[Parent(i)].Delay > delay) @@ -931,7 +929,7 @@ bool NoteOffQueue::Pop(AutoNoteOff &item) // //========================================================================== -void NoteOffQueue::AdvanceTime(DWORD time) +void NoteOffQueue::AdvanceTime(uint32_t time) { // Because the time is decreasing by the same amount for every entry, // the heap property is maintained. @@ -985,7 +983,7 @@ void NoteOffQueue::Heapify() HMISong::TrackInfo *HMISong::FindNextDue () { TrackInfo *track; - DWORD best; + uint32_t best; int i; // Give precedence to whichever track last had events taken from it. diff --git a/src/sound/music_midi_base.cpp b/src/sound/music_midi_base.cpp index 01915b8eda..9391ed9129 100644 --- a/src/sound/music_midi_base.cpp +++ b/src/sound/music_midi_base.cpp @@ -1,3 +1,6 @@ +#include "i_midi_win32.h" + + #include "i_musicinterns.h" #include "c_dispatch.h" #include "i_music.h" @@ -65,7 +68,7 @@ static void MIDIDeviceChanged(int newdev) } #ifdef _WIN32 -UINT mididevice; +unsigned mididevice; CUSTOM_CVAR (Int, snd_mididevice, -1, CVAR_ARCHIVE|CVAR_GLOBALCONFIG) { diff --git a/src/sound/music_midi_timidity.cpp b/src/sound/music_midi_timidity.cpp index c3fbe31b19..a45a1f501b 100644 --- a/src/sound/music_midi_timidity.cpp +++ b/src/sound/music_midi_timidity.cpp @@ -1,3 +1,6 @@ +#include "i_midi_win32.h" + + #include "i_musicinterns.h" #include "c_cvars.h" #include "cmdlib.h" @@ -20,6 +23,46 @@ void ChildSigHandler (int signum) } #endif +class TimidityPPMIDIDevice : public PseudoMIDIDevice +{ +public: + TimidityPPMIDIDevice(const char *args); + ~TimidityPPMIDIDevice(); + + int Open(MidiCallback, void *userdata); + bool Preprocess(MIDIStreamer *song, bool looping); + bool IsOpen() const; + int Resume(); + + void Stop(); + bool IsOpen(); + void TimidityVolumeChanged(); + +protected: + bool LaunchTimidity(); + + FTempFileName DiskName; +#ifdef _WIN32 + HANDLE ReadWavePipe; + HANDLE WriteWavePipe; + HANDLE ChildProcess; + bool Validated; + bool ValidateTimidity(); +#else // _WIN32 + int WavePipe[2]; + pid_t ChildProcess; +#endif + FString CommandLine; + size_t LoopPos; + + static bool FillStream(SoundStream *stream, void *buff, int len, void *userdata); +#ifdef _WIN32 + static const char EventName[]; +#endif +}; + + + #ifdef _WIN32 @@ -183,7 +226,7 @@ int TimidityPPMIDIDevice::Open(MidiCallback callback, void *userdata) int pipeSize; #ifdef _WIN32 - static SECURITY_ATTRIBUTES inheritable = { sizeof(inheritable), NULL, TRUE }; + static SECURITY_ATTRIBUTES inheritable = { sizeof(inheritable), NULL, true }; if (!Validated && !ValidateTimidity ()) { @@ -392,7 +435,7 @@ bool TimidityPPMIDIDevice::LaunchTimidity () startup.lpTitle = TimidityTitle; startup.wShowWindow = SW_SHOWMINNOACTIVE; - if (CreateProcess(NULL, CommandLine.LockBuffer(), NULL, NULL, TRUE, + if (CreateProcess(NULL, CommandLine.LockBuffer(), NULL, NULL, true, DETACHED_PROCESS, NULL, NULL, &startup, &procInfo)) { ChildProcess = procInfo.hProcess; @@ -728,3 +771,9 @@ BOOL SafeTerminateProcess(HANDLE hProcess, UINT uExitCode) return bSuccess; } #endif + + +MIDIDevice *CreateTimidityPPMIDIDevice(const char *args) +{ + return new TimidityPPMIDIDevice(args); +} diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index f6895faaaa..e75fe08444 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -34,6 +34,18 @@ // HEADER FILES ------------------------------------------------------------ + +#include "i_midi_win32.h" +/* +#ifdef _WIN32 +DWORD PlayerLoop(); + +HANDLE PlayerThread; +HANDLE ExitEvent; +HANDLE BufferDoneEvent; +#endif +*/ + #include "i_musicinterns.h" #include "templates.h" #include "doomdef.h" @@ -61,7 +73,9 @@ EXTERN_CVAR(Float, snd_musicvolume) EXTERN_CVAR(Int, snd_mididevice) #ifdef _WIN32 -extern UINT mididevice; +DWORD WINAPI PlayerProc(LPVOID lpParameter); + +extern unsigned mididevice; #endif extern char MIDI_EventLengths[7]; @@ -92,11 +106,12 @@ static const uint8_t StaticMIDIhead[] = MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args) : #ifdef _WIN32 - PlayerThread(0), ExitEvent(0), BufferDoneEvent(0), + //PlayerThread(0), ExitEvent(0), BufferDoneEvent(0), #endif MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), Args(args) { memset(Buffer, 0, sizeof(Buffer)); + /* #ifdef _WIN32 BufferDoneEvent = CreateEvent(NULL, FALSE, FALSE, NULL); if (BufferDoneEvent == NULL) @@ -110,6 +125,7 @@ MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args) return; } #endif +*/ } //========================================================================== @@ -121,15 +137,17 @@ MIDIStreamer::MIDIStreamer(EMidiDevice type, const char *args) MIDIStreamer::MIDIStreamer(const char *dumpname, EMidiDevice type) : #ifdef _WIN32 - PlayerThread(0), ExitEvent(0), BufferDoneEvent(0), + //PlayerThread(0), ExitEvent(0), BufferDoneEvent(0), #endif MIDI(0), Division(0), InitialTempo(500000), DeviceType(type), DumpFilename(dumpname) { memset(Buffer, 0, sizeof(Buffer)); + /* #ifdef _WIN32 BufferDoneEvent = NULL; ExitEvent = NULL; #endif +*/ } //========================================================================== @@ -141,6 +159,7 @@ MIDIStreamer::MIDIStreamer(const char *dumpname, EMidiDevice type) MIDIStreamer::~MIDIStreamer() { Stop(); + /* #ifdef _WIN32 if (ExitEvent != NULL) { @@ -151,6 +170,7 @@ MIDIStreamer::~MIDIStreamer() CloseHandle(BufferDoneEvent); } #endif +*/ if (MIDI != NULL) { delete MIDI; @@ -179,7 +199,7 @@ bool MIDIStreamer::IsMIDI() const bool MIDIStreamer::IsValid() const { #ifdef _WIN32 - return ExitEvent != NULL && Division != 0; + return /*ExitEvent != NULL &&*/ Division != 0; #else return Division != 0; #endif @@ -264,7 +284,7 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype) const { case MDEV_MMAPI: #ifdef _WIN32 - return new WinMIDIDevice(mididevice); + return CreateWinMIDIDevice(mididevice); #endif assert(0); // Intentional fall-through for non-Windows systems. @@ -289,11 +309,11 @@ MIDIDevice *MIDIStreamer::CreateMIDIDevice(EMidiDevice devtype) const { // The creation of an OPL MIDI device can abort with an error if no GENMIDI lump can be found. Printf("Unable to create OPL MIDI device: %s\nFalling back to Sound System playback", err.GetMessage()); - return new SndSysMIDIDevice; + return GSnd->CreateMIDIDevice(); } case MDEV_TIMIDITY: - return new TimidityPPMIDIDevice(Args); + return CreateTimidityPPMIDIDevice(Args); case MDEV_WILDMIDI: return new WildMIDIDevice(Args); @@ -373,6 +393,7 @@ void MIDIStreamer::Play(bool looping, int subsong) } else { + /* #ifdef _WIN32 if (MIDI->NeedThreadedCallback()) { @@ -389,6 +410,7 @@ void MIDIStreamer::Play(bool looping, int subsong) } else #endif +*/ { m_Status = STATE_Playing; } @@ -418,10 +440,12 @@ void MIDIStreamer::StartPlayback() MusicVolumeChanged(); // set volume to current music's properties OutputVolume(Volume); + /* #ifdef _WIN32 ResetEvent(ExitEvent); ResetEvent(BufferDoneEvent); #endif +*/ // Fill the initial buffers for the song. BufferNum = 0; @@ -507,6 +531,8 @@ void MIDIStreamer::Resume() void MIDIStreamer::Stop() { EndQueued = 4; + + /* #ifdef _WIN32 if (PlayerThread != NULL) { @@ -516,6 +542,7 @@ void MIDIStreamer::Stop() PlayerThread = NULL; } #endif +*/ if (MIDI != NULL && MIDI->IsOpen()) { MIDI->Stop(); @@ -656,7 +683,7 @@ void MIDIStreamer::WildMidiSetOption(int opt, int set) // //========================================================================== -void MIDIStreamer::OutputVolume (DWORD volume) +void MIDIStreamer::OutputVolume (uint32_t volume) { if (MIDI != NULL && MIDI->FakeVolume()) { @@ -701,6 +728,7 @@ void MIDIStreamer::Callback(void *userdata) { return; } + /* #ifdef _WIN32 if (self->PlayerThread != NULL) { @@ -708,6 +736,7 @@ void MIDIStreamer::Callback(void *userdata) } else #endif +*/ { self->ServiceEvent(); } @@ -724,6 +753,7 @@ void MIDIStreamer::Callback(void *userdata) void MIDIStreamer::Update() { + /* #ifdef _WIN32 // If the PlayerThread is signalled, then it's dead. if (PlayerThread != NULL && @@ -785,6 +815,7 @@ void MIDIStreamer::Update() Stop(); } #endif +*/ } //========================================================================== @@ -796,9 +827,10 @@ void MIDIStreamer::Update() //========================================================================== #ifdef _WIN32 -DWORD WINAPI MIDIStreamer::PlayerProc (LPVOID lpParameter) +DWORD WINAPI PlayerProc(LPVOID lpParameter) { - return ((MIDIStreamer *)lpParameter)->PlayerLoop(); +// return ((MIDIStreamer *)lpParameter)->PlayerLoop(); + return 0; } #endif @@ -809,6 +841,7 @@ DWORD WINAPI MIDIStreamer::PlayerProc (LPVOID lpParameter) // Services MIDI playback events. // //========================================================================== +/* #ifdef _WIN32 DWORD MIDIStreamer::PlayerLoop() @@ -837,8 +870,10 @@ DWORD MIDIStreamer::PlayerLoop() return MMSYSERR_ERROR; } } + return 0; } #endif +*/ //========================================================================== // @@ -920,7 +955,7 @@ fill: // //========================================================================== -int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time) +int MIDIStreamer::FillBuffer(int buffer_num, int max_events, uint32_t max_time) { if (!Restarting && CheckDone()) { @@ -928,9 +963,9 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time) } int i; - DWORD *events = Events[buffer_num], *max_event_p; - DWORD tot_time = 0; - DWORD time = 0; + uint32_t *events = Events[buffer_num], *max_event_p; + uint32_t tot_time = 0; + uint32_t time = 0; // The final event is for a NOP to hold the delay from the last event. max_event_p = events + (max_events - 1) * 3; @@ -1009,7 +1044,7 @@ int MIDIStreamer::FillBuffer(int buffer_num, int max_events, DWORD max_time) int MIDIStreamer::FillStopBuffer(int buffer_num) { - DWORD *events = Events[buffer_num]; + uint32_t *events = Events[buffer_num]; int i; events = WriteStopNotes(events); @@ -1040,7 +1075,7 @@ int MIDIStreamer::FillStopBuffer(int buffer_num) // //========================================================================== -DWORD *MIDIStreamer::WriteStopNotes(DWORD *events) +uint32_t *MIDIStreamer::WriteStopNotes(uint32_t *events) { for (int i = 0; i < 16; ++i) { @@ -1080,8 +1115,8 @@ void MIDIStreamer::Precache() // Simulate playback to pick out used instruments. while (!CheckDone()) { - DWORD *event_end = MakeEvents(Events[0], &Events[0][MAX_EVENTS*3], 1000000*600); - for (DWORD *event = Events[0]; event < event_end; ) + uint32_t *event_end = MakeEvents(Events[0], &Events[0][MAX_EVENTS*3], 1000000*600); + for (uint32_t *event = Events[0]; event < event_end; ) { if (MEVENT_EVENTTYPE(event[2]) == 0) { @@ -1187,15 +1222,15 @@ void MIDIStreamer::CreateSMF(TArray &file, int looplimit) while (!CheckDone()) { - DWORD *event_end = MakeEvents(Events[0], &Events[0][MAX_EVENTS*3], 1000000*600); - for (DWORD *event = Events[0]; event < event_end; ) + uint32_t *event_end = MakeEvents(Events[0], &Events[0][MAX_EVENTS*3], 1000000*600); + for (uint32_t *event = Events[0]; event < event_end; ) { delay += event[0]; if (MEVENT_EVENTTYPE(event[2]) == MEVENT_TEMPO) { WriteVarLen(file, delay); delay = 0; - DWORD tempo = MEVENT_EVENTPARM(event[2]); + uint32_t tempo = MEVENT_EVENTPARM(event[2]); file.Push(MIDI_META); file.Push(MIDI_META_TEMPO); file.Push(3); @@ -1208,7 +1243,7 @@ void MIDIStreamer::CreateSMF(TArray &file, int looplimit) { WriteVarLen(file, delay); delay = 0; - DWORD len = MEVENT_EVENTPARM(event[2]); + uint32_t len = MEVENT_EVENTPARM(event[2]); uint8_t *bytes = (uint8_t *)&event[3]; if (bytes[0] == MIDI_SYSEX) { @@ -1398,6 +1433,27 @@ bool MIDIStreamer::SetMIDISubsong(int subsong) return subsong == 0; } +//========================================================================== +// +// MIDIStreamer :: CheckExitEvent +// +// +// +//========================================================================== + +bool MIDIStreamer::CheckExitEvent() +{ + /* +#ifdef _WIN32 + if (ExitEvent == NULL) + { + return false; + } +#endif +*/ + return true; +} + //========================================================================== // // MIDIDevice stubs. diff --git a/src/sound/music_mus_midiout.cpp b/src/sound/music_mus_midiout.cpp index a01c89593f..bf12702529 100644 --- a/src/sound/music_mus_midiout.cpp +++ b/src/sound/music_mus_midiout.cpp @@ -96,12 +96,10 @@ static const uint8_t CtrlTranslate[15] = MUSSong2::MUSSong2 (FileReader &reader, EMidiDevice type, const char *args) : MIDIStreamer(type, args), MusHeader(0), MusBuffer(0) { -#ifdef _WIN32 - if (ExitEvent == NULL) + if (!CheckExitEvent()) { return; } -#endif uint8_t front[32]; int start; @@ -260,10 +258,10 @@ void MUSSong2::Precache() // //========================================================================== -DWORD *MUSSong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) +uint32_t *MUSSong2::MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time) { - DWORD tot_time = 0; - DWORD time = 0; + uint32_t tot_time = 0; + uint32_t time = 0; max_time = max_time * Division / Tempo; diff --git a/src/sound/music_smf_midiout.cpp b/src/sound/music_smf_midiout.cpp index d1317e60be..39555dcb4b 100644 --- a/src/sound/music_smf_midiout.cpp +++ b/src/sound/music_smf_midiout.cpp @@ -60,8 +60,8 @@ struct MIDISong2::TrackInfo const uint8_t *TrackBegin; size_t TrackP; size_t MaxTrackP; - DWORD Delay; - DWORD PlayedTime; + uint32_t Delay; + uint32_t PlayedTime; bool Finished; uint8_t RunningStatus; bool Designated; @@ -70,11 +70,11 @@ struct MIDISong2::TrackInfo uint16_t Designation; size_t LoopBegin; - DWORD LoopDelay; + uint32_t LoopDelay; int LoopCount; bool LoopFinished; - DWORD ReadVarLen (); + uint32_t ReadVarLen (); }; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -108,12 +108,10 @@ MIDISong2::MIDISong2 (FileReader &reader, EMidiDevice type, const char *args) int p; int i; -#ifdef _WIN32 - if (ExitEvent == NULL) + if (!CheckExitEvent()) { return; } -#endif SongLen = reader.GetLength(); MusHeader = new uint8_t[SongLen]; if (reader.Read(MusHeader, SongLen) != SongLen) @@ -149,13 +147,13 @@ MIDISong2::MIDISong2 (FileReader &reader, EMidiDevice type, const char *args) // Gather information about each track for (i = 0, p = 14; i < NumTracks && p < SongLen + 8; ++i) { - DWORD chunkLen = + uint32_t chunkLen = (MusHeader[p+4]<<24) | (MusHeader[p+5]<<16) | (MusHeader[p+6]<<8) | (MusHeader[p+7]); - if (chunkLen + p + 8 > (DWORD)SongLen) + if (chunkLen + p + 8 > (uint32_t)SongLen) { // Track too long, so truncate it chunkLen = SongLen - p - 8; } @@ -298,12 +296,12 @@ bool MIDISong2::CheckDone() // //========================================================================== -DWORD *MIDISong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) +uint32_t *MIDISong2::MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time) { - DWORD *start_events; - DWORD tot_time = 0; - DWORD time = 0; - DWORD delay; + uint32_t *start_events; + uint32_t tot_time = 0; + uint32_t time = 0; + uint32_t delay; start_events = events; while (TrackDue && events < max_event_p && tot_time <= max_time) @@ -323,7 +321,7 @@ DWORD *MIDISong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) do { bool sysex_noroom = false; - DWORD *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom); + uint32_t *new_events = SendCommand(events, TrackDue, time, max_event_p - events, sysex_noroom); if (sysex_noroom) { return events; @@ -351,7 +349,7 @@ DWORD *MIDISong2::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) // //========================================================================== -void MIDISong2::AdvanceTracks(DWORD time) +void MIDISong2::AdvanceTracks(uint32_t time) { for (int i = 0; i < NumTracks; ++i) { @@ -371,9 +369,9 @@ void MIDISong2::AdvanceTracks(DWORD time) // //========================================================================== -DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptrdiff_t room, bool &sysex_noroom) +uint32_t *MIDISong2::SendCommand (uint32_t *events, TrackInfo *track, uint32_t delay, ptrdiff_t room, bool &sysex_noroom) { - DWORD len; + uint32_t len; uint8_t event, data1 = 0, data2 = 0; int i; @@ -456,7 +454,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr case 110: // EMIDI Track Designation - InitBeat only // Instruments 4, 5, 6, and 7 are all FM synth. // The rest are all wavetable. - if (track->PlayedTime < (DWORD)Division) + if (track->PlayedTime < (uint32_t)Division) { if (data2 == 127) { @@ -473,7 +471,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr break; case 111: // EMIDI Track Exclusion - InitBeat only - if (track->PlayedTime < (DWORD)Division) + if (track->PlayedTime < (uint32_t)Division) { if (track->Designated && data2 <= 9) { @@ -485,7 +483,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr case 112: // EMIDI Program Change // Ignored unless it also appears in the InitBeat - if (track->PlayedTime < (DWORD)Division || track->EProgramChange) + if (track->PlayedTime < (uint32_t)Division || track->EProgramChange) { track->EProgramChange = true; event = 0xC0 | (event & 0x0F); @@ -496,7 +494,7 @@ DWORD *MIDISong2::SendCommand (DWORD *events, TrackInfo *track, DWORD delay, ptr case 113: // EMIDI Volume // Ignored unless it also appears in the InitBeat - if (track->PlayedTime < (DWORD)Division || track->EVolume) + if (track->PlayedTime < (uint32_t)Division || track->EVolume) { track->EVolume = true; data1 = 7; @@ -700,7 +698,7 @@ void MIDISong2::ProcessInitialMetaEvents () TrackInfo *track; int i; uint8_t event; - DWORD len; + uint32_t len; for (i = 0; i < NumTracks; ++i) { @@ -747,9 +745,9 @@ void MIDISong2::ProcessInitialMetaEvents () // //========================================================================== -DWORD MIDISong2::TrackInfo::ReadVarLen () +uint32_t MIDISong2::TrackInfo::ReadVarLen () { - DWORD time = 0, t = 0x80; + uint32_t time = 0, t = 0x80; while ((t & 0x80) && TrackP < MaxTrackP) { @@ -771,7 +769,7 @@ DWORD MIDISong2::TrackInfo::ReadVarLen () MIDISong2::TrackInfo *MIDISong2::FindNextDue () { TrackInfo *track; - DWORD best; + uint32_t best; int i; // Give precedence to whichever track last had events taken from it. diff --git a/src/sound/music_timidity_mididevice.cpp b/src/sound/music_timidity_mididevice.cpp index afc570ae1f..3d5fb1622d 100644 --- a/src/sound/music_timidity_mididevice.cpp +++ b/src/sound/music_timidity_mididevice.cpp @@ -34,6 +34,8 @@ // HEADER FILES ------------------------------------------------------------ +#include "i_midi_win32.h" + #include "i_musicinterns.h" #include "templates.h" #include "doomdef.h" @@ -46,21 +48,22 @@ // MACROS ------------------------------------------------------------------ // TYPES ------------------------------------------------------------------- +// MIDI file played with TiMidity++ and possibly streamed through the Sound System struct FmtChunk { - DWORD ChunkID; - DWORD ChunkLen; + uint32_t ChunkID; + uint32_t ChunkLen; uint16_t FormatTag; uint16_t Channels; - DWORD SamplesPerSec; - DWORD AvgBytesPerSec; + uint32_t SamplesPerSec; + uint32_t AvgBytesPerSec; uint16_t BlockAlign; uint16_t BitsPerSample; uint16_t ExtensionSize; uint16_t ValidBitsPerSample; - DWORD ChannelMask; - DWORD SubFormatA; + uint32_t ChannelMask; + uint32_t SubFormatA; uint16_t SubFormatB; uint16_t SubFormatC; uint8_t SubFormatD[8]; @@ -250,7 +253,7 @@ TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename, File = fopen(filename, "wb"); if (File != NULL) { // Write wave header - DWORD work[3]; + uint32_t work[3]; FmtChunk fmt; work[0] = MAKE_ID('R','I','F','F'); @@ -259,7 +262,7 @@ TimidityWaveWriterMIDIDevice::TimidityWaveWriterMIDIDevice(const char *filename, if (3 != fwrite(work, 4, 3, File)) goto fail; fmt.ChunkID = MAKE_ID('f','m','t',' '); - fmt.ChunkLen = LittleLong(DWORD(sizeof(fmt) - 8)); + fmt.ChunkLen = LittleLong(uint32_t(sizeof(fmt) - 8)); fmt.FormatTag = LittleShort(0xFFFE); // WAVE_FORMAT_EXTENSIBLE fmt.Channels = LittleShort(2); fmt.SamplesPerSec = LittleLong((int)Renderer->rate); @@ -305,15 +308,15 @@ TimidityWaveWriterMIDIDevice::~TimidityWaveWriterMIDIDevice() if (File != NULL) { long pos = ftell(File); - DWORD size; + uint32_t size; // data chunk size - size = LittleLong(DWORD(pos - 8)); + size = LittleLong(uint32_t(pos - 8)); if (0 == fseek(File, 4, SEEK_SET)) { if (1 == fwrite(&size, 4, 1, File)) { - size = LittleLong(DWORD(pos - 12 - sizeof(FmtChunk) - 8)); + size = LittleLong(uint32_t(pos - 12 - sizeof(FmtChunk) - 8)); if (0 == fseek(File, 4 + sizeof(FmtChunk) + 4, SEEK_CUR)) { if (1 == fwrite(&size, 4, 1, File)) diff --git a/src/sound/music_win_mididevice.cpp b/src/sound/music_win_mididevice.cpp index d607793987..cb59878304 100644 --- a/src/sound/music_win_mididevice.cpp +++ b/src/sound/music_win_mididevice.cpp @@ -34,6 +34,20 @@ #ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#define USE_WINDOWS_DWORD +#if defined(_WIN32_WINNT) && _WIN32_WINNT < 0x0400 +#undef _WIN32_WINNT +#endif +#ifndef _WIN32_WINNT +#define _WIN32_WINNT 0x0400 +#endif +#ifndef USE_WINDOWS_DWORD +#define USE_WINDOWS_DWORD +#endif +#include +#include + // HEADER FILES ------------------------------------------------------------ #include "i_musicinterns.h" @@ -58,6 +72,43 @@ static bool IgnoreMIDIVolume(UINT id); // EXTERNAL DATA DECLARATIONS ---------------------------------------------- // PRIVATE DATA DEFINITIONS ------------------------------------------------ +// WinMM implementation of a MIDI output device ----------------------------- + +class WinMIDIDevice : public MIDIDevice +{ +public: + WinMIDIDevice(int dev_id); + ~WinMIDIDevice(); + int Open(MidiCallback, void *userdata); + void Close(); + bool IsOpen() const; + int GetTechnology() const; + int SetTempo(int tempo); + int SetTimeDiv(int timediv); + int StreamOut(MidiHeader *data); + int StreamOutSync(MidiHeader *data); + int Resume(); + void Stop(); + int PrepareHeader(MidiHeader *data); + int UnprepareHeader(MidiHeader *data); + bool FakeVolume(); + bool NeedThreadedCallback(); + bool Pause(bool paused); + void PrecacheInstruments(const uint16_t *instruments, int count); + +protected: + static void CALLBACK CallbackFunc(HMIDIOUT, UINT, DWORD_PTR, DWORD, DWORD); + + HMIDISTRM MidiOut; + UINT DeviceID; + DWORD SavedVolume; + MIDIHDR WinMidiHeaders[2]; + int HeaderIndex; + bool VolumeWorks; + + MidiCallback Callback; + void *CallbackData; +}; // PUBLIC DATA DEFINITIONS ------------------------------------------------- @@ -487,4 +538,10 @@ static bool IgnoreMIDIVolume(UINT id) return false; } +MIDIDevice *CreateWinMIDIDevice(int mididevice) +{ + return new WinMIDIDevice(mididevice); +} #endif + + diff --git a/src/sound/music_xmi_midiout.cpp b/src/sound/music_xmi_midiout.cpp index b233f89b35..9f16098ed3 100644 --- a/src/sound/music_xmi_midiout.cpp +++ b/src/sound/music_xmi_midiout.cpp @@ -72,15 +72,15 @@ struct XMISong::TrackInfo const uint8_t *TimbreChunk; size_t TimbreLen; - DWORD Delay; - DWORD PlayedTime; + uint32_t Delay; + uint32_t PlayedTime; bool Finished; LoopInfo ForLoops[MAX_FOR_DEPTH]; int ForDepth; - DWORD ReadVarLen(); - DWORD ReadDelay(); + uint32_t ReadVarLen(); + uint32_t ReadDelay(); }; // EXTERNAL FUNCTION PROTOTYPES -------------------------------------------- @@ -111,12 +111,10 @@ extern char MIDI_CommonLengths[15]; XMISong::XMISong (FileReader &reader, EMidiDevice type, const char *args) : MIDIStreamer(type, args), MusHeader(0), Songs(0) { -#ifdef _WIN32 - if (ExitEvent == NULL) + if (!CheckExitEvent()) { return; } -#endif SongLen = reader.GetLength(); MusHeader = new uint8_t[SongLen]; if (reader.Read(MusHeader, SongLen) != SongLen) @@ -313,12 +311,12 @@ bool XMISong::CheckDone() // //========================================================================== -DWORD *XMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) +uint32_t *XMISong::MakeEvents(uint32_t *events, uint32_t *max_event_p, uint32_t max_time) { - DWORD *start_events; - DWORD tot_time = 0; - DWORD time = 0; - DWORD delay; + uint32_t *start_events; + uint32_t tot_time = 0; + uint32_t time = 0; + uint32_t delay; start_events = events; while (EventDue != EVENT_None && events < max_event_p && tot_time <= max_time) @@ -338,7 +336,7 @@ DWORD *XMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) do { bool sysex_noroom = false; - DWORD *new_events = SendCommand(events, EventDue, time, max_event_p - events, sysex_noroom); + uint32_t *new_events = SendCommand(events, EventDue, time, max_event_p - events, sysex_noroom); if (sysex_noroom) { return events; @@ -366,7 +364,7 @@ DWORD *XMISong::MakeEvents(DWORD *events, DWORD *max_event_p, DWORD max_time) // //========================================================================== -void XMISong::AdvanceSong(DWORD time) +void XMISong::AdvanceSong(uint32_t time) { if (time != 0) { @@ -387,9 +385,9 @@ void XMISong::AdvanceSong(DWORD time) // //========================================================================== -DWORD *XMISong::SendCommand (DWORD *events, EventSource due, DWORD delay, ptrdiff_t room, bool &sysex_noroom) +uint32_t *XMISong::SendCommand (uint32_t *events, EventSource due, uint32_t delay, ptrdiff_t room, bool &sysex_noroom) { - DWORD len; + uint32_t len; uint8_t event, data1 = 0, data2 = 0; if (due == EVENT_Fake) @@ -617,7 +615,7 @@ void XMISong::ProcessInitialMetaEvents () { TrackInfo *track = CurrSong; uint8_t event; - DWORD len; + uint32_t len; while (!track->Finished && track->EventP < track->EventLen - 3 && @@ -646,9 +644,9 @@ void XMISong::ProcessInitialMetaEvents () // //========================================================================== -DWORD XMISong::TrackInfo::ReadVarLen() +uint32_t XMISong::TrackInfo::ReadVarLen() { - DWORD time = 0, t = 0x80; + uint32_t time = 0, t = 0x80; while ((t & 0x80) && EventP < EventLen) { @@ -667,9 +665,9 @@ DWORD XMISong::TrackInfo::ReadVarLen() // //========================================================================== -DWORD XMISong::TrackInfo::ReadDelay() +uint32_t XMISong::TrackInfo::ReadDelay() { - DWORD time = 0, t; + uint32_t time = 0, t; while (EventP < EventLen && !((t = EventChunk[EventP]) & 0x80)) { @@ -697,8 +695,8 @@ XMISong::EventSource XMISong::FindNextDue() } // Which is due sooner? The current song or the note-offs? - DWORD real_delay = CurrSong->Finished ? 0xFFFFFFFF : CurrSong->Delay; - DWORD fake_delay = NoteOffs.Size() == 0 ? 0xFFFFFFFF : NoteOffs[0].Delay; + uint32_t real_delay = CurrSong->Finished ? 0xFFFFFFFF : CurrSong->Delay; + uint32_t fake_delay = NoteOffs.Size() == 0 ? 0xFFFFFFFF : NoteOffs[0].Delay; return (fake_delay <= real_delay) ? EVENT_Fake : EVENT_Real; } diff --git a/src/sound/oalsound.cpp b/src/sound/oalsound.cpp index 27c0435e42..99ccee82ff 100644 --- a/src/sound/oalsound.cpp +++ b/src/sound/oalsound.cpp @@ -2055,10 +2055,10 @@ void OpenALSoundRenderer::PrintDriversList() MIDIDevice* OpenALSoundRenderer::CreateMIDIDevice() const { #ifdef _WIN32 - extern UINT mididevice; - return new WinMIDIDevice(mididevice); + extern unsigned mididevice; + return CreateWinMIDIDevice(mididevice); #elif defined __APPLE__ - return new AudioToolboxMIDIDevice; + return CreateAudioToolboxMIDIDevice; #else return new OPLMIDIDevice(nullptr); #endif diff --git a/src/win32/critsec.h b/src/win32/critsec.cpp similarity index 57% rename from src/win32/critsec.h rename to src/win32/critsec.cpp index e95bf1b052..a270fcef54 100644 --- a/src/win32/critsec.h +++ b/src/win32/critsec.cpp @@ -1,22 +1,19 @@ // Wraps a Windows critical section object. -#ifndef CRITSEC_H -#define CRITSEC_H - #ifndef _WINNT_ #define WIN32_LEAN_AND_MEAN #include #define USE_WINDOWS_DWORD #endif -class FCriticalSection +class FInternalCriticalSection { public: - FCriticalSection() + FInternalCriticalSection() { InitializeCriticalSection(&CritSec); } - ~FCriticalSection() + ~FInternalCriticalSection() { DeleteCriticalSection(&CritSec); } @@ -39,4 +36,23 @@ private: CRITICAL_SECTION CritSec; }; -#endif + +FInternalCriticalSection *CreateCriticalSection() +{ + return new FInternalCriticalSection(); +} + +void DeleteCriticalSection(FInternalCriticalSection *c) +{ + delete c; +} + +void EnterCriticalSection(FInternalCriticalSection *c) +{ + c->Enter(); +} + +void LeaveCriticalSection(FInternalCriticalSection *c) +{ + c->Leave(); +} diff --git a/src/win32/i_system.h b/src/win32/i_system.h index e6b19cea5c..5959b61120 100644 --- a/src/win32/i_system.h +++ b/src/win32/i_system.h @@ -175,10 +175,10 @@ FString I_GetLongPathName(FString shortpath); struct findstate_t { - DWORD Attribs; - DWORD Times[3*2]; - DWORD Size[2]; - DWORD Reserved[2]; + uint32_t Attribs; + uint32_t Times[3*2]; + uint32_t Size[2]; + uint32_t Reserved[2]; char Name[MAX_PATH]; char AltName[14]; };