From 8a5529e75229a2188860e4dd0ff52984527efe61 Mon Sep 17 00:00:00 2001 From: a dinosaur Date: Sun, 10 Mar 2024 19:34:07 +1100 Subject: [PATCH] SDL3 port --- .gitignore | 3 + CMakeLists.txt | 4 +- src/CMakeLists.txt | 13 +-- src/analogue.c | 160 +++++++++++++++++----------------- src/draw.c | 35 ++++---- src/draw.h | 7 -- src/gl/draw_opengl.c | 13 ++- src/glcore/draw_opengl_core.c | 13 ++- src/metal/draw_metal.m | 53 ++++------- 9 files changed, 130 insertions(+), 171 deletions(-) diff --git a/.gitignore b/.gitignore index dca0dae..d0e2617 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,8 @@ .idea/ +.vs/ +.vscode/ cmake-build-*/ build/ +out/ .DS_Store diff --git a/CMakeLists.txt b/CMakeLists.txt index 3d1b09d..404b1b6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.3 FATAL_ERROR) +cmake_minimum_required(VERSION 3.5 FATAL_ERROR) project(padlab C) set(TARGET padlab) @@ -15,7 +15,7 @@ elseif (MSVC) string(REPLACE "/W3" "/W4" CMAKE_C_FLAGS "${CMAKE_C_FLAGS}") endif() -find_package(SDL2 REQUIRED) +find_package(SDL3 REQUIRED CONFIG) if (BUILD_OPENGL OR BUILD_OPENGL_LEGACY) if (NOT DEFINED OpenGL_GL_PREFERENCE) set(OpenGL_GL_PREFERENCE "GLVND") diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 9cd84a2..fdf134c 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -11,14 +11,15 @@ set(SOURCES_OPENGL glcore/draw_opengl_core.c) set(SOURCES_OPENGL_LEGACY gl/draw_opengl.c) function (common_setup _TARGET) - target_link_libraries(${_TARGET} - $<$:SDL2::SDL2main> - SDL2::SDL2 - $<$:m>) + target_link_libraries(${_TARGET} SDL3::SDL3 $<$:m>) target_compile_options(${_TARGET} PRIVATE $<$:-Wall -Wextra -pedantic -Wno-unused-parameter>) - target_link_options(${_TARGET} PRIVATE - $<$:-Wl,-rpath,/Library/Frameworks>) + if (CMAKE_SYSTEM_NAME STREQUAL "Darwin") + get_property(SDL3_IMPORTED_LOCATION TARGET SDL3::SDL3 PROPERTY IMPORTED_LOCATION) + if (SDL3_IMPORTED_LOCATION MATCHES "^/Library/Frameworks/") + target_link_options(${_TARGET} PRIVATE -Wl,-rpath,/Library/Frameworks) + endif() + endif() endfunction() add_executable(${TARGET} ${SOURCES_COMMON} ${SOURCES_SDL_RENDERER}) diff --git a/src/analogue.c b/src/analogue.c index f20e645..075813c 100644 --- a/src/analogue.c +++ b/src/analogue.c @@ -2,6 +2,7 @@ #include "draw.h" #include "stick.h" #include +#include #include #include @@ -9,57 +10,54 @@ #define WINDOW_WIDTH 512 #define WINDOW_HEIGHT 288 + static SDL_Window* window = NULL; static SDL_JoystickID joyid = -1; -static SDL_GameController* pad = NULL; +static SDL_Gamepad* pad = NULL; -static bool UseGamepad(int aJoyid) +static bool UseGamepad(SDL_JoystickID aJoyid) { - pad = SDL_GameControllerOpen(aJoyid); - joyid = SDL_JoystickGetDeviceInstanceID(aJoyid); - if (pad != NULL) - { - printf("using gamepad #%d, \"%s\"\n", aJoyid, SDL_GameControllerName(pad)); - return true; - } - return false; + pad = SDL_OpenGamepad(aJoyid); + if (!pad) + return false; + joyid = aJoyid; + printf("using gamepad #%d, \"%s\"\n", aJoyid, SDL_GetGamepadName(pad)); + return true; } #define FATAL(CONDITION, RETURN) if (CONDITION) { res = (RETURN); goto error; } int main(int argc, char** argv) { - int res; - - res = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER); + int res = SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMEPAD); if (res < 0) goto error; - const int winpos = SDL_WINDOWPOS_CENTERED; + int winflg = SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIGH_PIXEL_DENSITY; #ifdef USE_OPENGL - const int winflg = SDL_WINDOW_RESIZABLE | SDL_WINDOW_OPENGL | SDL_WINDOW_ALLOW_HIGHDPI; + winflg |= SDL_WINDOW_OPENGL; #elif defined USE_METAL - const int winflg = SDL_WINDOW_RESIZABLE | SDL_WINDOW_METAL | SDL_WINDOW_ALLOW_HIGHDPI; -#else - const int winflg = SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI; + winflg |= SDL_WINDOW_METAL; #endif - int winw = WINDOW_WIDTH; - int winh = WINDOW_HEIGHT; + int winw = WINDOW_WIDTH, winh = WINDOW_HEIGHT; DrawWindowHints(); - window = SDL_CreateWindow(CAPTION, winpos, winpos, winw, winh, winflg); + window = SDL_CreateWindow(CAPTION, winw, winh, winflg); FATAL(window == NULL, -1) FATAL(InitDraw(window), -1) - size rendSize = GetDrawSizeInPixels(); + size rendSize; + SDL_GetWindowSizeInPixels(window, &rendSize.w, &rendSize.h); - if ((res = SDL_GameControllerAddMappingsFromFile("gamecontrollerdb.txt")) != -1) + if ((res = SDL_AddGamepadMappingsFromFile("gamecontrollerdb.txt")) != -1) printf("read %d mappings from gamecontrollerdb.txt\n", res); - for (int i = 0; i < SDL_NumJoysticks(); ++i) + + int numJoy; + SDL_JoystickID* joyIds = SDL_GetJoysticks(&numJoy); + if (joyIds) { - if (SDL_IsGameController(i)) - { - if (UseGamepad(i)) + for (int i = 0; i < numJoy; ++i) + if (SDL_IsGamepad(joyIds[i]) || UseGamepad(joyIds[i])) break; - } + SDL_free(joyIds); } vector plrpos = {10.0, 10.0}; @@ -70,13 +68,13 @@ int main(int argc, char** argv) bool running = true; bool repaint = true; bool showavatar = false; - uint32_t tickslast = SDL_GetTicks(); + uint64_t tickslast = SDL_GetTicks(); int side = 0; while (running) { //FIXME: probably doesn't matter but this isn't very precise - const uint32_t ticks = SDL_GetTicks(); + const uint64_t ticks = SDL_GetTicks(); const double framedelta = (double)(ticks - tickslast); tickslast = ticks; @@ -97,7 +95,7 @@ int main(int argc, char** argv) { switch (event.type) { - case (SDL_KEYDOWN): + case (SDL_EVENT_KEY_DOWN): if (event.key.keysym.sym == SDLK_ESCAPE) { running = false; @@ -109,67 +107,65 @@ int main(int argc, char** argv) } break; - case (SDL_CONTROLLERBUTTONDOWN): - if (event.cbutton.button == SDL_CONTROLLER_BUTTON_BACK) + case (SDL_EVENT_GAMEPAD_BUTTON_DOWN): + if (event.gbutton.button == SDL_GAMEPAD_BUTTON_BACK) { showavatar = !showavatar; repaint = true; } break; - case (SDL_QUIT): + case (SDL_EVENT_QUIT): running = false; break; - case (SDL_WINDOWEVENT): - if (event.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) + case (SDL_EVENT_WINDOW_RESIZED): + winw = event.window.data1; + winh = event.window.data2; + break; + + case (SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED): + rendSize = (size){event.window.data1, event.window.data2}; + SetDrawViewport(rendSize); + repaint = true; + break; + + case (SDL_EVENT_WINDOW_EXPOSED): + repaint = true; + break; + + case (SDL_EVENT_GAMEPAD_AXIS_MOTION): + if (event.gaxis.which != joyid) + break; + switch (event.gaxis.axis) { - winw = event.window.data1; - winh = event.window.data2; - rendSize = GetDrawSizeInPixels(); - SetDrawViewport(rendSize); - repaint = true; - } - else if (event.window.event == SDL_WINDOWEVENT_EXPOSED) - { - repaint = true; + case (SDL_GAMEPAD_AXIS_LEFTX): + stickl.rawpos.x = (vec_t)event.gaxis.value / (vec_t)0x7FFF; + repaint = stickl.recalc = true; + break; + case (SDL_GAMEPAD_AXIS_LEFTY): + stickl.rawpos.y = (vec_t)event.gaxis.value / (vec_t)0x7FFF; + repaint = stickl.recalc = true; + break; + case (SDL_GAMEPAD_AXIS_RIGHTX): + stickr.rawpos.x = (vec_t)event.gaxis.value / (vec_t)0x7FFF; + repaint = stickr.recalc = true; + break; + case (SDL_GAMEPAD_AXIS_RIGHTY): + stickr.rawpos.y = (vec_t)event.gaxis.value / (vec_t)0x7FFF; + repaint = stickr.recalc = true; + break; + default: + break; } break; - case (SDL_CONTROLLERAXISMOTION): - if (event.caxis.which == joyid) - { - if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTX) - { - stickl.rawpos.x = (vec_t)event.caxis.value / (vec_t)0x7FFF; - repaint = stickl.recalc = true; - } - else if (event.caxis.axis == SDL_CONTROLLER_AXIS_LEFTY) - { - stickl.rawpos.y = (vec_t)event.caxis.value / (vec_t)0x7FFF; - repaint = stickl.recalc = true; - } - else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTX) - { - stickr.rawpos.x = (vec_t)event.caxis.value / (vec_t)0x7FFF; - repaint = stickr.recalc = true; - } - else if (event.caxis.axis == SDL_CONTROLLER_AXIS_RIGHTY) - { - stickr.rawpos.y = (vec_t)event.caxis.value / (vec_t)0x7FFF; - repaint = stickr.recalc = true; - } - } - break; - - case (SDL_MOUSEBUTTONDOWN): - if (event.button.state & (SDL_BUTTON_LMASK | SDL_BUTTON_RMASK )) - { + case (SDL_EVENT_MOUSE_BUTTON_DOWN): + if (event.button.state & (SDL_BUTTON_LMASK | SDL_BUTTON_RMASK)) side = (event.button.x > winw / 2) ? 1 : 0; - } break; - case (SDL_MOUSEMOTION): + case (SDL_EVENT_MOUSE_MOTION): if (event.motion.state & SDL_BUTTON_LMASK) { const double hwinw = winw / 2.0; @@ -203,15 +199,15 @@ int main(int argc, char** argv) } break; - case (SDL_CONTROLLERDEVICEADDED): + case (SDL_EVENT_GAMEPAD_ADDED): if (pad == NULL) - UseGamepad(event.cdevice.which); + UseGamepad(event.gdevice.which); break; - case (SDL_CONTROLLERDEVICEREMOVED): - if (pad != NULL && event.cdevice.which == joyid) + case (SDL_EVENT_GAMEPAD_REMOVED): + if (pad != NULL && event.gdevice.which == joyid) { - SDL_GameControllerClose(pad); + SDL_CloseGamepad(pad); pad = NULL; printf("active gamepad was removed\n"); } @@ -258,7 +254,7 @@ int main(int argc, char** argv) res = 0; error: - SDL_GameControllerClose(pad); + SDL_CloseGamepad(pad); QuitDraw(); SDL_DestroyWindow(window); SDL_Quit(); diff --git a/src/draw.c b/src/draw.c index 94ebde9..6a1e493 100644 --- a/src/draw.c +++ b/src/draw.c @@ -1,6 +1,8 @@ #include "draw.h" #include "maths.h" #include +#include + static SDL_Renderer* rend = NULL; @@ -9,7 +11,7 @@ void DrawWindowHints(void) {} int InitDraw(SDL_Window* window) { const int rendflags = SDL_RENDERER_PRESENTVSYNC; - rend = SDL_CreateRenderer(window, -1, rendflags); + rend = SDL_CreateRenderer(window, NULL, rendflags); return (rend == NULL) ? -1 : 0; } @@ -20,13 +22,6 @@ void QuitDraw(void) } -size GetDrawSizeInPixels(void) -{ - size out = {0, 0}; - SDL_GetRendererOutputSize(rend, &out.w, &out.h); - return out; -} - void SetDrawViewport(size size) {} @@ -46,20 +41,20 @@ void DrawClear(void) void DrawPoint(int x, int y) { - SDL_RenderDrawPoint(rend, x, y); + SDL_RenderPoint(rend, (float)x, (float)y); } void DrawRect(int x, int y, int w, int h) { - SDL_Rect dst = { - .x = x, .y = y, - .w = w, .h = h }; - SDL_RenderDrawRect(rend, &dst); + SDL_FRect dst = { + .x = (float)x, .y = (float)y, + .w = (float)w, .h = (float)h }; + SDL_RenderRect(rend, &dst); } void DrawLine(int x1, int y1, int x2, int y2) { - SDL_RenderDrawLine(rend, x1, y1, x2, y2); + SDL_RenderLine(rend, (float)x1, (float)y1, (float)x2, (float)y2); } void DrawCircleSteps(int x, int y, int r, int steps) @@ -73,9 +68,9 @@ void DrawCircleSteps(int x, int y, int r, int steps) int ofsx = (int)round(cos(stepsz * i) * mag); int ofsy = (int)round(sin(stepsz * i) * mag); - SDL_RenderDrawLine(rend, - x + lastx, y + lasty, - x + ofsx, y + ofsy); + SDL_RenderLine(rend, + (float)(x + lastx), (float)(y + lasty), + (float)(x + ofsx), (float)(y + ofsy)); lastx = ofsx; lasty = ofsy; @@ -96,9 +91,9 @@ void DrawArcSteps(int x, int y, int r, int startAng, int endAng, int steps) int ofsx = (int)round(cos(theta) * mag); int ofsy = (int)round(-sin(theta) * mag); - SDL_RenderDrawLine(rend, - x + lastx, y + lasty, - x + ofsx, y + ofsy); + SDL_RenderLine(rend, + (float)(x + lastx), (float)(y + lasty), + (float)(x + ofsx), (float)(y + ofsy)); lastx = ofsx; lasty = ofsy; diff --git a/src/draw.h b/src/draw.h index a578f7f..3951999 100644 --- a/src/draw.h +++ b/src/draw.h @@ -27,13 +27,6 @@ int InitDraw(SDL_Window* window); // subsystem is uninitialised. void QuitDraw(void); -// Get the actual size of the canvas in pixels. -// -// Returns: -// size struct with 'w' and 'h' set to the width & -// height of the canvas in actual pixels. -size GetDrawSizeInPixels(void); - // Call on resize for backends that need manual viewport resizing. void SetDrawViewport(size size); diff --git a/src/gl/draw_opengl.c b/src/gl/draw_opengl.c index ac30854..3845f13 100644 --- a/src/gl/draw_opengl.c +++ b/src/gl/draw_opengl.c @@ -2,8 +2,10 @@ #include "maths.h" #include #include +#include #include + static SDL_GLContext* ctx = NULL; static SDL_Window* window = NULL; static uint32_t colour = 0x00000000; @@ -43,7 +45,9 @@ int InitDraw(SDL_Window* w) glDisable(GL_CULL_FACE); glEnable(GL_MULTISAMPLE); - SetDrawViewport(GetDrawSizeInPixels()); // Fills scaleWidth & scaleHeight + size size; + SDL_GetWindowSizeInPixels(w, &size.w, &size.h); + SetDrawViewport(size); // Fills scaleWidth & scaleHeight glLineWidth(2.0f); @@ -64,13 +68,6 @@ void QuitDraw(void) } -size GetDrawSizeInPixels(void) -{ - size out; - SDL_GL_GetDrawableSize(SDL_GL_GetCurrentWindow(), &out.w, &out.h); - return out; -} - void SetDrawViewport(size size) { glViewport(0, 0, size.w, size.h); diff --git a/src/glcore/draw_opengl_core.c b/src/glcore/draw_opengl_core.c index fd4816a..4eeb095 100644 --- a/src/glcore/draw_opengl_core.c +++ b/src/glcore/draw_opengl_core.c @@ -4,8 +4,10 @@ #include #include #include +#include #include + typedef struct { float x, y; } vertex; enum { ATTRIB_VERTPOS, NUM_ATTRIBS }; @@ -215,7 +217,9 @@ int InitDraw(SDL_Window* _window) glVertexAttribPointer(ATTRIB_VERTPOS, 2, GL_FLOAT, GL_FALSE, sizeof(vertex), (GLvoid*)0); // Reset viewport & clear - SetDrawViewport(GetDrawSizeInPixels()); + size size; + SDL_GetWindowSizeInPixels(window, &size.w, &size.h); + SetDrawViewport(size); glUniform4f(uColour, 1.0f, 1.0f, 1.0f, 1.0f); glClearColor(0.0f, 0.0f, 0.0f, 0.0f); glClear(GL_COLOR_BUFFER_BIT); @@ -261,13 +265,6 @@ void QuitDraw(void) } -size GetDrawSizeInPixels(void) -{ - size out; - SDL_GL_GetDrawableSize(SDL_GL_GetCurrentWindow(), &out.w, &out.h); - return out; -} - void SetDrawViewport(size size) { glViewport(0, 0, size.w, size.h); diff --git a/src/metal/draw_metal.m b/src/metal/draw_metal.m index 2eb7772..0224e97 100644 --- a/src/metal/draw_metal.m +++ b/src/metal/draw_metal.m @@ -7,6 +7,9 @@ #import #import +#define DRAWLIST_CHUNK_SIZE 480 +#define DRAWLIST_INIT_SIZE (DRAWLIST_CHUNK_SIZE * 3) + @interface MetalRenderer : NSObject @@ -15,9 +18,8 @@ - (id) init:(SDL_Window*)window; - (void) dealloc; -- (unsigned) resizeBuffer:(id *)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count; +- (NSUInteger) resizeBuffer:(id *)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count; -- (size) getDrawSize; - (void) setView:(size)viewportSize; - (void) clear; - (void) reserveVertices:(unsigned)count; @@ -29,9 +31,6 @@ @end -#define DRAWLIST_CHUNK_SIZE 480 -#define DRAWLIST_INIT_SIZE (DRAWLIST_CHUNK_SIZE * 3) - @implementation MetalRenderer { SDL_Window* _window; @@ -44,7 +43,8 @@ MTLViewport _viewport; vector_float4 _drawColourF; - unsigned _vtxListCount, _vtxListReserve, _idxListCount, _idxListReserve; + unsigned _vtxListCount, _idxListCount; + NSUInteger _vtxListReserve, _idxListReserve; id _vtxMtlBuffer, _idxMtlBuffer; } @@ -54,10 +54,8 @@ return nil; self.drawColour = BLACK; - _vtxListReserve = 0; - _idxListReserve = 0; - _vtxMtlBuffer = nil; - _idxMtlBuffer = nil; + _vtxListReserve = _idxListReserve = 0; + _vtxMtlBuffer = _idxMtlBuffer = nil; // Create Metal view _window = window; @@ -117,7 +115,9 @@ [pipeDesc release]; // Set viewport - [self setView:[self getDrawSize]]; + size size; + SDL_GetWindowSizeInPixels(_window, &size.w, &size.h); + [self setView:size]; return self; } @@ -129,12 +129,11 @@ } -- (unsigned) resizeBuffer:(id *)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count +- (NSUInteger) resizeBuffer:(id *)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count { - unsigned reserve; - if (*buf) - if (count * nsz <= (reserve = [*buf length])) - return reserve; + NSUInteger reserve; + if (*buf && count * nsz <= (reserve = [*buf length])) + return reserve; // Calculate new capacity unsigned newCapacity = (count + DRAWLIST_CHUNK_SIZE - 1) / DRAWLIST_CHUNK_SIZE * DRAWLIST_CHUNK_SIZE; @@ -155,13 +154,6 @@ } -- (size) getDrawSize -{ - size out; - SDL_Metal_GetDrawableSize(_window, &out.w, &out.h); - return out; -} - - (void) setDrawColour:(uint32_t)colour { _drawColour = colour; @@ -282,43 +274,31 @@ int InitDraw(SDL_Window* window) return 0; } - void QuitDraw(void) { [renderer release]; } - -size GetDrawSizeInPixels(void) -{ - return renderer ? [renderer getDrawSize] : (size){ 0, 0 }; -} - - void SetDrawViewport(size size) { [renderer setView:size]; } - void SetDrawColour(uint32_t c) { renderer.drawColour = c; } - void DrawClear(void) { [renderer clear]; } - void DrawPoint(int x, int y) { DrawCircleSteps(x, y, 1, 4); } - void DrawRect(int x, int y, int w, int h) { [renderer reserveVertices:4]; @@ -333,14 +313,12 @@ void DrawRect(int x, int y, int w, int h) [renderer queueIndices:indices count:sizeof(indices) / sizeof(uint16_t)]; } - void DrawLine(int x1, int y1, int x2, int y2) { [renderer queueIndex:[renderer queueVertex:x1 :y1]]; [renderer queueIndex:[renderer queueVertex:x2 :y2]]; } - void DrawCircleSteps(int x, int y, int r, int steps) { const float fx = (float)x, fy = (float)y; @@ -360,7 +338,6 @@ void DrawCircleSteps(int x, int y, int r, int steps) [renderer queueIndex:base]; } - void DrawArcSteps(int x, int y, int r, int startAng, int endAng, int steps) { const float fx = (float)x, fy = (float)y;