summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile294
-rw-r--r--include/glamac_events.h11
-rw-r--r--include/glamac_render.h13
-rw-r--r--include/glamac_view.h11
-rw-r--r--include/glamacdef.h1
-rw-r--r--src/glamac/glamac.c43
-rw-r--r--src/glamac/glamac_events.c84
-rw-r--r--src/glamac/glamac_render.c194
-rw-r--r--src/glamac/glamac_view.c19
9 files changed, 450 insertions, 220 deletions
diff --git a/Makefile b/Makefile
index 904806c..69b9f44 100644
--- a/Makefile
+++ b/Makefile
@@ -1,67 +1,269 @@
+# Simple Makefile for glamac - SDL3 version
+# Supports: Arch Linux native, Windows cross-compilation
CC=gcc
-# Base Directories
+MINGW_CC=x86_64-w64-mingw32-gcc
+
+# Directories
SRCDIR=src
BINDIR=bin
+BINDIR_WIN=bin/win
INCDIR=include
-RESDIR=res
+
+# SDL3 paths for cross-compilation
+CROSS_WIN_SDL3_PREFIX ?= /usr/x86_64-w64-mingw32
+CROSS_WIN_SDL3_INCLUDE ?= $(CROSS_WIN_SDL3_PREFIX)/include
+CROSS_WIN_SDL3_LIB ?= $(CROSS_WIN_SDL3_PREFIX)/lib
+
+# DLL cache directory
+DLL_CACHE_DIR = $(HOME)/.cache/glamac-dlls
# Common flags
-CFLAGS=-I$(INCDIR) -O2 -march=native -flto #-ffast-math
+CFLAGS_BASE=-I$(INCDIR) -O2 -flto
+CFLAGS_NATIVE=$(CFLAGS_BASE) -march=native
+CFLAGS_CROSS=$(CFLAGS_BASE) -I$(CROSS_WIN_SDL3_INCLUDE)
-# Resource compiler for Windows
-WINDRES=windres
+# OS Detection
+ifeq ($(OS),Windows_NT)
+ # Windows host
+ EXE_EXT=.exe
+ MKDIR=mkdir
+ RM=del /Q
+ RMDIR=rmdir /s /q
+ SDL3_LDFLAGS=-lSDL3 -lSDL3_ttf -mwindows
+ NATIVE_CC=$(CC)
+ NATIVE_CFLAGS=$(CFLAGS_BASE)
+ NATIVE_LDFLAGS=$(SDL3_LDFLAGS)
+ NATIVE_EXT=.exe
+else
+ # Linux host (Arch)
+ EXE_EXT=
+ MKDIR=mkdir -p
+ RM=rm -f
+ RMDIR=rm -rf
+ SDL3_LDFLAGS=$(shell pkg-config --cflags --libs sdl3 SDL3_ttf 2>/dev/null || echo -lSDL3 -lSDL3_ttf) -lm
+ NATIVE_CC=$(CC)
+ NATIVE_CFLAGS=$(CFLAGS_NATIVE)
+ NATIVE_LDFLAGS=$(SDL3_LDFLAGS)
+ NATIVE_EXT=
+ # Cross-compilation flags
+ CROSS_LDFLAGS=-L$(CROSS_WIN_SDL3_LIB) -lmingw32 -lSDL3 -lSDL3_ttf -mwindows -static-libgcc
+endif
-# Resource file definitions
-RESOURCE_FILE=glamac.rc # Your resource script file with icon definitions
-RESOURCE_OBJ=$(BINDIR)/glamac_res.o # The compiled resource object file
+# Source files
+GLAMAC_SRC_LIST=$(SRCDIR)/glamac/glamac.c \
+ $(SRCDIR)/glamac/glamac_view.c \
+ $(SRCDIR)/glamac/glamac_render.c \
+ $(SRCDIR)/glamac/glamac_events.c \
+ $(SRCDIR)/glamac/glass_data.c
+
+GLAMAC_SRC=$(wildcard $(GLAMAC_SRC_LIST))
+EXPECTED_GLAMAC_FILES=5
+FOUND_GLAMAC_FILES=$(words $(GLAMAC_SRC))
-# glautils
GLA_SRCS=$(wildcard $(SRCDIR)/glautils/*.c)
-GLA_EXES=$(patsubst $(SRCDIR)/glautils/%.c, $(BINDIR)/%.exe, $(GLA_SRCS))
-
-# glamac
-GLAMAC_SRC=$(SRCDIR)/glamac/glamac.c \
- $(SRCDIR)/glamac/glamac_view.c \
- $(SRCDIR)/glamac/glamac_render.c \
- $(SRCDIR)/glamac/glamac_events.c \
- $(SRCDIR)/glamac/glass_data.c
-
-# SDL2 Flags
-SDL2_CFLAGS=-I$(USERPROFILE)/scoop/apps/sdl2/current/include/SDl2 -I$(USERPROFILE)/scoop/apps/sdl2-ttf/current/include/SDL2_ttf -O2 -march=native -flto -s #-ffast-math
-SDL2_LDFLAGS=-L$(USERPROFILE)/scoop/apps/sdl2/current/lib -L$(USERPROFILE)/scoop/apps/sdl2-ttf/current/lib -lSDL2main -lSDL2 -lSDL2_ttf -mwindows -flto
-SDL2_DLL_SRC=$(USERPROFILE)/scoop/apps/sdl2/current/lib/SDL2.dll
-SDL2_tff_DLL_SRC=$(USERPROFILE)/scoop/apps/sdl2-ttf/current/lib/SDL2_ttf.dll
-SDL2_DLL_DEST=$(BINDIR)
-
-# Setup target
+GLA_EXES_NATIVE=$(patsubst $(SRCDIR)/glautils/%.c, $(BINDIR)/%$(NATIVE_EXT), $(GLA_SRCS))
+GLA_EXES_WIN=$(patsubst $(SRCDIR)/glautils/%.c, $(BINDIR_WIN)/%.exe, $(GLA_SRCS))
+
+# Setup targets
setup:
- mkdir -p $(BINDIR)
+ $(MKDIR) $(BINDIR)
+
+setup-cross:
+ $(MKDIR) $(BINDIR) $(BINDIR_WIN)
+
+# Check source files
+check-files:
+ @echo "Checking for glamac source files..."
+ @echo "Expected $(EXPECTED_GLAMAC_FILES) files, found $(FOUND_GLAMAC_FILES)"
+ @if [ $(FOUND_GLAMAC_FILES) -ne $(EXPECTED_GLAMAC_FILES) ]; then \
+ echo "ERROR: Missing glamac source files!"; \
+ exit 1; \
+ fi
+ @echo "All glamac source files found."
+
+# Default: build for current platform
+all: check-files setup glamac glautils
+
+# Native compilation
+glamac: check-files $(BINDIR)/glamac$(NATIVE_EXT)
+glautils: $(GLA_EXES_NATIVE)
+
+$(BINDIR)/glamac$(NATIVE_EXT): $(GLAMAC_SRC)
+ @echo "Compiling glamac..."
+ $(NATIVE_CC) $^ $(NATIVE_CFLAGS) $(NATIVE_LDFLAGS) -o $@
+
+$(BINDIR)/%$(NATIVE_EXT): $(SRCDIR)/glautils/%.c
+ $(NATIVE_CC) $< $(NATIVE_CFLAGS) -o $@
-all: glautils glamac sdl2 structure
+# Windows cross-compilation (Linux only)
+ifeq ($(OS),Windows_NT)
+# Windows host - no cross-compilation needed
+glamac-win all-win:
+ @echo "Cross-compilation not needed on Windows. Use 'make all' instead."
-glautils: $(GLA_EXES)
-$(BINDIR)/%.exe: $(SRCDIR)/glautils/%.c
- $(CC) $< $(CFLAGS) -o $@
+install-sdl3-cross download-dlls install-dlls copy-dlls-win:
+ @echo "Cross-compilation operations not available on Windows host."
-# Compile resource file
-$(RESOURCE_OBJ): $(RESOURCE_FILE)
- $(WINDRES) -i $< -o $@
+else
+# Linux host - cross-compilation available
-# Link glamac with resources
-glamac: $(BINDIR)/glamac.exe
-$(BINDIR)/glamac.exe: $(GLAMAC_SRC) $(RESOURCE_OBJ)
- $(CC) $^ $(CFLAGS) $(SDL2_CFLAGS) $(SDL2_LDFLAGS) -o $@
+# Check cross-compilation dependencies
+check-cross-deps:
+ @echo "Checking cross-compilation dependencies..."
+ @which $(MINGW_CC) >/dev/null 2>&1 || (echo "ERROR: $(MINGW_CC) not found. Install with: sudo pacman -S mingw-w64-gcc" && exit 1)
+ @test -f $(CROSS_WIN_SDL3_INCLUDE)/SDL3/SDL.h || (echo "ERROR: SDL3 headers not found. Run 'make install-sdl3-cross'" && exit 1)
+ @test -f $(CROSS_WIN_SDL3_LIB)/libSDL3.dll.a || (echo "ERROR: SDL3 libraries not found. Run 'make install-sdl3-cross'" && exit 1)
+ @echo "Cross-compilation dependencies OK"
-sdl2:
- cp $(SDL2_DLL_SRC) $(SDL2_DLL_DEST)
- cp $(SDL2_tff_DLL_SRC) $(SDL2_DLL_DEST)
+# Windows targets
+glamac-win: check-files check-cross-deps setup-cross $(BINDIR_WIN)/glamac.exe copy-dlls-win
+all-win: glamac-win $(GLA_EXES_WIN)
+$(BINDIR_WIN)/glamac.exe: $(GLAMAC_SRC)
+ @echo "Cross-compiling glamac for Windows..."
+ $(MINGW_CC) $^ $(CFLAGS_CROSS) $(CROSS_LDFLAGS) -o $@
+
+$(BINDIR_WIN)/%.exe: $(SRCDIR)/glautils/%.c
+ $(MINGW_CC) $< $(CFLAGS_CROSS) -static-libgcc -o $@
+
+# DLL Management
+
+# Download DLLs to cache (only once)
+download-dlls:
+ @echo "Downloading SDL3 DLLs to cache..."
+ @$(MKDIR) $(DLL_CACHE_DIR)
+
+ @if [ ! -f "$(DLL_CACHE_DIR)/SDL3.dll" ]; then \
+ echo "Downloading SDL3.dll..."; \
+ cd $(DLL_CACHE_DIR) && \
+ wget -q https://github.com/libsdl-org/SDL/releases/download/release-3.2.10/SDL3-3.2.10-win32-x64.zip && \
+ unzip -j SDL3-3.2.10-win32-x64.zip SDL3.dll && \
+ rm SDL3-3.2.10-win32-x64.zip; \
+ else \
+ echo "SDL3.dll already cached"; \
+ fi
+
+ @if [ ! -f "$(DLL_CACHE_DIR)/SDL3_ttf.dll" ]; then \
+ echo "Downloading SDL3_ttf.dll..."; \
+ cd $(DLL_CACHE_DIR) && \
+ wget -q https://github.com/libsdl-org/SDL_ttf/releases/download/release-3.2.2/SDL3_ttf-3.2.2-win32-x64.zip && \
+ unzip -j SDL3_ttf-3.2.2-win32-x64.zip SDL3_ttf.dll && \
+ rm SDL3_ttf-3.2.2-win32-x64.zip; \
+ else \
+ echo "SDL3_ttf.dll already cached"; \
+ fi
+
+ @echo "DLLs cached in $(DLL_CACHE_DIR)/"
+
+# Install DLLs to system location (optional, for system-wide access)
+install-dlls: download-dlls
+ @echo "Installing DLLs to system location..."
+ sudo cp $(DLL_CACHE_DIR)/SDL3.dll $(CROSS_WIN_SDL3_PREFIX)/bin/ 2>/dev/null || \
+ (sudo mkdir -p $(CROSS_WIN_SDL3_PREFIX)/bin && sudo cp $(DLL_CACHE_DIR)/SDL3.dll $(CROSS_WIN_SDL3_PREFIX)/bin/)
+ sudo cp $(DLL_CACHE_DIR)/SDL3_ttf.dll $(CROSS_WIN_SDL3_PREFIX)/bin/
+ @echo "DLLs installed to $(CROSS_WIN_SDL3_PREFIX)/bin/"
+
+# Copy DLLs to Windows build directory
+copy-dlls-win: download-dlls
+ @echo "Copying DLLs for Windows distribution..."
+ @$(MKDIR) $(BINDIR_WIN)
+ cp $(DLL_CACHE_DIR)/SDL3.dll $(BINDIR_WIN)/
+ cp $(DLL_CACHE_DIR)/SDL3_ttf.dll $(BINDIR_WIN)/
+ @echo ""
+ @echo "Windows distribution ready in $(BINDIR_WIN)/"
+ @ls -la $(BINDIR_WIN)/
+ @echo ""
+ @echo "Copy the entire $(BINDIR_WIN)/ directory to your Windows machine."
+
+# Install SDL3 for cross-compilation
+install-sdl3-cross:
+ @echo "Installing SDL3 development libraries for MinGW cross-compilation..."
+ @echo "Latest versions: SDL3 3.2.10, SDL3_ttf 3.2.2"
+ @read -p "Continue? [y/N] " confirm && [ "$$confirm" = "y" ] || exit 1
+
+ @which wget >/dev/null 2>&1 || (echo "ERROR: wget not found. Install with: sudo pacman -S wget" && exit 1)
+ @which $(MINGW_CC) >/dev/null 2>&1 || (echo "ERROR: MinGW not found. Install with: sudo pacman -S mingw-w64-gcc" && exit 1)
+
+ sudo mkdir -p $(CROSS_WIN_SDL3_PREFIX)/include $(CROSS_WIN_SDL3_PREFIX)/lib
+
+ @echo "Downloading SDL3 development libraries..."
+ cd /tmp && \
+ wget -q https://github.com/libsdl-org/SDL/releases/download/release-3.2.10/SDL3-devel-3.2.10-mingw.tar.gz && \
+ wget -q https://github.com/libsdl-org/SDL_ttf/releases/download/release-3.2.2/SDL3_ttf-devel-3.2.2-mingw.tar.gz && \
+ tar -xzf SDL3-devel-3.2.10-mingw.tar.gz && \
+ tar -xzf SDL3_ttf-devel-3.2.2-mingw.tar.gz && \
+ sudo cp -r SDL3-3.2.10/x86_64-w64-mingw32/include/* $(CROSS_WIN_SDL3_PREFIX)/include/ && \
+ sudo cp -r SDL3-3.2.10/x86_64-w64-mingw32/lib/* $(CROSS_WIN_SDL3_PREFIX)/lib/ && \
+ sudo cp -r SDL3_ttf-3.2.2/x86_64-w64-mingw32/include/* $(CROSS_WIN_SDL3_PREFIX)/include/ && \
+ sudo cp -r SDL3_ttf-3.2.2/x86_64-w64-mingw32/lib/* $(CROSS_WIN_SDL3_PREFIX)/lib/ && \
+ rm -rf SDL3-3.2.10* SDL3_ttf-3.2.2*
+
+ @echo "SDL3 cross-compilation libraries installed successfully!"
+
+endif
+
+# Arch Linux SDL3 installation
+install-sdl3-arch:
+ @echo "Installing SDL3 on Arch Linux..."
+ sudo pacman -S sdl3
+ @echo "Installing SDL3_ttf from AUR (using yay)..."
+ yay -S sdl3_ttf
+ @echo "SDL3 installation complete!"
+
+# Clean targets
clean:
- rm -f $(BINDIR)/*
- rm -f structure.txt
+ifeq ($(OS),Windows_NT)
+ @if exist $(BINDIR) $(RMDIR) $(BINDIR)
+else
+ $(RMDIR) $(BINDIR) 2>/dev/null || true
+endif
+
+clean-dlls:
+ifneq ($(OS),Windows_NT)
+ $(RMDIR) $(DLL_CACHE_DIR) 2>/dev/null || true
+ @echo "DLL cache cleared"
+else
+ @echo "DLL cache operations not available on Windows"
+endif
rebuild: clean all
-# Generate project structure
-structure:
- @powershell -Command "(Get-Item .).Name | Set-Content structure.txt; (tree /a /f | Select-Object -Skip 3) | Add-Content structure.txt"
+# Help
+help:
+ @echo "GlaMaC Build System - SDL3"
+ @echo ""
+ @echo "Native targets (any platform):"
+ @echo " all - Build for current platform"
+ @echo " glamac - Build glamac only"
+ @echo " glautils - Build utilities only"
+ @echo " clean - Clean build artifacts"
+ @echo " rebuild - Clean and rebuild"
+ @echo ""
+ifeq ($(OS),Windows_NT)
+ @echo "Windows host - use native targets above"
+else
+ @echo "Cross-compilation targets (Arch Linux → Windows):"
+ @echo " glamac-win - Build glamac for Windows (includes DLLs)"
+ @echo " all-win - Build everything for Windows"
+ @echo ""
+ @echo "Setup and maintenance:"
+ @echo " install-sdl3-arch - Install SDL3 on Arch Linux"
+ @echo " install-sdl3-cross - Install SDL3 for cross-compilation"
+ @echo " download-dlls - Download Windows DLLs to cache"
+ @echo " install-dlls - Install DLLs to system location"
+ @echo " copy-dlls-win - Copy DLLs to Windows build directory"
+ @echo " clean-dlls - Clear DLL cache"
+ @echo " check-cross-deps - Check cross-compilation setup"
+endif
+ @echo ""
+ @echo "Quick start:"
+ifeq ($(OS),Windows_NT)
+ @echo " 1. Install SDL3: (install SDL3 development libraries)"
+ @echo " 2. make all"
+else
+ @echo " 1. sudo pacman -S mingw-w64-gcc # Install cross-compiler"
+ @echo " 2. make install-sdl3-cross # Install SDL3 for Windows"
+ @echo " 3. make glamac-win # Build for Windows (auto-downloads DLLs)"
+endif
+
+.PHONY: all setup setup-cross glamac glautils glamac-win all-win check-files check-cross-deps download-dlls install-dlls copy-dlls-win install-sdl3-cross install-sdl3-arch clean clean-dlls rebuild help
diff --git a/include/glamac_events.h b/include/glamac_events.h
index 47ecb74..c4145c0 100644
--- a/include/glamac_events.h
+++ b/include/glamac_events.h
@@ -1,19 +1,10 @@
/**
* glamac_events.h - header file from glamac_events.c.
- *
- * Copyright (C) 2025 https://optics-design.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * See the COPYING file for the full license text.
*/
#ifndef GLAMAC_EVENTS_H
#define GLAMAC_EVENTS_H
-#include <SDL.h>
+#include <SDL3/SDL.h>
#include "glamacdef.h"
#include "glamac_view.h"
diff --git a/include/glamac_render.h b/include/glamac_render.h
index df609c3..f18d53f 100644
--- a/include/glamac_render.h
+++ b/include/glamac_render.h
@@ -1,20 +1,11 @@
/**
* glamac_render.h - header file from glamac_render.c.
- *
- * Copyright (C) 2025 https://optics-design.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * See the COPYING file for the full license text.
*/
#ifndef GLAMAC_RENDER_H
#define GLAMAC_RENDER_H
-#include <SDL.h>
-#include <SDL_ttf.h>
+#include <SDL3/SDL.h>
+#include <SDL3_ttf/SDL_ttf.h>
#include "glamacdef.h"
#include "glamac_view.h"
diff --git a/include/glamac_view.h b/include/glamac_view.h
index b6846ad..8f0b984 100644
--- a/include/glamac_view.h
+++ b/include/glamac_view.h
@@ -1,19 +1,10 @@
/**
* glamac_view.h - header file from glamac_view.c.
- *
- * Copyright (C) 2025 https://optics-design.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * See the COPYING file for the full license text.
*/
#ifndef GLAMAC_VIEW_H
#define GLAMAC_VIEW_H
-#include <SDL.h>
+#include <SDL3/SDL.h>
#include "glamacdef.h"
// Constants for view
diff --git a/include/glamacdef.h b/include/glamacdef.h
index 13fffbf..563df70 100644
--- a/include/glamacdef.h
+++ b/include/glamacdef.h
@@ -15,6 +15,7 @@
#include <stdint.h>
#include <uchar.h>
+#include <stddef.h>
/* Type definitions for consistent sizing across platforms. Idea taken from https://nullprogram.com/blog/2023/10/08/ (archive link: ) */
typedef uint8_t u8;
typedef char16_t c16;
diff --git a/src/glamac/glamac.c b/src/glamac/glamac.c
index d176403..b834dbc 100644
--- a/src/glamac/glamac.c
+++ b/src/glamac/glamac.c
@@ -1,17 +1,8 @@
/**
* glamac.c - main source file for the GlaMaC.
- *
- * Copyright (C) 2025 https://optics-design.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * See the COPYING file for the full license text.
*/
-#include <SDL.h>
-#include <SDL_ttf.h>
+#include <SDL3/SDL.h>
+#include <SDL3_ttf/SDL_ttf.h>
#include <stdio.h>
#include "glamacdef.h" // Type definitions
#include "glass_data.h" // Glass catalog
@@ -31,23 +22,22 @@ int main(int argc, char* argv[]) {
SDL_Renderer* renderer = NULL;
FontSet fonts = {0};
- // Initialize SDL2
- if (SDL_Init(SDL_INIT_VIDEO) < 0) {
- printf("SDL2 could not initialize! SDL_Error: %s\n", SDL_GetError());
+ // Initialize SDL3
+ if (!SDL_Init(SDL_INIT_VIDEO)) {
+ printf("SDL3 could not initialize! SDL_Error: %s\n", SDL_GetError());
return 1;
}
- // Initialize SDL_ttf
- if (TTF_Init() < 0) {
- printf("SDL_ttf could not initialize! TTF_Error: %s\n", TTF_GetError());
+ // Initialize SDL3_ttf
+ if (!TTF_Init()) {
+ printf("SDL3_ttf could not initialize! SDL_Error: %s\n", SDL_GetError());
SDL_Quit();
return 1;
}
- // Create window with SDL2
- window = SDL_CreateWindow("GlaMaC", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED,
- INITIAL_WIDTH, INITIAL_HEIGHT,
- SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE);
+ // Create window with SDL3
+ window = SDL_CreateWindow("GlaMaC", INITIAL_WIDTH, INITIAL_HEIGHT,
+ SDL_WINDOW_RESIZABLE);
if (window == NULL) {
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
TTF_Quit();
@@ -56,7 +46,7 @@ int main(int argc, char* argv[]) {
}
// Create renderer with hardware acceleration and vsync
- renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
+ renderer = SDL_CreateRenderer(window, NULL);
if (renderer == NULL) {
printf("Renderer could not be created! SDL_Error: %s\n", SDL_GetError());
SDL_DestroyWindow(window);
@@ -65,6 +55,9 @@ int main(int argc, char* argv[]) {
return 1;
}
+ // Enable vsync
+ SDL_SetRenderVSync(renderer, 1);
+
// Load fonts
if (!load_fonts(&fonts)) {
SDL_DestroyRenderer(renderer);
@@ -93,12 +86,12 @@ int main(int argc, char* argv[]) {
b32 dragging = 0;
// Enable text input
- SDL_StartTextInput();
+ SDL_StartTextInput(window);
// Main loop
while (!quit) {
// Handle events on queue
- while (SDL_PollEvent(&e) != 0) {
+ while (SDL_PollEvent(&e)) {
process_events(&e, &view, window, &lastMouseX, &lastMouseY, &dragging, &quit);
}
@@ -107,7 +100,7 @@ int main(int argc, char* argv[]) {
}
// Stop text input
- SDL_StopTextInput();
+ SDL_StopTextInput(window);
// Clean up resources
free_fonts(&fonts);
diff --git a/src/glamac/glamac_events.c b/src/glamac/glamac_events.c
index 29b7232..e5c706c 100644
--- a/src/glamac/glamac_events.c
+++ b/src/glamac/glamac_events.c
@@ -1,22 +1,13 @@
/**
* glamac_events.c - source file detailing keyboard and mouse events used in GlaMaC.
- *
- * Copyright (C) 2025 https://optics-design.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * See the COPYING file for the full license text.
*/
-#include <SDL.h>
+#include <SDL3/SDL.h>
#include "glamac_view.h"
// Process key event
b32 process_key_event(SDL_KeyboardEvent *key, ViewState *view, SDL_Window *window, b32 *quit) {
- switch (key->keysym.sym) {
- case SDLK_g:
+ switch (key->key) {
+ case SDLK_G:
// First key in sequence
view->gKeyPressed = 1;
// Store the time when 'g' was pressed
@@ -28,7 +19,7 @@ b32 process_key_event(SDL_KeyboardEvent *key, ViewState *view, SDL_Window *windo
// Check if this is part of "g?" sequence (with shift for '?')
if (view->gKeyPressed && (SDL_GetTicks() - view->gKeyTime < 1000)) {
// If Shift is held (for '?' on most layouts) or it's a direct '?' key
- if ((key->keysym.mod & KMOD_SHIFT) || key->keysym.sym == SDLK_QUESTION) {
+ if ((key->mod & SDL_KMOD_SHIFT) || key->key == SDLK_QUESTION) {
view->showHelp = !view->showHelp;
}
view->gKeyPressed = 0;
@@ -48,7 +39,7 @@ b32 process_key_event(SDL_KeyboardEvent *key, ViewState *view, SDL_Window *windo
view->gKeyPressed = 0;
return 1;
- case SDLK_q:
+ case SDLK_Q:
if (view->showHelp) {
view->showHelp = 0;
} else {
@@ -72,38 +63,38 @@ b32 process_key_event(SDL_KeyboardEvent *key, ViewState *view, SDL_Window *windo
view->gKeyPressed = 0; // Reset g key state
return 1;
- case SDLK_r:
+ case SDLK_R:
// Reset view
reset_view(view);
view->gKeyPressed = 0; // Reset g key state
return 1;
- case SDLK_f:
+ case SDLK_F:
// Toggle fullscreen
toggle_fullscreen(window);
view->gKeyPressed = 0; // Reset g key state
return 1;
// Vim-like navigation
- case SDLK_h:
+ case SDLK_H:
// Move left
view->offsetX += PAN_STEP;
view->gKeyPressed = 0; // Reset g key state
return 1;
- case SDLK_l:
+ case SDLK_L:
// Move right
view->offsetX -= PAN_STEP;
view->gKeyPressed = 0; // Reset g key state
return 1;
- case SDLK_k:
+ case SDLK_K:
// Move up
view->offsetY -= PAN_STEP;
view->gKeyPressed = 0; // Reset g key state
return 1;
- case SDLK_j:
+ case SDLK_J:
// Move down
view->offsetY += PAN_STEP;
view->gKeyPressed = 0; // Reset g key state
@@ -115,15 +106,15 @@ b32 process_key_event(SDL_KeyboardEvent *key, ViewState *view, SDL_Window *windo
// Process mouse button event
b32 process_mouse_button(SDL_MouseButtonEvent *button, ViewState *view, i32 *lastMouseX, i32 *lastMouseY, b32 *dragging) {
- i32 mouseX, mouseY;
+ f32 mouseX, mouseY;
switch (button->button) {
case SDL_BUTTON_LEFT:
- if (button->type == SDL_MOUSEBUTTONDOWN) {
+ if (button->type == SDL_EVENT_MOUSE_BUTTON_DOWN) {
SDL_GetMouseState(&mouseX, &mouseY);
// Check if click is near a glass point
- i32 nearestGlass = find_nearest_glass(mouseX, mouseY, view, 15); // 15 pixels max distance
+ i32 nearestGlass = find_nearest_glass((i32)mouseX, (i32)mouseY, view, 15); // 15 pixels max distance
if (nearestGlass >= 0) {
view->selectedGlass = nearestGlass;
// Don't start dragging when selecting a glass
@@ -132,11 +123,11 @@ b32 process_mouse_button(SDL_MouseButtonEvent *button, ViewState *view, i32 *las
view->selectedGlass = -1;
// Start dragging for panning
*dragging = 1;
- *lastMouseX = mouseX;
- *lastMouseY = mouseY;
+ *lastMouseX = (i32)mouseX;
+ *lastMouseY = (i32)mouseY;
}
return 1;
- } else if (button->type == SDL_MOUSEBUTTONUP) {
+ } else if (button->type == SDL_EVENT_MOUSE_BUTTON_UP) {
*dragging = 0;
return 1;
}
@@ -150,21 +141,21 @@ b32 process_mouse_button(SDL_MouseButtonEvent *button, ViewState *view, i32 *las
b32 process_mouse_motion(SDL_MouseMotionEvent *motion, ViewState *view, i32 *lastMouseX, i32 *lastMouseY, b32 dragging) {
if (dragging) {
// Get current mouse position
- i32 mouseX, mouseY;
+ f32 mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
// Calculate normalized delta
const i32 padding = (i32)(view->windowWidth * PADDING_PERCENT);
- const f32 dx = (f32)(mouseX - *lastMouseX) / (view->windowWidth - 2 * padding);
- const f32 dy = (f32)(mouseY - *lastMouseY) / (view->windowHeight - 2 * padding);
+ const f32 dx = (mouseX - *lastMouseX) / (view->windowWidth - 2 * padding);
+ const f32 dy = (mouseY - *lastMouseY) / (view->windowHeight - 2 * padding);
// Update offset - inverted movement for natural feel
view->offsetX += dx;
view->offsetY -= dy;
// Update last mouse position
- *lastMouseX = mouseX;
- *lastMouseY = mouseY;
+ *lastMouseX = (i32)mouseX;
+ *lastMouseY = (i32)mouseY;
return 1;
}
@@ -174,11 +165,10 @@ b32 process_mouse_motion(SDL_MouseMotionEvent *motion, ViewState *view, i32 *las
// Process window event
b32 process_window_event(SDL_WindowEvent *window_event, ViewState *view) {
- switch (window_event->event) {
- case SDL_WINDOWEVENT_RESIZED:
- case SDL_WINDOWEVENT_SIZE_CHANGED:
- view->windowWidth = window_event->data1;
- view->windowHeight = window_event->data2;
+ switch (window_event->type) {
+ case SDL_EVENT_WINDOW_RESIZED:
+ view->windowWidth = (i32)window_event->data1;
+ view->windowHeight = (i32)window_event->data2;
return 1;
}
@@ -189,29 +179,31 @@ b32 process_window_event(SDL_WindowEvent *window_event, ViewState *view) {
b32 process_events(SDL_Event *event, ViewState *view, SDL_Window *window,
i32 *lastMouseX, i32 *lastMouseY, b32 *dragging, b32 *quit) {
switch (event->type) {
- case SDL_QUIT:
+ case SDL_EVENT_QUIT:
*quit = 1;
return 1;
- case SDL_KEYDOWN:
+ case SDL_EVENT_KEY_DOWN:
return process_key_event(&event->key, view, window, quit);
- case SDL_MOUSEWHEEL:
+ case SDL_EVENT_MOUSE_WHEEL:
// Get mouse position for centered zoom
- i32 mouseX, mouseY;
+ f32 mouseX, mouseY;
SDL_GetMouseState(&mouseX, &mouseY);
- handle_mouse_wheel_zoom(event->wheel.y, mouseX, mouseY, view);
+ handle_mouse_wheel_zoom((i32)event->wheel.y, (i32)mouseX, (i32)mouseY, view);
return 1;
- case SDL_MOUSEBUTTONDOWN:
- case SDL_MOUSEBUTTONUP:
+ case SDL_EVENT_MOUSE_BUTTON_DOWN:
+ case SDL_EVENT_MOUSE_BUTTON_UP:
return process_mouse_button(&event->button, view, lastMouseX, lastMouseY, dragging);
- case SDL_MOUSEMOTION:
+ case SDL_EVENT_MOUSE_MOTION:
return process_mouse_motion(&event->motion, view, lastMouseX, lastMouseY, *dragging);
- case SDL_WINDOWEVENT:
- return process_window_event(&event->window, view);
+ case SDL_EVENT_WINDOW_RESIZED:
+ view->windowWidth = (i32)event->window.data1;
+ view->windowHeight = (i32)event->window.data2;
+ return 1;
}
return 0;
diff --git a/src/glamac/glamac_render.c b/src/glamac/glamac_render.c
index a39a670..619a6e0 100644
--- a/src/glamac/glamac_render.c
+++ b/src/glamac/glamac_render.c
@@ -1,18 +1,11 @@
/**
- * glamac_render.c - source file dealing with the rendering of GlaMaC using SDL2.
- *
- * Copyright (C) 2025 https://optics-design.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * See the COPYING file for the full license text.
+ * glamac_render.c - source file dealing with the rendering of GlaMaC using SDL3.
*/
#include <stdio.h>
#include <math.h>
#include <string.h>
+#include <SDL3/SDL.h>
+#include <SDL3_ttf/SDL_ttf.h>
#include "glamac_render.h"
#include "glass_data.h"
@@ -33,7 +26,7 @@ typedef struct {
static CachedText textCache[MAX_TEXT_CACHE] = {0};
static i32 cacheCount = 0;
-// Function to draw text using SDL_ttf with caching for improved performance
+// Function to draw text using SDL3_ttf with caching for improved performance
void draw_text(SDL_Renderer *renderer, TTF_Font *font, const char *text, i32 x, i32 y, SDL_Color color) {
// Check if we already have this text cached
for (i32 i = 0; i < cacheCount; i++) {
@@ -48,29 +41,29 @@ void draw_text(SDL_Renderer *renderer, TTF_Font *font, const char *text, i32 x,
entry->color.a == color.a) {
// Use the cached texture
- SDL_Rect rect = {x, y, entry->width, entry->height};
- SDL_RenderCopy(renderer, entry->texture, NULL, &rect);
+ SDL_FRect rect = {(f32)x, (f32)y, (f32)entry->width, (f32)entry->height};
+ SDL_RenderTexture(renderer, entry->texture, NULL, &rect);
return;
}
}
// Text not in cache, create a new texture
- SDL_Surface *surface = TTF_RenderText_Blended(font, text, color);
+ SDL_Surface *surface = TTF_RenderText_Blended(font, text, 0, color);
if (!surface) {
- printf("TTF_RenderText_Blended failed: %s\n", TTF_GetError());
+ printf("TTF_RenderText_Blended failed: %s\n", SDL_GetError());
return;
}
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
if (!texture) {
printf("SDL_CreateTextureFromSurface failed: %s\n", SDL_GetError());
- SDL_FreeSurface(surface);
+ SDL_DestroySurface(surface);
return;
}
// Draw the text
- SDL_Rect rect = {x, y, surface->w, surface->h};
- SDL_RenderCopy(renderer, texture, NULL, &rect);
+ SDL_FRect rect = {(f32)x, (f32)y, (f32)surface->w, (f32)surface->h};
+ SDL_RenderTexture(renderer, texture, NULL, &rect);
// Add to cache if there is space
if (cacheCount < MAX_TEXT_CACHE) {
@@ -90,21 +83,11 @@ void draw_text(SDL_Renderer *renderer, TTF_Font *font, const char *text, i32 x,
SDL_DestroyTexture(texture);
}
- SDL_FreeSurface(surface);
+ SDL_DestroySurface(surface);
}
-// Clear the text cache - should be called on shutdown
-void clear_text_cache(void) {
- for (i32 i = 0; i < cacheCount; i++) {
- if (textCache[i].texture) {
- SDL_DestroyTexture(textCache[i].texture);
- textCache[i].texture = NULL;
- }
- }
- cacheCount = 0;
-}
-// Function to draw a filled circle using SDL2's primitive functions
+// Function to draw a filled circle using SDL3's primitive functions
void draw_filled_circle(SDL_Renderer *renderer, i32 centerX, i32 centerY, i32 radius) {
// Draw a filled circle using a series of horizontal lines
// This is significantly faster than the pixel-by-pixel approach
@@ -113,10 +96,10 @@ void draw_filled_circle(SDL_Renderer *renderer, i32 centerX, i32 centerY, i32 ra
i32 x_width = (i32)sqrtf((float)(radius * radius - y * y));
// Draw a horizontal line from left to right edge of the circle
- SDL_RenderDrawLine(
+ SDL_RenderLine(
renderer,
- centerX - x_width, centerY + y,
- centerX + x_width, centerY + y
+ (f32)(centerX - x_width), (f32)(centerY + y),
+ (f32)(centerX + x_width), (f32)(centerY + y)
);
}
}
@@ -130,12 +113,12 @@ void draw_axes(SDL_Renderer *renderer, TTF_Font *font, TTF_Font *titleFont, cons
// X-axis
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
- SDL_RenderDrawLine(renderer, padding, view->windowHeight - padding,
- view->windowWidth - padding, view->windowHeight - padding);
+ SDL_RenderLine(renderer, (f32)padding, (f32)(view->windowHeight - padding),
+ (f32)(view->windowWidth - padding), (f32)(view->windowHeight - padding));
// Y-axis
- SDL_RenderDrawLine(renderer, padding, padding,
- padding, view->windowHeight - padding);
+ SDL_RenderLine(renderer, (f32)padding, (f32)padding,
+ (f32)padding, (f32)(view->windowHeight - padding));
// Calculate visible range based on current view
f32 visibleMinAbbe, visibleMaxAbbe, visibleMinRI, visibleMaxRI;
@@ -148,7 +131,8 @@ void draw_axes(SDL_Renderer *renderer, TTF_Font *font, TTF_Font *titleFont, cons
f32 value = visibleMaxAbbe - i * (visibleMaxAbbe - visibleMinAbbe) / 5;
i32 x = padding + i * (view->windowWidth - 2 * padding) / 5;
- SDL_RenderDrawLine(renderer, x, view->windowHeight - padding, x, view->windowHeight - padding + 5);
+ SDL_RenderLine(renderer, (f32)x, (f32)(view->windowHeight - padding),
+ (f32)x, (f32)(view->windowHeight - padding + 5));
sprintf(label, "%.1f", value);
draw_text(renderer, font, label, x - 15, view->windowHeight - padding + 10, black);
}
@@ -158,7 +142,7 @@ void draw_axes(SDL_Renderer *renderer, TTF_Font *font, TTF_Font *titleFont, cons
f32 value = visibleMinRI + i * (visibleMaxRI - visibleMinRI) / 5;
i32 y = view->windowHeight - padding - i * (view->windowHeight - 2 * padding) / 5;
- SDL_RenderDrawLine(renderer, padding - 5, y, padding, y);
+ SDL_RenderLine(renderer, (f32)(padding - 5), (f32)y, (f32)padding, (f32)y);
sprintf(label, "%.3f", value);
draw_text(renderer, font, label, padding - 50, y - 10, black);
}
@@ -178,6 +162,7 @@ void draw_axes(SDL_Renderer *renderer, TTF_Font *font, TTF_Font *titleFont, cons
// Draw the closing parenthesis
draw_text(renderer, titleFont, ")", padding + 141, padding - 35, black);
}
+
// Function to draw a grid based on visible data range
void draw_grid(SDL_Renderer *renderer, const ViewState* view) {
const i32 padding = (i32)(view->windowWidth * PADDING_PERCENT);
@@ -208,7 +193,8 @@ void draw_grid(SDL_Renderer *renderer, const ViewState* view) {
data_to_screen_coords(x, visibleMinRI, view, &screenX, &screenY);
if (screenX >= padding && screenX <= view->windowWidth - padding) {
- SDL_RenderDrawLine(renderer, screenX, padding, screenX, view->windowHeight - padding);
+ SDL_RenderLine(renderer, (f32)screenX, (f32)padding,
+ (f32)screenX, (f32)(view->windowHeight - padding));
}
}
@@ -218,7 +204,8 @@ void draw_grid(SDL_Renderer *renderer, const ViewState* view) {
data_to_screen_coords(visibleMinAbbe, y, view, &screenX, &screenY);
if (screenY >= padding && screenY <= view->windowHeight - padding) {
- SDL_RenderDrawLine(renderer, padding, screenY, view->windowWidth - padding, screenY);
+ SDL_RenderLine(renderer, (f32)padding, (f32)screenY,
+ (f32)(view->windowWidth - padding), (f32)screenY);
}
}
}
@@ -289,14 +276,14 @@ void draw_glass_properties(SDL_Renderer *renderer, TTF_Font *font, TTF_Font *tit
}
// Draw background with slight transparency
- SDL_Rect windowRect = {windowX, windowY, windowWidth, windowHeight};
+ SDL_FRect windowRect = {(f32)windowX, (f32)windowY, (f32)windowWidth, (f32)windowHeight};
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, 245, 245, 245, 235);
SDL_RenderFillRect(renderer, &windowRect);
// Draw border
SDL_SetRenderDrawColor(renderer, 40, 40, 40, 255);
- SDL_RenderDrawRect(renderer, &windowRect);
+ SDL_RenderRect(renderer, &windowRect);
// Draw glass name as title
SDL_Color darkBlue = {0, 0, 120, 255};
@@ -326,14 +313,14 @@ void draw_help_window(SDL_Renderer *renderer, TTF_Font *font, TTF_Font *titleFon
i32 x = (view->windowWidth - width) / 2;
i32 y = (view->windowHeight - height) / 2;
- SDL_Rect helpRect = {x, y, width, height};
+ SDL_FRect helpRect = {(f32)x, (f32)y, (f32)width, (f32)height};
SDL_SetRenderDrawBlendMode(renderer, SDL_BLENDMODE_BLEND);
SDL_SetRenderDrawColor(renderer, 245, 245, 245, 230);
SDL_RenderFillRect(renderer, &helpRect);
// Draw border
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
- SDL_RenderDrawRect(renderer, &helpRect);
+ SDL_RenderRect(renderer, &helpRect);
// Draw help title
SDL_Color black = {0, 0, 0, 255};
@@ -390,7 +377,7 @@ void render(SDL_Renderer *renderer, TTF_Font *font, TTF_Font *titleFont, TTF_Fon
}
// Add a small hint about help in the corner
- draw_text(renderer, labelFont, "Press g? for help", 10, 0.975*view->windowHeight, black);
+ draw_text(renderer, labelFont, "Press g? for help", 10, (i32)(0.975*view->windowHeight), black);
// Draw help window if toggled
if (view->showHelp) {
@@ -403,27 +390,104 @@ void render(SDL_Renderer *renderer, TTF_Font *font, TTF_Font *titleFont, TTF_Fon
// Font management
+// Helper function to try loading a font with fallbacks
+static TTF_Font* try_load_font_from_paths(const char** fontNames, i32 numFonts, i32 size) {
+ TTF_Font* font = NULL;
+
+ // Try all font paths
+ for (i32 i = 0; i < numFonts; i++) {
+ font = TTF_OpenFont(fontNames[i], size);
+ if (font) {
+ printf("Successfully loaded font: %s (size %d)\n", fontNames[i], size);
+ return font;
+ }
+ }
+
+ // If all specific paths fail, try some generic system approaches
+ #ifndef _WIN32
+ // Try to find any sans-serif font using common naming patterns
+ const char* genericFonts[] = {
+ "/usr/share/fonts/truetype/droid/DroidSans.ttf",
+ "/usr/share/fonts/truetype/noto/NotoSans-Regular.ttf",
+ "/usr/share/fonts/TTF/DroidSans.ttf",
+ "/usr/share/fonts/noto/NotoSans-Regular.ttf",
+ "/usr/share/fonts/google-noto/NotoSans-Regular.ttf",
+ };
+
+ const i32 numGeneric = sizeof(genericFonts) / sizeof(genericFonts[0]);
+ for (i32 i = 0; i < numGeneric; i++) {
+ font = TTF_OpenFont(genericFonts[i], size);
+ if (font) {
+ printf("Successfully loaded generic font: %s (size %d)\n", genericFonts[i], size);
+ return font;
+ }
+ }
+ #endif
+
+ return NULL;
+}
+
// Load all required fonts
b32 load_fonts(FontSet *fonts) {
- fonts->regular = TTF_OpenFont("C:\\Windows\\Fonts\\arial.ttf", 14);
+ // Common font names to try, in order of preference
+ const char* fontNames[] = {
+ #ifdef _WIN32
+ "C:\\Windows\\Fonts\\arial.ttf",
+ "C:\\Windows\\Fonts\\tahoma.ttf",
+ "C:\\Windows\\Fonts\\verdana.ttf",
+ "C:\\Windows\\Fonts\\calibri.ttf",
+ #else
+ // Ubuntu/Debian paths
+ "/usr/share/fonts/truetype/dejavu/DejaVuSans.ttf",
+ "/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf",
+ "/usr/share/fonts/truetype/freefont/FreeSans.ttf",
+ // Arch Linux paths
+ "/usr/share/fonts/TTF/DejaVuSans.ttf",
+ "/usr/share/fonts/TTF/LiberationSans-Regular.ttf",
+ "/usr/share/fonts/gnu-free/FreeSans.ttf",
+ // Fedora/CentOS paths
+ "/usr/share/fonts/dejavu/DejaVuSans.ttf",
+ "/usr/share/fonts/liberation/LiberationSans-Regular.ttf",
+ // OpenSUSE paths
+ "/usr/share/fonts/truetype/DejaVuSans.ttf",
+ // Alternative common locations
+ "/usr/share/fonts/TTF/arial.ttf",
+ "/usr/share/fonts/truetype/msttcorefonts/arial.ttf",
+ "/System/Library/Fonts/Arial.ttf", // macOS
+ // Try local fonts directory
+ "./fonts/DejaVuSans.ttf",
+ "./DejaVuSans.ttf",
+ #endif
+ };
+
+ const i32 numFonts = sizeof(fontNames) / sizeof(fontNames[0]);
+ i32 fontSizes[] = {14, 18, 12}; // regular, title, label
+
+ // Load regular font
+ fonts->regular = try_load_font_from_paths(fontNames, numFonts, fontSizes[0]);
if (!fonts->regular) {
- printf("Failed to load regular font! TTF_Error: %s\n", TTF_GetError());
+ printf("Failed to load any regular font!\n");
+ printf("SDL_Error: %s\n", SDL_GetError());
+ #ifndef _WIN32
+ printf("Suggestion: Install fonts with: sudo apt install fonts-dejavu-core fonts-liberation (Ubuntu/Debian)\n");
+ printf(" sudo pacman -S ttf-dejavu ttf-liberation (Arch)\n");
+ printf(" sudo dnf install dejavu-sans-fonts liberation-fonts (Fedora)\n");
+ #endif
return 0;
}
- fonts->title = TTF_OpenFont("C:\\Windows\\Fonts\\arial.ttf", 18);
+ // Load title font (try larger size first, fallback to regular font)
+ fonts->title = try_load_font_from_paths(fontNames, numFonts, fontSizes[1]);
if (!fonts->title) {
- printf("Failed to load title font! TTF_Error: %s\n", TTF_GetError());
- TTF_CloseFont(fonts->regular);
- return 0;
+ printf("Warning: Could not load title font, using regular font\n");
+ fonts->title = fonts->regular; // Use the same font
}
- fonts->label = TTF_OpenFont("C:\\Windows\\Fonts\\arial.ttf", 12);
+ // Load label font (try smaller size first, fallback to regular font)
+ fonts->label = try_load_font_from_paths(fontNames, numFonts, fontSizes[2]);
if (!fonts->label) {
- printf("Failed to load label font! TTF_Error: %s\n", TTF_GetError());
- TTF_CloseFont(fonts->title);
- TTF_CloseFont(fonts->regular);
- return 0;
+ printf("Warning: Could not load label font, using regular font\n");
+ fonts->label = fonts->regular; // Use the same font
}
return 1;
@@ -431,7 +495,19 @@ b32 load_fonts(FontSet *fonts) {
// Free all fonts
void free_fonts(FontSet *fonts) {
+ // Only close fonts that are different from regular font
if (fonts->regular) TTF_CloseFont(fonts->regular);
- if (fonts->title) TTF_CloseFont(fonts->title);
- if (fonts->label) TTF_CloseFont(fonts->label);
+ if (fonts->title && fonts->title != fonts->regular) TTF_CloseFont(fonts->title);
+ if (fonts->label && fonts->label != fonts->regular) TTF_CloseFont(fonts->label);
+}
+
+// Clear text cache
+void clear_text_cache(void) {
+ for (i32 i = 0; i < cacheCount; i++) {
+ if (textCache[i].texture) {
+ SDL_DestroyTexture(textCache[i].texture);
+ textCache[i].texture = NULL;
+ }
+ }
+ cacheCount = 0;
}
diff --git a/src/glamac/glamac_view.c b/src/glamac/glamac_view.c
index 3078ae8..22d6401 100644
--- a/src/glamac/glamac_view.c
+++ b/src/glamac/glamac_view.c
@@ -1,16 +1,8 @@
/**
* glamac_view.c - Source file dealing with view states, filtering, zooming etc. of GlaMaC.
- *
- * Copyright (C) 2025 https://optics-design.com
- *
- * This program is free software: you can redistribute it and/or modify
- * it under the terms of the GNU Affero General Public License as
- * published by the Free Software Foundation, either version 3 of the
- * License, or (at your option) any later version.
- *
- * See the COPYING file for the full license text.
*/
#include <math.h>
+#include <SDL3/SDL.h>
#include "glamac_view.h"
#include "glass_data.h"
@@ -103,11 +95,12 @@ void handle_mouse_wheel_zoom(i32 wheelY, i32 mouseX, i32 mouseY, ViewState* view
// Toggle fullscreen
void toggle_fullscreen(SDL_Window* window) {
- const u32 flags = SDL_GetWindowFlags(window);
- if ((flags & SDL_WINDOW_FULLSCREEN_DESKTOP) == 0) {
- SDL_SetWindowFullscreen(window, SDL_WINDOW_FULLSCREEN_DESKTOP);
+ bool isFullscreen = SDL_GetWindowFlags(window) & SDL_WINDOW_FULLSCREEN;
+
+ if (!isFullscreen) {
+ SDL_SetWindowFullscreen(window, true);
} else {
- SDL_SetWindowFullscreen(window, 0);
+ SDL_SetWindowFullscreen(window, false);
}
}
Back to https://optics-design.com