From 9678ec3e5829c45025ecc918140d35b872ba8dba Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Tue, 12 Apr 2016 22:29:39 +0200 Subject: [PATCH 1/2] Enabled Multi-Threading (as an option) + OpenPandora specific changes (for Shoulder As Mouse Buttons) --- Sources/CMakeLists.txt | 28 ++++++-- Sources/Engine/Base/Lists.cpp | 3 +- Sources/Engine/Base/SDL/SDLEvents.cpp | 22 ++++++ Sources/Engine/Base/SDL/SDLInput.cpp | 68 +++++++++++++++---- Sources/Engine/Base/Stream.cpp | 2 +- Sources/Engine/Base/Timer.cpp | 9 +-- Sources/Engine/Base/Timer.h | 4 ++ .../Engine/Base/Unix/UnixSynchronization.cpp | 13 +++- Sources/Engine/Engine.cpp | 8 +++ Sources/Engine/Graphics/GfxLibrary.cpp | 12 ++++ Sources/GameMP/Game.cpp | 5 +- 11 files changed, 145 insertions(+), 29 deletions(-) mode change 100644 => 100755 Sources/Engine/Base/SDL/SDLEvents.cpp mode change 100644 => 100755 Sources/Engine/Base/Timer.cpp mode change 100644 => 100755 Sources/Engine/Base/Timer.h diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index 30e7290..90f322b 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -139,7 +139,10 @@ endif() # !!! FIXME: I currently force this, but you shouldn't _have_ to. -add_definitions(-DSINGLE_THREADED=1) +option(USE_SINGLE_THREAD "Use Single Threaded version" TRUE) +if(USE_SINGLE_THREAD) + add_definitions(-DSINGLE_THREADED=1) +endif() include_directories( @@ -572,6 +575,22 @@ if (USE_I386_ASM) list(APPEND ADDITIONAL_ENGINE_SRCS SoundMixer386.o) endif() +if(USE_SINGLE_THREAD) + set(SYNCHRO_SRCS + Engine/Base/NullSynchronization.cpp # single threaded. + ) +else() + #!! TODO Win32/Linux case + set(SYNCHRO_SRCS + Engine/Base/Unix/UnixSynchronization.cpp # multithreaded Unix. + #Engine/Base/SDL/SDLSynchronization.cpp + #Engine/Base/SDL/SDLThreadLocalStorage.cpp # multithreaded Unix. + ) + #Engine/Base/Registry.cpp # Windows only. + #Engine/Base/StackDump.cpp # Windows only. + #Engine/Base/Win32/Win32Synchronization.cpp # Windows only. +endif() + set(ENGINE_SRCS ${ENGINE_ENTITIES_CPP} Engine/Engine.cpp @@ -610,12 +629,7 @@ set(ENGINE_SRCS Engine/Base/SDL/SDLTimer.cpp Engine/Base/SDL/SDLInput.cpp Engine/Base/SDL/SDLEvents.cpp - Engine/Base/NullSynchronization.cpp # single threaded. - #Engine/Base/Unix/UnixSynchronization.cpp # multithreaded Unix. - #Engine/Base/SDL/SDLThreadLocalStorage.cpp # multithreaded Unix. - #Engine/Base/Registry.cpp # Windows only. - #Engine/Base/StackDump.cpp # Windows only. - #Engine/Base/Win32/Win32Synchronization.cpp # Windows only. + ${SYNCHRO_SRCS} Engine/Brushes/Brush.cpp Engine/Brushes/BrushIO.cpp Engine/Brushes/BrushShadows.cpp diff --git a/Sources/Engine/Base/Lists.cpp b/Sources/Engine/Base/Lists.cpp index c6ff234..414fb0b 100644 --- a/Sources/Engine/Base/Lists.cpp +++ b/Sources/Engine/Base/Lists.cpp @@ -234,7 +234,8 @@ void CListNode::Remove(void) ASSERT(next.IsTailMarker() || next.IsLinked()); ASSERT(prev.IsHeadMarker() || prev.IsLinked()); - next.ln_Pred = &prev; + if(ln_Succ) + next.ln_Pred = &prev; prev.ln_Succ = &next; // make a non-linked node ln_Succ = NULL; diff --git a/Sources/Engine/Base/SDL/SDLEvents.cpp b/Sources/Engine/Base/SDL/SDLEvents.cpp old mode 100644 new mode 100755 index 7732a66..aad7b99 --- a/Sources/Engine/Base/SDL/SDLEvents.cpp +++ b/Sources/Engine/Base/SDL/SDLEvents.cpp @@ -50,6 +50,13 @@ BOOL PeekMessage(MSG *msg, void *hwnd, UINT wMsgFilterMin, case SDL_KEYUP: if (sdlevent.key.keysym.sym == SDLK_BACKQUOTE) msg->unicode = '~'; // !!! FIXME: this is all a hack. + #ifdef PLATFORM_PANDORA + if(sdlevent.key.keysym.sym == SDLK_RCTRL) { + msg->message = (sdlevent.type==SDL_KEYDOWN)?WM_RBUTTONDOWN:WM_RBUTTONUP; + } else if(sdlevent.key.keysym.sym == SDLK_RSHIFT) { + msg->message = (sdlevent.type==SDL_KEYDOWN)?WM_LBUTTONDOWN:WM_LBUTTONUP; + } else + #endif msg->wParam = sdlevent.key.keysym.sym; return TRUE; @@ -107,17 +114,28 @@ void DispatchMessage(MSG *msg) SHORT GetKeyState(int vk) { SHORT retval = 0; +#ifdef PLATFORM_PANDORA + Uint8 *keystate = SDL_GetKeyboardState(NULL); +#endif switch (vk) { case VK_LBUTTON: if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_LMASK) retval = 0x8000; + #ifdef PLATFORM_PANDORA + if(keystate[SDL_SCANCODE_RSHIFT]) + retval = 0x8000; + #endif break; case VK_RBUTTON: if (SDL_GetMouseState(NULL, NULL) & SDL_BUTTON_RMASK) retval = 0x8000; + #ifdef PLATFORM_PANDORA + if(keystate[SDL_SCANCODE_RCTRL]) + retval = 0x8000; + #endif break; case VK_MBUTTON: @@ -127,7 +145,11 @@ SHORT GetKeyState(int vk) default: STUBBED("this can't possibly be right, yeah?"); + #ifdef PLATFORM_PANDORA + if (keystate[SDL_GetScancodeFromKey((SDL_Keycode)vk)]) + #else if (SDL_GetKeyboardState(NULL)[SDL_GetScancodeFromKey((SDL_Keycode)vk)]) + #endif retval = 0x8000; break; } // switch diff --git a/Sources/Engine/Base/SDL/SDLInput.cpp b/Sources/Engine/Base/SDL/SDLInput.cpp index ef4efd5..be6b63c 100755 --- a/Sources/Engine/Base/SDL/SDLInput.cpp +++ b/Sources/Engine/Base/SDL/SDLInput.cpp @@ -49,6 +49,8 @@ INDEX inp_bMsgDebugger = FALSE; INDEX inp_bForceJoystickPolling = 0; INDEX inp_bAutoDisableJoysticks = 0; +static CTCriticalSection sl_csInput; + extern INDEX inp_ctJoysticksAllowed; /* @@ -281,6 +283,16 @@ static void SetKeyFromEvent(const SDL_Event *event, const BOOL bDown) return; } // if + #ifdef PLATFORM_PANDORA + if(event->key.keysym.sym==SDLK_RSHIFT) { + _abKeysPressed[KID_MOUSE1] = bDown; + return; + } else if(event->key.keysym.sym==SDLK_RCTRL) { + _abKeysPressed[KID_MOUSE2] = bDown; + return; + } + #endif + // convert virtualkey to kid const INDEX iKID = _aiScancodeToKid[event->key.keysym.scancode]; @@ -333,10 +345,14 @@ static void sdl_event_handler(const SDL_Event *event) int SE_SDL_InputEventPoll(SDL_Event *sdlevent) { ASSERT(sdlevent != NULL); - const int retval = SDL_PollEvent(sdlevent); - if (retval) - sdl_event_handler(sdlevent); - return retval; + CTSingleLock slInput(&sl_csInput, FALSE); + if(slInput.TryToLock()) { + const int retval = SDL_PollEvent(sdlevent); + if (retval) + sdl_event_handler(sdlevent); + return retval; + } + return 0; } // SE_SDL_InputEventPoll @@ -495,6 +511,9 @@ BOOL CInput::PlatformInit(void) _pShell->DeclareSymbol("persistent user INDEX inp_bSDLPermitCtrlG;", (void*)&inp_bSDLPermitCtrlG); _pShell->DeclareSymbol("persistent user INDEX inp_bSDLGrabInput;", (void*)&inp_bSDLGrabInput); MakeConversionTables(); + + sl_csInput.cs_iIndex = 3000; + return(TRUE); } @@ -697,12 +716,25 @@ void CInput::GetInput(BOOL bPreScan) // get codes INDEX iKID = kc.kc_iKID; //INDEX iScan = kc.kc_iScanCode; - //INDEX iVirt = kc.kc_iVirtKey; - - // if snooped that key is pressed - if (_abKeysPressed[iKID]) { - // mark it as pressed - inp_ubButtonsBuffer[iKID] = 0xFF; + INDEX iVirt = kc.kc_iVirtKey; + // if reading async keystate + if (inp_iKeyboardReadingMethod==0) { + // if there is a valid virtkey + if (iVirt>=0) { + // is state is pressed + if (SDL_GetKeyboardState(NULL)[SDL_GetScancodeFromKey((SDL_Keycode)iVirt)]) { + // mark it as pressed + inp_ubButtonsBuffer[iKID] = 0xFF; + } + } + } + else + { + // if snooped that key is pressed + if (_abKeysPressed[iKID]) { + // mark it as pressed + inp_ubButtonsBuffer[iKID] = 0xFF; + } } } } @@ -712,7 +744,16 @@ void CInput::GetInput(BOOL bPreScan) _abKeysPressed[KID_MOUSEWHEELDOWN] = FALSE; // read mouse position - if ((mouse_relative_x != 0) || (mouse_relative_y != 0)) { + //#define USE_MOUSEWARP 1 + #ifdef USE_MOUSEWARP + int iMx, iMy; + SDL_GetRelativeMouseState(&iMx, &iMy); + mouse_relative_x = iMx; + mouse_relative_y = iMy; + #else + if ((mouse_relative_x != 0) || (mouse_relative_y != 0)) + #endif + { FLOAT fDX = FLOAT( mouse_relative_x ); FLOAT fDY = FLOAT( mouse_relative_y ); @@ -762,11 +803,14 @@ void CInput::GetInput(BOOL bPreScan) inp_caiAllAxisInfo[1].cai_fReading = fMouseRelX; inp_caiAllAxisInfo[2].cai_fReading = fMouseRelY; inp_caiAllAxisInfo[3].cai_fReading = fMouseRelZ; - } else { + } + #ifndef USE_MOUSEWARP + else { inp_caiAllAxisInfo[1].cai_fReading = 0.0; inp_caiAllAxisInfo[2].cai_fReading = 0.0; inp_caiAllAxisInfo[3].cai_fReading = 0.0; } + #endif /* // if not pre-scanning diff --git a/Sources/Engine/Base/Stream.cpp b/Sources/Engine/Base/Stream.cpp index d1ead10..ff63451 100644 --- a/Sources/Engine/Base/Stream.cpp +++ b/Sources/Engine/Base/Stream.cpp @@ -12,7 +12,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ - +#pragma GCC optimize 0 #include "Engine/StdH.h" #include diff --git a/Sources/Engine/Base/Timer.cpp b/Sources/Engine/Base/Timer.cpp old mode 100644 new mode 100755 index 43be607..0171591 --- a/Sources/Engine/Base/Timer.cpp +++ b/Sources/Engine/Base/Timer.cpp @@ -190,8 +190,9 @@ void __stdcall CTimer_TimerFunc(UINT uID, UINT uMsg, ULONG dwUser, ULONG dw1, UL } #elif (defined PLATFORM_UNIX) #include "SDL.h" -Uint32 CTimer_TimerFunc_SDL(Uint32 interval) +Uint32 CTimer_TimerFunc_SDL(Uint32 interval, void* param) { + (void)param; // access to the list of handlers must be locked CTSingleLock slHooks(&_pTimer->tm_csHooks, TRUE); // handle all timers @@ -421,8 +422,8 @@ CTimer::CTimer(BOOL bInterrupt /*=TRUE*/) #else if (SDL_Init(SDL_INIT_TIMER) == -1) FatalError(TRANS("Cannot initialize multimedia timer!")); - SDL_SetTimer(ULONG(TickQuantum*1000.0f), CTimer_TimerFunc_SDL); - + tm_TimerID = SDL_AddTimer(ULONG(TickQuantum*1000.0f), CTimer_TimerFunc_SDL, NULL); + if( tm_TimerID==NULL) FatalError(TRANS("Cannot initialize multimedia timer!")); #endif // make sure that timer interrupt is ticking @@ -461,7 +462,7 @@ CTimer::~CTimer(void) ASSERT(tm_lhHooks.IsEmpty()); #else - SDL_SetTimer(0, NULL); + SDL_RemoveTimer(tm_TimerID); #endif #endif diff --git a/Sources/Engine/Base/Timer.h b/Sources/Engine/Base/Timer.h old mode 100644 new mode 100755 index 0d77e62..f0660e1 --- a/Sources/Engine/Base/Timer.h +++ b/Sources/Engine/Base/Timer.h @@ -82,7 +82,11 @@ public: FLOAT tm_fLerpFactor; // factor used for lerping between frames FLOAT tm_fLerpFactor2; // secondary lerp-factor used for unpredicted movement + #ifdef PLATFORM_WIN32 ULONG tm_TimerID; // windows timer ID + #else + int tm_TimerID; // SDL_TimerID in fact + #endif CTCriticalSection tm_csHooks; // access to timer hooks CListHead tm_lhHooks; // a list head for timer hooks diff --git a/Sources/Engine/Base/Unix/UnixSynchronization.cpp b/Sources/Engine/Base/Unix/UnixSynchronization.cpp index 07dc8f9..12e6d77 100644 --- a/Sources/Engine/Base/Unix/UnixSynchronization.cpp +++ b/Sources/Engine/Base/Unix/UnixSynchronization.cpp @@ -6,7 +6,7 @@ #include "Engine/StdH.h" #include - +//#pragma GCC optimize 0 CTCriticalSection::CTCriticalSection(void) { cs_pvObject = (void *) new pthread_mutex_t; @@ -25,7 +25,14 @@ INDEX CTCriticalSection::Lock(void) { if (owner == pthread_self()) return(++LockCounter); - + if(owner==0 && LockCounter) { + //printf("Warning, suspicious mutex state, force unlocking...\n"); + pthread_mutex_unlock((pthread_mutex_t *) cs_pvObject); + LockCounter=0; + } + if(owner!=0) { + // do something??? + } pthread_mutex_lock((pthread_mutex_t *) cs_pvObject); owner = pthread_self(); return(++LockCounter); @@ -51,7 +58,7 @@ INDEX CTCriticalSection::Unlock(void) { if (--LockCounter == 0) { - pthread_mutex_unlock((pthread_mutex_t *) cs_pvObject); + int ret = pthread_mutex_unlock((pthread_mutex_t *) cs_pvObject); owner = 0; } } diff --git a/Sources/Engine/Engine.cpp b/Sources/Engine/Engine.cpp index 3c2721c..c07171f 100644 --- a/Sources/Engine/Engine.cpp +++ b/Sources/Engine/Engine.cpp @@ -648,7 +648,12 @@ ENGINE_API void SE_InitEngine(const char *argv0, CTString strGameID) ReleaseDC( NULL, hdc); #else // !!! FIXME : rcg01072002 This CAN be done with SDL, actually. Move this somewhere. + #ifdef PLATFORM_PANDORA + // hacked gamma support + _pGfx->gl_ulFlags |= GLF_ADJUSTABLEGAMMA; + #else CPrintF( TRANS("\nWARNING: Gamma, brightness and contrast are not adjustable!\n\n")); + #endif #endif // !!! FIXME : rcg12072001 Move this somewhere else. @@ -688,6 +693,9 @@ ENGINE_API void SE_EndEngine(void) //ASSERT(bOK); ReleaseDC( NULL, hdc); } +#elif defined(PLATFORM_PANDORA) + // restore default gamma + system("sudo /usr/pandora/scripts/op_gamma.sh 0"); #endif // free stocks diff --git a/Sources/Engine/Graphics/GfxLibrary.cpp b/Sources/Engine/Graphics/GfxLibrary.cpp index 203e9f3..4d8b657 100644 --- a/Sources/Engine/Graphics/GfxLibrary.cpp +++ b/Sources/Engine/Graphics/GfxLibrary.cpp @@ -1992,6 +1992,18 @@ void CGfxLibrary::SwapBuffers(CViewPort *pvp) } } else +#elif defined(PLATFORM_PANDORA) + if( gl_ulFlags & GLF_ADJUSTABLEGAMMA) { + //hacky Gamma only (no Contrast/Brightness) support. + static float old_pandora_gamma = 0.0f; + if (old_pandora_gamma!=gfx_fGamma) { + char buf[50]; + sprintf(buf,"sudo /usr/pandora/scripts/op_gamma.sh %.2f", gfx_fGamma); + system(buf); + old_pandora_gamma = gfx_fGamma; + } + } + else #endif // if not supported { diff --git a/Sources/GameMP/Game.cpp b/Sources/GameMP/Game.cpp index f630c37..cf7b7b9 100755 --- a/Sources/GameMP/Game.cpp +++ b/Sources/GameMP/Game.cpp @@ -2224,7 +2224,10 @@ void CGame::GameRedrawView( CDrawPort *pdpDrawPort, ULONG ulFlags) _pInput->GetInput(TRUE); } // timer must not occur during prescanning - { CTSingleLock csTimer(&_pTimer->tm_csHooks, TRUE); + { +#if defined(PLATFORM_UNIX) && !defined(SINGLE_THREADED) + CTSingleLock csTimer(&_pTimer->tm_csHooks, TRUE); +#endif // for each local player for( INDEX i=0; i<4; i++) { // if local player From cd2a586a9ec6a56082ed45d01b44dd648babe240 Mon Sep 17 00:00:00 2001 From: ptitSeb Date: Wed, 13 Apr 2016 08:21:50 +0200 Subject: [PATCH 2/2] Better #if condition, and add a warning to be better checked latter --- Sources/Engine/Base/Lists.cpp | 3 +-- Sources/Engine/Base/SDL/SDLInput.cpp | 6 +++++- Sources/Engine/Base/Stream.cpp | 2 +- Sources/GameMP/Game.cpp | 2 ++ 4 files changed, 9 insertions(+), 4 deletions(-) mode change 100644 => 100755 Sources/Engine/Base/Lists.cpp mode change 100644 => 100755 Sources/Engine/Base/Stream.cpp diff --git a/Sources/Engine/Base/Lists.cpp b/Sources/Engine/Base/Lists.cpp old mode 100644 new mode 100755 index 414fb0b..c6ff234 --- a/Sources/Engine/Base/Lists.cpp +++ b/Sources/Engine/Base/Lists.cpp @@ -234,8 +234,7 @@ void CListNode::Remove(void) ASSERT(next.IsTailMarker() || next.IsLinked()); ASSERT(prev.IsHeadMarker() || prev.IsLinked()); - if(ln_Succ) - next.ln_Pred = &prev; + next.ln_Pred = &prev; prev.ln_Succ = &next; // make a non-linked node ln_Succ = NULL; diff --git a/Sources/Engine/Base/SDL/SDLInput.cpp b/Sources/Engine/Base/SDL/SDLInput.cpp index be6b63c..d378cc1 100755 --- a/Sources/Engine/Base/SDL/SDLInput.cpp +++ b/Sources/Engine/Base/SDL/SDLInput.cpp @@ -675,11 +675,16 @@ void CInput::DisableInput( void) inp_bPollJoysticks = FALSE; } +#define USE_MOUSEWARP 1 +// Define this to use GetMouse instead of using Message to read mouse coordinates // blank any queued mousemove events...SDLInput.cpp needs this when // returning from the menus/console to game or the viewport will jump... void CInput::ClearRelativeMouseMotion(void) { + #if USE_MOUSEWARP + SDL_GetRelativeMouseState(NULL, NULL); + #endif mouse_relative_x = mouse_relative_y = 0; } @@ -744,7 +749,6 @@ void CInput::GetInput(BOOL bPreScan) _abKeysPressed[KID_MOUSEWHEELDOWN] = FALSE; // read mouse position - //#define USE_MOUSEWARP 1 #ifdef USE_MOUSEWARP int iMx, iMy; SDL_GetRelativeMouseState(&iMx, &iMy); diff --git a/Sources/Engine/Base/Stream.cpp b/Sources/Engine/Base/Stream.cpp old mode 100644 new mode 100755 index ff63451..d1ead10 --- a/Sources/Engine/Base/Stream.cpp +++ b/Sources/Engine/Base/Stream.cpp @@ -12,7 +12,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. */ -#pragma GCC optimize 0 + #include "Engine/StdH.h" #include diff --git a/Sources/GameMP/Game.cpp b/Sources/GameMP/Game.cpp index cf7b7b9..2befdbf 100755 --- a/Sources/GameMP/Game.cpp +++ b/Sources/GameMP/Game.cpp @@ -2226,6 +2226,8 @@ void CGame::GameRedrawView( CDrawPort *pdpDrawPort, ULONG ulFlags) // timer must not occur during prescanning { #if defined(PLATFORM_UNIX) && !defined(SINGLE_THREADED) + #warning "This seems to cause Race Condition, so disabled" +#else CTSingleLock csTimer(&_pTimer->tm_csHooks, TRUE); #endif // for each local player