chore(build): use SDL3

This commit is contained in:
phaneron 2025-04-12 04:38:19 -04:00
parent 9d04a35d87
commit b3c0734a9e
3286 changed files with 866354 additions and 554996 deletions

View file

@ -0,0 +1,45 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_N3DS
#include <3ds.h>
#include "../../events/SDL_events_c.h"
#include "SDL_n3dsevents_c.h"
#include "SDL_n3dstouch.h"
void N3DS_PumpEvents(SDL_VideoDevice *_this)
{
hidScanInput();
N3DS_PollTouch(_this);
if (!aptMainLoop()) {
SDL_Event ev;
ev.type = SDL_EVENT_QUIT;
ev.common.timestamp = 0;
SDL_PushEvent(&ev);
return;
}
}
#endif // SDL_VIDEO_DRIVER_N3DS

View file

@ -0,0 +1,29 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_n3dsevents_c_h_
#define SDL_n3dsevents_c_h_
#include "SDL_internal.h"
extern void N3DS_PumpEvents(SDL_VideoDevice *_this);
#endif // SDL_n3dsevents_c_h_

View file

@ -0,0 +1,161 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_N3DS
#include "../SDL_sysvideo.h"
#include "../../SDL_properties_c.h"
#include "SDL_n3dsframebuffer_c.h"
#include "SDL_n3dsvideo.h"
#define N3DS_SURFACE "SDL.internal.window.surface"
typedef struct
{
int width, height;
} Dimensions;
static void CopyFramebuffertoN3DS_16(u16 *dest, const Dimensions dest_dim, const u16 *source, const Dimensions source_dim);
static void CopyFramebuffertoN3DS_24(u8 *dest, const Dimensions dest_dim, const u8 *source, const Dimensions source_dim);
static void CopyFramebuffertoN3DS_32(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim);
static int GetDestOffset(int x, int y, int dest_width);
static int GetSourceOffset(int x, int y, int source_width);
static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen);
bool SDL_N3DS_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch)
{
SDL_Surface *framebuffer;
const SDL_DisplayMode *mode;
int w, h;
SDL_N3DS_DestroyWindowFramebuffer(_this, window);
mode = SDL_GetCurrentDisplayMode(SDL_GetDisplayForWindow(window));
SDL_GetWindowSizeInPixels(window, &w, &h);
framebuffer = SDL_CreateSurface(w, h, mode->format);
if (!framebuffer) {
return false;
}
SDL_SetSurfaceProperty(SDL_GetWindowProperties(window), N3DS_SURFACE, framebuffer);
*format = mode->format;
*pixels = framebuffer->pixels;
*pitch = framebuffer->pitch;
return true;
}
bool SDL_N3DS_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects)
{
SDL_WindowData *drv_data = window->internal;
SDL_Surface *surface;
u16 width, height;
void *framebuffer;
u32 bufsize;
surface = (SDL_Surface *)SDL_GetPointerProperty(SDL_GetWindowProperties(window), N3DS_SURFACE, NULL);
if (!surface) {
return SDL_SetError("%s: Unable to get the window surface.", __func__);
}
// Get the N3DS internal framebuffer and its size
framebuffer = gfxGetFramebuffer(drv_data->screen, GFX_LEFT, &width, &height);
bufsize = width * height * 4;
if (SDL_BYTESPERPIXEL(surface->format) == 2)
CopyFramebuffertoN3DS_16(framebuffer, (Dimensions){ width, height },
surface->pixels, (Dimensions){ surface->w, surface->h });
else if (SDL_BYTESPERPIXEL(surface->format) == 3)
CopyFramebuffertoN3DS_24(framebuffer, (Dimensions){ width, height },
surface->pixels, (Dimensions){ surface->w, surface->h });
else
CopyFramebuffertoN3DS_32(framebuffer, (Dimensions){ width, height },
surface->pixels, (Dimensions){ surface->w, surface->h });
FlushN3DSBuffer(framebuffer, bufsize, drv_data->screen);
return true;
}
static void CopyFramebuffertoN3DS_16(u16 *dest, const Dimensions dest_dim, const u16 *source, const Dimensions source_dim)
{
int rows = SDL_min(dest_dim.width, source_dim.height);
int cols = SDL_min(dest_dim.height, source_dim.width);
for (int y = 0; y < rows; ++y) {
for (int x = 0; x < cols; ++x) {
const u16 *s = source + GetSourceOffset(x, y, source_dim.width);
u16 *d = dest + GetDestOffset(x, y, dest_dim.width);
*d = *s;
}
}
}
static void CopyFramebuffertoN3DS_24(u8 *dest, const Dimensions dest_dim, const u8 *source, const Dimensions source_dim)
{
int rows = SDL_min(dest_dim.width, source_dim.height);
int cols = SDL_min(dest_dim.height, source_dim.width);
for (int y = 0; y < rows; ++y) {
for (int x = 0; x < cols; ++x) {
const u8 *s = source + GetSourceOffset(x, y, source_dim.width) * 3;
u8 *d = dest + GetDestOffset(x, y, dest_dim.width) * 3;
d[0] = s[0];
d[1] = s[1];
d[2] = s[2];
}
}
}
static void CopyFramebuffertoN3DS_32(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim)
{
int rows = SDL_min(dest_dim.width, source_dim.height);
int cols = SDL_min(dest_dim.height, source_dim.width);
for (int y = 0; y < rows; ++y) {
for (int x = 0; x < cols; ++x) {
const u32 *s = source + GetSourceOffset(x, y, source_dim.width);
u32 *d = dest + GetDestOffset(x, y, dest_dim.width);
*d = *s;
}
}
}
static int GetDestOffset(int x, int y, int dest_width)
{
return dest_width - y - 1 + dest_width * x;
}
static int GetSourceOffset(int x, int y, int source_width)
{
return x + y * source_width;
}
static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen)
{
GSPGPU_FlushDataCache(buffer, bufsize);
gfxScreenSwapBuffers(screen, false);
}
void SDL_N3DS_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window)
{
SDL_ClearProperty(SDL_GetWindowProperties(window), N3DS_SURFACE);
}
#endif // SDL_VIDEO_DRIVER_N3DS

