Работа по переписыванию на SDL3 стандартную библеотеку C

This commit is contained in:
DepressedTWM 2026-05-30 10:07:56 -04:00
parent 7763b998a6
commit 78114ba0c9
21 changed files with 193 additions and 332 deletions

View File

@ -234,8 +234,6 @@ void ALStream::openSource(const std::string &filename){
char buf[512]; char buf[512];
snprintf(buf, sizeof(buf), "Unable to decode audio stream: %s: %s", filename.c_str(), handler.errorMsg.c_str()); snprintf(buf, sizeof(buf), "Unable to decode audio stream: %s: %s", filename.c_str(), handler.errorMsg.c_str());
crash(buf, Exception::MEOW, false); crash(buf, Exception::MEOW, false);
Debug() << buf;
} }
} }

View File

@ -28,8 +28,7 @@
#include <SDL3/SDL_thread.h> #include <SDL3/SDL_thread.h>
#include <SDL3/SDL_timer.h> #include <SDL3/SDL_timer.h>
AudioStream::AudioStream(ALStream::LoopMode loopMode, AudioStream::AudioStream(ALStream::LoopMode loopMode, const std::string &threadId)
const std::string &threadId)
: extPaused(false), : extPaused(false),
noResumeStop(false), noResumeStop(false),
stream(loopMode, threadId) stream(loopMode, threadId)

View File

@ -113,8 +113,7 @@ struct AudioStream{
uint32_t startTicks; uint32_t startTicks;
} fadeIn; } fadeIn;
AudioStream(ALStream::LoopMode loopMode, AudioStream(ALStream::LoopMode loopMode, const std::string &threadId);
const std::string &threadId);
~AudioStream(); ~AudioStream();
void play(const std::string &filename, int volume, int pitch, float offset = 0); void play(const std::string &filename, int volume, int pitch, float offset = 0);

View File

@ -48,8 +48,7 @@
#define GUARD_MEGA \ #define GUARD_MEGA \
{ \ { \
if (p->megaSurface) \ if (p->megaSurface) \
throw Exception(Exception::MKXPError, \ crash("Operation not supported for mega surfaces", Exception::MKXPError, true); \
"Operation not supported for mega surfaces"); \
} }
#define OUTLINE_SIZE 1 #define OUTLINE_SIZE 1
@ -1034,15 +1033,10 @@ void Bitmap::drawText(const IntRect &rect, const char *str, int align){
TEX::bind(p->gl.tex); TEX::bind(p->gl.tex);
if (!subImage){ if (!subImage){
TEX::uploadSubImage(posRect.x, posRect.y, TEX::uploadSubImage(posRect.x, posRect.y, posRect.w, posRect.h, txtSurf->pixels, GL_RGBA);
posRect.w, posRect.h,
txtSurf->pixels, GL_RGBA);
} }
else{ else{
GLMeta::subRectImageUpload(txtSurf->w, subSrcX, subSrcY, GLMeta::subRectImageUpload(txtSurf->w, subSrcX, subSrcY, posRect.x, posRect.y, posRect.w, posRect.h, txtSurf, GL_RGBA);
posRect.x, posRect.y,
posRect.w, posRect.h,
txtSurf, GL_RGBA);
GLMeta::subRectImageEnd(); GLMeta::subRectImageEnd();
} }
} }

View File

