diff --git a/Aerofoil/GpSystemServices_Win32.cpp b/Aerofoil/GpSystemServices_Win32.cpp index 0e52b22..97f69d8 100644 --- a/Aerofoil/GpSystemServices_Win32.cpp +++ b/Aerofoil/GpSystemServices_Win32.cpp @@ -95,6 +95,11 @@ bool GpSystemServices_Win32::IsUsingMouseAsTouch() const return m_isTouchscreenSimulation; } +bool GpSystemServices_Win32::IsTextInputObstructive() const +{ + return false; +} + void GpSystemServices_Win32::SetTouchscreenSimulation(bool isTouchscreenSimulation) { m_isTouchscreenSimulation = isTouchscreenSimulation; diff --git a/Aerofoil/GpSystemServices_Win32.h b/Aerofoil/GpSystemServices_Win32.h index 945fafe..3528136 100644 --- a/Aerofoil/GpSystemServices_Win32.h +++ b/Aerofoil/GpSystemServices_Win32.h @@ -24,6 +24,7 @@ public: void Beep() const override; bool IsTouchscreen() const override; bool IsUsingMouseAsTouch() const override; + bool IsTextInputObstructive() const override; void SetTouchscreenSimulation(bool isTouchscreenSimulation); diff --git a/AerofoilAndroid/app/jni/main/GpMain_SDL_Android.cpp b/AerofoilAndroid/app/jni/main/GpMain_SDL_Android.cpp index 6d545e2..69ceb8f 100644 --- a/AerofoilAndroid/app/jni/main/GpMain_SDL_Android.cpp +++ b/AerofoilAndroid/app/jni/main/GpMain_SDL_Android.cpp @@ -18,6 +18,8 @@ #include "GpAndroid.h" +#include + GpAndroidGlobals g_gpAndroidGlobals; extern "C" IGpFontHandler *GpDriver_CreateFontHandler_FreeType2(const GpFontHandlerProperties &properties); @@ -38,7 +40,7 @@ int main(int argc, char* argv[]) g_gpGlobalConfig.m_displayDriverType = EGpDisplayDriverType_SDL_GL2; - g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_None; + g_gpGlobalConfig.m_audioDriverType = EGpAudioDriverType_SDL2; g_gpGlobalConfig.m_fontHandlerType = EGpFontHandlerType_FreeType2; @@ -55,5 +57,12 @@ int main(int argc, char* argv[]) int returnCode = GpMain::Run(); + SDL_Quit(); + + // This doesn't even actually exit, but it does stop this stupid brain-damaged OS from + // just calling "main" again with no cleanup... + // That'll have to do until proper cleanup code is added to everything. + exit(returnCode); + return returnCode; } diff --git a/AerofoilAndroid/app/jni/main/GpSystemServices_Android.cpp b/AerofoilAndroid/app/jni/main/GpSystemServices_Android.cpp index 823ed6a..2d8e118 100644 --- a/AerofoilAndroid/app/jni/main/GpSystemServices_Android.cpp +++ b/AerofoilAndroid/app/jni/main/GpSystemServices_Android.cpp @@ -58,7 +58,7 @@ typedef GpMutex_Cpp11 GpMutex_Cpp11_Recursive; class GpThreadEvent_Cpp11 final : public PortabilityLayer::HostThreadEvent { public: - GpThreadEvent_Cpp11(); + GpThreadEvent_Cpp11(bool autoReset, bool startSignaled); ~GpThreadEvent_Cpp11(); void Wait() override; @@ -70,10 +70,12 @@ private: std::mutex m_mutex; std::condition_variable m_cvar; bool m_flag; + bool m_autoReset; }; -GpThreadEvent_Cpp11::GpThreadEvent_Cpp11() - : m_flag(false) +GpThreadEvent_Cpp11::GpThreadEvent_Cpp11(bool autoReset, bool startSignaled) + : m_flag(startSignaled) + , m_autoReset(autoReset) { } @@ -84,14 +86,43 @@ GpThreadEvent_Cpp11::~GpThreadEvent_Cpp11() void GpThreadEvent_Cpp11::Wait() { std::unique_lock lock(m_mutex); - m_cvar.wait(lock,[&]()->bool{ return m_flag; }); + if (m_autoReset) + { + m_cvar.wait(lock,[&]()->bool{ + if (m_flag) + { + m_flag = false; + return true; + } + else + return false; + }); + } + else + m_cvar.wait(lock,[&]()->bool{ return m_flag; }); } bool GpThreadEvent_Cpp11::WaitTimed(uint32_t msec) { std::unique_lock lock(m_mutex); - if (!m_cvar.wait_for(lock, std::chrono::milliseconds(msec), [&]()->bool{ return m_flag; })) - return false; + if (m_autoReset) + { + if (!m_cvar.wait_for(lock, std::chrono::milliseconds(msec), [&]()->bool{ + if (m_flag) + { + m_flag = false; + return true; + } + else + return false; + })) + return false; + } + else + { + if (!m_cvar.wait_for(lock, std::chrono::milliseconds(msec), [&]()->bool{ return m_flag; })) + return false; + } return true; } @@ -100,7 +131,10 @@ void GpThreadEvent_Cpp11::Signal() m_mutex.lock(); m_flag = true; m_mutex.unlock(); - m_cvar.notify_all(); + if (m_autoReset) + m_cvar.notify_one(); + else + m_cvar.notify_all(); } void GpThreadEvent_Cpp11::Destroy() @@ -154,7 +188,7 @@ PortabilityLayer::HostThreadEvent *GpSystemServices_Android::CreateThreadEvent(b if (!evt) return nullptr; - return new (evt) GpThreadEvent_Cpp11(); + return new (evt) GpThreadEvent_Cpp11(autoReset, startSignaled); } uint64_t GpSystemServices_Android::GetFreeMemoryCosmetic() const @@ -166,6 +200,21 @@ void GpSystemServices_Android::Beep() const { } +bool GpSystemServices_Android::IsTouchscreen() const +{ + return true; +} + +bool GpSystemServices_Android::IsUsingMouseAsTouch() const +{ + return true; +} + +bool GpSystemServices_Android::IsTextInputObstructive() const +{ + return true; +} + GpSystemServices_Android *GpSystemServices_Android::GetInstance() { return &ms_instance; diff --git a/AerofoilAndroid/app/jni/main/GpSystemServices_Android.h b/AerofoilAndroid/app/jni/main/GpSystemServices_Android.h index 893e67f..8fe5ff6 100644 --- a/AerofoilAndroid/app/jni/main/GpSystemServices_Android.h +++ b/AerofoilAndroid/app/jni/main/GpSystemServices_Android.h @@ -15,6 +15,9 @@ public: PortabilityLayer::HostThreadEvent *CreateThreadEvent(bool autoReset, bool startSignaled) override; uint64_t GetFreeMemoryCosmetic() const override; void Beep() const override; + bool IsTouchscreen() const override; + bool IsUsingMouseAsTouch() const override; + bool IsTextInputObstructive() const override; static GpSystemServices_Android *GetInstance(); diff --git a/AerofoilSDL/GpAudioDriver_SDL2.cpp b/AerofoilSDL/GpAudioDriver_SDL2.cpp index 471062f..5520454 100644 --- a/AerofoilSDL/GpAudioDriver_SDL2.cpp +++ b/AerofoilSDL/GpAudioDriver_SDL2.cpp @@ -525,21 +525,27 @@ void GpAudioDriver_SDL2::RefillMixChunk(GpAudioChannel_SDL2 *const*channels, siz audioMixBuffer += alignPadding; } + bool noAudio = true; + for (size_t i = 0; i < numChannels; i++) { channels[i]->Consume(audioMixBuffer, kMixChunkSize); if (i == 0) { + noAudio = false; for (size_t j = 0; j < kMixChunkSize; j++) - m_mixChunk[j] = audioMixBuffer[j] - 0x80; + m_mixChunk[j] = (audioMixBuffer[j] - 0x80) * 25; } else { for (size_t j = 0; j < kMixChunkSize; j++) - m_mixChunk[j] += audioMixBuffer[j] - 0x80; + m_mixChunk[j] += (audioMixBuffer[j] - 0x80) * 25; } } + + if (noAudio) + memset(m_mixChunk, 0, kMixChunkSize * sizeof(m_mixChunk[0])); } diff --git a/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp b/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp index 07d36ce..a2080a5 100644 --- a/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp +++ b/AerofoilSDL/GpDisplayDriver_SDL_GL2.cpp @@ -700,7 +700,7 @@ public: bool Init(); - static void TranslateSDLMessage(const SDL_Event *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY); + static void TranslateSDLMessage(const SDL_Event *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY, bool obstructiveTextInput); void Run() override; void Shutdown() override; @@ -1540,7 +1540,7 @@ static void PostKeyboardEvent(IGpVOSEventQueue *eventQueue, GpKeyboardInputEvent } } -void GpDisplayDriver_SDL_GL2::TranslateSDLMessage(const SDL_Event *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY) +void GpDisplayDriver_SDL_GL2::TranslateSDLMessage(const SDL_Event *msg, IGpVOSEventQueue *eventQueue, float pixelScaleX, float pixelScaleY, bool obstructiveTextInput) { switch (msg->type) { @@ -1642,9 +1642,11 @@ void GpDisplayDriver_SDL_GL2::TranslateSDLMessage(const SDL_Event *msg, IGpVOSEv PostKeyboardEvent(eventQueue, keyEventType, subset, key, 1); } - // Monster hack. This needs to be redone to support OSK. - SDL_StopTextInput(); - SDL_StartTextInput(); + if (!obstructiveTextInput) + { + SDL_StopTextInput(); + SDL_StartTextInput(); + } } break; case SDL_QUIT: @@ -1674,7 +1676,10 @@ void GpDisplayDriver_SDL_GL2::Run() m_window = SDL_CreateWindow(GP_APPLICATION_NAME, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, m_windowWidthPhysical, m_windowHeightPhysical, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE); - SDL_StartTextInput(); + const bool obstructiveTextInput = m_properties.m_systemServices->IsTextInputObstructive(); + + if (!obstructiveTextInput) + SDL_StartTextInput(); StartOpenGLForWindow(logger); @@ -1696,7 +1701,7 @@ void GpDisplayDriver_SDL_GL2::Run() //else if (msg.type == SDL_MOUSELEAVE) // Does SDL support this?? // m_mouseIsInClientArea = false; - TranslateSDLMessage(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY); + TranslateSDLMessage(&msg, m_properties.m_eventQueue, m_pixelScaleX, m_pixelScaleY, obstructiveTextInput); } else { diff --git a/ApplicationResourcePatches/PICT/1973.bmp b/ApplicationResourcePatches/PICT/1973.bmp index 956f29a..8ca08e9 100644 Binary files a/ApplicationResourcePatches/PICT/1973.bmp and b/ApplicationResourcePatches/PICT/1973.bmp differ diff --git a/ApplicationResourcePatches/PICT/1974.bmp b/ApplicationResourcePatches/PICT/1974.bmp index 3942532..94c10d5 100644 Binary files a/ApplicationResourcePatches/PICT/1974.bmp and b/ApplicationResourcePatches/PICT/1974.bmp differ diff --git a/ApplicationResourcePatches/PICT/1975.bmp b/ApplicationResourcePatches/PICT/1975.bmp index 6f8f76f..a836c7e 100644 Binary files a/ApplicationResourcePatches/PICT/1975.bmp and b/ApplicationResourcePatches/PICT/1975.bmp differ diff --git a/ApplicationResourcePatches/PICT/1984.bmp b/ApplicationResourcePatches/PICT/1984.bmp index 732abb4..524da04 100644 Binary files a/ApplicationResourcePatches/PICT/1984.bmp and b/ApplicationResourcePatches/PICT/1984.bmp differ diff --git a/GpApp/GliderStructs.h b/GpApp/GliderStructs.h index 2b9c8b8..9761263 100644 --- a/GpApp/GliderStructs.h +++ b/GpApp/GliderStructs.h @@ -422,7 +422,7 @@ namespace touchScreenControlGraphics typedef touchScreenControlGraphics::touchScreenControlGraphic touchScreenControlGraphic_t; -typedef struct +struct touchScreenControlState { static const int kMaxFingers = 4; @@ -430,4 +430,6 @@ typedef struct touchScreenFingerState fingers[kMaxFingers]; DrawSurface *graphics[touchScreenControlGraphics::Count]; -} touchScreenControlState, *touchScreenControlStatePtr; +}; + +typedef touchScreenControlState *touchScreenControlStatePtr; diff --git a/GpApp/Music.cpp b/GpApp/Music.cpp index 67eaaec..9c79f4b 100644 --- a/GpApp/Music.cpp +++ b/GpApp/Music.cpp @@ -60,17 +60,17 @@ PLError_t StartMusic (void) { PLError_t theErr; short soundVolume; - + theErr = PLErrors::kNone; - + if (dontLoadMusic) return(theErr); if (musicMutex == nullptr) return(theErr); - + UnivGetSoundVolume(&soundVolume, thisMac.hasSM3); - + if ((soundVolume != 0) && (!failedMusic)) { musicChannel->AddBuffer(theMusicData[musicState.musicSoundID], true); @@ -83,10 +83,10 @@ PLError_t StartMusic (void) musicChannel->AddBuffer(theMusicData[musicState.musicSoundID], true); musicChannel->AddCallback(MusicCallBack, true); - + isMusicOn = true; } - + return (theErr); } @@ -95,16 +95,16 @@ PLError_t StartMusic (void) void StopTheMusic (void) { PLError_t theErr; - + if (dontLoadMusic) return; - + theErr = PLErrors::kNone; if ((isMusicOn) && (!failedMusic)) { musicChannel->ClearAllCommands(); musicChannel->Stop(); - + isMusicOn = false; } } @@ -114,10 +114,10 @@ void StopTheMusic (void) void ToggleMusicWhilePlaying (void) { PLError_t theErr; - + if (dontLoadMusic) return; - + if (isPlayMusicGame) { if (!isMusicOn) @@ -133,7 +133,7 @@ void ToggleMusicWhilePlaying (void) //-------------------------------------------------------------- SetMusicalPiece void SetMusicalMode (short newMode) -{ +{ if (dontLoadMusic || failedMusic) return; @@ -143,11 +143,11 @@ void SetMusicalMode (short newMode) case kKickGameScoreMode: musicState.musicCursor = 2; break; - + case kProdGameScoreMode: musicState.musicCursor = -1; break; - + default: musicState.musicMode = newMode; musicState.musicCursor = 0; @@ -176,14 +176,14 @@ void MusicCallBack (PortabilityLayer::AudioChannel *theChannel) musicState.musicSoundID = gameScore[musicState.musicCursor]; } break; - + case kPlayWholeScoreMode: musicState.musicCursor++; if (musicState.musicCursor >= kLastMusicPiece - 1) musicState.musicCursor = 0; musicState.musicSoundID = musicScore[musicState.musicCursor]; break; - + default: musicState.musicSoundID = musicState.musicMode; break; @@ -204,18 +204,18 @@ PLError_t LoadMusicSounds (void) long soundDataSize; PLError_t theErr; short i; - + theErr = PLErrors::kNone; - + for (i = 0; i < kMaxMusic; i++) theMusicData[i] = nil; - + for (i = 0; i < kMaxMusic; i++) { theSound = ParseAndConvertSound(PortabilityLayer::ResourceManager::GetInstance()->GetAppResource('snd ', i + kBaseBufferMusicID)); if (theSound == nil) return PLErrors::kOutOfMemory; - + soundDataSize = GetHandleSize(theSound); theMusicData[i] = PortabilityLayer::MemoryManager::GetInstance()->Alloc(soundDataSize); @@ -234,16 +234,16 @@ PLError_t DumpMusicSounds (void) { PLError_t theErr; short i; - + theErr = PLErrors::kNone; - + for (i = 0; i < kMaxMusic; i++) { if (theMusicData[i] != nil) PortabilityLayer::MemoryManager::GetInstance()->Release(theMusicData[i]); theMusicData[i] = nil; } - + return (theErr); } @@ -252,12 +252,12 @@ PLError_t DumpMusicSounds (void) PLError_t OpenMusicChannel (void) { PLError_t theErr; - + theErr = PLErrors::kNone; - + if (musicChannel != nil) return (theErr); - + musicChannel = PortabilityLayer::SoundSystem::GetInstance()->CreateChannel(); if (musicChannel == nil) @@ -271,13 +271,13 @@ PLError_t OpenMusicChannel (void) PLError_t CloseMusicChannel (void) { PLError_t theErr; - + theErr = PLErrors::kNone; - + if (musicChannel != nil) musicChannel->Destroy(false); musicChannel = nil; - + return (theErr); } @@ -286,12 +286,12 @@ PLError_t CloseMusicChannel (void) void InitMusic (void) { PLError_t theErr; - + if (dontLoadMusic) return; - + musicChannel = nil; - + failedMusic = false; isMusicOn = false; theErr = LoadMusicSounds(); @@ -308,7 +308,7 @@ void InitMusic (void) failedMusic = true; return; } - + musicScore[0] = 0; musicScore[1] = 1; musicScore[2] = 2; @@ -325,14 +325,14 @@ void InitMusic (void) musicScore[13] = kPlayRefrainSparse2; musicScore[14] = kPlayChorus; musicScore[15] = kPlayChorus; - + gameScore[0] = kPlayRefrainSparse2; gameScore[1] = kPlayRefrainSparse1; gameScore[2] = -1; gameScore[3] = kPlayRefrainSparse2; gameScore[4] = kPlayChorus; gameScore[5] = kPlayChorus; - + musicState.musicCursor = 0; musicState.musicSoundID = musicScore[musicState.musicCursor]; musicState.musicMode = kPlayWholeScoreMode; @@ -340,7 +340,7 @@ void InitMusic (void) musicMutex = PortabilityLayer::HostSystemServices::GetInstance()->CreateMutex(); PL_NotYetImplemented_TODO("MusicSync"); - + if (isPlayMusicIdle) { theErr = StartMusic(); @@ -357,13 +357,15 @@ void InitMusic (void) void KillMusic (void) { PLError_t theErr; - + if (dontLoadMusic) return; theErr = CloseMusicChannel(); theErr = DumpMusicSounds(); - musicMutex->Destroy(); + + if (musicMutex) + musicMutex->Destroy(); } //-------------------------------------------------------------- MusicBytesNeeded @@ -372,7 +374,7 @@ long MusicBytesNeeded (void) { size_t totalBytes; short i; - + totalBytes = 0L; for (i = 0; i < kMaxMusic; i++) { @@ -391,7 +393,7 @@ void TellHerNoMusic (void) { #define kNoMemForMusicAlert 1038 short hitWhat; - + // CenterAlert(kNoMemForMusicAlert); hitWhat = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNoMemForMusicAlert, nullptr); } diff --git a/GpApp/Prefs.cpp b/GpApp/Prefs.cpp index 534cf2b..f54e4c2 100644 --- a/GpApp/Prefs.cpp +++ b/GpApp/Prefs.cpp @@ -66,7 +66,7 @@ Boolean WritePrefs (const prefsInfo *thePrefs, short versionNow, THandleFileExists(PortabilityLayer::VirtualDirectories::kPrefs, fileName)) { @@ -148,7 +148,7 @@ Boolean WritePrefs (const prefsInfo *thePrefs, short versionNow, THandleClose(); - + return(true); } @@ -158,7 +158,7 @@ Boolean SavePrefs (prefsInfo *thePrefs, THandle *modulePrefs, short versio { if (!WritePrefs(thePrefs, versionNow, modulePrefs->StaticCast())) return(false); - + return(true); } @@ -197,14 +197,14 @@ PLError_t ReadPrefs (prefsInfo *thePrefs, short versionNeed, Boolean *isOldVersi *isOldVersion = false; PortabilityLayer::FileManager *fm = PortabilityLayer::FileManager::GetInstance(); - + PasStringCopy(kPrefFileName, fileName); - + theSpecs = MakeVFileSpec(PortabilityLayer::VirtualDirectory_t::kPrefs, fileName); if (!PortabilityLayer::FileManager::GetInstance()->FileExists(theSpecs.m_dir, theSpecs.m_name)) return PLErrors::kFileNotFound; - + theErr = fm->OpenFileData(theSpecs.m_dir, theSpecs.m_name, PortabilityLayer::EFilePermission_Read, fileStream); if (theErr != PLErrors::kNone) { @@ -226,7 +226,7 @@ PLError_t ReadPrefs (prefsInfo *thePrefs, short versionNeed, Boolean *isOldVersi fileStream->Close(); return(PLErrors::kNone); } - + byteCount = sizeof(*thePrefs); if (fileStream->Read(thePrefs, byteCount) != byteCount) @@ -309,7 +309,7 @@ PLError_t ReadPrefs (prefsInfo *thePrefs, short versionNeed, Boolean *isOldVersi } } } - + fileStream->Close(); return(theErr); @@ -324,7 +324,7 @@ Boolean DeletePrefs () PLError_t theErr; PasStringCopy(kPrefFileName, fileName); - + theSpecs = MakeVFileSpec(PortabilityLayer::VirtualDirectories::kPrefs, fileName); return PortabilityLayer::FileManager::GetInstance()->DeleteFile(theSpecs.m_dir, theSpecs.m_name); @@ -337,9 +337,13 @@ bool RunFunctionOnAllPrefsHandlers (void *context, bool (*func) (void *context, if (ddHandler && !func(context, ddHandler)) return false; - IGpPrefsHandler *adHandler = PortabilityLayer::HostAudioDriver::GetInstance()->GetPrefsHandler(); - if (adHandler && !func(context, adHandler)) - return false; + + if (IGpAudioDriver *audioDriver = PortabilityLayer::HostAudioDriver::GetInstance()) + { + IGpPrefsHandler *adHandler = audioDriver->GetPrefsHandler(); + if (adHandler && !func(context, adHandler)) + return false; + } size_t numInputDrivers = PortabilityLayer::HostInputDriver::NumInstances(); @@ -364,7 +368,7 @@ Boolean LoadPrefs (prefsInfo *thePrefs, THandle *modulePrefs, short versio Boolean isOldVersion = 0; THandle mPrefs; - + theErr = ReadPrefs(thePrefs, versionNeed, &isOldVersion, &mPrefs); if (theErr == PLErrors::kFileNotFound) @@ -383,7 +387,7 @@ Boolean LoadPrefs (prefsInfo *thePrefs, THandle *modulePrefs, short versio noProblems = DeletePrefs(); return(false); } - + *modulePrefs = mPrefs.StaticCast(); return (true); @@ -537,7 +541,7 @@ Boolean ApplyModulePrefs (THandle *modulePrefs) void BringUpDeletePrefsAlert (void) { short whoCares; - + InitCursor(); // CenterAlert(kNewPrefsAlertID); whoCares = PortabilityLayer::DialogManager::GetInstance()->DisplayAlert(kNewPrefsAlertID, nullptr); diff --git a/PortabilityLayer/HostSystemServices.h b/PortabilityLayer/HostSystemServices.h index e0f6124..4c971c0 100644 --- a/PortabilityLayer/HostSystemServices.h +++ b/PortabilityLayer/HostSystemServices.h @@ -25,6 +25,7 @@ namespace PortabilityLayer virtual void Beep() const = 0; virtual bool IsTouchscreen() const = 0; virtual bool IsUsingMouseAsTouch() const = 0; + virtual bool IsTextInputObstructive() const = 0; static void SetInstance(HostSystemServices *instance); static HostSystemServices *GetInstance();