View file

@ -0,0 +1,31 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_n3dsframebuffer_c_h_
#define SDL_n3dsframebuffer_c_h_
#include "SDL_internal.h"
extern bool SDL_N3DS_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormat *format, void **pixels, int *pitch);
extern bool SDL_N3DS_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, const SDL_Rect *rects, int numrects);
extern void SDL_N3DS_DestroyWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window);
#endif // SDL_n3dsframebuffer_c_h_

View file

@ -0,0 +1,69 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_N3DS
#include <3ds.h>
#include "SDL_n3dsswkb.h"
static SwkbdState sw_keyboard;
const static size_t BUFFER_SIZE = 256;
void N3DS_SwkbInit(void)
{
swkbdInit(&sw_keyboard, SWKBD_TYPE_NORMAL, 2, -1);
}
void N3DS_SwkbPoll(void)
{
return;
}
void N3DS_SwkbQuit(void)
{
return;
}
bool N3DS_HasScreenKeyboardSupport(SDL_VideoDevice *_this)
{
return true;
}
bool N3DS_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props)
{
char buffer[BUFFER_SIZE];
SwkbdButton button_pressed;
button_pressed = swkbdInputText(&sw_keyboard, buffer, BUFFER_SIZE);
if (button_pressed == SWKBD_BUTTON_CONFIRM) {
SDL_SendKeyboardText(buffer);
}
return true;
}
bool N3DS_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window)
{
return true;
}
#endif // SDL_VIDEO_DRIVER_N3DS

View file

