Merge pull request #24 from ptitSeb/master

More OpenPandora support (special keymap) and optionnal Multi-Threading.
This commit is contained in:
Ryan C. Gordon 2016-04-15 14:52:56 -04:00
commit dc2c869cfc
11 changed files with 148 additions and 27 deletions

View File

@ -152,7 +152,10 @@ endif()
# !!! FIXME: I currently force this, but you shouldn't _have_ to.
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

0
Sources/Engine/Base/Lists.cpp Normal file → Executable file
View File

22
Sources/Engine/Base/SDL/SDLEvents.cpp Normal file → Executable file
View File

@ -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

View File

@ -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);
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,8 +721,20 @@ void CInput::GetInput(BOOL bPreScan)
// get codes
INDEX iKID = kc.kc_iKID;
//INDEX iScan = kc.kc_iScanCode;
//INDEX iVirt = kc.kc_iVirtKey;
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
@ -706,13 +742,22 @@ void CInput::GetInput(BOOL bPreScan)
}
}
}
}
// reset this every frame (since we explicitly ignore the button-up events).
_abKeysPressed[KID_MOUSEWHEELUP] = FALSE;
_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

0
Sources/Engine/Base/Stream.cpp Normal file → Executable file
View File

9
Sources/Engine/Base/Timer.cpp Normal file → Executable file
View File

@ -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

4
Sources/Engine/Base/Timer.h Normal file → Executable file
View File

@ -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

View File

@ -6,7 +6,7 @@
#include "Engine/StdH.h"
#include <Engine/Base/Synchronization.h>
//#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;
}
}

View File

@ -648,8 +648,13 @@ 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.
#ifdef PLATFORM_WIN32
@ -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

View File

@ -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
{

View File

@ -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