@ -28,7 +28,7 @@
#include <physfs.h> #include <physfs.h>
#include <fstream> #include <fstream>
#include <stdint.h> #include <SDL3/SDL_stdinc.h>
#include <cstdlib> #include <cstdlib>
#include "debugwriter.h" #include "debugwriter.h"
@ -129,8 +129,7 @@ void Config::read(int argc, char *argv[]){
/* Parse command line options */ /* Parse command line options */
try{ try{
po::parsed_options cmdPo = po::parsed_options cmdPo = po::command_line_parser(argc, argv).options(podesc).run();
po::command_line_parser(argc, argv).options(podesc).run();
po::store(cmdPo, vm); po::store(cmdPo, vm);
} }
catch (po::error &error){ catch (po::error &error){
@ -186,7 +185,7 @@ void Config::read(int argc, char *argv[]){
#ifdef STEAM #ifdef STEAM
/* Override fullscreen config if Big Picture */ /* Override fullscreen config if Big Picture */
if (const char *env = std::getenv("SteamTenfoot")){ if (const char *env = std::getenv("SteamTenfoot")){
if (!strcmp(env, "1")) if (!SDL_strcmp(env, "1"))
fullscreen = true; fullscreen = true;
} }
#endif #endif

View File

@ -38,7 +38,7 @@
#include "oneshot.h" #include "oneshot.h"
#include <string.h> #include <SDL3/SDL_stdinc.h>
#include <map> #include <map>
@ -307,8 +307,7 @@ void EventThread::process(RGSSThreadData &rtData){
if (fullscreen){ if (fullscreen){
/* Prevent fullscreen flicker */ /* Prevent fullscreen flicker */
strncpy(pendingTitle, rtData.config.windowTitle.c_str(), SDL_strlcpy(pendingTitle, rtData.config.windowTitle.c_str(), sizeof(pendingTitle));
sizeof(pendingTitle));
break; break;
} }
@ -455,7 +454,7 @@ void EventThread::process(RGSSThreadData &rtData){
case SDL_EVENT_FINGER_UP : case SDL_EVENT_FINGER_UP :
i = event.tfinger.fingerID; i = event.tfinger.fingerID;
memset(&touchState.fingers[i], 0, sizeof(touchState.fingers[0])); SDL_memset(&touchState.fingers[i], 0, sizeof(touchState.fingers[0]));
break; break;
default : default :
@ -471,10 +470,8 @@ void EventThread::process(RGSSThreadData &rtData){
break; break;
case REQUEST_MESSAGEBOX : case REQUEST_MESSAGEBOX :
SDL_ShowSimpleMessageBox(event.user.code, SDL_ShowSimpleMessageBox(event.user.code, rtData.config.windowTitle.c_str(), (const char*) event.user.data1, win);
rtData.config.windowTitle.c_str(), SDL_free(event.user.data1);
(const char*) event.user.data1, win);
free(event.user.data1);
msgBoxDone.set(); msgBoxDone.set();
break; break;
@ -487,12 +484,12 @@ void EventThread::process(RGSSThreadData &rtData){
if (!fps.sendUpdates) if (!fps.sendUpdates)
break; break;
snprintf(buffer, sizeof(buffer), "%s - %d FPS", rtData.config.windowTitle.c_str(), event.user.code); SDL_snprintf(buffer, sizeof(buffer), "%s - %d FPS", rtData.config.windowTitle.c_str(), event.user.code);
/* Updating the window title in fullscreen /* Updating the window title in fullscreen
* mode seems to cause flickering */ * mode seems to cause flickering */
if (fullscreen){ if (fullscreen){
strncpy(pendingTitle, buffer, sizeof(pendingTitle)); SDL_strlcpy(pendingTitle, buffer, sizeof(pendingTitle));
break; break;
} }
@ -585,15 +582,15 @@ void EventThread::cleanup(){
while (SDL_PollEvent(&event)) while (SDL_PollEvent(&event))
if ((event.type - usrIdStart) == REQUEST_MESSAGEBOX) if ((event.type - usrIdStart) == REQUEST_MESSAGEBOX)
free(event.user.data1); SDL_free(event.user.data1);
} }
void EventThread::resetInputStates(){ void EventThread::resetInputStates(){
memset(&keyStates, 0, sizeof(keyStates)); SDL_memset(&keyStates, 0, sizeof(keyStates));
memset(&gcState, 0, sizeof(gcState)); SDL_memset(&gcState, 0, sizeof(gcState));
memset(&joyState, 0, sizeof(joyState)); SDL_memset(&joyState, 0, sizeof(joyState));
memset(&mouseState.buttons, 0, sizeof(mouseState.buttons)); SDL_memset(&mouseState.buttons, 0, sizeof(mouseState.buttons));
memset(&touchState, 0, sizeof(touchState)); SDL_memset(&touchState, 0, sizeof(touchState));
} }
void EventThread::setFullscreen(SDL_Window *win, bool mode){ void EventThread::setFullscreen(SDL_Window *win, bool mode){

View File

@ -35,8 +35,6 @@
#include <string> #include <string>
#include <stdint.h>
#include <alc.h> #include <alc.h>
//typedef struct ALCdevice_struct ALCdevice; //typedef struct ALCdevice_struct ALCdevice;
@ -256,11 +254,7 @@ struct RGSSThreadData{
std::string inputText; std::string inputText;
int inputTextLimit; int inputTextLimit;
RGSSThreadData(EventThread *ethread, RGSSThreadData(EventThread *ethread, SDL_Window *window, ALCdevice *alcDev, int refreshRate, const Config& newconf)
SDL_Window *window,
ALCdevice *alcDev,
int refreshRate,
const Config& newconf)
: allowExit(true), : allowExit(true),
ethread(ethread), ethread(ethread),
window(window), window(window),

View File

@ -33,9 +33,7 @@
#include <physfs.h> #include <physfs.h>
#include <SDL3_sound/SDL_sound.h> #include <SDL3_sound/SDL_sound.h>
#include <SDL3/SDL_stdinc.h>
#include <stdio.h>
#include <string.h>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include <stack> #include <stack>
@ -233,11 +231,11 @@ static int SDL_RWopsCloseFree(void *userdata)
* Returns copied bytes (minus terminating null) */ * Returns copied bytes (minus terminating null) */
static size_t strcpySafe(char *dst, const char *src, size_t dstMax, int srcN){ static size_t strcpySafe(char *dst, const char *src, size_t dstMax, int srcN){
if (srcN < 0) if (srcN < 0)
srcN = strlen(src); srcN = SDL_strlen(src);
size_t cpyMax = std::min<size_t>(dstMax-1, srcN); size_t cpyMax = std::min<size_t>(dstMax-1, srcN);
memcpy(dst, src, cpyMax); SDL_memcpy(dst, src, cpyMax);
dst[cpyMax] = '\0'; dst[cpyMax] = '\0';
return cpyMax; return cpyMax;
@ -249,7 +247,7 @@ static size_t strcpySafe(char *dst, const char *src, size_t dstMax, int srcN){
static const char *findExt(const char *filename){ static const char *findExt(const char *filename){
size_t len; size_t len;
for (len = strlen(filename); len > 0; --len){ for (len = SDL_strlen(filename); len > 0; --len){
if (filename[len] == '/') if (filename[len] == '/')
return 0; return 0;
@ -357,7 +355,7 @@ struct CacheEnumData{
/* Converts in-place */ /* Converts in-place */
void toNFC(char *inout){ void toNFC(char *inout){
#ifdef OS_OSX #ifdef OS_OSX
size_t srcSize = strlen(inout); size_t srcSize = SDL_strlen(inout);
size_t bufSize = sizeof(buf); size_t bufSize = sizeof(buf);
char *bufPtr = buf; char *bufPtr = buf;
char *inoutPtr = inout; char *inoutPtr = inout;
@ -365,9 +363,7 @@ struct CacheEnumData{
/* Reserve room for null terminator */ /* Reserve room for null terminator */
--bufSize; --bufSize;
iconv(nfd2nfc, iconv(nfd2nfc, &inoutPtr, &srcSize, &bufPtr, &bufSize);
&inoutPtr, &srcSize,
&bufPtr, &bufSize);
/* Null-terminate */ /* Null-terminate */
*bufPtr = 0; *bufPtr = 0;
strcpy(inout, buf); strcpy(inout, buf);
@ -382,9 +378,9 @@ static PHYSFS_EnumerateCallbackResult cacheEnumCB(void *d, const char *origdir,
char fullPath[512]; char fullPath[512];
if (!*origdir) if (!*origdir)
snprintf(fullPath, sizeof(fullPath), "%s", fname); SDL_snprintf(fullPath, sizeof(fullPath), "%s", fname);
else else
snprintf(fullPath, sizeof(fullPath), "%s/%s", origdir, fname); SDL_snprintf(fullPath, sizeof(fullPath), "%s/%s", origdir, fname);
/* Deal with OSX' weird UTF-8 standards */ /* Deal with OSX' weird UTF-8 standards */
data.toNFC(fullPath); data.toNFC(fullPath);
@ -448,11 +444,11 @@ static PHYSFS_EnumerateCallbackResult fontSetEnumCB (void *data, const char *dir
lowExt[i] = tolower(ext[i]); lowExt[i] = tolower(ext[i]);
lowExt[i] = '\0'; lowExt[i] = '\0';
if (strcmp(lowExt, "ttf") && strcmp(lowExt, "otf") && strcmp(lowExt, "ttc")) if (SDL_strcmp(lowExt, "ttf") && SDL_strcmp(lowExt, "otf") && SDL_strcmp(lowExt, "ttc"))
return PHYSFS_ENUM_OK; return PHYSFS_ENUM_OK;
char filename[512]; char filename[512];
snprintf(filename, sizeof(filename), "%s/%s", dir, fname); SDL_snprintf(filename, sizeof(filename), "%s/%s", dir, fname);
PHYSFS_File *handle = PHYSFS_openRead(filename); PHYSFS_File *handle = PHYSFS_openRead(filename);
if (!handle) if (!handle)
@ -494,9 +490,7 @@ struct OpenReadEnumData{
* doesn't get changed before we get back into our code */ * doesn't get changed before we get back into our code */
const char *physfsError; const char *physfsError;
OpenReadEnumData(FileSystem::OpenHandler &handler, OpenReadEnumData(FileSystem::OpenHandler &handler, const char *filename, size_t filenameN, BoostHash<std::string, std::string> *pathTrans)
const char *filename, size_t filenameN,
BoostHash<std::string, std::string> *pathTrans)
: handler(handler), filename(filename), filenameN(filenameN), : handler(handler), filename(filename), filenameN(filenameN),
pathTrans(pathTrans), matchCount(0), stopSearching(false), pathTrans(pathTrans), matchCount(0), stopSearching(false),
physfsError(0) physfsError(0)
@ -513,14 +507,14 @@ openReadEnumCB(void *d, const char *dirpath, const char *filename){
return PHYSFS_ENUM_STOP; return PHYSFS_ENUM_STOP;
/* If there's not even a partial match, continue searching */ /* If there's not even a partial match, continue searching */
if (strncmp(filename, data.filename, data.filenameN) != 0) if (SDL_strncmp(filename, data.filename, data.filenameN) != 0)
return PHYSFS_ENUM_OK; return PHYSFS_ENUM_OK;
if (!*dirpath){ if (!*dirpath){
fullPath = filename; fullPath = filename;
} }
else{ else{
snprintf(buffer, sizeof(buffer), "%s/%s", dirpath, filename); SDL_snprintf(buffer, sizeof(buffer), "%s/%s", dirpath, filename);
fullPath = buffer; fullPath = buffer;
} }
@ -587,8 +581,7 @@ void FileSystem::openRead(OpenHandler &handler, const char *filename){
dir = buffer; dir = buffer;
} }
OpenReadEnumData data(handler, file, len + buffer - delim - !root, OpenReadEnumData data(handler, file, len + buffer - delim - !root, p->havePathCache ? &p->pathCache : 0);
p->havePathCache ? &p->pathCache : 0);
if (p->havePathCache){ if (p->havePathCache){
/* Get the list of files contained in this directory /* Get the list of files contained in this directory

View File

@ -39,7 +39,7 @@ struct GLDebugLoggerPrivate{
void writeTimestamp(){ void writeTimestamp(){
time(&timestamp); time(&timestamp);
*stream << "[GLDEBUG | " << ctime(&timestamp) << "]"; *stream << "[GLDEBUG " << ctime(&timestamp) << "]";
} }
void writeLine(const char *line){ void writeLine(const char *line){

View File

@ -24,7 +24,7 @@
#include "gl-fun.h" #include "gl-fun.h"
#include <stdio.h> #include <SDL3/SDL_stdinc.h>
#include <algorithm> #include <algorithm>
struct GLDebugLoggerPrivate; struct GLDebugLoggerPrivate;
@ -42,7 +42,7 @@ private:
if (gl.StringMarker) \ if (gl.StringMarker) \
{ \ { \
char buf[128]; \ char buf[128]; \
int len = snprintf(buf, sizeof(buf), format, ##__VA_ARGS__); \ int len = SDL_snprintf(buf, sizeof(buf), format, ##__VA_ARGS__); \
gl.StringMarker(std::min<size_t>(len, sizeof(buf)), buf); \ gl.StringMarker(std::min<size_t>(len, sizeof(buf)), buf); \
} }

View File

@ -5,7 +5,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <SDL3/SDL_stdinc.h>
char** strdict = 0; char** strdict = 0;
unsigned int nStr = 0; unsigned int nStr = 0;
@ -35,10 +35,10 @@ const char* findtext(unsigned int msgid, const char* fallback) {
void unloadLocale() { void unloadLocale() {
for (unsigned int i = 0; i < nStr; i++) { for (unsigned int i = 0; i < nStr; i++) {
free(strdict[i]); SDL_free(strdict[i]);
} }
free(strdict); SDL_free(strdict);
free(currentLocale); SDL_free(currentLocale);
strdict = 0; strdict = 0;
nStr = 0; nStr = 0;
} }
@ -50,16 +50,16 @@ void unloadLanguageMetadata() {
LanguageFontAndSize* ldata = languageMetadata[i]; LanguageFontAndSize* ldata = languageMetadata[i];
if (ldata) { if (ldata) {
if (ldata->font_name) { if (ldata->font_name) {
free(ldata->font_name); SDL_free(ldata->font_name);
} }
if (ldata->lang_code) { if (ldata->lang_code) {
free(ldata->lang_code); SDL_free(ldata->lang_code);
} }
free(ldata); SDL_free(ldata);
} }
} }
} }
free(languageMetadata); SDL_free(languageMetadata);
} }
void loadLanguageMetadata() { void loadLanguageMetadata() {
@ -77,27 +77,27 @@ void loadLanguageMetadata() {
int languageMetadataIndex = 0; int languageMetadataIndex = 0;
while (fgets(line, 1024, fontsFile)) { while (fgets(line, 1024, fontsFile)) {
char* indexOfEquals = strchr(line, '='); char* indexOfEquals = SDL_strchr(line, '=');
if (indexOfEquals) { if (indexOfEquals) {
// splitting the string in place here // splitting the string in place here
indexOfEquals[0] = 0; indexOfEquals[0] = 0;
char* indexOfFontName = indexOfEquals + 1; char* indexOfFontName = indexOfEquals + 1;
// remove new line from end of font name // remove new line from end of font name
char* indexOfNewLine = strchr(indexOfFontName, '\n'); char* indexOfNewLine = SDL_strchr(indexOfFontName, '\n');
if (indexOfNewLine) { if (indexOfNewLine) {
indexOfNewLine[0] = 0; indexOfNewLine[0] = 0;
} }
// make new strings for code and font name // make new strings for code and font name
char* langCode = (char*)calloc(LANGCODE_SIZE, sizeof(char)); char* langCode = (char*)SDL_calloc(LANGCODE_SIZE, sizeof(char));
char* langFont = (char*)calloc(LANGFONT_SIZE, sizeof(char)); char* langFont = (char*)SDL_calloc(LANGFONT_SIZE, sizeof(char));
strcpy(langCode, line); SDL_strlcpy(langCode, line, sizeof(line));
strcpy(langFont, indexOfFontName); SDL_strlcpy(langFont, indexOfFontName, sizeof(indexOfFontName));
// allocate metadata mem // allocate metadata mem
LanguageFontAndSize* metadata = (LanguageFontAndSize*) calloc(1, sizeof(LanguageFontAndSize)); LanguageFontAndSize* metadata = (LanguageFontAndSize*) SDL_calloc(1, sizeof(LanguageFontAndSize));
metadata->font_name = langFont; metadata->font_name = langFont;
metadata->lang_code = langCode; metadata->lang_code = langCode;
@ -118,7 +118,7 @@ void loadLanguageMetadata() {
if (fontSizesFile) { if (fontSizesFile) {
while (fgets(line, 1024, fontSizesFile)) { while (fgets(line, 1024, fontSizesFile)) {
int languageMetadataIndex = 0; int languageMetadataIndex = 0;
char* indexOfEquals = strchr(line, '='); char* indexOfEquals = SDL_strchr(line, '=');
if (indexOfEquals) { if (indexOfEquals) {
// splitting the string in place here // splitting the string in place here
indexOfEquals[0] = 0; indexOfEquals[0] = 0;
@ -135,22 +135,20 @@ void loadLanguageMetadata() {
for (int i = 0; i < MAX_LANGUAGES; i++) { for (int i = 0; i < MAX_LANGUAGES; i++) {
// search for corresponding langCode in metadata array to populate font size in the appropriate metadata // search for corresponding langCode in metadata array to populate font size in the appropriate metadata
LanguageFontAndSize* metadata = languageMetadata[i]; LanguageFontAndSize* metadata = languageMetadata[i];
if (metadata && strcmp(line, metadata->lang_code) == 0) { if (metadata && SDL_strcmp(line, metadata->lang_code) == 0) {
metadata->size = fontSize; metadata->size = fontSize;
break; break;
} }
} }
} }
} }
//fclose(fontSizesFile);
} }
} }
int getFontSize() { int getFontSize() {
for (int i = 0; i < MAX_LANGUAGES; i++) { for (int i = 0; i < MAX_LANGUAGES; i++) {
LanguageFontAndSize* metadata = languageMetadata[i]; LanguageFontAndSize* metadata = languageMetadata[i];
if (metadata && strcmp(currentLocale, metadata->lang_code) == 0) { if (metadata && SDL_strcmp(currentLocale, metadata->lang_code) == 0) {
return metadata->size; return metadata->size;
} }
} }
@ -162,7 +160,7 @@ int getFontSize() {
char* getFontName() { char* getFontName() {
for (int i = 0; i < MAX_LANGUAGES; i++) { for (int i = 0; i < MAX_LANGUAGES; i++) {
LanguageFontAndSize* metadata = languageMetadata[i]; LanguageFontAndSize* metadata = languageMetadata[i];
if (metadata && strcmp(currentLocale, metadata->lang_code) == 0) { if (metadata && SDL_strcmp(currentLocale, metadata->lang_code) == 0) {
return metadata->font_name; return metadata->font_name;
} }
} }
@ -178,21 +176,21 @@ void loadLocale(const char* locale) {
unloadLocale(); unloadLocale();
currentLocale = (char*) calloc(128, sizeof(char)); currentLocale = (char*) SDL_calloc(128, sizeof(char));
strncpy(currentLocale, locale, 128 - 1); SDL_strlcpy(currentLocale, locale, 128 - 1);
int dictSize = 100; int dictSize = 100;
// currently there are 52, but 100 should be plenty if we ever do add more // currently there are 52, but 100 should be plenty if we ever do add more
strdict = (char**)malloc(sizeof(char*) * dictSize); strdict = (char**)SDL_malloc(sizeof(char*) * dictSize);
sprintf(pathbuf, "Languages/internal/%s.po", locale); sprintf(pathbuf, "Languages/internal/%s.po", locale);
locfile = fopen(pathbuf, "r"); locfile = fopen(pathbuf, "r");
if (locfile) { if (locfile) {
while (fgets(line, 1024, locfile)) { while (fgets(line, 1024, locfile)) {
if (strncmp("msgstr \"", line, 8) == 0) { if (SDL_strncmp("msgstr \"", line, 8) == 0) {
char* lineWithoutMsgid = line + 8; char* lineWithoutMsgid = line + 8;
char* endQuoteAddress = strrchr(lineWithoutMsgid, '"'); char* endQuoteAddress = SDL_strrchr(lineWithoutMsgid, '"');
// end string at last quotation mark // end string at last quotation mark
if (endQuoteAddress != 0) { if (endQuoteAddress != 0) {
@ -201,10 +199,10 @@ void loadLocale(const char* locale) {
decodeEscapeChars(lineWithoutMsgid); decodeEscapeChars(lineWithoutMsgid);
int lineLen = strlen(lineWithoutMsgid); int lineLen = SDL_strlen(lineWithoutMsgid);
strdict[nStr] = (char*)malloc(lineLen + 1); strdict[nStr] = (char*)malloc(lineLen + 1);
strcpy(strdict[nStr], lineWithoutMsgid); SDL_strlcpy(strdict[nStr], lineWithoutMsgid, sizeof(lineWithoutMsgid));
nStr++; nStr++;
} }

View File

@ -30,7 +30,7 @@
#include <SDL3/SDL_mouse.h> #include <SDL3/SDL_mouse.h>
#include <vector> #include <vector>
#include <string.h> #include <SDL3/SDL_stdinc.h>
#include <assert.h> #include <assert.h>
#define BUTTON_CODE_COUNT 24 #define BUTTON_CODE_COUNT 24
@ -113,9 +113,7 @@ struct GcButtonBinding : public Binding{
struct GcAxisBinding : public Binding{ struct GcAxisBinding : public Binding{
GcAxisBinding() {} GcAxisBinding() {}
GcAxisBinding(uint8_t source, GcAxisBinding(uint8_t source, AxisDir dir, Input::ButtonCode target)
AxisDir dir,
Input::ButtonCode target)
: Binding(target), : Binding(target),
source(source), source(source),
dir(dir) dir(dir)
@ -157,9 +155,7 @@ struct JsButtonBinding : public Binding{
struct JsAxisBinding : public Binding{ struct JsAxisBinding : public Binding{
JsAxisBinding() {} JsAxisBinding() {}
JsAxisBinding(uint8_t source, JsAxisBinding(uint8_t source, AxisDir dir, Input::ButtonCode target)
AxisDir dir,
Input::ButtonCode target)
: Binding(target), : Binding(target),
source(source), source(source),
dir(dir) dir(dir)
@ -186,9 +182,7 @@ struct JsAxisBinding : public Binding{
struct JsHatBinding : public Binding{ struct JsHatBinding : public Binding{
JsHatBinding() {} JsHatBinding() {}
JsHatBinding(uint8_t source, JsHatBinding(uint8_t source, uint8_t pos, Input::ButtonCode target)
uint8_t pos,
Input::ButtonCode target)
: Binding(target), : Binding(target),
source(source), source(source),
pos(pos) pos(pos)
@ -211,8 +205,7 @@ struct JsHatBinding : public Binding{
struct MsBinding : public Binding{ struct MsBinding : public Binding{
MsBinding() {} MsBinding() {}
MsBinding(int buttonIndex, MsBinding(int buttonIndex, Input::ButtonCode target)
Input::ButtonCode target)
: Binding(target), : Binding(target),
index(buttonIndex) index(buttonIndex)
{} {}
@ -373,7 +366,7 @@ struct InputPrivate {
void clearBuffer(){ void clearBuffer(){
const size_t size = sizeof(ButtonState) * BUTTON_CODE_COUNT; const size_t size = sizeof(ButtonState) * BUTTON_CODE_COUNT;
memset(states, 0, size); SDL_memset(states, 0, size);
} }
void checkBindingChange(const RGSSThreadData &rtData){ void checkBindingChange(const RGSSThreadData &rtData){
@ -508,8 +501,7 @@ struct InputPrivate {
updateDir8(); updateDir8();
} }
void pollBindingPriv(const Binding &b, void pollBindingPriv(const Binding &b, Input::ButtonCode &repeatCand){
Input::ButtonCode &repeatCand){
if (!b.sourceActive()) if (!b.sourceActive())
return; return;

View File

@ -24,7 +24,7 @@
#include "config.h" #include "config.h"
#include "util.h" #include "util.h"
#include <stdio.h> #include <SDL3/SDL_stdinc.h>
struct KbBindingData{ struct KbBindingData{
SDL_Scancode source; SDL_Scancode source;
@ -156,7 +156,7 @@ struct Header{
}; };
static void buildPath(const std::string &dir, char *out, size_t outSize){ static void buildPath(const std::string &dir, char *out, size_t outSize){
snprintf(out, outSize, "%skeybindings.dat", dir.c_str()); SDL_snprintf(out, outSize, "%skeybindings.dat", dir.c_str());
} }
static bool writeBindings(const BDescVec &d, const std::string &dir){ static bool writeBindings(const BDescVec &d, const std::string &dir){

View File

@ -27,7 +27,7 @@
#include <SDL3/SDL_scancode.h> #include <SDL3/SDL_scancode.h>
#include <SDL3/SDL_joystick.h> #include <SDL3/SDL_joystick.h>
#include <SDL3/SDL_gamepad.h> #include <SDL3/SDL_gamepad.h>
#include <stdint.h> #include <SDL3/SDL_stdinc.h>
#include <assert.h> #include <assert.h>
#include <vector> #include <vector>

View File

@ -33,7 +33,7 @@
#else #else
#include <unistd.h> #include <unistd.h>
#endif #endif
#include <string.h> #include <SDL3/SDL_stdinc.h>
#include <assert.h> #include <assert.h>
#include <string> #include <string>
#include <iostream> #include <iostream>
@ -88,7 +88,7 @@ int rgssThreadFun(void *userdata){
glCtx = SDL_GL_CreateContext(win); glCtx = SDL_GL_CreateContext(win);
if (!glCtx){ if (!glCtx){
snprintf(msg, sizeof msg, "Error creating context: %s", SDL_GetError()); SDL_snprintf(msg, sizeof msg, "Error creating context: %s", SDL_GetError());
crash(msg, Exception::MEOW, false); crash(msg, Exception::MEOW, false);
rgssThreadError(threadData, std::string(msg)); rgssThreadError(threadData, std::string(msg));
return 0; return 0;
@ -230,7 +230,7 @@ int main(int argc, char *argv[]){
/* initialize SDL first */ /* initialize SDL first */
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) == false){ if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_JOYSTICK | SDL_INIT_GAMEPAD) == false){
snprintf(msg, sizeof msg, "Error initializing SDL: %s", SDL_GetError()); SDL_snprintf(msg, sizeof msg, "Error initializing SDL: %s", SDL_GetError());
crash(msg, Exception::MEOW, false); crash(msg, Exception::MEOW, false);
return 0; return 0;
} }
@ -276,7 +276,7 @@ int main(int argc, char *argv[]){
if (!conf.gameFolder.empty()){ if (!conf.gameFolder.empty()){
if (chdir(conf.gameFolder.c_str()) != 0){ if (chdir(conf.gameFolder.c_str()) != 0){
snprintf(msg, sizeof msg, "Unable to switch into gameFolder %s", conf.gameFolder); SDL_snprintf(msg, sizeof msg, "Unable to switch into gameFolder %s", conf.gameFolder);
crash(msg, Exception::MEOW, false); crash(msg, Exception::MEOW, false);
return 0; return 0;
} }
@ -290,13 +290,13 @@ int main(int argc, char *argv[]){
conf.windowTitle = conf.game.title; conf.windowTitle = conf.game.title;
if (TTF_Init() == false){ if (TTF_Init() == false){
snprintf(msg, sizeof msg, "Error initializing SDL_ttf: %s", SDL_GetError()); SDL_snprintf(msg, sizeof msg, "Error initializing SDL_ttf: %s", SDL_GetError());
crash(msg, Exception::MEOW, false); crash(msg, Exception::MEOW, false);
SDL_Quit(); SDL_Quit();
} }
if (Sound_Init() == false){ if (Sound_Init() == false){
snprintf(msg, sizeof msg, "Error initializing SDL_sound: %s", Sound_GetError()); SDL_snprintf(msg, sizeof msg, "Error initializing SDL_sound: %s", Sound_GetError());
crash(msg, Exception::MEOW, false); crash(msg, Exception::MEOW, false);
TTF_Quit(); TTF_Quit();
SDL_Quit(); SDL_Quit();
@ -316,7 +316,7 @@ int main(int argc, char *argv[]){
SDL_SetWindowFullscreen(win, true); SDL_SetWindowFullscreen(win, true);
if (!win){ if (!win){
snprintf(msg, sizeof msg, "Error creating window: %s", SDL_GetError()); SDL_snprintf(msg, sizeof msg, "Error creating window: %s", SDL_GetError());
crash(msg, Exception::MEOW, false); crash(msg, Exception::MEOW, false);
return 0; return 0;
} }

View File

@ -13,7 +13,7 @@
#include "config.h" #include "config.h"
#include "gl-debug.h" #include "gl-debug.h"
#include "gl-fun.h" #include "gl-fun.h"
#include <stdio.h> #include <SDL3/SDL_stdinc.h>
#include <time.h> #include <time.h>
#include <fstream> #include <fstream>
#include <ruby.h> #include <ruby.h>
@ -29,7 +29,6 @@
#include "xdg-user-dir-lookup.h" #include "xdg-user-dir-lookup.h"
#endif #endif
SDL_MessageBoxButtonData buttons[] = { SDL_MessageBoxButtonData buttons[] = {
{ SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Yes" }, { SDL_MESSAGEBOX_BUTTON_RETURNKEY_DEFAULT, 1, "Yes" },
{ SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "No" } { SDL_MESSAGEBOX_BUTTON_ESCAPEKEY_DEFAULT, 2, "No" }
@ -39,10 +38,9 @@ static inline const char* glGetStringInt(GLenum name){
return (const char*) gl.GetString(name); return (const char*) gl.GetString(name);
} }
void crash(const char* reason, Exception::Type t, bool do_exp){ void crash(const char* reason, Exception::Type t, bool do_exp){
char msg[1024]; char msg[1024];
snprintf(msg, sizeof msg, "Error occured! Error message: %s\n\n Want to create a crash log? You can share the crash log with the developers and help resolve the issue.", reason); SDL_snprintf(msg, sizeof msg, "Error occured! Error message: %s\n\n Want to create a crash log? You can share the crash log with the developers and help resolve the issue.", reason);
SDL_MessageBoxData messageboxdata = { SDL_MessageBoxData messageboxdata = {
.flags = SDL_MESSAGEBOX_ERROR, .flags = SDL_MESSAGEBOX_ERROR,
.window = NULL, .window = NULL,

View File

@ -42,33 +42,28 @@ static int pipeReady(PipeType fd);
#ifdef _WIN32 #ifdef _WIN32
static int pipeReady(PipeType fd) static int pipeReady(PipeType fd){
{
DWORD avail = 0; DWORD avail = 0;
return (PeekNamedPipe(fd, NULL, 0, NULL, &avail, NULL) && (avail > 0)); return (PeekNamedPipe(fd, NULL, 0, NULL, &avail, NULL) && (avail > 0));
} /* pipeReady */ } /* pipeReady */
static int writePipe(PipeType fd, const void *buf, const unsigned int _len) static int writePipe(PipeType fd, const void *buf, const unsigned int _len){
{
const DWORD len = (DWORD) _len; const DWORD len = (DWORD) _len;
DWORD bw = 0; DWORD bw = 0;
return ((WriteFile(fd, buf, len, &bw, NULL) != 0) && (bw == len)); return ((WriteFile(fd, buf, len, &bw, NULL) != 0) && (bw == len));
} /* writePipe */ } /* writePipe */
static int readPipe(PipeType fd, void *buf, const unsigned int _len) static int readPipe(PipeType fd, void *buf, const unsigned int _len){
{
const DWORD len = (DWORD) _len; const DWORD len = (DWORD) _len;
DWORD br = 0; DWORD br = 0;
return ReadFile(fd, buf, len, &br, NULL) ? (int) br : -1; return ReadFile(fd, buf, len, &br, NULL) ? (int) br : -1;
} /* readPipe */ } /* readPipe */
static void closePipe(PipeType fd) static void closePipe(PipeType fd){
{
CloseHandle(fd); CloseHandle(fd);
} /* closePipe */ } /* closePipe */
static char *getEnvVar(const char *key, char *buf, const size_t buflen) static char *getEnvVar(const char *key, char *buf, const size_t buflen){
{
const DWORD rc = GetEnvironmentVariableA(key, buf, buflen); const DWORD rc = GetEnvironmentVariableA(key, buf, buflen);
/* rc doesn't count null char, hence "<". */ /* rc doesn't count null char, hence "<". */
return ((rc > 0) && (rc < buflen)) ? buf : NULL; return ((rc > 0) && (rc < buflen)) ? buf : NULL;
@ -76,37 +71,32 @@ static char *getEnvVar(const char *key, char *buf, const size_t buflen)
#else #else
static int pipeReady(PipeType fd) static int pipeReady(PipeType fd){
{
int rc; int rc;
struct pollfd pfd = { fd, POLLIN | POLLERR | POLLHUP, 0 }; struct pollfd pfd = { fd, POLLIN | POLLERR | POLLHUP, 0 };
while (((rc = poll(&pfd, 1, 0)) == -1) && (errno == EINTR)) { /*spin*/ } while (((rc = poll(&pfd, 1, 0)) == -1) && (errno == EINTR)) { /*spin*/ }
return (rc == 1); return (rc == 1);
} /* pipeReady */ } /* pipeReady */
static int writePipe(PipeType fd, const void *buf, const unsigned int _len) static int writePipe(PipeType fd, const void *buf, const unsigned int _len){
{
const ssize_t len = (ssize_t) _len; const ssize_t len = (ssize_t) _len;
ssize_t bw; ssize_t bw;
while (((bw = write(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ } while (((bw = write(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ }
return (bw == len); return (bw == len);
} /* writePipe */ } /* writePipe */
static int readPipe(PipeType fd, void *buf, const unsigned int _len) static int readPipe(PipeType fd, void *buf, const unsigned int _len){
{
const ssize_t len = (ssize_t) _len; const ssize_t len = (ssize_t) _len;
ssize_t br; ssize_t br;
while (((br = read(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ } while (((br = read(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ }
return (int) br; return (int) br;
} /* readPipe */ } /* readPipe */
static void closePipe(PipeType fd) static void closePipe(PipeType fd){
{
close(fd); close(fd);
} /* closePipe */ } /* closePipe */
static char *getEnvVar(const char *key, char *buf, const size_t buflen) static char *getEnvVar(const char *key, char *buf, const size_t buflen){
{
const char *envr = getenv(key); const char *envr = getenv(key);
if (!envr || (strlen(envr) >= buflen)) if (!envr || (strlen(envr) >= buflen))
return NULL; return NULL;
@ -120,8 +110,7 @@ static char *getEnvVar(const char *key, char *buf, const size_t buflen)
static PipeType GPipeRead = NULLPIPE; static PipeType GPipeRead = NULLPIPE;
static PipeType GPipeWrite = NULLPIPE; static PipeType GPipeWrite = NULLPIPE;
typedef enum ShimCmd typedef enum ShimCmd{
{
SHIMCMD_BYE, SHIMCMD_BYE,
SHIMCMD_PUMP, SHIMCMD_PUMP,
SHIMCMD_REQUESTSTATS, SHIMCMD_REQUESTSTATS,
@ -137,26 +126,22 @@ typedef enum ShimCmd
SHIMCMD_GETCURRENTGAMELANGUAGE, SHIMCMD_GETCURRENTGAMELANGUAGE,
} ShimCmd; } ShimCmd;
static int write1ByteCmd(const uint8 b1) static int write1ByteCmd(const uint8 b1){
{
const uint8 buf[] = { 1, b1 }; const uint8 buf[] = { 1, b1 };
return writePipe(GPipeWrite, buf, sizeof (buf)); return writePipe(GPipeWrite, buf, sizeof (buf));
} /* write1ByteCmd */ } /* write1ByteCmd */
static int write2ByteCmd(const uint8 b1, const uint8 b2) static int write2ByteCmd(const uint8 b1, const uint8 b2){
{
const uint8 buf[] = { 2, b1, b2 }; const uint8 buf[] = { 2, b1, b2 };
return writePipe(GPipeWrite, buf, sizeof (buf)); return writePipe(GPipeWrite, buf, sizeof (buf));
} /* write2ByteCmd */ } /* write2ByteCmd */
static inline int writeBye(void) static inline int writeBye(void){
{
dbgpipe("Child sending SHIMCMD_BYE().\n"); dbgpipe("Child sending SHIMCMD_BYE().\n");
return write1ByteCmd(SHIMCMD_BYE); return write1ByteCmd(SHIMCMD_BYE);
} // writeBye } // writeBye
static int initPipes(void) static int initPipes(void){
{
char buf[64]; char buf[64];
if (!getEnvVar("STEAMSHIM_READHANDLE", buf, sizeof (buf))) if (!getEnvVar("STEAMSHIM_READHANDLE", buf, sizeof (buf)))
@ -171,11 +156,9 @@ static int initPipes(void)
} /* initPipes */ } /* initPipes */
int STEAMSHIM_init(void) int STEAMSHIM_init(void){
{
dbgpipe("Child init start.\n"); dbgpipe("Child init start.\n");
if (!initPipes()) if (!initPipes()){
{
dbgpipe("Child init failed.\n"); dbgpipe("Child init failed.\n");
return 0; return 0;
} /* if */ } /* if */
@ -188,11 +171,9 @@ int STEAMSHIM_init(void)
return 1; return 1;
} /* STEAMSHIM_init */ } /* STEAMSHIM_init */
void STEAMSHIM_deinit(void) void STEAMSHIM_deinit(void){
{
dbgpipe("Child deinit.\n"); dbgpipe("Child deinit.\n");
if (GPipeWrite != NULLPIPE) if (GPipeWrite != NULLPIPE){
{
writeBye(); writeBye();
closePipe(GPipeWrite); closePipe(GPipeWrite);
} /* if */ } /* if */
@ -207,23 +188,19 @@ void STEAMSHIM_deinit(void)
#endif #endif
} /* STEAMSHIM_deinit */ } /* STEAMSHIM_deinit */
static inline int isAlive(void) static inline int isAlive(void){
{
return ((GPipeRead != NULLPIPE) && (GPipeWrite != NULLPIPE)); return ((GPipeRead != NULLPIPE) && (GPipeWrite != NULLPIPE));
} /* isAlive */ } /* isAlive */
static inline int isDead(void) static inline int isDead(void){
{
return !isAlive(); return !isAlive();
} /* isDead */ } /* isDead */
int STEAMSHIM_alive(void) int STEAMSHIM_alive(void){
{
return isAlive(); return isAlive();
} /* STEAMSHIM_alive */ } /* STEAMSHIM_alive */
static const STEAMSHIM_Event *processEvent(const uint8 *buf, size_t buflen) static const STEAMSHIM_Event *processEvent(const uint8 *buf, size_t buflen){
{
static STEAMSHIM_Event event; static STEAMSHIM_Event event;
const STEAMSHIM_EventType type = (STEAMSHIM_EventType) *(buf++); const STEAMSHIM_EventType type = (STEAMSHIM_EventType) *(buf++);
buflen--; buflen--;
@ -313,8 +290,7 @@ static const STEAMSHIM_Event *processEvent(const uint8 *buf, size_t buflen)
return &event; return &event;
} /* processEvent */ } /* processEvent */
const STEAMSHIM_Event *STEAMSHIM_pump(void) const STEAMSHIM_Event *STEAMSHIM_pump(void){
{
static uint8 buf[256]; static uint8 buf[256];
static int br = 0; static int br = 0;
int evlen = (br > 0) ? ((int) buf[0]) : 0; int evlen = (br > 0) ? ((int) buf[0]) : 0;
@ -337,8 +313,7 @@ const STEAMSHIM_Event *STEAMSHIM_pump(void)
} /* if */ } /* if */
} /* if */ } /* if */
if (evlen && (br > evlen)) if (evlen && (br > evlen)){
{
const STEAMSHIM_Event *retval = processEvent(buf+1, evlen); const STEAMSHIM_Event *retval = processEvent(buf+1, evlen);
br -= evlen + 1; br -= evlen + 1;
if (br > 0) if (br > 0)
@ -347,8 +322,7 @@ const STEAMSHIM_Event *STEAMSHIM_pump(void)
} /* if */ } /* if */
/* Run Steam event loop. */ /* Run Steam event loop. */
if (br == 0) if (br == 0){
{
dbgpipe("Child sending SHIMCMD_PUMP().\n"); dbgpipe("Child sending SHIMCMD_PUMP().\n");
write1ByteCmd(SHIMCMD_PUMP); write1ByteCmd(SHIMCMD_PUMP);
} /* if */ } /* if */
@ -356,22 +330,19 @@ const STEAMSHIM_Event *STEAMSHIM_pump(void)
return NULL; return NULL;
} /* STEAMSHIM_pump */ } /* STEAMSHIM_pump */
void STEAMSHIM_requestStats(void) void STEAMSHIM_requestStats(void){
{
if (isDead()) return; if (isDead()) return;
dbgpipe("Child sending SHIMCMD_REQUESTSTATS().\n"); dbgpipe("Child sending SHIMCMD_REQUESTSTATS().\n");
write1ByteCmd(SHIMCMD_REQUESTSTATS); write1ByteCmd(SHIMCMD_REQUESTSTATS);
} /* STEAMSHIM_requestStats */ } /* STEAMSHIM_requestStats */
void STEAMSHIM_storeStats(void) void STEAMSHIM_storeStats(void){
{
if (isDead()) return; if (isDead()) return;
dbgpipe("Child sending SHIMCMD_STORESTATS().\n"); dbgpipe("Child sending SHIMCMD_STORESTATS().\n");
write1ByteCmd(SHIMCMD_STORESTATS); write1ByteCmd(SHIMCMD_STORESTATS);
} /* STEAMSHIM_storeStats */ } /* STEAMSHIM_storeStats */
void STEAMSHIM_setAchievement(const char *name, const int enable) void STEAMSHIM_setAchievement(const char *name, const int enable){
{
uint8 buf[256]; uint8 buf[256];
uint8 *ptr = buf+1; uint8 *ptr = buf+1;
if (isDead()) return; if (isDead()) return;
@ -384,8 +355,7 @@ void STEAMSHIM_setAchievement(const char *name, const int enable)
writePipe(GPipeWrite, buf, buf[0] + 1); writePipe(GPipeWrite, buf, buf[0] + 1);
} /* STEAMSHIM_setAchievement */ } /* STEAMSHIM_setAchievement */
void STEAMSHIM_getAchievement(const char *name) void STEAMSHIM_getAchievement(const char *name){
{
uint8 buf[256]; uint8 buf[256];
uint8 *ptr = buf+1; uint8 *ptr = buf+1;
if (isDead()) return; if (isDead()) return;
@ -397,15 +367,13 @@ void STEAMSHIM_getAchievement(const char *name)
writePipe(GPipeWrite, buf, buf[0] + 1); writePipe(GPipeWrite, buf, buf[0] + 1);
} /* STEAMSHIM_getAchievement */ } /* STEAMSHIM_getAchievement */
void STEAMSHIM_resetStats(const int bAlsoAchievements) void STEAMSHIM_resetStats(const int bAlsoAchievements){
{
if (isDead()) return; if (isDead()) return;
dbgpipe("Child sending SHIMCMD_RESETSTATS(%salsoAchievements).\n", bAlsoAchievements ? "" : "!"); dbgpipe("Child sending SHIMCMD_RESETSTATS(%salsoAchievements).\n", bAlsoAchievements ? "" : "!");
write2ByteCmd(SHIMCMD_RESETSTATS, bAlsoAchievements ? 1 : 0); write2ByteCmd(SHIMCMD_RESETSTATS, bAlsoAchievements ? 1 : 0);
} /* STEAMSHIM_resetStats */ } /* STEAMSHIM_resetStats */
static void writeStatThing(const ShimCmd cmd, const char *name, const void *val, const size_t vallen) static void writeStatThing(const ShimCmd cmd, const char *name, const void *val, const size_t vallen){
{
uint8 buf[256]; uint8 buf[256];
uint8 *ptr = buf+1; uint8 *ptr = buf+1;
if (isDead()) return; if (isDead()) return;
@ -421,40 +389,34 @@ static void writeStatThing(const ShimCmd cmd, const char *name, const void *val,
writePipe(GPipeWrite, buf, buf[0] + 1); writePipe(GPipeWrite, buf, buf[0] + 1);
} /* writeStatThing */ } /* writeStatThing */
void STEAMSHIM_setStatI(const char *name, const int _val) void STEAMSHIM_setStatI(const char *name, const int _val){
{
const int32 val = (int32) _val; const int32 val = (int32) _val;
dbgpipe("Child sending SHIMCMD_SETSTATI('%s', val %d).\n", name, val); dbgpipe("Child sending SHIMCMD_SETSTATI('%s', val %d).\n", name, val);
writeStatThing(SHIMCMD_SETSTATI, name, &val, sizeof (val)); writeStatThing(SHIMCMD_SETSTATI, name, &val, sizeof (val));
} /* STEAMSHIM_setStatI */ } /* STEAMSHIM_setStatI */
void STEAMSHIM_getStatI(const char *name) void STEAMSHIM_getStatI(const char *name){
{
dbgpipe("Child sending SHIMCMD_GETSTATI('%s').\n", name); dbgpipe("Child sending SHIMCMD_GETSTATI('%s').\n", name);
writeStatThing(SHIMCMD_GETSTATI, name, NULL, 0); writeStatThing(SHIMCMD_GETSTATI, name, NULL, 0);
} /* STEAMSHIM_getStatI */ } /* STEAMSHIM_getStatI */
void STEAMSHIM_setStatF(const char *name, const float val) void STEAMSHIM_setStatF(const char *name, const float val){
{
dbgpipe("Child sending SHIMCMD_SETSTATF('%s', val %f).\n", name, val); dbgpipe("Child sending SHIMCMD_SETSTATF('%s', val %f).\n", name, val);
writeStatThing(SHIMCMD_SETSTATF, name, &val, sizeof (val)); writeStatThing(SHIMCMD_SETSTATF, name, &val, sizeof (val));
} /* STEAMSHIM_setStatF */ } /* STEAMSHIM_setStatF */
void STEAMSHIM_getStatF(const char *name) void STEAMSHIM_getStatF(const char *name){
{
dbgpipe("Child sending SHIMCMD_GETSTATF('%s').\n", name); dbgpipe("Child sending SHIMCMD_GETSTATF('%s').\n", name);
writeStatThing(SHIMCMD_GETSTATF, name, NULL, 0); writeStatThing(SHIMCMD_GETSTATF, name, NULL, 0);
} /* STEAMSHIM_getStatF */ } /* STEAMSHIM_getStatF */
void STEAMSHIM_getPersonaName() void STEAMSHIM_getPersonaName(){
{
if (isDead()) return; if (isDead()) return;
dbgpipe("Child sending SHIMCMD_GETPERSONANAME().\n"); dbgpipe("Child sending SHIMCMD_GETPERSONANAME().\n");
write1ByteCmd(SHIMCMD_GETPERSONANAME); write1ByteCmd(SHIMCMD_GETPERSONANAME);
} /* STEAMSHIM_getPersonaName */ } /* STEAMSHIM_getPersonaName */
void STEAMSHIM_getCurrentGameLanguage() void STEAMSHIM_getCurrentGameLanguage(){
{
if (isDead()) return; if (isDead()) return;
dbgpipe("Child sending SHIMCMD_GETCURRENTGAMELANGUAGE().\n"); dbgpipe("Child sending SHIMCMD_GETCURRENTGAMELANGUAGE().\n");
write1ByteCmd(SHIMCMD_GETCURRENTGAMELANGUAGE); write1ByteCmd(SHIMCMD_GETCURRENTGAMELANGUAGE);

View File

@ -5,8 +5,7 @@
extern "C" { extern "C" {
#endif #endif
typedef enum STEAMSHIM_EventType typedef enum STEAMSHIM_EventType{
{
SHIMEVENT_BYE, SHIMEVENT_BYE,
SHIMEVENT_STATSRECEIVED, SHIMEVENT_STATSRECEIVED,
SHIMEVENT_STATSSTORED, SHIMEVENT_STATSSTORED,
@ -22,8 +21,7 @@ typedef enum STEAMSHIM_EventType
} STEAMSHIM_EventType; } STEAMSHIM_EventType;
/* not all of these fields make sense in a given event. */ /* not all of these fields make sense in a given event. */
typedef struct STEAMSHIM_Event typedef struct STEAMSHIM_Event{
{
STEAMSHIM_EventType type; STEAMSHIM_EventType type;
int okay; int okay;
int ivalue; int ivalue;

View File

@ -2,7 +2,7 @@ cmake_minimum_required(VERSION 2.8.11)
set(STEAMWORKS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../steamworks" CACHE PATH "Path to Steamworks folder") set(STEAMWORKS_PATH "${CMAKE_CURRENT_SOURCE_DIR}/../steamworks" CACHE PATH "Path to Steamworks folder")
set(GAME_LAUNCH_NAME "oneshot" CACHE STRING "Game launch name") set(GAME_LAUNCH_NAME "oneshot" CACHE STRING "Game launch name")
option(DEBUG "Debug mode" OFF) option(DEBUG "Debug" OFF)
if(DEBUG) if(DEBUG)
set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g3 -O0 -fno-omit-frame-pointer -ggdb") set(CMAKE_C_FLAGS_DEBUG "${CMAKE_C_FLAGS_DEBUG} -g3 -O0 -fno-omit-frame-pointer -ggdb")
@ -17,6 +17,8 @@ include_directories(${STEAMWORKS_PATH}/public)
add_definitions(-DGAME_LAUNCH_NAME="${GAME_LAUNCH_NAME}") add_definitions(-DGAME_LAUNCH_NAME="${GAME_LAUNCH_NAME}")
find_package(SDL3 CONFIG)
IF(DEBUG) IF(DEBUG)
add_definitions(-DSTEAMSHIM_DEBUG) add_definitions(-DSTEAMSHIM_DEBUG)
ENDIF() ENDIF()
@ -37,4 +39,4 @@ add_executable(steamshim
) )
set_target_properties(steamshim PROPERTIES LINK_FLAGS "-Wl,-rpath,$ORIGIN -no-pie") set_target_properties(steamshim PROPERTIES LINK_FLAGS "-Wl,-rpath,$ORIGIN -no-pie")
target_link_libraries(steamshim ${steamworks}) target_link_libraries(steamshim ${steamworks} SDL3::SDL3)

View File

@ -35,6 +35,8 @@ static inline void dbgpipe(const char *fmt, ...) {
} }
#endif #endif
#include <SDL3/SDL_messagebox.h>
/* platform-specific mainline calls this. */ /* platform-specific mainline calls this. */
static int mainline(void); static int mainline(void);
@ -50,29 +52,24 @@ static bool launchChild(ProcessType *pid);
static int closeProcess(ProcessType *pid); static int closeProcess(ProcessType *pid);
#ifdef _WIN32 #ifdef _WIN32
static void fail(const char *err) static void fail(const char *err){
{
MessageBoxA(NULL, err, "ERROR", MB_ICONERROR | MB_OK); MessageBoxA(NULL, err, "ERROR", MB_ICONERROR | MB_OK);
ExitProcess(1); ExitProcess(1);
} // fail } // fail
static bool writePipe(PipeType fd, const void *buf, const unsigned int _len) static bool writePipe(PipeType fd, const void *buf, const unsigned int _len){
{
const DWORD len = (DWORD) _len; const DWORD len = (DWORD) _len;
DWORD bw = 0; DWORD bw = 0;
return ((WriteFile(fd, buf, len, &bw, NULL) != 0) && (bw == len)); return ((WriteFile(fd, buf, len, &bw, NULL) != 0) && (bw == len));
} // writePipe } // writePipe
static int readPipe(PipeType fd, void *buf, const unsigned int _len) static int readPipe(PipeType fd, void *buf, const unsigned int _len){
{
const DWORD len = (DWORD) _len; const DWORD len = (DWORD) _len;
DWORD br = 0; DWORD br = 0;
return ReadFile(fd, buf, len, &br, NULL) ? (int) br : -1; return ReadFile(fd, buf, len, &br, NULL) ? (int) br : -1;
} // readPipe } // readPipe
static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite, static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite, PipeType *pPipeChildRead, PipeType *pPipeChildWrite){
PipeType *pPipeChildRead, PipeType *pPipeChildWrite)
{
SECURITY_ATTRIBUTES pipeAttr; SECURITY_ATTRIBUTES pipeAttr;
pipeAttr.nLength = sizeof (pipeAttr); pipeAttr.nLength = sizeof (pipeAttr);
@ -84,8 +81,7 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
pipeAttr.nLength = sizeof (pipeAttr); pipeAttr.nLength = sizeof (pipeAttr);
pipeAttr.lpSecurityDescriptor = NULL; pipeAttr.lpSecurityDescriptor = NULL;
pipeAttr.bInheritHandle = TRUE; pipeAttr.bInheritHandle = TRUE;
if (!CreatePipe(pPipeChildRead, pPipeParentWrite, &pipeAttr, 0)) if (!CreatePipe(pPipeChildRead, pPipeParentWrite, &pipeAttr, 0)){
{
CloseHandle(*pPipeParentRead); CloseHandle(*pPipeParentRead);
CloseHandle(*pPipeChildWrite); CloseHandle(*pPipeChildWrite);
return 0; return 0;
@ -94,18 +90,15 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
return 1; return 1;
} // createPipes } // createPipes
static void closePipe(PipeType fd) static void closePipe(PipeType fd){
{
CloseHandle(fd); CloseHandle(fd);
} // closePipe } // closePipe
static bool setEnvVar(const char *key, const char *val) static bool setEnvVar(const char *key, const char *val){
{
return (SetEnvironmentVariableA(key, val) != 0); return (SetEnvironmentVariableA(key, val) != 0);
} // setEnvVar } // setEnvVar
static LPWSTR genCommandLine() static LPWSTR genCommandLine(){
{
// Construct a command line with the appropriate filename // Construct a command line with the appropriate filename
LPWSTR cmdline = GetCommandLineW(); LPWSTR cmdline = GetCommandLineW();
@ -113,21 +106,16 @@ static LPWSTR genCommandLine()
int iFirstArg = -1; int iFirstArg = -1;
bool quote = false; bool quote = false;
bool whitespace = false; bool whitespace = false;
for (int i = 0; cmdline[i]; ++i) for (int i = 0; cmdline[i]; ++i){
{ if (cmdline[i] == '"' && (i == 0 || cmdline[i-1] != '\\')){
if (cmdline[i] == '"' && (i == 0 || cmdline[i-1] != '\\'))
{
quote = !quote; quote = !quote;
whitespace = false; whitespace = false;
} }
else if (!quote && (cmdline[i] == ' ' || cmdline[i] == '\t')) else if (!quote && (cmdline[i] == ' ' || cmdline[i] == '\t')){
{
whitespace = true; whitespace = true;
} }
else else{
{ if (whitespace){
if (whitespace)
{
iFirstArg = i; iFirstArg = i;
break; break;
} }
@ -148,8 +136,7 @@ static LPWSTR genCommandLine()
return newcmdline; return newcmdline;
} }
static bool launchChild(ProcessType *pid) static bool launchChild(ProcessType *pid){
{
STARTUPINFOW si; STARTUPINFOW si;
memset(&si, 0, sizeof(si)); memset(&si, 0, sizeof(si));
return CreateProcessW(TEXT(".\\" GAME_LAUNCH_NAME ".exe"), return CreateProcessW(TEXT(".\\" GAME_LAUNCH_NAME ".exe"),
@ -157,16 +144,13 @@ static bool launchChild(ProcessType *pid)
NULL, &si, pid); NULL, &si, pid);
} // launchChild } // launchChild
static int closeProcess(ProcessType *pid) static int closeProcess(ProcessType *pid){
{
CloseHandle(pid->hProcess); CloseHandle(pid->hProcess);
CloseHandle(pid->hThread); CloseHandle(pid->hThread);
return 0; return 0;
} // closeProcess } // closeProcess
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
LPSTR lpCmdLine, int nCmdShow)
{
mainline(); mainline();
ExitProcess(0); ExitProcess(0);
return 0; // just in case. return 0; // just in case.
@ -175,32 +159,27 @@ int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
#else // everyone else that isn't Windows. #else // everyone else that isn't Windows.
static void fail(const char *err) static void fail(const char *err){
{ SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Steamshim parent error", err, NULL);
// !!! FIXME: zenity or something.
fprintf(stderr, "%s\n", err); fprintf(stderr, "%s\n", err);
_exit(1); _exit(1);
} // fail } // fail
static bool writePipe(PipeType fd, const void *buf, const unsigned int _len) static bool writePipe(PipeType fd, const void *buf, const unsigned int _len){
{
const ssize_t len = (ssize_t) _len; const ssize_t len = (ssize_t) _len;
ssize_t bw; ssize_t bw;
while (((bw = write(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ } while (((bw = write(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ }
return (bw == len); return (bw == len);
} // writePipe } // writePipe
static int readPipe(PipeType fd, void *buf, const unsigned int _len) static int readPipe(PipeType fd, void *buf, const unsigned int _len){
{
const ssize_t len = (ssize_t) _len; const ssize_t len = (ssize_t) _len;
ssize_t br; ssize_t br;
while (((br = read(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ } while (((br = read(fd, buf, len)) == -1) && (errno == EINTR)) { /*spin*/ }
return (int) br; return (int) br;
} // readPipe } // readPipe
static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite, static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite, PipeType *pPipeChildRead, PipeType *pPipeChildWrite){
PipeType *pPipeChildRead, PipeType *pPipeChildWrite)
{
int fds[2]; int fds[2];
if (pipe(fds) == -1) if (pipe(fds) == -1)
return 0; return 0;
@ -209,8 +188,7 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
*pPipeParentRead = fds[0]; *pPipeParentRead = fds[0];
*pPipeChildWrite = fds[1]; *pPipeChildWrite = fds[1];
if (pipe(fds) == -1) if (pipe(fds) == -1){
{
close(*pPipeParentRead); close(*pPipeParentRead);
close(*pPipeChildWrite); close(*pPipeChildWrite);
return 0; return 0;
@ -224,21 +202,18 @@ static bool createPipes(PipeType *pPipeParentRead, PipeType *pPipeParentWrite,
return 1; return 1;
} // createPipes } // createPipes
static void closePipe(PipeType fd) static void closePipe(PipeType fd){
{
close(fd); close(fd);
} // closePipe } // closePipe
static bool setEnvVar(const char *key, const char *val) static bool setEnvVar(const char *key, const char *val){
{
return (setenv(key, val, 1) != -1); return (setenv(key, val, 1) != -1);
} // setEnvVar } // setEnvVar
static int GArgc = 0; static int GArgc = 0;
static char **GArgv = NULL; static char **GArgv = NULL;
static bool launchChild(ProcessType *pid) static bool launchChild(ProcessType *pid){
{
*pid = fork(); *pid = fork();
if (*pid == -1) // failed if (*pid == -1) // failed
return false; return false;
@ -253,8 +228,7 @@ static bool launchChild(ProcessType *pid)
_exit(1); _exit(1);
} // launchChild } // launchChild
static int closeProcess(ProcessType *pid) static int closeProcess(ProcessType *pid){
{
int rc = 0; int rc = 0;
while ((waitpid(*pid, &rc, 0) == -1) && (errno == EINTR)) { /*spin*/ } while ((waitpid(*pid, &rc, 0) == -1) && (errno == EINTR)) { /*spin*/ }
if (!WIFEXITED(rc)) if (!WIFEXITED(rc))
@ -262,8 +236,7 @@ static int closeProcess(ProcessType *pid)
return WEXITSTATUS(rc); return WEXITSTATUS(rc);
} // closeProcess } // closeProcess
int main(int argc, char **argv) int main(int argc, char **argv){
{
signal(SIGPIPE, SIG_IGN); signal(SIGPIPE, SIG_IGN);
GArgc = argc; GArgc = argc;
GArgv = argv; GArgv = argv;
@ -330,26 +303,22 @@ typedef enum ShimEvent
SHIMEVENT_GETCURRENTGAMELANGUAGE, SHIMEVENT_GETCURRENTGAMELANGUAGE,
} ShimEvent; } ShimEvent;
static bool write1ByteCmd(PipeType fd, const uint8 b1) static bool write1ByteCmd(PipeType fd, const uint8 b1){
{
const uint8 buf[] = { 1, b1 }; const uint8 buf[] = { 1, b1 };
return writePipe(fd, buf, sizeof (buf)); return writePipe(fd, buf, sizeof (buf));
} // write1ByteCmd } // write1ByteCmd
static bool write2ByteCmd(PipeType fd, const uint8 b1, const uint8 b2) static bool write2ByteCmd(PipeType fd, const uint8 b1, const uint8 b2){
{
const uint8 buf[] = { 2, b1, b2 }; const uint8 buf[] = { 2, b1, b2 };
return writePipe(fd, buf, sizeof (buf)); return writePipe(fd, buf, sizeof (buf));
} // write2ByteCmd } // write2ByteCmd
static bool write3ByteCmd(PipeType fd, const uint8 b1, const uint8 b2, const uint8 b3) static bool write3ByteCmd(PipeType fd, const uint8 b1, const uint8 b2, const uint8 b3){
{
const uint8 buf[] = { 3, b1, b2, b3 }; const uint8 buf[] = { 3, b1, b2, b3 };
return writePipe(fd, buf, sizeof (buf)); return writePipe(fd, buf, sizeof (buf));
} // write3ByteCmd } // write3ByteCmd
static bool writeString(PipeType fd, ShimEvent event, const char *str) static bool writeString(PipeType fd, ShimEvent event, const char *str){
{
uint8 buf[256]; uint8 buf[256];
buf[0] = strlen(str) + 2; buf[0] = strlen(str) + 2;
buf[1] = (uint8) event; buf[1] = (uint8) event;
@ -357,26 +326,22 @@ static bool writeString(PipeType fd, ShimEvent event, const char *str)
return writePipe(fd, buf, buf[0] + 1); return writePipe(fd, buf, buf[0] + 1);
} // writeString } // writeString
static inline bool writeBye(PipeType fd) static inline bool writeBye(PipeType fd){
{
dbgpipe("Parent sending SHIMEVENT_BYE().\n"); dbgpipe("Parent sending SHIMEVENT_BYE().\n");
return write1ByteCmd(fd, SHIMEVENT_BYE); return write1ByteCmd(fd, SHIMEVENT_BYE);
} // writeBye } // writeBye
static inline bool writeStatsReceived(PipeType fd, const bool okay) static inline bool writeStatsReceived(PipeType fd, const bool okay){
{
dbgpipe("Parent sending SHIMEVENT_STATSRECEIVED(%sokay).\n", okay ? "" : "!"); dbgpipe("Parent sending SHIMEVENT_STATSRECEIVED(%sokay).\n", okay ? "" : "!");
return write2ByteCmd(fd, SHIMEVENT_STATSRECEIVED, okay ? 1 : 0); return write2ByteCmd(fd, SHIMEVENT_STATSRECEIVED, okay ? 1 : 0);
} // writeStatsReceived } // writeStatsReceived
static inline bool writeStatsStored(PipeType fd, const bool okay) static inline bool writeStatsStored(PipeType fd, const bool okay){
{
dbgpipe("Parent sending SHIMEVENT_STATSSTORED(%sokay).\n", okay ? "" : "!"); dbgpipe("Parent sending SHIMEVENT_STATSSTORED(%sokay).\n", okay ? "" : "!");
return write2ByteCmd(fd, SHIMEVENT_STATSSTORED, okay ? 1 : 0); return write2ByteCmd(fd, SHIMEVENT_STATSSTORED, okay ? 1 : 0);
} // writeStatsStored } // writeStatsStored
static bool writeAchievementSet(PipeType fd, const char *name, const bool enable, const bool okay) static bool writeAchievementSet(PipeType fd, const char *name, const bool enable, const bool okay){
{
uint8 buf[256]; uint8 buf[256];
uint8 *ptr = buf+1; uint8 *ptr = buf+1;
dbgpipe("Parent sending SHIMEVENT_SETACHIEVEMENT('%s', %senable, %sokay).\n", name, enable ? "" : "!", okay ? "" : "!"); dbgpipe("Parent sending SHIMEVENT_SETACHIEVEMENT('%s', %senable, %sokay).\n", name, enable ? "" : "!", okay ? "" : "!");
@ -389,8 +354,7 @@ static bool writeAchievementSet(PipeType fd, const char *name, const bool enable
return writePipe(fd, buf, buf[0] + 1); return writePipe(fd, buf, buf[0] + 1);
} // writeAchievementSet } // writeAchievementSet
static bool writeAchievementGet(PipeType fd, const char *name, const int status, const uint64 time) static bool writeAchievementGet(PipeType fd, const char *name, const int status, const uint64 time){
{
uint8 buf[256]; uint8 buf[256];
uint8 *ptr = buf+1; uint8 *ptr = buf+1;
dbgpipe("Parent sending SHIMEVENT_GETACHIEVEMENT('%s', status %d, time " LLUFMT ").\n", name, status, (unsigned long long) time); dbgpipe("Parent sending SHIMEVENT_GETACHIEVEMENT('%s', status %d, time " LLUFMT ").\n", name, status, (unsigned long long) time);
@ -404,14 +368,12 @@ static bool writeAchievementGet(PipeType fd, const char *name, const int status,
return writePipe(fd, buf, buf[0] + 1); return writePipe(fd, buf, buf[0] + 1);
} // writeAchievementGet } // writeAchievementGet
static inline bool writeResetStats(PipeType fd, const bool alsoAch, const bool okay) static inline bool writeResetStats(PipeType fd, const bool alsoAch, const bool okay){
{
dbgpipe("Parent sending SHIMEVENT_RESETSTATS(%salsoAchievements, %sokay).\n", alsoAch ? "" : "!", okay ? "" : "!"); dbgpipe("Parent sending SHIMEVENT_RESETSTATS(%salsoAchievements, %sokay).\n", alsoAch ? "" : "!", okay ? "" : "!");
return write3ByteCmd(fd, SHIMEVENT_RESETSTATS, alsoAch ? 1 : 0, okay ? 1 : 0); return write3ByteCmd(fd, SHIMEVENT_RESETSTATS, alsoAch ? 1 : 0, okay ? 1 : 0);
} // writeResetStats } // writeResetStats
static bool writeStatThing(PipeType fd, const ShimEvent ev, const char *name, const void *val, const size_t vallen, const bool okay) static bool writeStatThing(PipeType fd, const ShimEvent ev, const char *name, const void *val, const size_t vallen, const bool okay){
{
uint8 buf[256]; uint8 buf[256];
uint8 *ptr = buf+1; uint8 *ptr = buf+1;
*(ptr++) = (uint8) ev; *(ptr++) = (uint8) ev;
@ -424,26 +386,22 @@ static bool writeStatThing(PipeType fd, const ShimEvent ev, const char *name, co
return writePipe(fd, buf, buf[0] + 1); return writePipe(fd, buf, buf[0] + 1);
} // writeStatThing } // writeStatThing
static inline bool writeSetStatI(PipeType fd, const char *name, const int32 val, const bool okay) static inline bool writeSetStatI(PipeType fd, const char *name, const int32 val, const bool okay){
{
dbgpipe("Parent sending SHIMEVENT_SETSTATI('%s', val %d, %sokay).\n", name, (int) val, okay ? "" : "!"); dbgpipe("Parent sending SHIMEVENT_SETSTATI('%s', val %d, %sokay).\n", name, (int) val, okay ? "" : "!");
return writeStatThing(fd, SHIMEVENT_SETSTATI, name, &val, sizeof (val), okay); return writeStatThing(fd, SHIMEVENT_SETSTATI, name, &val, sizeof (val), okay);
} // writeSetStatI } // writeSetStatI
static inline bool writeSetStatF(PipeType fd, const char *name, const float val, const bool okay) static inline bool writeSetStatF(PipeType fd, const char *name, const float val, const bool okay){
{
dbgpipe("Parent sending SHIMEVENT_SETSTATF('%s', val %f, %sokay).\n", name, val, okay ? "" : "!"); dbgpipe("Parent sending SHIMEVENT_SETSTATF('%s', val %f, %sokay).\n", name, val, okay ? "" : "!");
return writeStatThing(fd, SHIMEVENT_SETSTATF, name, &val, sizeof (val), okay); return writeStatThing(fd, SHIMEVENT_SETSTATF, name, &val, sizeof (val), okay);
} // writeSetStatF } // writeSetStatF
static inline bool writeGetStatI(PipeType fd, const char *name, const int32 val, const bool okay) static inline bool writeGetStatI(PipeType fd, const char *name, const int32 val, const bool okay){
{
dbgpipe("Parent sending SHIMEVENT_GETSTATI('%s', val %d, %sokay).\n", name, (int) val, okay ? "" : "!"); dbgpipe("Parent sending SHIMEVENT_GETSTATI('%s', val %d, %sokay).\n", name, (int) val, okay ? "" : "!");
return writeStatThing(fd, SHIMEVENT_GETSTATI, name, &val, sizeof (val), okay); return writeStatThing(fd, SHIMEVENT_GETSTATI, name, &val, sizeof (val), okay);
} // writeGetStatI } // writeGetStatI
static inline bool writeGetStatF(PipeType fd, const char *name, const float val, const bool okay) static inline bool writeGetStatF(PipeType fd, const char *name, const float val, const bool okay){
{
dbgpipe("Parent sending SHIMEVENT_GETSTATF('%s', val %f, %sokay).\n", name, val, okay ? "" : "!"); dbgpipe("Parent sending SHIMEVENT_GETSTATF('%s', val %f, %sokay).\n", name, val, okay ? "" : "!");
return writeStatThing(fd, SHIMEVENT_GETSTATF, name, &val, sizeof (val), okay); return writeStatThing(fd, SHIMEVENT_GETSTATF, name, &val, sizeof (val), okay);
} // writeGetStatF } // writeGetStatF
@ -457,22 +415,19 @@ SteamBridge::SteamBridge(PipeType _fd)
{ {
} // SteamBridge::SteamBridge } // SteamBridge::SteamBridge
void SteamBridge::OnUserStatsReceived(UserStatsReceived_t *pCallback) void SteamBridge::OnUserStatsReceived(UserStatsReceived_t *pCallback){
{
if (GAppID != pCallback->m_nGameID) return; if (GAppID != pCallback->m_nGameID) return;
if (GUserID != pCallback->m_steamIDUser.ConvertToUint64()) return; if (GUserID != pCallback->m_steamIDUser.ConvertToUint64()) return;
writeStatsReceived(fd, pCallback->m_eResult == k_EResultOK); writeStatsReceived(fd, pCallback->m_eResult == k_EResultOK);
} // SteamBridge::OnUserStatsReceived } // SteamBridge::OnUserStatsReceived
void SteamBridge::OnUserStatsStored(UserStatsStored_t *pCallback) void SteamBridge::OnUserStatsStored(UserStatsStored_t *pCallback){
{
if (GAppID != pCallback->m_nGameID) return; if (GAppID != pCallback->m_nGameID) return;
writeStatsStored(fd, pCallback->m_eResult == k_EResultOK); writeStatsStored(fd, pCallback->m_eResult == k_EResultOK);
} // SteamBridge::OnUserStatsStored } // SteamBridge::OnUserStatsStored
static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd) static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd){
{
if (buflen == 0) if (buflen == 0)
return true; return true;
@ -522,8 +477,7 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
break; break;
case SHIMCMD_SETACHIEVEMENT: case SHIMCMD_SETACHIEVEMENT:
if (buflen >= 2) if (buflen >= 2){
{
const bool enable = (*(buf++) != 0); const bool enable = (*(buf++) != 0);
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible. const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
if (!GSteamStats) if (!GSteamStats)
@ -538,8 +492,7 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
break; break;
case SHIMCMD_GETACHIEVEMENT: case SHIMCMD_GETACHIEVEMENT:
if (buflen) if (buflen){
{
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible. const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
bool ach = false; bool ach = false;
uint32 t = 0; uint32 t = 0;
@ -551,16 +504,14 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
break; break;
case SHIMCMD_RESETSTATS: case SHIMCMD_RESETSTATS:
if (buflen) if (buflen){
{
const bool alsoAch = (*(buf++) != 0); const bool alsoAch = (*(buf++) != 0);
writeResetStats(fd, alsoAch, (GSteamStats) && (GSteamStats->ResetAllStats(alsoAch))); writeResetStats(fd, alsoAch, (GSteamStats) && (GSteamStats->ResetAllStats(alsoAch)));
} // if } // if
break; break;
case SHIMCMD_SETSTATI: case SHIMCMD_SETSTATI:
if (buflen >= 5) if (buflen >= 5){
{
const int32 val = *((int32 *) buf); const int32 val = *((int32 *) buf);
buf += sizeof (int32); buf += sizeof (int32);
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible. const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
@ -569,8 +520,7 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
break; break;
case SHIMCMD_GETSTATI: case SHIMCMD_GETSTATI:
if (buflen) if (buflen){
{
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible. const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
int32 val = 0; int32 val = 0;
if ((GSteamStats) && (GSteamStats->GetStat(name, &val))) if ((GSteamStats) && (GSteamStats->GetStat(name, &val)))
@ -581,8 +531,7 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
break; break;
case SHIMCMD_SETSTATF: case SHIMCMD_SETSTATF:
if (buflen >= 5) if (buflen >= 5){
{
const float val = *((float *) buf); const float val = *((float *) buf);
buf += sizeof (float); buf += sizeof (float);
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible. const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
@ -591,8 +540,7 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
break; break;
case SHIMCMD_GETSTATF: case SHIMCMD_GETSTATF:
if (buflen) if (buflen){
{
const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible. const char *name = (const char *) buf; // !!! FIXME: buffer overflow possible.
float val = 0; float val = 0;
if ((GSteamStats) && (GSteamStats->GetStat(name, &val))) if ((GSteamStats) && (GSteamStats->GetStat(name, &val)))
@ -616,22 +564,17 @@ static bool processCommand(const uint8 *buf, unsigned int buflen, PipeType fd)
return true; // keep going. return true; // keep going.
} // processCommand } // processCommand
static void processCommands(PipeType pipeParentRead, PipeType pipeParentWrite) static void processCommands(PipeType pipeParentRead, PipeType pipeParentWrite){
{
bool quit = false; bool quit = false;
uint8 buf[256]; uint8 buf[256];
int br; int br;
// this read blocks. // this read blocks.
while (!quit && ((br = readPipe(pipeParentRead, buf, sizeof (buf))) > 0)) while (!quit && ((br = readPipe(pipeParentRead, buf, sizeof (buf))) > 0)){
{ while (br > 0){
while (br > 0)
{
const int cmdlen = (int) buf[0]; const int cmdlen = (int) buf[0];
if ((br-1) >= cmdlen) if ((br-1) >= cmdlen){
{ if (!processCommand(buf+1, cmdlen, pipeParentWrite)){
if (!processCommand(buf+1, cmdlen, pipeParentWrite))
{
quit = true; quit = true;
break; break;
} // if } // if
@ -643,8 +586,7 @@ static void processCommands(PipeType pipeParentRead, PipeType pipeParentWrite)
else // get more data. else // get more data.
{ {
const int morebr = readPipe(pipeParentRead, buf+br, sizeof (buf) - br); const int morebr = readPipe(pipeParentRead, buf+br, sizeof (buf) - br);
if (morebr <= 0) if (morebr <= 0){
{
quit = true; // uhoh. quit = true; // uhoh.
break; break;
} // if } // if
@ -654,8 +596,7 @@ static void processCommands(PipeType pipeParentRead, PipeType pipeParentWrite)
} // while } // while
} // processCommands } // processCommands
static bool setEnvironmentVars(PipeType pipeChildRead, PipeType pipeChildWrite) static bool setEnvironmentVars(PipeType pipeChildRead, PipeType pipeChildWrite){
{
char buf[64]; char buf[64];
snprintf(buf, sizeof (buf), LLUFMT, (unsigned long long) pipeChildRead); snprintf(buf, sizeof (buf), LLUFMT, (unsigned long long) pipeChildRead);
if (!setEnvVar("STEAMSHIM_READHANDLE", buf)) if (!setEnvVar("STEAMSHIM_READHANDLE", buf))
@ -668,8 +609,7 @@ static bool setEnvironmentVars(PipeType pipeChildRead, PipeType pipeChildWrite)
return true; return true;
} // setEnvironmentVars } // setEnvironmentVars
static bool initSteamworks(PipeType fd) static bool initSteamworks(PipeType fd){
{
// this can fail for many reasons: // this can fail for many reasons:
// - you forgot a steam_appid.txt in the current working directory. // - you forgot a steam_appid.txt in the current working directory.
// - you don't have Steam running // - you don't have Steam running
@ -690,8 +630,7 @@ static bool initSteamworks(PipeType fd)
return 1; return 1;
} // initSteamworks } // initSteamworks
static void deinitSteamworks(void) static void deinitSteamworks(void){
{
SteamAPI_Shutdown(); SteamAPI_Shutdown();
delete GSteamBridge; delete GSteamBridge;
GSteamBridge = NULL; GSteamBridge = NULL;
@ -700,8 +639,7 @@ static void deinitSteamworks(void)
GSteamUser = NULL; GSteamUser = NULL;
} // deinitSteamworks } // deinitSteamworks
static int mainline(void) static int mainline(void){
{
PipeType pipeParentRead = NULLPIPE; PipeType pipeParentRead = NULLPIPE;
PipeType pipeParentWrite = NULLPIPE; PipeType pipeParentWrite = NULLPIPE;
PipeType pipeChildRead = NULLPIPE; PipeType pipeChildRead = NULLPIPE;

View File

@ -1,2 +1,2 @@
#!/bin/bash #!/bin/sh
curl -s https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt > assets/gamecontrollerdb.txt curl -s https://raw.githubusercontent.com/mdqinc/SDL_GameControllerDB/refs/heads/master/gamecontrollerdb.txt > assets/gamecontrollerdb.txt