@ -0,0 +1,36 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_n3dskeyboard_h_
#define SDL_n3dskeyboard_h_
#include "../../events/SDL_events_c.h"
void N3DS_SwkbInit();
void N3DS_SwkbPoll();
void N3DS_SwkbQuit();
bool N3DS_HasScreenKeyboardSupport(SDL_VideoDevice *_this);
bool N3DS_StartTextInput(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID props);
bool N3DS_StopTextInput(SDL_VideoDevice *_this, SDL_Window *window);
#endif // SDL_n3dskeyboard_h_

View file

@ -0,0 +1,86 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_N3DS
#include <3ds.h>
#include "../../events/SDL_touch_c.h"
#include "../SDL_sysvideo.h"
#include "SDL_n3dstouch.h"
#include "SDL_n3dsvideo.h"
#define N3DS_TOUCH_ID 1
#define N3DS_TOUCH_FINGER 1
/*
Factors used to convert touchscreen coordinates to
SDL's 0-1 values. Note that the N3DS's screen is
internally in a portrait disposition so the
GSP_SCREEN constants are flipped.
*/
#define TOUCHSCREEN_SCALE_X 1.0f / (GSP_SCREEN_HEIGHT_BOTTOM - 1)
#define TOUCHSCREEN_SCALE_Y 1.0f / (GSP_SCREEN_WIDTH - 1)
void N3DS_InitTouch(void)
{
SDL_AddTouch(N3DS_TOUCH_ID, SDL_TOUCH_DEVICE_DIRECT, "Touchscreen");
}
void N3DS_QuitTouch(void)
{
SDL_DelTouch(N3DS_TOUCH_ID);
}
void N3DS_PollTouch(SDL_VideoDevice *_this)
{
SDL_VideoData *internal = (SDL_VideoData *)_this->internal;
touchPosition touch;
SDL_Window *window;
SDL_VideoDisplay *display;
static bool was_pressed = false;
bool pressed;
hidTouchRead(&touch);
pressed = (touch.px != 0 || touch.py != 0);
display = SDL_GetVideoDisplay(internal->touch_display);
window = display ? display->fullscreen_window : NULL;
if (pressed != was_pressed) {
was_pressed = pressed;
SDL_SendTouch(0, N3DS_TOUCH_ID, N3DS_TOUCH_FINGER,
window,
pressed ? SDL_EVENT_FINGER_DOWN : SDL_EVENT_FINGER_UP,
touch.px * TOUCHSCREEN_SCALE_X,
touch.py * TOUCHSCREEN_SCALE_Y,
pressed ? 1.0f : 0.0f);
} else if (pressed) {
SDL_SendTouchMotion(0, N3DS_TOUCH_ID, N3DS_TOUCH_FINGER,
window,
touch.px * TOUCHSCREEN_SCALE_X,
touch.py * TOUCHSCREEN_SCALE_Y,
1.0f);
}
}
#endif // SDL_VIDEO_DRIVER_N3DS

View file

@ -0,0 +1,29 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#ifndef SDL_n3dstouch_h_
#define SDL_n3dstouch_h_
void N3DS_InitTouch(void);
void N3DS_QuitTouch(void);
void N3DS_PollTouch(SDL_VideoDevice *_this);
#endif // SDL_n3dstouch_h_

View file

