SDL1 to SDL2 internal changes

This commit is contained in:
SpinDizzy 2020-04-19 08:34:58 +00:00
parent 14e2a50212
commit 4f347ff3f1
12 changed files with 466 additions and 416 deletions

View file

@ -1,3 +1,9 @@
#
# TODO: MacOS port is probably broken. Someone with MacOS needs to figure out
# how to compile with SDL2.
#
##
## Supermodel
## A Sega Model 3 Arcade Emulator.
@ -51,7 +57,7 @@ LD = gcc
#
SDL_CFLAGS =
SDL_LIBS = -framework SDL -framework AGL -framework OpenGL -framework GLUT -framework Cocoa
SDL_LIBS = -framework SDL2 -framework AGL -framework OpenGL -framework GLUT -framework Cocoa
#
# OSX-specific

View file

@ -50,15 +50,15 @@ LD = gcc
# SDL
#
SDL_CFLAGS = `sdl-config --cflags`
SDL_LIBS = `sdl-config --libs`
SDL2_CFLAGS = `sdl2-config --cflags`
SDL2_LIBS = `sdl2-config --libs`
#
# UNIX-specific
#
PLATFORM_CFLAGS = $(SDL_CFLAGS)
PLATFORM_LDFLAGS = $(SDL_LIBS) -lGL -lGLU -lz -lm -lstdc++
PLATFORM_CFLAGS = $(SDL2_CFLAGS)
PLATFORM_LDFLAGS = $(SDL2_LIBS) -lGL -lGLU -lz -lm -lstdc++
###############################################################################

View file

@ -33,7 +33,7 @@
# Configuration
#
# Edit as necessary. Some users may need to edit the "Platform Configuration"
# section as well, namely SDL_LIBS and PLATFORM_LIBS.
# section as well, namely SDL2_LIBS and PLATFORM_LIBS.
###############################################################################
#
@ -42,10 +42,10 @@
BITS = 64
#
# Path to SDL
# Path to SDL2
#
SDL_INCLUDE_DIR = C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/include/SDL
SDL_LIB_DIR = C:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib
SDL2_INCLUDE_DIR = c:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/include/SDL2
SDL2_LIB_DIR = c:/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/lib/gcc/x86_64-w64-mingw32/8.1.0/lib
#
# Toolchain
@ -74,25 +74,20 @@ ifeq ($(strip $(MSYSTEM)),)
endif
#
# SDL
# SDL2
#
#
# (At least for SDL) The linked libs order is fundamental for a successful compiling!
# https://stackoverflow.com/questions/24596596/sdl-doesnt-compile-in-native-enviroment
# http://www.cplusplus.com/forum/beginner/110753/
#
SDL_LIBS = -lmingw32 -static-libgcc -static-libstdc++ -lSDLmain -lSDL -lm -luser32 -lgdi32 -lwinmm -ldxguid
SDL_CFLAGS = -D_GNU_SOURCE=1 -Dmain=SDL_main
SDL2_LIBS = -lmingw32 -lSDL2main -lSDL2 -luser32 -lgdi32 -lwinmm -limm32 -lversion -lsetupapi
SDL2_CFLAGS =
#
# MinGW/Windows-specific
#
PLATFORM_INCLUDE_DIR = $(SDL_INCLUDE_DIR)
PLATFORM_LIB_DIR = $(SDL_LIB_DIR)
PLATFORM_INCLUDE_DIR = $(SDL2_INCLUDE_DIR)
PLATFORM_LIB_DIR = $(SDL2_LIB_DIR)
PLATFORM_LIBS = -ldinput8 -lglu32 -lole32 -loleaut32 -lopengl32 -lwbemuuid -lws2_32 -lz
PLATFORM_CFLAGS = $(SDL_CFLAGS) -DSUPERMODEL_WIN32 $(addprefix -I,$(sort $(PLATFORM_INCLUDE_DIR)))
PLATFORM_LDFLAGS = -static -L$(sort $(PLATFORM_LIB_DIR)) $(SDL_LIBS) $(PLATFORM_LIBS)
PLATFORM_CFLAGS = $(SDL2_CFLAGS) -DSUPERMODEL_WIN32 $(addprefix -I,$(sort $(PLATFORM_INCLUDE_DIR)))
PLATFORM_LDFLAGS = -static -L$(sort $(PLATFORM_LIB_DIR)) $(SDL2_LIBS) $(PLATFORM_LIBS)
###############################################################################

View file

