SDL3 port

This commit is contained in:
2024-03-10 19:34:07 +11:00
parent 2496f9e2a3
commit 8a5529e752
9 changed files with 130 additions and 171 deletions

3
.gitignore vendored
View File

@ -1,5 +1,8 @@
.idea/
.vs/
.vscode/
cmake-build-*/
build/
out/
.DS_Store

View File

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

View File

@ -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}
$<$<PLATFORM_ID:Windows>:SDL2::SDL2main>
SDL2::SDL2
$<$<BOOL:${GNU}>:m>)
target_link_libraries(${_TARGET} SDL3::SDL3 $<$<BOOL:${GNU}>:m>)
target_compile_options(${_TARGET} PRIVATE
$<$<BOOL:${GNU}>:-Wall -Wextra -pedantic -Wno-unused-parameter>)
target_link_options(${_TARGET} PRIVATE
$<$<PLATFORM_ID:Darwin>:-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})

View File

@ -2,6 +2,7 @@
#include "draw.h"
#include "stick.h"
#include <SDL.h>
#include <SDL_main.h>
#include <stdio.h>
#include <stdbool.h>
@ -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;
}
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;
rendSize = GetDrawSizeInPixels();
break;
case (SDL_EVENT_WINDOW_PIXEL_SIZE_CHANGED):
rendSize = (size){event.window.data1, event.window.data2};
SetDrawViewport(rendSize);
repaint = true;
}
else if (event.window.event == SDL_WINDOWEVENT_EXPOSED)
{
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)
{
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):
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();

View File

@ -1,6 +1,8 @@
#include "draw.h"
#include "maths.h"
#include <SDL_render.h>
#include <stdlib.h>
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;

View File

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

View File

@ -2,8 +2,10 @@
#include "maths.h"
#include <SDL_video.h>
#include <SDL_opengl.h>
#include <stdlib.h>
#include <stdbool.h>
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);

View File

@ -4,8 +4,10 @@
#include <GL/gl3w.h>
#include <SDL_video.h>
#include <stdbool.h>
#include <stdlib.h>
#include <stdio.h>
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);

View File

@ -7,6 +7,9 @@
#import <Metal/Metal.h>
#import <QuartzCore/CAMetalLayer.h>
#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 <MTLBuffer>*)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count;
- (NSUInteger) resizeBuffer:(id <MTLBuffer>*)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<MTLBuffer> _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,11 +129,10 @@
}
- (unsigned) resizeBuffer:(id <MTLBuffer>*)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count
- (NSUInteger) resizeBuffer:(id <MTLBuffer>*)buf itemSize:(unsigned)nsz requiredNum:(unsigned)count
{
unsigned reserve;
if (*buf)
if (count * nsz <= (reserve = [*buf length]))
NSUInteger reserve;
if (*buf && count * nsz <= (reserve = [*buf length]))
return reserve;
// Calculate new capacity
@ -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;