чување 398d7d42d7df8a8de8fbdd831cb805b62b9c302d
родитељ 7c8cb914a1295544e7680c2ce84fc183505ab362
Аутор: Страхиња Радић <sr@strahinja.org>
Датум: Tue, 8 Jul 2025 22:17:27 +0200
WIP switch to SDL3; better font handling
Diffstat:
| M | config.mk | | | 8 | ++++---- |
| M | lav-sdl.c | | | 204 | ++++++++++++++++++++++++++++++++++++++++++++----------------------------------- |
измењених датотека: 2, додавања: 118(+), брисања: 94(-)
diff --git a/config.mk b/config.mk
@@ -2,13 +2,13 @@
CFLAGS = -Os -Wall -pedantic -std=c99
_CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L \
-D_XOPEN_SOURCE=700
-INCLUDE = -I/usr/include/SDL2
+INCLUDE = -I/usr/include
# OpenBSD
#_CPPFLAGS = -D_DEFAULT_SOURCE -D_POSIX_C_SOURCE=200809L \
# -D_XOPEN_SOURCE=700 -D_BSD_SOURCE
-#INCLUDE = -I/usr/local/include/SDL2
+#INCLUDE = -I/usr/local/include
INSTALL = install
-LIBS = -lSDL2_image -lSDL2 -lm
+LIBS = -lSDL3_image -lSDL3 -lm
SRC = lav-sdl.c
HEADERS = local.h
OBJS = lav-sdl.o
@@ -20,7 +20,7 @@ BINDIR = $(PREFIX)/bin
CPPFLAGS = $(_CPPFLAGS) $(INCLUDE)
DATADIR = $(PREFIX)/share/$(PROG)
DOCDIR = $(PREFIX)/share/doc/$(PROG)
-#MANPREFIX = $(PREFIX)/share/man
+MANPREFIX = $(PREFIX)/share/man
# OpenBSD
#MANPREFIX = $(PREFIX)/man
#MANPAGE = $(PROG).1
diff --git a/lav-sdl.c b/lav-sdl.c
@@ -2,8 +2,8 @@
* any later version. Copyright (C) 2023-2024 Strahinya Radich.
* See the file LICENSE for exact copyright and license details. */
-#include <SDL.h>
-#include <SDL_image.h>
+#include <SDL3/SDL.h>
+#include <SDL3_image/SDL_image.h>
#include <errno.h>
#include <math.h>
#include <stdarg.h>
@@ -17,16 +17,16 @@
#define CELL_SIZE 32
#define DEFAULT_WIDTH 1280
#define DEFAULT_HEIGHT 720
-#define HELP_DIALOG_WIDTH 640
-#define HELP_DIALOG_HEIGHT 300
+#define HELP_DIALOG_WIDTH 1200
+#define HELP_DIALOG_HEIGHT 600
#define LABYRINTH_MAXHEIGHT 20
#define LABYRINTH_MAXWIDTH 40
#define LOCATION_STACK_MAX (LABYRINTH_MAXWIDTH * LABYRINTH_MAXHEIGHT)
#define PRINT_BUFSIZE 4096
#define PROGNAME "lav-sdl"
-#define SEARCHING_DELAY 10
-#define TER16_HEIGHT 17
+#define SEARCHING_DELAY 0
#define TER16_WIDTH 8
+#define TER16_HEIGHT 17
#define WIN_TITLE "Lavirint (SDL version)"
#define MIN(a, b) (((a) < (b)) ? (a) : (b))
@@ -106,19 +106,20 @@ static int state = STATE_SEARCHING_PAUSED;
static SDL_Texture* ter16_texture = NULL;
static SDL_Texture* background = NULL;
static SDL_Window* window = NULL;
+static float text_scale_factor = 2.0f;
void assign_pointIF(const SDL_Point* from, SDL_FPoint* to);
void assign_point_xyIF(const int x, const int y, SDL_FPoint* to);
void calculate_delta(void);
void cleanup(void);
void draw(void);
-void draw_background(SDL_Rect* bg_rect, SDL_Rect* cell_rect,
+void draw_background(SDL_FRect* bg_rect, SDL_FRect* cell_rect,
SDL_FRect* dest_rect);
void draw_help_dialog(void);
void draw_text(const int x, const int y, const int font_width,
const int font_height, SDL_Texture* font_tex, const char* text, ...);
-void get_hero_sprite_xy(int* x, int* y);
-void get_sprite_xy(const char cell, int* x, int* y);
+void get_hero_sprite_xy(float* x, float* y);
+void get_sprite_xy(const char cell, float* x, float* y);
void handle_event(SDL_Event* event);
void labyrinth_coord_to_screen_coord(const int x, const int y,
const float startx, const float starty, float* to_x, float* to_y);
@@ -186,17 +187,19 @@ cleanup(void)
if (window)
SDL_DestroyWindow(window);
- IMG_Quit();
+ // IMG_Quit();
SDL_Quit();
}
void
draw(void)
{
- SDL_Rect bg_rect, cell_rect;
+ SDL_FRect bg_rect, cell_rect;
SDL_FRect dest_rect;
int x, y;
int cx, cy;
+ float crx, cry;
+ float drx, dry;
float startx, starty;
cx = screen_width / 2;
@@ -225,7 +228,7 @@ draw(void)
dest_rect.y = starty;
dest_rect.w = bg_rect.w;
dest_rect.h = bg_rect.h;
- SDL_RenderCopyF(renderer, background, &bg_rect, &dest_rect);
+ SDL_RenderTexture(renderer, background, &bg_rect, &dest_rect);
/* Draw nuggets/cobwebs */
dest_rect.w = CELL_SIZE;
@@ -239,26 +242,32 @@ draw(void)
|| (x == end.x && y == end.y))
continue;
- get_sprite_xy(labyrinth.cells[y][x], &cell_rect.x,
- &cell_rect.y);
+ get_sprite_xy(labyrinth.cells[y][x], &crx, &cry);
+ cell_rect.x = crx;
+ cell_rect.y = cry;
labyrinth_coord_to_screen_coord(x, y, startx, starty,
- &dest_rect.x, &dest_rect.y);
- SDL_RenderCopyF(renderer, sprites, &cell_rect,
+ &drx, &dry);
+ dest_rect.x = drx;
+ dest_rect.y = dry;
+ SDL_RenderTexture(renderer, sprites, &cell_rect,
&dest_rect);
}
/* Draw hero */
dest_rect.w = CELL_SIZE;
dest_rect.h = CELL_SIZE;
- get_hero_sprite_xy(&cell_rect.x, &cell_rect.y);
+ get_hero_sprite_xy(&crx, &cry);
+ cell_rect.x = crx;
+ cell_rect.y = cry;
if (animation.active)
labyrinth_coord_to_screen_coordF(animation.position.x,
- animation.position.y, startx, starty, &dest_rect.x,
- &dest_rect.y);
+ animation.position.y, startx, starty, &drx, &dry);
else
labyrinth_coord_to_screen_coord(hero.x, hero.y, startx, starty,
- &dest_rect.x, &dest_rect.y);
- SDL_RenderCopyF(renderer, sprites, &cell_rect, &dest_rect);
+ &drx, &dry);
+ dest_rect.x = drx;
+ dest_rect.y = dry;
+ SDL_RenderTexture(renderer, sprites, &cell_rect, &dest_rect);
/* Render status */
draw_text(startx, starty + bg_rect.h, TER16_WIDTH, TER16_HEIGHT,
@@ -273,18 +282,28 @@ draw(void)
}
void
-draw_background(SDL_Rect* bg_rect, SDL_Rect* cell_rect, SDL_FRect* dest_rect)
+draw_background(SDL_FRect* bg_rect, SDL_FRect* cell_rect, SDL_FRect* dest_rect)
{
- SDL_DisplayMode mode;
+ const SDL_DisplayMode* mode;
+ SDL_DisplayID display;
+ float crx, cry;
+ float drx, dry;
+
+ if ((display = SDL_GetDisplayForWindow(window)) == 0)
+ {
+ print_error("SDL_GetDisplayForWindow failed: %s",
+ SDL_GetError());
+ exit(1);
+ }
- if (SDL_GetCurrentDisplayMode(0, &mode) < 0)
+ if ((mode = SDL_GetCurrentDisplayMode(display)) == NULL)
{
print_error("SDL_GetCurrentDisplayMode failed: %s",
SDL_GetError());
exit(1);
}
- background = SDL_CreateTexture(renderer, mode.format,
+ background = SDL_CreateTexture(renderer, mode->format,
SDL_TEXTUREACCESS_TARGET, bg_rect->w, bg_rect->h);
if (!background)
{
@@ -292,7 +311,7 @@ draw_background(SDL_Rect* bg_rect, SDL_Rect* cell_rect, SDL_FRect* dest_rect)
SDL_GetError());
exit(1);
}
- if (SDL_SetRenderTarget(renderer, background) < 0)
+ if (!SDL_SetRenderTarget(renderer, background))
{
print_error("SDL_SetRenderTarget failed: %s", SDL_GetError());
exit(1);
@@ -312,11 +331,15 @@ draw_background(SDL_Rect* bg_rect, SDL_Rect* cell_rect, SDL_FRect* dest_rect)
|| (x == end.x && y == end.y)))
continue;
- get_sprite_xy(labyrinth.cells[y][x], &cell_rect->x,
- &cell_rect->y);
- labyrinth_coord_to_screen_coord(x, y, 0.0f, 0.0f,
- &dest_rect->x, &dest_rect->y);
- SDL_RenderCopyF(renderer, sprites, cell_rect, dest_rect);
+ get_sprite_xy(labyrinth.cells[y][x], &crx, &cry);
+ cell_rect->x = crx;
+ cell_rect->y = cry;
+ labyrinth_coord_to_screen_coord(x, y, 0.0f, 0.0f, &drx,
+ &dry);
+ dest_rect->x = drx;
+ dest_rect->y = dry;
+ SDL_RenderTexture(renderer, sprites, cell_rect,
+ dest_rect);
}
SDL_SetRenderTarget(renderer, NULL);
@@ -328,7 +351,7 @@ draw_help_dialog(void)
const char** phelp_text = help_text;
int sx = screen_width / 2 - HELP_DIALOG_WIDTH / 2;
int sy = screen_height / 2 - HELP_DIALOG_HEIGHT / 2;
- SDL_Rect dialog_rect;
+ SDL_FRect dialog_rect;
dialog_rect.x = sx;
dialog_rect.y = sy;
@@ -341,24 +364,25 @@ draw_help_dialog(void)
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_NONE);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, SDL_ALPHA_OPAQUE);
- SDL_RenderDrawRect(renderer, &dialog_rect);
+ SDL_RenderRect(renderer, &dialog_rect);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, SDL_ALPHA_OPAQUE);
dialog_rect.x--;
dialog_rect.y--;
dialog_rect.w += 2;
dialog_rect.h += 2;
- SDL_RenderDrawRect(renderer, &dialog_rect);
+ SDL_RenderRect(renderer, &dialog_rect);
dialog_rect.x--;
dialog_rect.y--;
dialog_rect.w += 2;
dialog_rect.h += 2;
- SDL_RenderDrawRect(renderer, &dialog_rect);
+ SDL_RenderRect(renderer, &dialog_rect);
while (*phelp_text)
{
- draw_text(sx + (2 * TER16_WIDTH),
- sy + (TER16_HEIGHT + 2)
- + (phelp_text - help_text) * (TER16_HEIGHT + 2),
+ draw_text(sx + text_scale_factor * (2 * TER16_WIDTH),
+ sy + text_scale_factor * (TER16_HEIGHT + 2)
+ + (phelp_text - help_text) * text_scale_factor
+ * (TER16_HEIGHT + 2),
TER16_WIDTH, TER16_HEIGHT, ter16_texture, *phelp_text);
phelp_text++;
}
@@ -373,13 +397,13 @@ draw_text(const int x, const int y, const int font_width, const int font_height,
const char* pbuf = NULL;
int xstart = 0;
int ystart = 0;
- SDL_Rect source_rect;
+ SDL_FRect source_rect;
SDL_FRect dest_rect;
int index = 0;
int chars_per_row = 0;
char first_char = ' ';
char last_char = '~';
- int tex_w, tex_h;
+ float tex_w, tex_h;
if (!text || !font_tex)
return;
@@ -393,18 +417,19 @@ draw_text(const int x, const int y, const int font_width, const int font_height,
dest_rect.x = x;
dest_rect.y = y;
- dest_rect.w = font_width;
- dest_rect.h = font_height;
+ dest_rect.w = text_scale_factor * font_width;
+ dest_rect.h = text_scale_factor * font_height;
- if (SDL_QueryTexture(font_tex, NULL, NULL, &tex_w, &tex_h) < 0)
+ if (!SDL_GetTextureSize(font_tex, &tex_w, &tex_h))
{
- print_error("SDL_QueryTexture failed: %s", SDL_GetError());
+ print_error("SDL_GetTextureSize failed: %s", SDL_GetError());
exit(1);
}
chars_per_row = tex_w / (font_width + 1);
pbuf = buf;
+ // SDL_SetRenderScale(renderer, scale_factor, scale_factor);
while (*pbuf)
{
if (*pbuf >= first_char && *pbuf <= last_char)
@@ -420,16 +445,17 @@ draw_text(const int x, const int y, const int font_width, const int font_height,
source_rect.x = xstart;
source_rect.y = ystart;
- SDL_RenderCopyF(renderer, font_tex, &source_rect, &dest_rect);
+ SDL_RenderTexture(renderer, font_tex, &source_rect, &dest_rect);
- dest_rect.x += font_width;
+ dest_rect.x += text_scale_factor * font_width;
pbuf++;
}
+ // SDL_SetRenderScale(renderer, 1.0f, 1.0f);
}
void
-get_hero_sprite_xy(int* x, int* y)
+get_hero_sprite_xy(float* x, float* y)
{
switch (state)
{
@@ -449,7 +475,7 @@ get_hero_sprite_xy(int* x, int* y)
}
void
-get_sprite_xy(const char cell, int* x, int* y)
+get_sprite_xy(const char cell, float* x, float* y)
{
switch (cell)
{
@@ -477,35 +503,28 @@ get_sprite_xy(const char cell, int* x, int* y)
*x = 1 + 5 * (CELL_SIZE + 1);
*y = 1;
}
+ /*print_debug("get_sprite_xy: %d @ (%0.0f, %0.0f)",
+ cell, *x, *y);*/
}
void
handle_event(SDL_Event* event)
{
- SDL_Keysym keysym;
-
if (!event)
return;
switch (event->type)
{
- case SDL_QUIT:
+ case SDL_EVENT_QUIT:
running = 0;
break;
- case SDL_WINDOWEVENT:
- switch (event->window.event)
- {
- case SDL_WINDOWEVENT_RESIZED:
- redraw = 1;
- break;
- }
+ case SDL_EVENT_WINDOW_RESIZED:
+ redraw = 1;
break;
- case SDL_KEYDOWN:
- keysym = event->key.keysym;
-
- print_debug("Got Keydown, sym = %X, mod = %X", keysym.sym,
- keysym.mod);
+ case SDL_EVENT_KEY_DOWN:
+ print_debug("Got Keydown, key = %X, mod = %X", event->key.key,
+ event->key.mod);
- switch (keysym.sym)
+ switch (event->key.key)
{
case SDLK_F1:
help_shown = 1;
@@ -532,23 +551,23 @@ handle_event(SDL_Event* event)
reset();
}
break;
- case SDLK_q:
- if (keysym.mod & KMOD_CTRL)
+ case SDLK_Q:
+ if (event->key.mod & SDL_KMOD_CTRL)
running = 0;
break;
default:
print_debug("switch fallthrough");
}
break;
- case SDL_MOUSEMOTION:
+ case SDL_EVENT_MOUSE_MOTION:
pointer.x = event->motion.x;
pointer.y = event->motion.y;
if (pointer.x <= 0 || pointer.y <= 0
|| pointer.x + 1 >= screen_width
|| pointer.y + 1 >= screen_height)
- SDL_ShowCursor(1);
+ SDL_ShowCursor();
else
- SDL_ShowCursor(0);
+ SDL_HideCursor();
break;
}
}
@@ -572,7 +591,8 @@ labyrinth_coord_to_screen_coordF(const float x, const float y,
int
load_textures(void)
{
- SDL_Surface* surface = NULL;
+ SDL_Surface* surface = NULL;
+ SDL_ScaleMode scale_mode = SDL_SCALEMODE_PIXELART;
surface = try_load(SPRITES_PNG);
if (!surface)
@@ -584,7 +604,8 @@ load_textures(void)
SDL_GetError());
exit(1);
}
- SDL_FreeSurface(surface);
+ SDL_SetTextureScaleMode(sprites, scale_mode);
+ SDL_DestroySurface(surface);
surface = try_load(TER16_PNG);
if (!surface)
@@ -596,8 +617,8 @@ load_textures(void)
SDL_GetError());
exit(1);
}
-
- SDL_FreeSurface(surface);
+ SDL_SetTextureScaleMode(ter16_texture, scale_mode);
+ SDL_DestroySurface(surface);
return 0;
}
@@ -869,14 +890,14 @@ try_load(const char* filename)
if (!surface)
{
print_debug("try_load: IMG_Load failed (%s): %s", tex_pathname,
- IMG_GetError());
+ SDL_GetError());
snprintf(tex_pathname, BUFSIZE, "./%s", filename);
print_debug("try_load: trying %s", tex_pathname);
surface = IMG_Load(tex_pathname);
if (!surface)
{
print_error("try_load: IMG_Load failed (%s): %s",
- tex_pathname, IMG_GetError());
+ tex_pathname, SDL_GetError());
exit(1);
}
}
@@ -888,33 +909,36 @@ int
main(int argc, char** argv)
{
SDL_Event event;
- int px, py;
+ float px, py;
char datafile_pathname[BUFSIZE];
atexit(&cleanup);
- if (SDL_Init(SDL_INIT_VIDEO) < 0)
+ if (!SDL_Init(SDL_INIT_VIDEO))
{
print_error("SDL_Init failed: %s", SDL_GetError());
exit(1);
}
- if (SDL_CreateWindowAndRenderer(DEFAULT_WIDTH, DEFAULT_HEIGHT,
- SDL_WINDOW_SHOWN | SDL_WINDOW_MAXIMIZED
- | SDL_WINDOW_FULLSCREEN_DESKTOP
- | SDL_WINDOW_BORDERLESS | SDL_WINDOW_RESIZABLE,
- &window, &renderer)
- < 0)
+ if (!SDL_CreateWindowAndRenderer(WIN_TITLE, DEFAULT_WIDTH,
+ DEFAULT_HEIGHT, SDL_WINDOW_MAXIMIZED | SDL_WINDOW_RESIZABLE,
+ &window, &renderer))
{
print_error("SDL_CreateWindowAndRenderer failed: %s",
SDL_GetError());
exit(1);
}
- SDL_SetWindowTitle(window, WIN_TITLE);
- SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "best");
+ SDL_SetWindowFullscreenMode(window, NULL);
+ SDL_SetWindowFullscreen(window, 1);
SDL_SetHintWithPriority(SDL_HINT_RENDER_VSYNC, "1", SDL_HINT_OVERRIDE);
- SDL_RenderSetLogicalSize(renderer, DEFAULT_WIDTH, DEFAULT_HEIGHT);
+ SDL_SetRenderLogicalPresentation(renderer, DEFAULT_WIDTH,
+ DEFAULT_HEIGHT, SDL_LOGICAL_PRESENTATION_LETTERBOX);
+ /*SDL_SetRenderLogicalPresentation(renderer, DEFAULT_WIDTH,
+ DEFAULT_HEIGHT, SDL_LOGICAL_PRESENTATION_INTEGER_SCALE);*/
+ /*float factor = (float)714/720;
+ print_debug("factor = %0.2f", factor);
+ SDL_SetRenderScale(renderer, 1.0f, factor);*/
if (load_textures() < 0)
exit(1);
@@ -947,10 +971,10 @@ main(int argc, char** argv)
= (SDL_Point*)calloc(LOCATION_STACK_MAX, sizeof(SDL_Point));
animation.active = 0;
- SDL_ShowCursor(0);
+ SDL_HideCursor();
SDL_GetMouseState(&px, &py);
- pointer.x = (float)px;
- pointer.y = (float)py;
+ pointer.x = px;
+ pointer.y = py;
while (running)
{
while (SDL_PollEvent(&event))
@@ -975,7 +999,7 @@ main(int argc, char** argv)
}
}
/* TODO: More sophisticated framerate/vsync/delay handling */
- SDL_Delay(10);
+ SDL_Delay(SEARCHING_DELAY);
}
return 0;