@ -2250,23 +2250,23 @@ bool CModel3::StartThreads(void)
// Create PPC main board thread, if multi-threading GPU
if (m_gpuMultiThreaded)
{
ppcBrdThread = CThread::CreateThread(StartMainBoardThread, this);
ppcBrdThread = CThread::CreateThread("MainBoard", StartMainBoardThread, this);
if (ppcBrdThread == NULL)
goto ThreadError;
}
// Create sound board thread (sync'd or unsync'd)
if (syncSndBrdThread)
sndBrdThread = CThread::CreateThread(StartSoundBoardThreadSyncd, this);
sndBrdThread = CThread::CreateThread("SoundBoardSync", StartSoundBoardThreadSyncd, this);
else
sndBrdThread = CThread::CreateThread(StartSoundBoardThread, this);
sndBrdThread = CThread::CreateThread("SoundBoardNoSync", StartSoundBoardThread, this);
if (sndBrdThread == NULL)
goto ThreadError;
// Create drive board thread, if drive board is attached
if (DriveBoard.IsAttached())
{
drvBrdThread = CThread::CreateThread(StartDriveBoardThread, this);
drvBrdThread = CThread::CreateThread("DriveBoard", StartDriveBoardThread, this);
if (drvBrdThread == NULL)
goto ThreadError;
}
@ -3237,7 +3237,7 @@ CModel3::CModel3(const Util::Config::Node &config)
}
// Dumps a memory region to a file for debugging purposes
/*
#if 0
static void Dump(const char *file, uint8_t *buf, size_t size, bool reverse32, bool reverse16)
{
FILE *fp = fopen(file, "wb");
@ -3254,7 +3254,7 @@ static void Dump(const char *file, uint8_t *buf, size_t size, bool reverse32, bo
else
printf("unable to dump %s\n", file);
}
*/
#endif
CModel3::~CModel3(void)
{

View file

@ -217,6 +217,7 @@ static void MixChannels(unsigned numSamples, INT16 *leftBuffer, INT16 *rightBuff
#endif // NUM_CHANNELS
}
/*
static void LogAudioInfo(SDL_AudioSpec *fmt)
{
InfoLog("Audio device information:");
@ -225,6 +226,7 @@ static void LogAudioInfo(SDL_AudioSpec *fmt)
InfoLog("Sample Format: %d", fmt->format);
InfoLog("");
}
*/
bool OpenAudio()
{
@ -241,18 +243,9 @@ bool OpenAudio()
fmt.samples = playSamples;
fmt.callback = PlayCallback;
// Try opening SDL audio output with that specification
SDL_AudioSpec obtained;
if (SDL_OpenAudio(&fmt, &obtained) < 0)
// Force SDL to use the format we requested; it will convert if necessary
if (SDL_OpenAudio(&fmt, nullptr) < 0)
return ErrorLog("Unable to open 44.1KHz 2-channel audio with SDL: %s\n", SDL_GetError());
LogAudioInfo(&obtained);
// Check if obtained format is what we really requested
if ((obtained.freq!=fmt.freq) || (obtained.channels!=fmt.channels) || (obtained.format!=fmt.format))
ErrorLog("Incompatible audio settings (44.1KHz, 16-bit required). Check drivers!\n");
// Check what buffer sample size was actually obtained, and use that
playSamples = obtained.samples;
// Create audio buffer
audioBufferSize = SAMPLE_RATE * BYTES_PER_SAMPLE * latency / MAX_LATENCY;

View file

@ -92,6 +92,8 @@ static Util::Config::Node s_runtime_config("Global");
Display Management
******************************************************************************/
static SDL_Window *s_window = nullptr;
/*
* Position and size of rectangular region within OpenGL display to render to.
* Unlike the config tree, these end up containing the actual resolution (and
@ -105,9 +107,11 @@ static unsigned totalXRes, totalYRes; // total resolution (the whole GL viewpo
static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio)
{
// What resolution did we actually get?
const SDL_VideoInfo *VideoInfo = SDL_GetVideoInfo();
*totalXResPtr = VideoInfo->current_w;
*totalYResPtr = VideoInfo->current_h;
int actualWidth;
int actualHeight;
SDL_GetWindowSize(s_window, &actualWidth, &actualHeight);
*totalXResPtr = actualWidth;
*totalYResPtr = actualHeight;
// If required, fix the aspect ratio of the resolution that the user passed to match Model 3 ratio
float xRes = float(*xResPtr);
@ -126,10 +130,10 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
*yOffsetPtr = (*yResPtr - (unsigned) yRes)/2;
// If the desired resolution is smaller than what we got, re-center again
if (int(*xResPtr) < VideoInfo->current_w)
*xOffsetPtr += (VideoInfo->current_w - *xResPtr)/2;
if (int(*yResPtr) < VideoInfo->current_h)
*yOffsetPtr += (VideoInfo->current_h - *yResPtr)/2;
if (int(*xResPtr) < actualWidth)
*xOffsetPtr += (actualWidth - *xResPtr)/2;
if (int(*yResPtr) < actualHeight)
*yOffsetPtr += (actualHeight - *yResPtr)/2;
// OpenGL initialization
glViewport(0,0,*xResPtr,*yResPtr);
@ -143,7 +147,7 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
for (int i = 0; i < 2; i++)
{
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
SDL_GL_SwapBuffers();
SDL_GL_SwapWindow(s_window);
}
// Write back resolution parameters
@ -159,7 +163,8 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
{
glScissor(0, correction, *totalXResPtr, *totalYResPtr - (correction * 2));
}
else {
else
{
glScissor(*xOffsetPtr + correction, *yOffsetPtr + correction, *xResPtr - (correction * 2), *yResPtr - (correction * 2));
}
return OKAY;
@ -177,12 +182,20 @@ static bool SetGLGeometry(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *
* NOTE: keepAspectRatio should always be true. It has not yet been tested with
* the wide screen hack.
*/
static bool CreateGLScreen(const std::string &caption, unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio, bool fullScreen)
static bool CreateGLScreen(const std::string &caption, bool focusWindow, unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio, bool fullScreen)
{
GLenum err;
// Call only once per program session (this is because of issues with
// DirectInput when the window is destroyed and a new one created). Use
// ResizeGLScreen() to change resolutions instead.
if (s_window != nullptr)
{
return ErrorLog("Internal error: CreateGLScreen() called more than once");
}
// Initialize video subsystem
if (SDL_InitSubSystem(SDL_INIT_VIDEO) != 0)
if (SDL_Init(SDL_INIT_VIDEO) != 0)
return ErrorLog("Unable to initialize SDL video subsystem: %s\n", SDL_GetError());
// Important GL attributes
@ -193,18 +206,32 @@ static bool CreateGLScreen(const std::string &caption, unsigned *xOffsetPtr, uns
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE,8);
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER,1);
// Set vsync
SDL_GL_SetAttribute(SDL_GL_SWAP_CONTROL, s_runtime_config["VSync"].ValueAsDefault<bool>(false) ? 1 : 0);
// Set video mode
if (SDL_SetVideoMode(*xResPtr,*yResPtr,0,SDL_OPENGL|(fullScreen?SDL_FULLSCREEN|SDL_HWSURFACE:0)) == NULL)
s_window = SDL_CreateWindow(caption.c_str(), SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, *xResPtr, *yResPtr, SDL_WINDOW_OPENGL | SDL_WINDOW_SHOWN | (fullScreen ? SDL_WINDOW_FULLSCREEN : 0));
if (nullptr == s_window)
{
ErrorLog("Unable to create an OpenGL display: %s\n", SDL_GetError());
return FAIL;
}
// Create window caption
SDL_WM_SetCaption(caption.c_str(),NULL);
if (focusWindow)
{
SDL_RaiseWindow(s_window);
}
// Create OpenGL context
SDL_GLContext context = SDL_GL_CreateContext(s_window);
if (nullptr == context)
{
ErrorLog("Unable to create OpenGL context: %s\n", SDL_GetError());
return FAIL;
}
// Set vsync
SDL_GL_SetSwapInterval(s_runtime_config["VSync"].ValueAsDefault<bool>(false) ? 1 : 0);
// Set the context as the current window context
SDL_GL_MakeCurrent(s_window, context);
// Initialize GLEW, allowing us to use features beyond OpenGL 1.2
err = glewInit();
@ -217,12 +244,21 @@ static bool CreateGLScreen(const std::string &caption, unsigned *xOffsetPtr, uns
return SetGLGeometry(xOffsetPtr, yOffsetPtr, xResPtr, yResPtr, totalXResPtr, totalYResPtr, keepAspectRatio);
}
static void DestroyGLScreen()
{
if (s_window != nullptr)
{
SDL_GL_DeleteContext(SDL_GL_GetCurrentContext());
SDL_DestroyWindow(s_window);
}
}
static bool ResizeGLScreen(unsigned *xOffsetPtr, unsigned *yOffsetPtr, unsigned *xResPtr, unsigned *yResPtr, unsigned *totalXResPtr, unsigned *totalYResPtr, bool keepAspectRatio, bool fullScreen)
{
// Set video mode
if (SDL_SetVideoMode(*xResPtr,*yResPtr,0,SDL_OPENGL|(fullScreen?SDL_FULLSCREEN|SDL_HWSURFACE:0)) == NULL)
// Set full screen mode
if (SDL_SetWindowFullscreen(s_window, fullScreen ? SDL_WINDOW_FULLSCREEN : 0) < 0)
{
ErrorLog("Unable to create an OpenGL display: %s\n", SDL_GetError());
ErrorLog("Unable to enter %s mode: %s\n", fullScreen ? "fullscreen" : "windowed", SDL_GetError());
return FAIL;
}
@ -240,7 +276,7 @@ static void PrintGLInfo(bool createScreen, bool infoLog, bool printExtensions)
unsigned xOffset, yOffset, xRes=496, yRes=384, totalXRes, totalYRes;
if (createScreen)
{
if (OKAY != CreateGLScreen("Supermodel - Querying OpenGL Information...", &xOffset, &yOffset, &xRes, &yRes, &totalXRes, &totalYRes, false, false))
if (OKAY != CreateGLScreen("Supermodel - Querying OpenGL Information...", false, &xOffset, &yOffset, &xRes, &yRes, &totalXRes, &totalYRes, false, false))
{
ErrorLog("Unable to query OpenGL.\n");
return;
@ -771,7 +807,7 @@ void EndFrameVideo()
UpdateCrosshairs(currentInputs, videoInputs, s_runtime_config["Crosshairs"].ValueAs<unsigned>());
// Swap the buffers
SDL_GL_SwapBuffers();
SDL_GL_SwapWindow(s_window);
}
static void SuperSleep(UINT32 time)
@ -814,15 +850,16 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
// Load NVRAM
LoadNVRAM(Model3);
// Start up SDL and open a GL window
// Set the video mode
char baseTitleStr[128];
char titleStr[128];
totalXRes = xRes = s_runtime_config["XResolution"].ValueAs<unsigned>();
totalYRes = yRes = s_runtime_config["YResolution"].ValueAs<unsigned>();
sprintf(baseTitleStr, "Supermodel - %s", game.title.c_str());
SDL_SetWindowTitle(s_window, baseTitleStr);
bool stretch = s_runtime_config["Stretch"].ValueAs<bool>();
bool fullscreen = s_runtime_config["FullScreen"].ValueAs<bool>();
if (OKAY != CreateGLScreen(baseTitleStr, &xOffset, &yOffset ,&xRes, &yRes, &totalXRes, &totalYRes, !stretch, fullscreen))
if (OKAY != ResizeGLScreen(&xOffset, &yOffset ,&xRes, &yRes, &totalXRes, &totalYRes, !stretch, fullscreen))
return 1;
// Info log GL information
@ -965,13 +1002,13 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
Model3->PauseThreads();
SetAudioEnabled(false);
sprintf(titleStr, "%s (Paused)", baseTitleStr);
SDL_WM_SetCaption(titleStr,NULL);
SDL_SetWindowTitle(s_window, titleStr);
}
else
{
Model3->ResumeThreads();
SetAudioEnabled(true);
SDL_WM_SetCaption(baseTitleStr,NULL);
SDL_SetWindowTitle(s_window, baseTitleStr);
}
// Send paused value as output
@ -1156,14 +1193,13 @@ int Supermodel(const Game &game, ROMSet *rom_set, IEmulator *Model3, CInputs *In
// Frame rate and limiting
unsigned currentFPSTicks = SDL_GetTicks();
unsigned currentTicks = currentFPSTicks;
if (s_runtime_config["ShowFrameRate"].ValueAs<bool>())
{
++fpsFramesElapsed;
if((currentFPSTicks-prevFPSTicks) >= 1000) // update FPS every 1 second (each tick is 1 ms)
{
sprintf(titleStr, "%s - %1.1f FPS%s", baseTitleStr, (float)fpsFramesElapsed/((float)(currentFPSTicks-prevFPSTicks)/1000.0f), paused ? " (Paused)" : "");
SDL_WM_SetCaption(titleStr,NULL);
SDL_SetWindowTitle(s_window, titleStr);
prevFPSTicks = currentFPSTicks; // reset tick count
fpsFramesElapsed = 0; // reset frame count
}
@ -1241,6 +1277,13 @@ static bool ConfigureInputs(CInputs *Inputs, Util::Config::Node *fileConfig, Uti
// If the user wants to configure the inputs, do that now
if (configure)
{
std::string title("Supermodel - ");
if (game.name.empty())
title.append("Configuring Default Inputs...");
else
title.append(Util::Format() << "Configuring Inputs for: " << game.title);
SDL_SetWindowTitle(s_window, title.c_str());
// Extract the relevant INI section (which will be the global section if no
// game was specified, otherwise the game's node) in the file config, which
// will be written back to disk
@ -1250,16 +1293,6 @@ static bool ConfigureInputs(CInputs *Inputs, Util::Config::Node *fileConfig, Uti
fileConfigRoot = &fileConfig->Add(game.name);
}
// Open an SDL window
unsigned xOffset, yOffset, xRes=496, yRes=384;
std::string title("Supermodel - ");
if (game.name.empty())
title.append("Configuring Default Inputs...");
else
title.append(Util::Format() << "Configuring Inputs for: " << game.title);
if (OKAY != CreateGLScreen(title, &xOffset, &yOffset, &xRes, &yRes, &totalXRes, &totalYRes, false, false))
return (bool) ErrorLog("Unable to start SDL to configure inputs.\n");
// Configure the inputs
if (Inputs->ConfigureInputs(game, xOffset, yOffset, xRes, yRes))
{
@ -1672,6 +1705,7 @@ int main(int argc, char **argv)
}
if (cmd_line.print_gl_info)
{
// We must exit after this because CreateGLScreen() is used
PrintGLInfo(true, false, false);
return 0;
}
@ -1715,6 +1749,7 @@ int main(int argc, char **argv)
Util::Config::MergeINISections(&s_runtime_config, config4, cmd_line.config); // apply command line overrides once more
}
LogConfig(s_runtime_config);
std::string selectedInputSystem = s_runtime_config["InputSystem"].ValueAs<std::string>();
// Initialize SDL (individual subsystems get initialized later)
if (SDL_Init(0) != 0)
@ -1723,33 +1758,42 @@ int main(int argc, char **argv)
return 1;
}
// Create Model 3 emulator
#ifdef DEBUG
IEmulator *Model3 = s_gfxStatePath.empty() ? static_cast<IEmulator *>(new CModel3(s_runtime_config)) : static_cast<IEmulator *>(new CModel3GraphicsState(s_runtime_config, s_gfxStatePath));
#else
IEmulator *Model3 = new CModel3(s_runtime_config);
#endif
// Create input system (default is SDL) and debugger
CInputSystem *InputSystem = NULL;
CInputs *Inputs = NULL;
COutputs *Outputs = NULL;
// Begin initializing various subsystems...
int exitCode = 0;
IEmulator *Model3 = nullptr;
CInputSystem *InputSystem = nullptr;
CInputs *Inputs = nullptr;
COutputs *Outputs = nullptr;
#ifdef SUPERMODEL_DEBUGGER
Debugger::CSupermodelDebugger *Debugger = NULL;
#endif // SUPERMODEL_DEBUGGER
// Create a window
xRes = 496;
yRes = 384;
if (OKAY != CreateGLScreen("Supermodel", false, &xOffset, &yOffset, &xRes, &yRes, &totalXRes, &totalYRes, false, false))
{
exitCode = 1;
goto Exit;
}
// Create Model 3 emulator
#ifdef DEBUG
Model3 = s_gfxStatePath.empty() ? static_cast<IEmulator *>(new CModel3(s_runtime_config)) : static_cast<IEmulator *>(new CModel3GraphicsState(s_runtime_config, s_gfxStatePath));
#else
Model3 = new CModel3(s_runtime_config);
#endif
// Create input system
std::string selectedInputSystem = s_runtime_config["InputSystem"].ValueAs<std::string>();
if (selectedInputSystem == "sdl")
InputSystem = new CSDLInputSystem();
#ifdef SUPERMODEL_WIN32
else if (selectedInputSystem == "dinput")
InputSystem = new CDirectInputSystem(s_runtime_config, false, false);
InputSystem = new CDirectInputSystem(s_runtime_config, s_window, false, false);
else if (selectedInputSystem == "xinput")
InputSystem = new CDirectInputSystem(s_runtime_config, false, true);
InputSystem = new CDirectInputSystem(s_runtime_config, s_window, false, true);
else if (selectedInputSystem == "rawinput")
InputSystem = new CDirectInputSystem(s_runtime_config, true, false);
InputSystem = new CDirectInputSystem(s_runtime_config, s_window, true, false);
#endif // SUPERMODEL_WIN32
else
{
@ -1836,6 +1880,7 @@ Exit:
delete InputSystem;
if (Outputs != NULL)
delete Outputs;
DestroyGLScreen();
SDL_Quit();
if (exitCode)

View file

@ -23,6 +23,10 @@
* SDLInputSystem.cpp
*
* Implementation of SDL input system.
*
* TODO:
* -----
* - Implement multiple keyboard and mouse support.
*/
#include "SDLInputSystem.h"
@ -34,157 +38,137 @@ using namespace std;
SDLKeyMapStruct CSDLInputSystem::s_keyMap[] =
{
// General keys
{ "BACKSPACE", SDLK_BACKSPACE },
{ "TAB", SDLK_TAB },
{ "CLEAR", SDLK_CLEAR },
{ "RETURN", SDLK_RETURN },
{ "PAUSE", SDLK_PAUSE },
{ "ESCAPE", SDLK_ESCAPE },
{ "SPACE", SDLK_SPACE },
{ "EXCLAIM", SDLK_EXCLAIM },
{ "DBLQUOTE", SDLK_QUOTEDBL },
{ "HASH", SDLK_HASH },
{ "DOLLAR", SDLK_DOLLAR },
{ "AMPERSAND", SDLK_AMPERSAND },
{ "QUOTE", SDLK_QUOTE },
{ "LEFTPAREN", SDLK_LEFTPAREN },
{ "RIGHTPAREN", SDLK_RIGHTPAREN },
{ "ASTERISK", SDLK_ASTERISK },
{ "PLUS", SDLK_PLUS },
{ "COMMA", SDLK_COMMA },
{ "MINUS", SDLK_MINUS },
{ "PERIOD", SDLK_PERIOD },
{ "SLASH", SDLK_SLASH },
{ "0", SDLK_0 },
{ "1", SDLK_1 },
{ "2", SDLK_2 },
{ "3", SDLK_3 },
{ "4", SDLK_4 },
{ "5", SDLK_5 },
{ "6", SDLK_6 },
{ "7", SDLK_7 },
{ "8", SDLK_8 },
{ "9", SDLK_9 },
{ "COLON", SDLK_COLON },
{ "SEMICOLON", SDLK_SEMICOLON },
{ "LESS", SDLK_LESS },
{ "EQUALS", SDLK_EQUALS },
{ "GREATER", SDLK_GREATER },
{ "QUESTION", SDLK_QUESTION },
{ "AT", SDLK_AT },
{ "LEFTBRACKET", SDLK_LEFTBRACKET },
{ "BACKSLASH", SDLK_BACKSLASH },
{ "RIGHTBRACKET", SDLK_RIGHTBRACKET },
{ "CARET", SDLK_CARET },
{ "UNDERSCORE", SDLK_UNDERSCORE },
{ "BACKQUOTE", SDLK_BACKQUOTE },
{ "A", SDLK_a },
{ "B", SDLK_b },
{ "C", SDLK_c },
{ "D", SDLK_d },
{ "E", SDLK_e },
{ "F", SDLK_f },
{ "G", SDLK_g },
{ "H", SDLK_h },
{ "I", SDLK_i },
{ "J", SDLK_j },
{ "K", SDLK_k },
{ "L", SDLK_l },
{ "M", SDLK_m },
{ "N", SDLK_n },
{ "O", SDLK_o },
{ "P", SDLK_p },
{ "Q", SDLK_q },
{ "R", SDLK_r },
{ "S", SDLK_s },
{ "T", SDLK_t },
{ "U", SDLK_u },
{ "V", SDLK_v },
{ "W", SDLK_w },
{ "X", SDLK_x },
{ "Y", SDLK_y },
{ "Z", SDLK_z },
{ "DEL", SDLK_DELETE },
{ "BACKSPACE", SDL_SCANCODE_BACKSPACE },
{ "TAB", SDL_SCANCODE_TAB },
{ "CLEAR", SDL_SCANCODE_CLEAR },
{ "RETURN", SDL_SCANCODE_RETURN },
{ "PAUSE", SDL_SCANCODE_PAUSE },
{ "ESCAPE", SDL_SCANCODE_ESCAPE },
{ "SPACE", SDL_SCANCODE_SPACE },
{ "QUOTE", SDL_SCANCODE_APOSTROPHE },
{ "LEFTPAREN", SDL_SCANCODE_KP_LEFTPAREN },
{ "RIGHTPAREN", SDL_SCANCODE_KP_RIGHTPAREN },
{ "COMMA", SDL_SCANCODE_COMMA },
{ "MINUS", SDL_SCANCODE_MINUS },
{ "PERIOD", SDL_SCANCODE_PERIOD },
{ "SLASH", SDL_SCANCODE_SLASH },
{ "0", SDL_SCANCODE_0 },
{ "1", SDL_SCANCODE_1 },
{ "2", SDL_SCANCODE_2 },
{ "3", SDL_SCANCODE_3 },
{ "4", SDL_SCANCODE_4 },
{ "5", SDL_SCANCODE_5 },
{ "6", SDL_SCANCODE_6 },
{ "7", SDL_SCANCODE_7 },
{ "8", SDL_SCANCODE_8 },
{ "9", SDL_SCANCODE_9 },
{ "SEMICOLON", SDL_SCANCODE_SEMICOLON },
{ "EQUALS", SDL_SCANCODE_EQUALS },
{ "LEFTBRACKET", SDL_SCANCODE_LEFTBRACKET },
{ "BACKSLASH", SDL_SCANCODE_BACKSLASH },
{ "RIGHTBRACKET", SDL_SCANCODE_RIGHTBRACKET },
{ "BACKQUOTE", SDL_SCANCODE_GRAVE },
{ "A", SDL_SCANCODE_A },
{ "B", SDL_SCANCODE_B },
{ "C", SDL_SCANCODE_C },
{ "D", SDL_SCANCODE_D },
{ "E", SDL_SCANCODE_E },
{ "F", SDL_SCANCODE_F },
{ "G", SDL_SCANCODE_G },
{ "H", SDL_SCANCODE_H },
{ "I", SDL_SCANCODE_I },
{ "J", SDL_SCANCODE_J },
{ "K", SDL_SCANCODE_K },
{ "L", SDL_SCANCODE_L },
{ "M", SDL_SCANCODE_M },
{ "N", SDL_SCANCODE_N },
{ "O", SDL_SCANCODE_O },
{ "P", SDL_SCANCODE_P },
{ "Q", SDL_SCANCODE_Q },
{ "R", SDL_SCANCODE_R },
{ "S", SDL_SCANCODE_S },
{ "T", SDL_SCANCODE_T },
{ "U", SDL_SCANCODE_U },
{ "V", SDL_SCANCODE_V },
{ "W", SDL_SCANCODE_W },
{ "X", SDL_SCANCODE_X },
{ "Y", SDL_SCANCODE_Y },
{ "Z", SDL_SCANCODE_Z },
{ "DEL", SDL_SCANCODE_DELETE },
// Keypad
{ "KEYPAD0", SDLK_KP0 },
{ "KEYPAD1", SDLK_KP1 },
{ "KEYPAD2", SDLK_KP2 },
{ "KEYPAD3", SDLK_KP3 },
{ "KEYPAD4", SDLK_KP4 },
{ "KEYPAD5", SDLK_KP5 },
{ "KEYPAD6", SDLK_KP6 },
{ "KEYPAD7", SDLK_KP7 },
{ "KEYPAD8", SDLK_KP8 },
{ "KEYPAD9", SDLK_KP9 },
{ "KEYPADPERIOD", SDLK_KP_PERIOD },
{ "KEYPADDIVIDE", SDLK_KP_DIVIDE },
{ "KEYPADMULTIPLY", SDLK_KP_MULTIPLY },
{ "KEYPADMINUS", SDLK_KP_MINUS },
{ "KEYPADPLUS", SDLK_KP_PLUS },
{ "KEYPADENTER", SDLK_KP_ENTER },
{ "KEYPADEQUALS", SDLK_KP_EQUALS },
{ "KEYPAD0", SDL_SCANCODE_KP_0 },
{ "KEYPAD1", SDL_SCANCODE_KP_1 },
{ "KEYPAD2", SDL_SCANCODE_KP_2 },
{ "KEYPAD3", SDL_SCANCODE_KP_3 },
{ "KEYPAD4", SDL_SCANCODE_KP_4 },
{ "KEYPAD5", SDL_SCANCODE_KP_5 },
{ "KEYPAD6", SDL_SCANCODE_KP_6 },
{ "KEYPAD7", SDL_SCANCODE_KP_7 },
{ "KEYPAD8", SDL_SCANCODE_KP_8 },
{ "KEYPAD9", SDL_SCANCODE_KP_9 },
{ "KEYPADPERIOD", SDL_SCANCODE_KP_PERIOD },
{ "KEYPADDIVIDE", SDL_SCANCODE_KP_DIVIDE },
{ "KEYPADMULTIPLY", SDL_SCANCODE_KP_MULTIPLY },
{ "KEYPADMINUS", SDL_SCANCODE_KP_MINUS },
{ "KEYPADPLUS", SDL_SCANCODE_KP_PLUS },
{ "KEYPADENTER", SDL_SCANCODE_KP_ENTER },
{ "KEYPADEQUALS", SDL_SCANCODE_KP_EQUALS },
// Arrows + Home/End Pad
{ "UP", SDLK_UP },
{ "DOWN", SDLK_DOWN },
{ "RIGHT", SDLK_RIGHT },
{ "LEFT", SDLK_LEFT },
{ "INSERT", SDLK_INSERT },
{ "HOME", SDLK_HOME },
{ "END", SDLK_END },
{ "PGUP", SDLK_PAGEUP },
{ "PGDN", SDLK_PAGEDOWN },
{ "UP", SDL_SCANCODE_UP },
{ "DOWN", SDL_SCANCODE_DOWN },
{ "RIGHT", SDL_SCANCODE_RIGHT },
{ "LEFT", SDL_SCANCODE_LEFT },
{ "INSERT", SDL_SCANCODE_INSERT },
{ "HOME", SDL_SCANCODE_HOME },
{ "END", SDL_SCANCODE_END },
{ "PGUP", SDL_SCANCODE_PAGEUP },
{ "PGDN", SDL_SCANCODE_PAGEDOWN },
// Function Key
{ "F1", SDLK_F1 },
{ "F2", SDLK_F2 },
{ "F3", SDLK_F3 },
{ "F4", SDLK_F4 },
{ "F5", SDLK_F5 },
{ "F6", SDLK_F6 },
{ "F7", SDLK_F7 },
{ "F8", SDLK_F8 },
{ "F9", SDLK_F9 },
{ "F10", SDLK_F10 },
{ "F11", SDLK_F11 },
{ "F12", SDLK_F12 },
{ "F13", SDLK_F13 },
{ "F14", SDLK_F14 },
{ "F15", SDLK_F15 },
{ "F1", SDL_SCANCODE_F1 },
{ "F2", SDL_SCANCODE_F2 },
{ "F3", SDL_SCANCODE_F3 },
{ "F4", SDL_SCANCODE_F4 },
{ "F5", SDL_SCANCODE_F5 },
{ "F6", SDL_SCANCODE_F6 },
{ "F7", SDL_SCANCODE_F7 },
{ "F8", SDL_SCANCODE_F8 },
{ "F9", SDL_SCANCODE_F9 },
{ "F10", SDL_SCANCODE_F10 },
{ "F11", SDL_SCANCODE_F11 },
{ "F12", SDL_SCANCODE_F12 },
{ "F13", SDL_SCANCODE_F13 },
{ "F14", SDL_SCANCODE_F14 },
{ "F15", SDL_SCANCODE_F15 },
// Modifier Keys
// Removed Numlock, Capslock and Scrollock as don't seem to be handled well by SDL
//{ "NUMLOCK", SDLK_NUMLOCK },
//{ "CAPSLOCK", SDLK_CAPSLOCK },
//{ "CAPSLOCK", SDL_SCANCODE_CAPSLOCK },
//{ "SCROLLLOCK", SDLK_SCROLLOCK },
{ "RIGHTSHIFT", SDLK_RSHIFT },
{ "LEFTSHIFT", SDLK_LSHIFT },
{ "RIGHTCTRL", SDLK_RCTRL },
{ "LEFTCTRL", SDLK_LCTRL },
{ "RIGHTALT", SDLK_RALT },
{ "LEFTALT", SDLK_LALT },
{ "RIGHTMETA", SDLK_RMETA },
{ "LEFTMETA", SDLK_LMETA },
{ "RIGHTWINDOWS", SDLK_RSUPER },
{ "LEFTWINDOWS", SDLK_LSUPER },
{ "ALTGR", SDLK_MODE },
{ "COMPOSE", SDLK_COMPOSE },
{ "RIGHTSHIFT", SDL_SCANCODE_RSHIFT },
{ "LEFTSHIFT", SDL_SCANCODE_LSHIFT },
{ "RIGHTCTRL", SDL_SCANCODE_RCTRL },
{ "LEFTCTRL", SDL_SCANCODE_LCTRL },
{ "RIGHTALT", SDL_SCANCODE_RALT },
{ "LEFTALT", SDL_SCANCODE_LALT },
{ "RIGHTMETA", SDL_SCANCODE_RGUI },
{ "LEFTMETA", SDL_SCANCODE_LGUI },
{ "ALTGR", SDL_SCANCODE_MODE },
// Other
{ "HELP", SDLK_HELP },
{ "PRINT", SDLK_PRINT },
{ "SYSREQ", SDLK_SYSREQ },
{ "BREAK", SDLK_BREAK },
{ "MENU", SDLK_MENU },
{ "POWER", SDLK_POWER },
{ "EURO", SDLK_EURO },
{ "UNDO", SDLK_UNDO }
{ "HELP", SDL_SCANCODE_HELP },
{ "SYSREQ", SDL_SCANCODE_SYSREQ },
{ "MENU", SDL_SCANCODE_MENU },
{ "POWER", SDL_SCANCODE_POWER },
{ "UNDO", SDL_SCANCODE_UNDO }
};
CSDLInputSystem::CSDLInputSystem()
: CInputSystem("SDL"),
m_keyState(NULL),
m_keyState(nullptr),
m_mouseX(0),
m_mouseY(0),
m_mouseZ(0),
@ -205,7 +189,7 @@ void CSDLInputSystem::OpenJoysticks()
for (int joyNum = 0; joyNum < numJoys; joyNum++)
{
SDL_Joystick *joystick = SDL_JoystickOpen(joyNum);
if (joystick == NULL)
if (joystick == nullptr)
{
ErrorLog("Unable to open joystick device %d with SDL - skipping joystick.\n", joyNum + 1);
continue;
@ -213,7 +197,7 @@ void CSDLInputSystem::OpenJoysticks()
// Gather joystick details (name, num POVs & buttons and which axes are available)
JoyDetails joyDetails;
const char *pName = SDL_JoystickName(joyNum);
const char *pName = SDL_JoystickName(joystick);
strncpy(joyDetails.name, pName, MAX_NAME_LENGTH);
joyDetails.name[MAX_NAME_LENGTH] = '\0';
joyDetails.numAxes = SDL_JoystickNumAxes(joystick);
@ -275,14 +259,14 @@ int CSDLInputSystem::GetKeyIndex(const char *keyName)
const char *CSDLInputSystem::GetKeyName(int keyIndex)
{
if (keyIndex < 0 || keyIndex >= NUM_SDL_KEYS)
return NULL;
return nullptr;
return s_keyMap[keyIndex].keyName;
}
bool CSDLInputSystem::IsKeyPressed(int kbdNum, int keyIndex)
{
// Get SDL key for given index and check if currently pressed
SDLKey sdlKey = s_keyMap[keyIndex].sdlKey;
SDL_Keycode sdlKey = s_keyMap[keyIndex].sdlKey;
return !!m_keyState[sdlKey];
}
@ -374,14 +358,14 @@ int CSDLInputSystem::GetNumJoysticks()
const KeyDetails *CSDLInputSystem::GetKeyDetails(int kbdNum)
{
// Return NULL as SDL 1.2 cannot handle multiple keyboards
return NULL;
// Return nullptr as SDL 1.2 cannot handle multiple keyboards
return nullptr;
}
const MouseDetails *CSDLInputSystem::GetMouseDetails(int mseNum)
{
// Return NULL as SDL 1.2 cannot handle multiple mice
return NULL;
// Return nullptr as SDL 1.2 cannot handle multiple mice
return nullptr;
}
const JoyDetails *CSDLInputSystem::GetJoyDetails(int joyNum)
@ -398,27 +382,29 @@ bool CSDLInputSystem::Poll()
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
return false;
else if (e.type == SDL_MOUSEBUTTONDOWN)
switch (e.type)
{
// Mouse wheel movements are not returned by SDL_GetMouseState below, so they are handled here instead
// The mouse absolute Z-axis value and mouse wheel direction value are updated appropriately
if (e.button.button == SDL_BUTTON_WHEELUP)
default:
break;
case SDL_QUIT:
return false;
case SDL_MOUSEWHEEL:
if (e.button.y > 0)
{
m_mouseZ += 5;
m_mouseWheelDir = 1;
}
else if (e.button.button == SDL_BUTTON_WHEELDOWN)
else if (e.button.y < 0)
{
m_mouseZ -= 5;
m_mouseWheelDir = -1;
}
break;
}
}
// Get key state from SDL
m_keyState = SDL_GetKeyState(NULL);
m_keyState = SDL_GetKeyboardState(nullptr);
// Get mouse state from SDL (except mouse wheel which was handled earlier)
m_mouseButtons = SDL_GetMouseState(&m_mouseX, &m_mouseY);

View file

@ -46,7 +46,7 @@ using namespace std;
struct SDLKeyMapStruct
{
const char *keyName;
SDLKey sdlKey;
SDL_Scancode sdlKey;
};
/*
@ -65,7 +65,7 @@ private:
vector<JoyDetails> m_joyDetails;
// Current key state obtained from SDL
Uint8 *m_keyState;
const Uint8 *m_keyState;
// Current mouse state obtained from SDL
int m_mouseX;

View file

@ -45,12 +45,12 @@ UINT32 CThread::GetTicks()
return SDL_GetTicks();
}
CThread *CThread::CreateThread(ThreadStart start, void *startParam)
CThread *CThread::CreateThread(const std::string &name, ThreadStart start, void *startParam)
{
SDL_Thread *impl = SDL_CreateThread(start, startParam);
SDL_Thread *impl = SDL_CreateThread(start, name.c_str(), startParam);
if (impl == NULL)
return NULL;
return new CThread(impl);
return new CThread(name, impl);
}
CSemaphore *CThread::CreateSemaphore(UINT32 initVal)
@ -82,14 +82,26 @@ const char *CThread::GetLastError()
return SDL_GetError();
}
CThread::CThread(void *impl) : m_impl(impl)
CThread::CThread(const std::string &name, void *impl)
: m_name(name),
m_impl(impl)
{
//
}
CThread::~CThread()
{
Kill();
// User should have called Wait() before thread object is destroyed
if (nullptr != m_impl)
{
ErrorLog("Runaway thread error. A thread was not properly halted: %s\n", GetName());
}
}
const std::string &CThread::GetName() const
{
return m_name;
}
UINT32 CThread::GetId()
@ -97,13 +109,6 @@ UINT32 CThread::GetId()
return SDL_GetThreadID((SDL_Thread*)m_impl);
}
void CThread::Kill()
{
if (m_impl != NULL)
SDL_KillThread((SDL_Thread*)m_impl);
m_impl = NULL;
}
int CThread::Wait()
{
int status;

View file

@ -28,6 +28,8 @@
#ifndef INCLUDED_THREADS_H
#define INCLUDED_THREADS_H
#include <string>
class CSemaphore;
class CMutex;
class CCondVar;
@ -42,9 +44,10 @@ typedef int (*ThreadStart)(void *startParam);
class CThread
{
private:
const std::string m_name;
void *m_impl;
CThread(void *impl);
CThread(const std::string &name, void *impl);
public:
/*
@ -66,7 +69,7 @@ public:
*
* Creates a new thread with the given ThreadStart callback and start parameter. The thread starts running immediately.
*/
static CThread *CreateThread(ThreadStart start, void *startParam);
static CThread *CreateThread(const std::string &name, ThreadStart start, void *startParam);
/*
* CreateSemaphore
@ -101,6 +104,13 @@ public:
*/
~CThread();
/*
* GetName
*
* Returns the name of this thread.
*/
const std::string &GetName() const;
/*
* GetId
*
@ -108,13 +118,6 @@ public:
*/
UINT32 GetId();
/*
* Kill
*
* Kills this thread.
*/
void Kill();
/*
* Wait
*

View file

@ -428,11 +428,11 @@ const char *CDirectInputSystem::ConstructName(bool useRawInput, bool useXInput)
return (useXInput ? "Xinput" : "DirectInput");
}
CDirectInputSystem::CDirectInputSystem(const Util::Config::Node &config, bool useRawInput, bool useXInput) :
CDirectInputSystem::CDirectInputSystem(const Util::Config::Node &config, SDL_Window *window, bool useRawInput, bool useXInput) :
CInputSystem(ConstructName(useRawInput, useXInput)),
m_config(config),
m_useRawInput(useRawInput), m_useXInput(useXInput), m_enableFFeedback(true),
m_initializedCOM(false), m_activated(false), m_hwnd(NULL), m_screenW(0), m_screenH(0),
m_initializedCOM(false), m_activated(false), m_window(window), m_hwnd(NULL), m_screenW(0), m_screenH(0),
m_getRIDevListPtr(NULL), m_getRIDevInfoPtr(NULL), m_regRIDevsPtr(NULL), m_getRIDataPtr(NULL),
m_xiGetCapabilitiesPtr(NULL), m_xiGetStatePtr(NULL), m_xiSetStatePtr(NULL), m_di8(NULL), m_di8Keyboard(NULL), m_di8Mouse(NULL)
{
@ -2051,8 +2051,10 @@ bool CDirectInputSystem::Poll()
// If not, then get Window handle of SDL window
SDL_SysWMinfo info;
SDL_VERSION(&info.version);
if (SDL_GetWMInfo(&info))
m_hwnd = info.window;
if (SDL_GetWindowWMInfo(m_window, &info))
{
m_hwnd = info.info.win.window;
}
// Tell SDL to pass on all Windows events
// Removed - see below
@ -2102,6 +2104,17 @@ bool CDirectInputSystem::Poll()
}
}
// SDL2: I'm not sure how the SDL1.x code was detecting quit events but in
// SDL2, it seems that we want to explicitly run SDL_PollEvent() after we
// have peeked at the message queue ourselves (above).
// Wait or poll for event from SDL
SDL_Event e;
while (SDL_PollEvent(&e))
{
if (e.type == SDL_QUIT)
return false;
}
// Poll keyboards, mice and joysticks
PollKeyboardsAndMice();
PollJoysticks();

View file

@ -33,10 +33,13 @@
#include "Inputs/InputSource.h"
#include "Inputs/InputSystem.h"
#include <SDL.h>
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <dinput.h>
#include <XInput.h>
#include <functional>
#include <vector>
using namespace std;
@ -125,6 +128,7 @@ private:
bool m_initializedCOM;
bool m_activated;
SDL_Window *m_window = nullptr;
// Function pointers for RawInput API
GetRawInputDeviceListPtr m_getRIDevListPtr;
@ -234,7 +238,7 @@ public:
* to the same shared axis and so cannot be distinguished when pressed together.
* If enableFFeedback is true then force feedback is enabled (for those joysticks which are force feedback capable).
*/
CDirectInputSystem(const Util::Config::Node &config, bool useRawInput, bool useXInput);
CDirectInputSystem(const Util::Config::Node &config, SDL_Window *window, bool useRawInput, bool useXInput);
~CDirectInputSystem();