diff --git a/Sources/CMakeLists.txt b/Sources/CMakeLists.txt index 7f823cb..e17288a 100644 --- a/Sources/CMakeLists.txt +++ b/Sources/CMakeLists.txt @@ -152,7 +152,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( @@ -585,6 +588,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 @@ -623,12 +642,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 old mode 100644 new mode 100755 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..d378cc1 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); } @@ -656,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; } @@ -697,12 +721,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 +749,15 @@ void CInput::GetInput(BOOL bPreScan) _abKeysPressed[KID_MOUSEWHEELDOWN] = FALSE; // read mouse position - if ((mouse_relative_x != 0) || (mouse_relative_y != 0)) { + #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 +807,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 old mode 100644 new mode 100755 diff --git a/Sources/Engine/Base/Timer.cpp b/Sources/Engine/Base/Timer.cpp old mode 100644 new mode 100755 index 8922297..db603b3 --- a/Sources/Engine/Base/Timer.cpp +++ b/Sources/Engine/Base/Timer.cpp @@ -195,8 +195,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 @@ -433,8 +434,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 @@ -473,7 +474,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..2befdbf 100755 --- a/Sources/GameMP/Game.cpp +++ b/Sources/GameMP/Game.cpp @@ -2224,7 +2224,12 @@ 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) + #warning "This seems to cause Race Condition, so disabled" +#else + CTSingleLock csTimer(&_pTimer->tm_csHooks, TRUE); +#endif // for each local player for( INDEX i=0; i<4; i++) { // if local player