@ -0,0 +1,259 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifdef SDL_VIDEO_DRIVER_N3DS
#include "../SDL_sysvideo.h"
#include "SDL_n3dsevents_c.h"
#include "SDL_n3dsframebuffer_c.h"
#include "SDL_n3dsswkb.h"
#include "SDL_n3dstouch.h"
#include "SDL_n3dsvideo.h"
#define N3DSVID_DRIVER_NAME "n3ds"
static bool AddN3DSDisplay(gfxScreen_t screen);
static bool N3DS_VideoInit(SDL_VideoDevice *_this);
static void N3DS_VideoQuit(SDL_VideoDevice *_this);
static bool N3DS_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display);
static bool N3DS_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode);
static bool N3DS_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect);
static bool N3DS_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props);
static void N3DS_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window);
struct SDL_DisplayData
{
gfxScreen_t screen;
};
struct SDL_DisplayModeData
{
GSPGPU_FramebufferFormat fmt;
};
static const struct
{
SDL_PixelFormat pixfmt;
GSPGPU_FramebufferFormat gspfmt;
} format_map[] = {
{ SDL_PIXELFORMAT_RGBA8888, GSP_RGBA8_OES },
{ SDL_PIXELFORMAT_BGR24, GSP_BGR8_OES },
{ SDL_PIXELFORMAT_RGB565, GSP_RGB565_OES },
{ SDL_PIXELFORMAT_RGBA5551, GSP_RGB5_A1_OES },
{ SDL_PIXELFORMAT_RGBA4444, GSP_RGBA4_OES }
};
// N3DS driver bootstrap functions
static void N3DS_DeleteDevice(SDL_VideoDevice *device)
{
SDL_free(device->internal);
SDL_free(device);
}
static SDL_VideoDevice *N3DS_CreateDevice(void)
{
SDL_VideoDevice *device;
SDL_VideoData *phdata;
// Initialize all variables that we clean on shutdown
device = (SDL_VideoDevice *)SDL_calloc(1, sizeof(SDL_VideoDevice));
if (!device) {
return NULL;
}
// Initialize internal data
phdata = (SDL_VideoData *)SDL_calloc(1, sizeof(SDL_VideoData));
if (!phdata) {
SDL_free(device);
return NULL;
}
device->internal = phdata;
device->VideoInit = N3DS_VideoInit;
device->VideoQuit = N3DS_VideoQuit;
device->GetDisplayModes = N3DS_GetDisplayModes;
device->SetDisplayMode = N3DS_SetDisplayMode;
device->GetDisplayBounds = N3DS_GetDisplayBounds;
device->CreateSDLWindow = N3DS_CreateWindow;
device->DestroyWindow = N3DS_DestroyWindow;
device->HasScreenKeyboardSupport = N3DS_HasScreenKeyboardSupport;
device->StartTextInput = N3DS_StartTextInput;
device->StopTextInput = N3DS_StopTextInput;
device->PumpEvents = N3DS_PumpEvents;
device->CreateWindowFramebuffer = SDL_N3DS_CreateWindowFramebuffer;
device->UpdateWindowFramebuffer = SDL_N3DS_UpdateWindowFramebuffer;
device->DestroyWindowFramebuffer = SDL_N3DS_DestroyWindowFramebuffer;
device->free = N3DS_DeleteDevice;
device->device_caps = VIDEO_DEVICE_CAPS_FULLSCREEN_ONLY;
return device;
}
VideoBootStrap N3DS_bootstrap = { N3DSVID_DRIVER_NAME, "N3DS Video Driver", N3DS_CreateDevice, NULL, /* no ShowMessageBox implementation */ false };
static bool N3DS_VideoInit(SDL_VideoDevice *_this)
{
SDL_VideoData *internal = (SDL_VideoData *)_this->internal;
gfxInit(GSP_RGBA8_OES, GSP_RGBA8_OES, false);
hidInit();
internal->top_display = AddN3DSDisplay(GFX_TOP);
internal->touch_display = AddN3DSDisplay(GFX_BOTTOM);
N3DS_InitTouch();
N3DS_SwkbInit();
return true;
}
static bool AddN3DSDisplay(gfxScreen_t screen)
{
SDL_DisplayMode mode;
SDL_DisplayModeData *modedata;
SDL_VideoDisplay display;
SDL_DisplayData *display_driver_data = SDL_calloc(1, sizeof(SDL_DisplayData));
if (!display_driver_data) {
return false;
}
SDL_zero(mode);
SDL_zero(display);
display_driver_data->screen = screen;
modedata = SDL_malloc(sizeof(SDL_DisplayModeData));
if (!modedata) {
return false;
}
mode.w = (screen == GFX_TOP) ? GSP_SCREEN_HEIGHT_TOP : GSP_SCREEN_HEIGHT_BOTTOM;
mode.h = GSP_SCREEN_WIDTH;
mode.refresh_rate = 60.0f;
mode.format = SDL_PIXELFORMAT_RGBA8888;
mode.internal = modedata;
modedata->fmt = GSP_RGBA8_OES;
display.name = (screen == GFX_TOP) ? "N3DS top screen" : "N3DS bottom screen";
display.desktop_mode = mode;
display.internal = display_driver_data;
if (SDL_AddVideoDisplay(&display, false) == 0) {
return false;
}
return true;
}
static void N3DS_VideoQuit(SDL_VideoDevice *_this)
{
N3DS_SwkbQuit();
N3DS_QuitTouch();
hidExit();
gfxExit();
}
static bool N3DS_GetDisplayModes(SDL_VideoDevice *_this, SDL_VideoDisplay *display)
{
SDL_DisplayData *displaydata = display->internal;
SDL_DisplayModeData *modedata;
SDL_DisplayMode mode;
int i;
for (i = 0; i < SDL_arraysize(format_map); i++) {
modedata = SDL_malloc(sizeof(SDL_DisplayModeData));
if (!modedata)
continue;
SDL_zero(mode);
mode.w = (displaydata->screen == GFX_TOP) ? GSP_SCREEN_HEIGHT_TOP : GSP_SCREEN_HEIGHT_BOTTOM;
mode.h = GSP_SCREEN_WIDTH;
mode.refresh_rate = 60.0f;
mode.format = format_map[i].pixfmt;
mode.internal = modedata;
modedata->fmt = format_map[i].gspfmt;
if (!SDL_AddFullscreenDisplayMode(display, &mode)) {
SDL_free(modedata);
}
}
return true;
}
static bool N3DS_SetDisplayMode(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_DisplayMode *mode)
{
SDL_DisplayData *displaydata = display->internal;
SDL_DisplayModeData *modedata = mode->internal;
gfxSetScreenFormat(displaydata->screen, modedata->fmt);
return true;
}
static bool N3DS_GetDisplayBounds(SDL_VideoDevice *_this, SDL_VideoDisplay *display, SDL_Rect *rect)
{
SDL_DisplayData *driver_data = display->internal;
if (!driver_data) {
return false;
}
rect->x = 0;
rect->y = (driver_data->screen == GFX_TOP) ? 0 : GSP_SCREEN_WIDTH;
rect->w = display->current_mode->w;
rect->h = display->current_mode->h;
return true;
}
static bool N3DS_CreateWindow(SDL_VideoDevice *_this, SDL_Window *window, SDL_PropertiesID create_props)
{
SDL_DisplayData *display_data;
SDL_WindowData *window_data = (SDL_WindowData *)SDL_calloc(1, sizeof(SDL_WindowData));
if (!window_data) {
return false;
}
display_data = SDL_GetDisplayDriverDataForWindow(window);
window_data->screen = display_data->screen;
window->internal = window_data;
SDL_SetKeyboardFocus(window);
return true;
}
static void N3DS_DestroyWindow(SDL_VideoDevice *_this, SDL_Window *window)
{
if (!window) {
return;
}
SDL_free(window->internal);
}
#endif // SDL_VIDEO_DRIVER_N3DS

View file

@ -0,0 +1,41 @@
/*
Simple DirectMedia Layer
Copyright (C) 1997-2025 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#include "SDL_internal.h"
#ifndef SDL_n3dsvideo_h_
#define SDL_n3dsvideo_h_
#include <3ds.h>
#include "../SDL_sysvideo.h"
struct SDL_VideoData
{
int top_display;
int touch_display;
};
struct SDL_WindowData
{
gfxScreen_t screen; /**< Keeps track of which N3DS screen is targeted */
};
#endif // SDL_n3dsvideo_h_