|
@@ -34,7 +34,9 @@ typedef struct
|
|
int width, height;
|
|
int width, height;
|
|
} Dimensions;
|
|
} Dimensions;
|
|
|
|
|
|
-static void CopyFramebuffertoN3DS(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim);
|
|
|
|
|
|
+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 GetDestOffset(int x, int y, int dest_width);
|
|
static int GetSourceOffset(int x, int y, int source_width);
|
|
static int GetSourceOffset(int x, int y, int source_width);
|
|
static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen);
|
|
static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen);
|
|
@@ -43,17 +45,21 @@ static void FlushN3DSBuffer(const void *buffer, u32 bufsize, gfxScreen_t screen)
|
|
int SDL_N3DS_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormatEnum *format, void **pixels, int *pitch)
|
|
int SDL_N3DS_CreateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window, SDL_PixelFormatEnum *format, void **pixels, int *pitch)
|
|
{
|
|
{
|
|
SDL_Surface *framebuffer;
|
|
SDL_Surface *framebuffer;
|
|
|
|
+ const SDL_DisplayMode *mode;
|
|
int w, h;
|
|
int w, h;
|
|
|
|
|
|
|
|
+ SDL_N3DS_DestroyWindowFramebuffer(_this, window);
|
|
|
|
+
|
|
|
|
+ mode = SDL_GetCurrentDisplayMode(SDL_GetDisplayForWindow(window));
|
|
SDL_GetWindowSizeInPixels(window, &w, &h);
|
|
SDL_GetWindowSizeInPixels(window, &w, &h);
|
|
- framebuffer = SDL_CreateSurface(w, h, FRAMEBUFFER_FORMAT);
|
|
|
|
|
|
+ framebuffer = SDL_CreateSurface(w, h, mode->format);
|
|
|
|
|
|
if (!framebuffer) {
|
|
if (!framebuffer) {
|
|
return -1;
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
|
|
SDL_SetSurfaceProperty(SDL_GetWindowProperties(window), N3DS_SURFACE, framebuffer);
|
|
SDL_SetSurfaceProperty(SDL_GetWindowProperties(window), N3DS_SURFACE, framebuffer);
|
|
- *format = FRAMEBUFFER_FORMAT;
|
|
|
|
|
|
+ *format = mode->format;
|
|
*pixels = framebuffer->pixels;
|
|
*pixels = framebuffer->pixels;
|
|
*pitch = framebuffer->pitch;
|
|
*pitch = framebuffer->pitch;
|
|
return 0;
|
|
return 0;
|
|
@@ -64,7 +70,7 @@ int SDL_N3DS_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window,
|
|
SDL_WindowData *drv_data = window->driverdata;
|
|
SDL_WindowData *drv_data = window->driverdata;
|
|
SDL_Surface *surface;
|
|
SDL_Surface *surface;
|
|
u16 width, height;
|
|
u16 width, height;
|
|
- u32 *framebuffer;
|
|
|
|
|
|
+ void *framebuffer;
|
|
u32 bufsize;
|
|
u32 bufsize;
|
|
|
|
|
|
surface = (SDL_Surface *)SDL_GetProperty(SDL_GetWindowProperties(window), N3DS_SURFACE, NULL);
|
|
surface = (SDL_Surface *)SDL_GetProperty(SDL_GetWindowProperties(window), N3DS_SURFACE, NULL);
|
|
@@ -73,26 +79,60 @@ int SDL_N3DS_UpdateWindowFramebuffer(SDL_VideoDevice *_this, SDL_Window *window,
|
|
}
|
|
}
|
|
|
|
|
|
/* Get the N3DS internal framebuffer and its size */
|
|
/* Get the N3DS internal framebuffer and its size */
|
|
- framebuffer = (u32 *)gfxGetFramebuffer(drv_data->screen, GFX_LEFT, &width, &height);
|
|
|
|
|
|
+ framebuffer = gfxGetFramebuffer(drv_data->screen, GFX_LEFT, &width, &height);
|
|
bufsize = width * height * 4;
|
|
bufsize = width * height * 4;
|
|
|
|
|
|
- CopyFramebuffertoN3DS(framebuffer, (Dimensions){ width, height },
|
|
|
|
- surface->pixels, (Dimensions){ surface->w, surface->h });
|
|
|
|
|
|
+ if (surface->format->bytes_per_pixel == 2)
|
|
|
|
+ CopyFramebuffertoN3DS_16(framebuffer, (Dimensions){ width, height },
|
|
|
|
+ surface->pixels, (Dimensions){ surface->w, surface->h });
|
|
|
|
+ else if (surface->format->bytes_per_pixel == 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);
|
|
FlushN3DSBuffer(framebuffer, bufsize, drv_data->screen);
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
|
|
-static void CopyFramebuffertoN3DS(u32 *dest, const Dimensions dest_dim, const u32 *source, const Dimensions source_dim)
|
|
|
|
|
|
+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 rows = SDL_min(dest_dim.width, source_dim.height);
|
|
int cols = SDL_min(dest_dim.height, source_dim.width);
|
|
int cols = SDL_min(dest_dim.height, source_dim.width);
|
|
for (int y = 0; y < rows; ++y) {
|
|
for (int y = 0; y < rows; ++y) {
|
|
for (int x = 0; x < cols; ++x) {
|
|
for (int x = 0; x < cols; ++x) {
|
|
- SDL_memcpy(
|
|
|
|
- dest + GetDestOffset(x, y, dest_dim.width),
|
|
|
|
- source + GetSourceOffset(x, y, source_dim.width),
|
|
|
|
- 4);
|
|
|
|
|
|
+ const u32 *s = source + GetSourceOffset(x, y, source_dim.width);
|
|
|
|
+ u32 *d = dest + GetDestOffset(x, y, dest_dim.width);
|
|
|
|
+ *d = *s;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|