* update to SDL 3.2.0 * remove SDL wrap * fix darwin and windows CI * update build box, correct msys sdl3 dependency * port leftovers from renderer backend to SDL3 * remove SDL main dep the main implementation is now included in a header * main.c: use SDL_main.h This needs to be included to work. * ci: use vcpkg and pkgconf to support SDL3 on MSVC * ci: use 7z to create zip * renwindow: create texture and surface suitable for the display * system: remove trailing whitespace * renderer: fix trailing whitespace * system: fix checking the wrong argument * system: port rmdir and stat to SDL3 API * system: remove unneeded API level check * system: fix wrong parameter index * system: make set_window_hit_test and set_window_bordered accept a window * docs/system: update docs * system: restore some comments * docs/system: add missing documentation for system.text_input * system: use SDL_setenv_unsafe * system: add back comment for setenv * system,renderer: remove unnecessary SDL_ClearError calls --------- Co-authored-by: takase1121 <20792268+takase1121@users.noreply.github.com> (cherry picked from commit 2716f14b6903f055f6bdf010a7e4a3d040cf059d)
145 lines
4.6 KiB
C
145 lines
4.6 KiB
C
#include <stdlib.h>
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include "renwindow.h"
|
|
|
|
#ifdef LITE_USE_SDL_RENDERER
|
|
static int query_surface_scale(RenWindow *ren) {
|
|
int w_pixels, h_pixels;
|
|
int w_points, h_points;
|
|
SDL_GetWindowSizeInPixels(ren->window, &w_pixels, &h_pixels);
|
|
SDL_GetWindowSize(ren->window, &w_points, &h_points);
|
|
/* We consider that the ratio pixel/point will always be an integer and
|
|
it is the same along the x and the y axis. */
|
|
assert(w_pixels % w_points == 0 && h_pixels % h_points == 0 && w_pixels / w_points == h_pixels / h_points);
|
|
return w_pixels / w_points;
|
|
}
|
|
|
|
static void setup_renderer(RenWindow *ren, int w, int h) {
|
|
/* Note that w and h here should always be in pixels and obtained from
|
|
a call to SDL_GetWindowSizeInPixels(). */
|
|
if (!ren->renderer) {
|
|
ren->renderer = SDL_CreateRenderer(ren->window, NULL);
|
|
}
|
|
if (ren->texture) {
|
|
SDL_DestroyTexture(ren->texture);
|
|
}
|
|
ren->texture = SDL_CreateTexture(ren->renderer, ren->rensurface.surface->format, SDL_TEXTUREACCESS_STREAMING, w, h);
|
|
ren->rensurface.scale = query_surface_scale(ren);
|
|
}
|
|
#endif
|
|
|
|
|
|
void renwin_init_surface(RenWindow *ren) {
|
|
ren->scale_x = ren->scale_y = 1;
|
|
#ifdef LITE_USE_SDL_RENDERER
|
|
if (ren->rensurface.surface) {
|
|
SDL_DestroySurface(ren->rensurface.surface);
|
|
}
|
|
int w, h;
|
|
SDL_GetWindowSizeInPixels(ren->window, &w, &h);
|
|
SDL_PixelFormat format = SDL_GetWindowPixelFormat(ren->window);
|
|
ren->rensurface.surface = SDL_CreateSurface(w, h, format == SDL_PIXELFORMAT_UNKNOWN ? SDL_PIXELFORMAT_BGRA32 : format);
|
|
if (!ren->rensurface.surface) {
|
|
fprintf(stderr, "Error creating surface: %s", SDL_GetError());
|
|
exit(1);
|
|
}
|
|
setup_renderer(ren, w, h);
|
|
#endif
|
|
}
|
|
|
|
void renwin_init_command_buf(RenWindow *ren) {
|
|
ren->command_buf = NULL;
|
|
ren->command_buf_idx = 0;
|
|
ren->command_buf_size = 0;
|
|
}
|
|
|
|
|
|
static RenRect scaled_rect(const RenRect rect, const int scale) {
|
|
return (RenRect) {rect.x * scale, rect.y * scale, rect.width * scale, rect.height * scale};
|
|
}
|
|
|
|
|
|
void renwin_clip_to_surface(RenWindow *ren) {
|
|
SDL_SetSurfaceClipRect(renwin_get_surface(ren).surface, NULL);
|
|
}
|
|
|
|
|
|
void renwin_set_clip_rect(RenWindow *ren, RenRect rect) {
|
|
RenSurface rs = renwin_get_surface(ren);
|
|
RenRect sr = scaled_rect(rect, rs.scale);
|
|
SDL_SetSurfaceClipRect(rs.surface, &(SDL_Rect){.x = sr.x, .y = sr.y, .w = sr.width, .h = sr.height});
|
|
}
|
|
|
|
|
|
RenSurface renwin_get_surface(RenWindow *ren) {
|
|
#ifdef LITE_USE_SDL_RENDERER
|
|
return ren->rensurface;
|
|
#else
|
|
SDL_Surface *surface = SDL_GetWindowSurface(ren->window);
|
|
if (!surface) {
|
|
fprintf(stderr, "Error getting window surface: %s", SDL_GetError());
|
|
exit(1);
|
|
}
|
|
return (RenSurface){.surface = surface, .scale = 1};
|
|
#endif
|
|
}
|
|
|
|
void renwin_resize_surface(RenWindow *ren) {
|
|
#ifdef LITE_USE_SDL_RENDERER
|
|
int new_w, new_h, new_scale;
|
|
SDL_GetWindowSizeInPixels(ren->window, &new_w, &new_h);
|
|
new_scale = query_surface_scale(ren);
|
|
/* Note that (w, h) may differ from (new_w, new_h) on retina displays. */
|
|
if (new_scale != ren->rensurface.scale ||
|
|
new_w != ren->rensurface.surface->w ||
|
|
new_h != ren->rensurface.surface->h) {
|
|
renwin_init_surface(ren);
|
|
renwin_clip_to_surface(ren);
|
|
setup_renderer(ren, new_w, new_h);
|
|
}
|
|
#endif
|
|
}
|
|
|
|
void renwin_update_scale(RenWindow *ren) {
|
|
#ifndef LITE_USE_SDL_RENDERER
|
|
SDL_Surface *surface = SDL_GetWindowSurface(ren->window);
|
|
int window_w = surface->w, window_h = surface->h;
|
|
SDL_GetWindowSize(ren->window, &window_w, &window_h);
|
|
ren->scale_x = (float)surface->w / window_w;
|
|
ren->scale_y = (float)surface->h / window_h;
|
|
#endif
|
|
}
|
|
|
|
void renwin_show_window(RenWindow *ren) {
|
|
SDL_ShowWindow(ren->window);
|
|
}
|
|
|
|
void renwin_update_rects(RenWindow *ren, RenRect *rects, int count) {
|
|
#ifdef LITE_USE_SDL_RENDERER
|
|
const int scale = ren->rensurface.scale;
|
|
for (int i = 0; i < count; i++) {
|
|
const RenRect *r = &rects[i];
|
|
const int x = scale * r->x, y = scale * r->y;
|
|
const int w = scale * r->width, h = scale * r->height;
|
|
const SDL_Rect sr = {.x = x, .y = y, .w = w, .h = h};
|
|
uint8_t *pixels = ((uint8_t *) ren->rensurface.surface->pixels) + y * ren->rensurface.surface->pitch + x * SDL_BYTESPERPIXEL(ren->rensurface.surface->format);
|
|
SDL_UpdateTexture(ren->texture, &sr, pixels, ren->rensurface.surface->pitch);
|
|
}
|
|
SDL_RenderTexture(ren->renderer, ren->texture, NULL, NULL);
|
|
SDL_RenderPresent(ren->renderer);
|
|
#else
|
|
SDL_UpdateWindowSurfaceRects(ren->window, (SDL_Rect*) rects, count);
|
|
#endif
|
|
}
|
|
|
|
void renwin_free(RenWindow *ren) {
|
|
#ifdef LITE_USE_SDL_RENDERER
|
|
SDL_DestroyTexture(ren->texture);
|
|
SDL_DestroyRenderer(ren->renderer);
|
|
SDL_DestroySurface(ren->rensurface.surface);
|
|
#endif
|
|
SDL_DestroyWindow(ren->window);
|
|
ren->window = NULL;
|
|
}
|