From 2fafad322d4866b6a706e630d2de69ab86e30601 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Fri, 7 Nov 2025 13:19:53 +0100 Subject: [PATCH 01/18] sdl3 window initialization --- CMakeLists.txt | 7 +- src/CMakeLists.txt | 33 +-- src/SDL2.sac | 344 ------------------------------- src/SDLdisplay.sac | 93 +-------- src/example.sac | 11 + src/src/SDL/SDLsac.h | 43 ---- src/src/SDL/destroyDisplay.c | 45 ----- src/src/SDL/drawArray.c | 77 ------- src/src/SDL/drawArrayOffset.c | 95 --------- src/src/SDL/drawPixel.c | 73 ------- src/src/SDL/getExtent.c | 17 -- src/src/SDL/getSelection.c | 52 ----- src/src/SDL/initDisplay.c | 312 ---------------------------- src/src/SDL2/SDL2data.h | 91 --------- src/src/SDL2/SDL2proto.h | 147 -------------- src/src/SDL2/SDL2sac.h | 19 -- src/src/SDL2/close.c | 25 --- src/src/SDL2/color.c | 117 ----------- src/src/SDL2/data.c | 98 --------- src/src/SDL2/display.c | 78 ------- src/src/SDL2/draw.c | 106 ---------- src/src/SDL2/event.c | 87 -------- src/src/SDL2/extent.c | 21 -- src/src/SDL2/font.c | 125 ------------ src/src/SDL2/fontdata.h | 369 ---------------------------------- src/src/SDL2/fontstruct.h | 43 ---- src/src/SDL2/init.c | 53 ----- src/src/SDL2/invert.c | 66 ------ src/src/SDL2/line.c | 129 ------------ src/src/SDL2/mouse.c | 138 ------------- src/src/SDL2/names.c | 44 ---- src/src/SDL2/pixel.c | 42 ---- src/src/SDL2/rect.c | 163 --------------- src/src/SDL2/resize.c | 56 ------ src/src/SDL2/select.c | 39 ---- src/src/SDL2/sem.c | 92 --------- src/src/SDL2/setup.c | 88 -------- src/src/SDL2/title.c | 45 ----- src/src/SDL2/update.c | 86 -------- src/src/SDL2/window.c | 41 ---- src/src/sdl3.c | 41 ++++ 41 files changed, 63 insertions(+), 3588 deletions(-) delete mode 100644 src/SDL2.sac create mode 100644 src/example.sac delete mode 100644 src/src/SDL/SDLsac.h delete mode 100644 src/src/SDL/destroyDisplay.c delete mode 100644 src/src/SDL/drawArray.c delete mode 100644 src/src/SDL/drawArrayOffset.c delete mode 100644 src/src/SDL/drawPixel.c delete mode 100644 src/src/SDL/getExtent.c delete mode 100644 src/src/SDL/getSelection.c delete mode 100644 src/src/SDL/initDisplay.c delete mode 100644 src/src/SDL2/SDL2data.h delete mode 100644 src/src/SDL2/SDL2proto.h delete mode 100644 src/src/SDL2/SDL2sac.h delete mode 100644 src/src/SDL2/close.c delete mode 100644 src/src/SDL2/color.c delete mode 100644 src/src/SDL2/data.c delete mode 100644 src/src/SDL2/display.c delete mode 100644 src/src/SDL2/draw.c delete mode 100644 src/src/SDL2/event.c delete mode 100644 src/src/SDL2/extent.c delete mode 100644 src/src/SDL2/font.c delete mode 100644 src/src/SDL2/fontdata.h delete mode 100644 src/src/SDL2/fontstruct.h delete mode 100644 src/src/SDL2/init.c delete mode 100644 src/src/SDL2/invert.c delete mode 100644 src/src/SDL2/line.c delete mode 100644 src/src/SDL2/mouse.c delete mode 100644 src/src/SDL2/names.c delete mode 100644 src/src/SDL2/pixel.c delete mode 100644 src/src/SDL2/rect.c delete mode 100644 src/src/SDL2/resize.c delete mode 100644 src/src/SDL2/select.c delete mode 100644 src/src/SDL2/sem.c delete mode 100644 src/src/SDL2/setup.c delete mode 100644 src/src/SDL2/title.c delete mode 100644 src/src/SDL2/update.c delete mode 100644 src/src/SDL2/window.c create mode 100644 src/src/sdl3.c diff --git a/CMakeLists.txt b/CMakeLists.txt index b18e5e4..d714510 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,13 +14,10 @@ LIST (APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-common") INCLUDE ("cmake-common/check-sac2c.cmake") INCLUDE ("cmake-common/misc-macros.cmake") -# NB: Despite the name SDL2.sac, the module still relies on the "old" libSDL1, not libSDL2. -SET (SDL_BUILDING_LIBRARY ON) -FIND_PACKAGE (SDL REQUIRED) +FIND_PACKAGE (SDL3 REQUIRED) FIND_PACKAGE (X11 REQUIRED) -SET (SAC2C_EXTRA_INC "-I${SDL_INCLUDE_DIR}" "-I${X11_INCLUDE_DIR}" - CACHE STRING "Extra include files that should be used by sac2c") +SET (SAC2C_EXTRA_INC "-I${X11_INCLUDE_DIR}") SET (SAC2C_CPP_INC "-Xl" "-lX11" "-Xtl" "-lX11") # For every target run CMakeLists.txt in src diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 390a085..b5c923f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -5,41 +5,12 @@ ADD_CUSTOM_TARGET (${TARGET}-all-modules ALL) # C files SET (C_DEPS_SRC - src/SDL/destroyDisplay.c - src/SDL/drawArray.c - src/SDL/drawArrayOffset.c - src/SDL/drawPixel.c - src/SDL/getExtent.c - src/SDL/getSelection.c - src/SDL/initDisplay.c - src/SDL2/close.c - src/SDL2/color.c - src/SDL2/data.c - src/SDL2/display.c - src/SDL2/draw.c - src/SDL2/event.c - src/SDL2/extent.c - src/SDL2/font.c - src/SDL2/init.c - src/SDL2/invert.c - src/SDL2/line.c - src/SDL2/mouse.c - src/SDL2/names.c - src/SDL2/pixel.c - src/SDL2/sem.c - src/SDL2/rect.c - src/SDL2/resize.c - src/SDL2/select.c - src/SDL2/setup.c - src/SDL2/title.c - src/SDL2/update.c - src/SDL2/window.c + src/sdl3.c ) # SaC files SET (SAC_SRC SDLdisplay.sac - SDL2.sac ) # For every C source, compile an object file maintaining the right @@ -92,7 +63,7 @@ FOREACH (name ${SAC_SRC}) ADD_CUSTOM_COMMAND ( OUTPUT ${mod} ${tree} - COMMAND ${SAC2C} -v0 -o ${DLL_BUILD_DIR} "${src}" + COMMAND ${SAC2C} -v0 -Xc "\"$(pkg-config --cflags --libs sdl3)\"" -o ${DLL_BUILD_DIR} "${src}" WORKING_DIRECTORY "${dir}" MAIN_DEPENDENCY "${src}" DEPENDS ${deps_list} diff --git a/src/SDL2.sac b/src/SDL2.sac deleted file mode 100644 index 1fc4a20..0000000 --- a/src/SDL2.sac +++ /dev/null @@ -1,344 +0,0 @@ -class SDL2; - -external classtype; - -use ArrayArith: { +, -, *, /, != }; -use ArrayBasics: { sel, modarray }; -use Color8: { Color8 }; -use String: { string }; -use World: { TheWorld }; - -export all; - -/****************************************************************************** - * - * This class implements a layer on top of the Simple DirectMedia Layer. - * It is backwards compatible with the 'SDLdisplay' SAC module. - * Compared to the 'SDLdisplay' module it adds features, is sometimes faster - * when copying data to pixel memory and may generate less screen updates. - * Debugging output is generated when the environment variable SDL2_DEBUG - * is set to 1, 2 or 3 for increasingly detailed output. - * - ******************************************************************************/ - -external SDL2 initDisplay(int[2] shp); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_display" - #pragma linkobj "src/SDL2/data.o" - #pragma linkobj "src/SDL2/display.o" - #pragma linkobj "src/SDL2/event.o" - #pragma linkobj "src/SDL2/init.o" - #pragma linkobj "src/SDL2/invert.o" - #pragma linkobj "src/SDL2/mouse.o" - #pragma linkobj "src/SDL2/names.o" - #pragma linkobj "src/SDL2/sem.o" - #pragma linkobj "src/SDL2/setup.o" - #pragma linkobj "src/SDL2/title.o" - #pragma linkobj "src/SDL2/update.o" - #pragma refcounting [1] - /* Open a new display window on screen. The parameter 'shp' gives the - * width/height dimensions. When width or height is zero then SDL will - * allocate the maximum screen size for that dimension. */ - -/* - * Backward compatibility: Open a new display. - * The parameter 'async' is ignored. - */ -inline SDL2 initDisplay(int[2] shp, bool async) -{ - return initDisplay(shp); -} - -/* - * Open a new display and divide the window into identical subsections. - * The parameter 'layout' gives the number and relative position - * of the subsections. The parameter 'disp_shp' gives the - * width/height dimensions of one subsection. - */ -SDL2 initMultiDisplay(int[2] layout, int[2] disp_shp) -{ - size = layout * disp_shp + (layout - 1) * 3; - res = initDisplay(size, true); - frame = with { - (. <= iv <= . step (disp_shp + 3) width disp_shp) : (Color8)[0,0,0]; - } : genarray(size, (Color8)[255,255,255]); - drawArray(res, frame); - return res; -} - -external void resizeDisplay(SDL2& disp, int[2] shp); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_resize" - #pragma linkobj "src/SDL2/resize.o" - #pragma refcounting [1] - /* Resize an existing display window on screen. The parameter 'shp' gives - * the desired Width/Height dimensions. Beware that resizing to smaller - * dimensions may cause problems for sub-windows of 'disp' when they are - * no longer contained in the new area of 'disp'. */ - -external void destroyDisplay(SDL2& disp); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_close" - #pragma linkobj "src/SDL2/close.o" - /* Close an existing display window and free associated resources. */ - -external SDL2 window(SDL2& disp, int[2] offset, int[2] size); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_window" - #pragma linkobj "src/SDL2/window.o" - #pragma linksign [0,1,2,3] - /* Create a sub-window of an existing display. - * This can be used to confine future draw operations to. - * - The parameter 'offset' gives the X/Y position of the window. - * - The parameter 'size' gives the Width/Height of the window. - * Offset must be non-negative and 'offset' + 'size' must fit in 'disp'. */ - -external void drawArray(SDL2& disp, Color8[.,.] array); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_draw" - #pragma linkobj "src/SDL2/draw.o" - #pragma refcounting [1] - /* Copy an array to a display window. - * These must have identical dimensions. */ - -/* - * Copy an array to a given subsection of a multi-display. - * The parameter 'pos' selects the subsection in the multi-display. - */ -void drawArrayMulti(SDL2& disp, Color8[2:shp] array, int[2] pos) -{ - drawArrayOffset(disp, array, (shp + 3) * pos); -} - -external void drawArrayOffset(SDL2& disp, Color8[.,.] array, int[2] offset); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_draw2" - #pragma linkobj "src/SDL2/draw.o" - #pragma refcounting [1] - /* Copy the array 'array' to a position on the display window 'disp'. The - * X/Y-offset are given by the parameter 'offset'. Offset must be non- - * negative and 'offset' + shape('array') must fit in the display window. */ - -external int[2] getExtent(SDL2 &disp); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_extent" - #pragma linkobj "src/SDL2/extent.o" - #pragma linksign [1,2] - /* Request the Width/Height dimensions of a display window. */ - -external void drawPixel(SDL2 &disp, int[2] idx, Color8 val); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_pixel" - #pragma linkobj "src/SDL2/pixel.o" - #pragma refcounting [1,2] - /* Change the color value of a single pixel in the pixel buffer. To update - * the pixel buffer to screen one of the update functions must be used. - * See below. It is efficient to draw a large number of pixels before - * one call to update the screen. */ - -external void drawLine(SDL2& disp, int[2] point1, int[2] point2, bool async); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_line" - #pragma linkobj "src/SDL2/line.o" - #pragma linksign [1,2,3,4] - /* Draw a line from point1 to point2. The parameter 'async' requests an - * asynchronous update when true. This is useful when drawing several lines - * in succession if the last operation is done synchronously. Try to limit - * the number of successive asynchronous operations. When 'async' is false - * a synchronous screen update is done immediately. */ - -external void drawRect(SDL2& disp, int[2] offset, int[2] size, bool async); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_draw_rect" - #pragma linkobj "src/SDL2/rect.o" - #pragma linksign [1,2,3,4] - /* Draw a rectangle on screen: - * - The parameter 'offset' gives the X/Y position - * - The parameter 'size' gives the Width/Height of the rectangle. - * Offset must be non-negative and 'offset' + 'size' must fit in 'disp'. - * The parameter 'async' has the same purpose as in drawLine. */ - -external void fillRect(SDL2& disp, int[2] offset, int[2] size, bool async); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_fill_rect" - #pragma linkobj "src/SDL2/rect.o" - #pragma linksign [1,2,3,4] - /* Fill a rectangle on screen: - * - The parameter 'offset' gives the X/Y position - * - The parameter 'size' gives the Width/Height of the rectangle. - * Offset must be non-negative and 'offset' + 'size' must fit in 'disp'. - * The parameter 'async' has the same purpose as in drawLine. */ - -external void fillDisp(SDL2& disp, bool async); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_fill_disp" - #pragma linkobj "src/SDL2/rect.o" - #pragma linksign [1,2] - /* Fill a window with the foreground color. - * The parameter 'async' has the same purpose as in drawLine. */ - -external void invertRect(SDL2& disp, int[2] offset, int[2] size); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_invert2" - #pragma linkobj "src/SDL2/invert.o" - #pragma linksign [1,2,3] - /* Invert the colors of a rectangle on screen: - * - The parameter 'offset' gives the X/Y position - * - The parameter 'size' gives the Width/Height of the rectangle. - * Offset must be non-negative and 'offset' + 'size' must fit in 'disp'. - * A double invert restores the original image. */ - -external void updateDisp(SDL2& disp, bool async); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_update" - #pragma linkobj "src/SDL2/update.o" - #pragma linksign [1,2] - /* Update the display or the sub-window. This copies the pixel buffer - * to screen. Use this function in combination with drawPixel. - * - When 'async' is false the function waits for the update to complete. - * - When 'async' is true the function generates an update request - * and immediately returns. Use this with caution. Give the system - * an appropriate amount of time to complete the request before - * generating another update request. Note that subsequent draw - * operations may also be shown by the asynchronous update. */ - -external void updateRect(SDL2& disp, int[2] offset, int[2] size, bool async); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_update2" - #pragma linkobj "src/SDL2/update.o" - #pragma linksign [1,2,3,4] - /* Update a rectangle in the display window similar to updateDisp: - * - offset gives the X/Y position - * - size the Width/Height of the rectangle. */ - -external void drawText(SDL2& disp, string text, int[2] offset, bool async); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_text" - #pragma linkobj "src/SDL2/font.o" - #pragma linksign [1,2,3,4] - /* Display text at the given offset. Offset must fit in disp. The drawing - * of 'text' is clipped by disp's dimensions. Newlines '\n' and tabs '\t' - * change the cursor position. The text is written in the foreground color. - * The background should have been cleared by the caller when this is - * desirable. */ - -external int[2,2] textExtent(string text); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_text_extent" - #pragma linkobj "src/SDL2/font.o" - #pragma linksign [1,2] - /* Calculate the offset and the dimensions of the area - * that will be needed to completely display a text string. */ - -external int[2,2] getSelection(SDL2 &disp); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_select" - #pragma linkobj "src/SDL2/select.o" - #pragma linksign [1,2] - /* Ask the user to select an area in the display window using - * the left mouse button. The middle mouse button cancels. */ - -/* - * Ask the user to select an area in any of the subsections - * of a multi-window using the left mouse button. - * The middle mouse button cancels. - */ -int[2], int[2,2] getSelectionMulti(SDL2 &disp, int[2] layout) -{ - selection = getSelection(disp); - extent = getExtent(disp); - shp = (extent - 3 * (layout - 1)) / layout; - - field = { [i] -> selection[[i]] / (shp + 3)}; - pos = { [i] -> selection[[i]] - 3 * field[[i]] - field[[i]] * shp}; - - if (_all_V_(field[[0]] != field[[1]])) { - pos[[1]] = shp - 1; - } - - return (field[[0]], pos); -} - -external void background(Color8 background); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_set_background" - #pragma linkobj "src/SDL2/color.o" - /* Set the background color for future drawing operations. */ - -external Color8 background(); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_get_background" - #pragma linkobj "src/SDL2/color.o" - #pragma linksign [1] - /* Request the current background color. */ - -external void foreground(Color8 foreground); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_set_foreground" - #pragma linkobj "src/SDL2/color.o" - /* Set the foreground color for future drawing operations. */ - -external Color8 foreground(); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_get_foreground" - #pragma linkobj "src/SDL2/color.o" - #pragma linksign [1] - /* Request the current foreground color. */ - -external Color8 getColor(string name); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_get_color" - #pragma linkobj "src/SDL2/color.o" - #pragma linksign [1, 2] - /* Request an RGB color representation for the named color. If name starts - * with a hash '#' either 3 or 6 hexadecimal digits must follow, which - * represent a color similar to HTML colors. Else name is looked up in - * the system's rgb.txt file. If no color could be found then the - * color white is returned. */ - -external void fullscreen(bool enable); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_enable_fullscreen" - #pragma linkobj "src/SDL2/display.o" - /* Create future display windows fullscreen. Please note that this may - * change the system X11 video mode! Give the user a mechanism to terminate - * the program gracefully or else the system may stay in an undesirable - * screen resolution. If all you want is the maximum screen resolution then - * specify a width and height of zero to 'initDisp' and use 'noframe' to - * get rid of the window manager frame. */ - -external void noframe(bool enable); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_enable_noframe" - #pragma linkobj "src/SDL2/display.o" - /* Create future display windows without a window manager frame. */ - -external void cursor(bool enable); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_cursor" - #pragma linkobj "src/SDL2/title.o" - /* Enable or disable the mouse cursor in the application display window. */ - -external void heading(string heading); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_heading" - #pragma linkobj "src/SDL2/title.o" - /* Change the window manager frame header. This may trigger an old bug in - * libX11 under certain circumstances and crash or deadlock. After creating - * a new display window let the window manager interact with it first - * before changing the 'heading'. The function getSelection also uses - * this function. */ - -external SDL2 nullDisplay(); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_null" - #pragma linkobj "src/SDL2/data.o" - #pragma linksign [0] - /* Return a NULL display as a placeholder. */ - -external bool isNullDisplay(SDL2& disp); - #pragma effect TheWorld - #pragma linkname "SAC_SDL2_isnull" - #pragma linkobj "src/SDL2/data.o" - #pragma linksign [0,1] - /* Test if a display is a NULL display. */ diff --git a/src/SDLdisplay.sac b/src/SDLdisplay.sac index 355fcfc..e782a1a 100644 --- a/src/SDLdisplay.sac +++ b/src/SDLdisplay.sac @@ -2,92 +2,13 @@ class SDLdisplay; external classtype; -use ArrayArith: { +, -, *, /, != }; -use ArrayBasics: { sel, modarray }; -use Color8: { Color8 }; -use World: { TheWorld }; - export all; -SDLdisplay initDisplay(int[.] shp) -{ - return initDisplay(shp, true); -} - -SDLdisplay initMultiDisplay(int[2] layout, int[2] disp_shp) -{ - size = layout * disp_shp + (layout - 1) * 3; - res = initDisplay(size, true); - - frame = with { - (. <= iv <= . step (disp_shp + 3) width disp_shp) : (Color8)[0,0,0]; - } : genarray(size, (Color8)[255,255,255]); - - drawArray(res, frame); - return res; -} - -external SDLdisplay initDisplay(int[2] shp, bool async); - #pragma effect TheWorld - #pragma linkname "SAC_SDL_initDisplay" - #pragma linkobj "src/SDL/initDisplay.o" - #pragma linkwith "SDL" - #pragma refcounting [1] - -external void destroyDisplay(SDLdisplay disp); - #pragma effect TheWorld - #pragma linkname "SAC_SDL_destroyDisplay" - #pragma linkobj "src/SDL/destroyDisplay.o" - #pragma linkwith "SDL" - -external int[2] getExtent(SDLdisplay &disp); - #pragma linkname "SAC_SDL_getExtent" - #pragma linkobj "src/SDL/getExtent.o" - #pragma linkwith "SDL" - #pragma linksign [1,2] - -external void drawArray(SDLdisplay &disp, Color8[.,.] array); - #pragma linkname "SAC_SDL_drawArray" - #pragma linkobj "src/SDL/drawArray.o" - #pragma linkwith "SDL" - #pragma refcounting [1] - -void drawArrayMulti(SDLdisplay &disp, Color8[2:shp] array, int[2] pos) -{ - drawArrayOffset(disp, array, (shp + 3) * pos); -} - -external void drawArrayOffset(SDLdisplay &disp, - Color8[.,.] array, int[2] pic_offset); - #pragma linkname "SAC_SDL_drawArrayOffset" - #pragma linkobj "src/SDL/drawArrayOffset.o" - #pragma linkwith "SDL" - #pragma refcounting [1] - -external void drawPixel(SDLdisplay &disp, int[2] idx, Color8 val); - #pragma linkname "SAC_SDL_drawPixel" - #pragma linkobj "src/SDL/drawPixel.o" - #pragma linkwith "SDL" - #pragma refcounting [1,2] - -external int[2,2] getSelection(SDLdisplay &disp); - #pragma linkname "SAC_SDL_getSelection" - #pragma linkobj "src/SDL/getSelection.o" - #pragma linkwith "SDL" - #pragma linksign [1,2] - -int[2], int[2,2] getSelectionMulti(SDLdisplay &disp, int[2] layout) -{ - selection = getSelection(disp); - extent = getExtent(disp); - shp = (extent - 3 * (layout - 1)) / layout; - - field = { [i] -> selection[[i]] / (shp + 3)}; - pos = { [i] -> selection[[i]] - 3 * field[[i]] - field[[i]] * shp}; - - if (_all_V_(field[[0]] != field[[1]])) { - pos[[1]] = shp - 1; - } +external SDLdisplay initDisplay(int w, int h); + #pragma effect World::TheWorld + #pragma linkobj "src/sdl3.o" + #pragma linkwith "SDL3" - return (field[[0]], pos); -} +external void closeDisplay(SDLdisplay disp); + #pragma linkobj "src/sdl3.o" + #pragma linkwith "SDL3" diff --git a/src/example.sac b/src/example.sac new file mode 100644 index 0000000..02eed0e --- /dev/null +++ b/src/example.sac @@ -0,0 +1,11 @@ +use SDLdisplay: all; +use StdIO: all; + +int main() { + printf("Hello, world!\n"); + disp = initDisplay(640, 480); + printf("Created window\n"); + closeDisplay(disp); + printf("Closed window\n"); + return 0; +} diff --git a/src/src/SDL/SDLsac.h b/src/src/SDL/SDLsac.h deleted file mode 100644 index 4399fad..0000000 --- a/src/src/SDL/SDLsac.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef _SDLSAC_H_ -#define _SDLSAC_H_ - -#include "sac.h" -#include "SDL.h" -#include "SDL_thread.h" - -#undef UPDATE_VIA_SEMAPHORE -#define ADAPTIVE_MODE - -typedef SDL_Surface* SDLdisplay; - -extern SDL_Thread *SDLsac_eventhandler; -extern SDL_mutex *SDLsac_mutex; -extern SDL_TimerID SDLsac_timer; - -#ifdef UPDATE_VIA_SEMAPHORE -extern SDL_sem *SDLsac_updatesem; -extern SDL_Thread *SDLsac_updater; -#endif /* UPDATE_VIA_SEMAPHORE */ - -extern bool SDLsac_isasync; - -typedef enum {SEL_none, SEL_top, SEL_bottom} selmode_t; -extern selmode_t SDLsac_selmode; -extern SDL_sem *SDLsac_selectsem; -extern int SDLsac_selection[4]; - -#define SDL_SAC_DEFAULT_HEADING "SaC SDL Display" -#define SDL_SAC_SELECT_HEADING "Click and drag to select an area, button-two click to cancel..." - -#define SDL_USEREVENT_DRAW (SDL_USEREVENT + 1) -#define SDL_USEREVENT_QUIT (SDL_USEREVENT + 2) - -#define disp_nt (disp, T_OLD((SCL, (HID, (NUQ,))))) -#define shp_nt (shp, T_OLD((AKS, (NHD, (NUQ,))))) -#define ar_nt (ar, T_OLD((AKD, (NHD, (NUQ,))))) -#define color_nt (col, T_OLD((AKS, (NHD, (NUQ,))))) -#define async_nt (async, T_OLD((SCL, (NHD, (NUQ,))))) -#define aks_out_nt (aks_out, T_OLD((AKS, (NHD, (NUQ,))))) -#define aks_nt (aks, T_OLD((AKS, (NHD, (NUQ,))))) - -#endif diff --git a/src/src/SDL/destroyDisplay.c b/src/src/SDL/destroyDisplay.c deleted file mode 100644 index c3b7eba..0000000 --- a/src/src/SDL/destroyDisplay.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "SDLsac.h" -#include -#include - -void SAC_SDL_destroyDisplay( SAC_ND_PARAM_in_nodesc( disp_nt, SDLdisplay)) -{ - SDL_Event event; - - if (SDLsac_isasync) { - /* stop the timer */ - if (SDLsac_timer != NULL) { - SDL_RemoveTimer( SDLsac_timer); - } - - /* tell the event handler to quit */ - event.type = SDL_USEREVENT_QUIT; - event.user.code = 0; - event.user.data1 = NULL; - event.user.data2 = NULL; - SDL_PushEvent(&event); - - /* wait for event handler to finish */ - if (SDLsac_eventhandler != NULL) { - SDL_WaitThread( SDLsac_eventhandler, NULL); - } - -#ifdef UPDATE_VIA_SEMAPHORE - /* kill the updater */ - SDL_KillThread( SDLsac_updater); - - /* destroy the semaphore */ - SDL_DestroySemaphore( SDLsac_updatesem); -#endif - } - - /* destroy the semaphore */ - SDL_DestroySemaphore( SDLsac_selectsem); - - /* finally, we can release this */ - if (SDLsac_mutex != NULL) { - SDL_DestroyMutex( SDLsac_mutex); - } - - SDL_Quit(); -} diff --git a/src/src/SDL/drawArray.c b/src/src/SDL/drawArray.c deleted file mode 100644 index d7aad46..0000000 --- a/src/src/SDL/drawArray.c +++ /dev/null @@ -1,77 +0,0 @@ -#include "SDLsac.h" - -#include - -void SAC_SDL_drawArray( SAC_ND_PARAM_inout_nodesc_bx( disp_nt, SDLdisplay), - SAC_ND_PARAM_in( ar_nt, int)) -{ - int xaxis, yaxis, aroffset, screenoffset; - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexP( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to lock the access mutex"); - } - - /* - * check bounds - */ - if ( (SAC_ND_A_DESC_SHAPE( ar_nt, 1) != NT_NAME( disp_nt)->w) || - (SAC_ND_A_DESC_SHAPE( ar_nt, 0) != NT_NAME( disp_nt)->h) ) { - SAC_RuntimeError( "Cannot draw array of shape [ %d, %d] on display\n" - "*** of size [ %d, %d] ! \n", - SAC_ND_A_DESC_SHAPE( ar_nt, 0), - SAC_ND_A_DESC_SHAPE( ar_nt, 1), - NT_NAME( disp_nt)->w, - NT_NAME( disp_nt)->h); - } - - /* - * lock the screen for drawing - */ - if (SDL_MUSTLOCK( NT_NAME( disp_nt))) { - if (SDL_LockSurface( NT_NAME( disp_nt)) < 0) { - SAC_RuntimeError( "Failed to lock the SDL Display"); - } - } - - /* - * draw - */ - aroffset = 0; - for (yaxis = 0; yaxis < SAC_ND_A_DESC_SHAPE( ar_nt, 0); yaxis ++) { - screenoffset = yaxis * NT_NAME( disp_nt)->pitch / 4; - for (xaxis = 0; xaxis < SAC_ND_A_DESC_SHAPE( ar_nt, 1); xaxis ++) { - Uint32 *bptr = (Uint32 *) NT_NAME( disp_nt)->pixels - + screenoffset + xaxis; - - *bptr = ( ((Uint32)SAC_ND_A_FIELD( ar_nt)[aroffset]) << 16 - | ((Uint32)SAC_ND_A_FIELD( ar_nt)[aroffset+1]) << 8 - | ((Uint32)SAC_ND_A_FIELD( ar_nt)[aroffset+2]) - ); - aroffset+=3; - } - } - - /* - * unlock it - */ - if (SDL_MUSTLOCK( NT_NAME( disp_nt))) { - SDL_UnlockSurface( NT_NAME( disp_nt)); - } - - if( !SDLsac_isasync) { - SDL_Flip( NT_NAME( disp_nt)); - } - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexV( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to unlock the access mutex"); - } - - SAC_ND_DEC_RC_FREE( ar_nt, 1, ) -} - diff --git a/src/src/SDL/drawArrayOffset.c b/src/src/SDL/drawArrayOffset.c deleted file mode 100644 index 081b049..0000000 --- a/src/src/SDL/drawArrayOffset.c +++ /dev/null @@ -1,95 +0,0 @@ -#include "SDLsac.h" - -#include - -void SAC_SDL_drawArrayOffset( - SAC_ND_PARAM_inout_nodesc_bx( disp_nt, SDLdisplay), - SAC_ND_PARAM_in( ar_nt, int), - int pic_offset[2] - ) -{ - int xaxis, yaxis, aroffset, screenoffset, xoffset, yoffset; - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexP( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to lock the access mutex"); - } - - xoffset = pic_offset[1]; - yoffset = pic_offset[0]; - - /* - * check bounds - */ - - - if ( xoffset < 0 || yoffset < 0 || - (SAC_ND_A_DESC_SHAPE( ar_nt, 1)+xoffset > NT_NAME( disp_nt)->w) || - (SAC_ND_A_DESC_SHAPE( ar_nt, 0)+yoffset > NT_NAME( disp_nt)->h) ) { - SAC_RuntimeError( "Cannot draw array of shape [ %d, %d] starting \n" - "***at [%d,%d] on display of size [ %d, %d] ! \n", - SAC_ND_A_DESC_SHAPE( ar_nt, 0), - SAC_ND_A_DESC_SHAPE( ar_nt, 1), - xoffset, - yoffset, - NT_NAME( disp_nt)->w, - NT_NAME( disp_nt)->h); - } - - - /* - * lock the screen for drawing - */ - if (SDL_MUSTLOCK( NT_NAME( disp_nt))) { - if (SDL_LockSurface( NT_NAME( disp_nt)) < 0) { - SAC_RuntimeError( "Failed to lock the SDL Display"); - } - } - - /* - * draw - */ - aroffset = 0; - for (yaxis = yoffset; - yaxis < SAC_ND_A_DESC_SHAPE( ar_nt, 0)+yoffset; yaxis ++) { - - screenoffset = yaxis * NT_NAME( disp_nt)->pitch / 4; - - for (xaxis = xoffset; - xaxis < SAC_ND_A_DESC_SHAPE( ar_nt, 1)+xoffset; xaxis ++) { - Uint32 *bptr = (Uint32 *) NT_NAME( disp_nt)->pixels - + screenoffset + xaxis; - - *bptr = ( ((Uint32)SAC_ND_A_FIELD( ar_nt)[aroffset]) << 16 - | ((Uint32)SAC_ND_A_FIELD( ar_nt)[aroffset+1]) << 8 - | ((Uint32)SAC_ND_A_FIELD( ar_nt)[aroffset+2]) - ); - aroffset+=3; - } - } - - /* - * unlock it - */ - if (SDL_MUSTLOCK( NT_NAME( disp_nt))) { - SDL_UnlockSurface( NT_NAME( disp_nt)); - } - - if( !SDLsac_isasync) { - SDL_UpdateRect( NT_NAME( disp_nt), xoffset, yoffset, - SAC_ND_A_DESC_SHAPE( ar_nt, 1), - SAC_ND_A_DESC_SHAPE( ar_nt, 0)); - } - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexV( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to unlock the access mutex"); - } - - SAC_ND_DEC_RC_FREE( ar_nt, 1, ) -} - diff --git a/src/src/SDL/drawPixel.c b/src/src/SDL/drawPixel.c deleted file mode 100644 index 0b6e8ff..0000000 --- a/src/src/SDL/drawPixel.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "SDLsac.h" - -void SAC_SDL_drawPixel( SAC_ND_PARAM_inout_nodesc_bx( disp_nt, SDLdisplay), - SAC_ND_PARAM_in( shp_nt, int), - SAC_ND_PARAM_in( color_nt, int)) -{ - int xoffset, yoffset; - Uint32 *bptr; - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexP( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to lock the access mutex"); - } - - /* - * check bounds - */ - if ( (SAC_ND_A_FIELD( shp_nt)[1] < 0) || - (SAC_ND_A_FIELD( shp_nt)[1] >= NT_NAME( disp_nt)->w) || - (SAC_ND_A_FIELD( shp_nt)[0] < 0) || - (SAC_ND_A_FIELD( shp_nt)[0] >= NT_NAME( disp_nt)->h) ) { - SAC_RuntimeError( "Cannot draw pixel at position [%d/%d]:\n" - "*** pixel out of bounds !\n", - SAC_ND_A_FIELD( shp_nt)[1], - SAC_ND_A_FIELD( shp_nt)[0]); - } - - /* - * lock the screen for drawing - */ - if (SDL_MUSTLOCK( NT_NAME( disp_nt))) { - if (SDL_LockSurface( NT_NAME( disp_nt)) < 0) { - SAC_RuntimeError( "Failed to lock the SDL Display"); - } - } - - /* - * draw - */ - yoffset = SAC_ND_A_FIELD( shp_nt)[0] * (NT_NAME( disp_nt)->pitch / 4); - xoffset = SAC_ND_A_FIELD( shp_nt)[1]; - - bptr = (Uint32 *) (NT_NAME( disp_nt)->pixels) + xoffset + yoffset; - *bptr = ( ((Uint32)SAC_ND_A_FIELD( color_nt)[0]) << 16 - | ((Uint32)SAC_ND_A_FIELD( color_nt)[1]) << 8 - | ((Uint32)SAC_ND_A_FIELD( color_nt)[2]) - ); - - /* - * unlock it - */ - if (SDL_MUSTLOCK( NT_NAME( disp_nt))) { - SDL_UnlockSurface( NT_NAME( disp_nt)); - } - - if( !SDLsac_isasync) { - SDL_UpdateRect( NT_NAME( disp_nt), SAC_ND_A_FIELD( shp_nt)[1], - SAC_ND_A_FIELD( shp_nt)[0], 1, 1); - } - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexV( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to unlock the access mutex"); - } - - SAC_ND_DEC_RC_FREE( shp_nt, 1, ) - SAC_ND_DEC_RC_FREE( color_nt, 1, ) -} - diff --git a/src/src/SDL/getExtent.c b/src/src/SDL/getExtent.c deleted file mode 100644 index 6f65082..0000000 --- a/src/src/SDL/getExtent.c +++ /dev/null @@ -1,17 +0,0 @@ - -#include "SDLsac.h" - -void SAC_SDL_getExtent( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), - SAC_ND_PARAM_inout_nodesc_bx( disp_nt, SDLdisplay)) -{ - SAC_ND_DECL__DATA( aks_nt, int, ); - - /* - * create result and write back with [Y,X] as result - */ - SAC_ND_A_FIELD( aks_nt) = SAC_MALLOC( sizeof( int) * 2); - SAC_ND_A_FIELD( aks_nt)[0] = NT_NAME( disp_nt)->h; - SAC_ND_A_FIELD( aks_nt)[1] = NT_NAME( disp_nt)->w; - - SAC_ND_RET_out__NODESC( aks_out_nt, aks_nt); -} diff --git a/src/src/SDL/getSelection.c b/src/src/SDL/getSelection.c deleted file mode 100644 index 5c404ee..0000000 --- a/src/src/SDL/getSelection.c +++ /dev/null @@ -1,52 +0,0 @@ - -#include "SDLsac.h" - -void SAC_SDL_getSelection( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), - SAC_ND_PARAM_inout_nodesc_bx( disp_nt, SDLdisplay)) -{ - SAC_ND_DECL__DATA( aks_nt, int, ); - - /* - * update window title and cursor to inform user of select mode - */ - SDL_WM_SetCaption( SDL_SAC_SELECT_HEADING, NULL); - SDL_ShowCursor( SDL_ENABLE); - - /* - * turn on select mode - */ - SDLsac_selmode = SEL_top; - - /* - * wait for result - */ - SDL_SemWait( SDLsac_selectsem); - - /* - * resume normal cursor and title - */ - SDL_WM_SetCaption( SDL_SAC_DEFAULT_HEADING, NULL); - SDL_ShowCursor( SDL_DISABLE); - - /* - * write back result, ensure that we have [topleft, bottomrigth] and - * [Y,X] coordinates - */ - SAC_ND_A_FIELD( aks_nt) = SAC_MALLOC( sizeof( int) * 4); - if (SDLsac_selection[0] <= SDLsac_selection[2]) { - SAC_ND_A_FIELD( aks_nt)[1] = SDLsac_selection[0]; - SAC_ND_A_FIELD( aks_nt)[3] = SDLsac_selection[2]; - } else { - SAC_ND_A_FIELD( aks_nt)[1] = SDLsac_selection[2]; - SAC_ND_A_FIELD( aks_nt)[3] = SDLsac_selection[0]; - } - if (SDLsac_selection[1] <= SDLsac_selection[3]) { - SAC_ND_A_FIELD( aks_nt)[0] = SDLsac_selection[1]; - SAC_ND_A_FIELD( aks_nt)[2] = SDLsac_selection[3]; - } else { - SAC_ND_A_FIELD( aks_nt)[0] = SDLsac_selection[3]; - SAC_ND_A_FIELD( aks_nt)[2] = SDLsac_selection[1]; - } - - SAC_ND_RET_out__NODESC( aks_out_nt, aks_nt); -} diff --git a/src/src/SDL/initDisplay.c b/src/src/SDL/initDisplay.c deleted file mode 100644 index 9a10a03..0000000 --- a/src/src/SDL/initDisplay.c +++ /dev/null @@ -1,312 +0,0 @@ -#include "SDLsac.h" -#include -#include -#include - -#define MIN_UPDATE_INTERVAL 50 -#define START_UPDATE_INTERVAL 200 - -SDL_Thread *SDLsac_eventhandler = NULL; -SDL_mutex *SDLsac_mutex = NULL; -SDL_TimerID SDLsac_timer = NULL; - -#ifdef UPDATE_VIA_SEMAPHORE -SDL_sem *SDLsac_updatesem = NULL; -SDL_Thread *SDLsac_updater = NULL; -#endif /* UPDATE_VIA_SEMAPHORE */ - -bool SDLsac_isasync = 0; - -selmode_t SDLsac_selmode = SEL_none; -SDL_sem *SDLsac_selectsem = NULL; -int SDLsac_selection[4] = {0,0,0,0}; - -static -int UpdateScreen( void *surface) -{ -#ifdef UPDATE_VIA_SEMAPHORE - while (1) { - /* - * wait for update event - */ - if (SDL_SemWait( SDLsac_updatesem) == 0) { - -#endif /* UPDATE_VIA_SEMAPHORE */ - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexP( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to lock the access mutex"); - } - - SDL_Flip( (SDL_Surface *) surface); - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexV( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to unlock the access mutex"); - } -#ifdef UPDATE_VIA_SEMAPHORE - } - } -#endif /* UPDATE_VIA_SEMAPHORE */ - - return 0; -} - -static -void InvertRect( SDLdisplay disp, int *pos) -{ - int yaxis, xaxis; - int x1, x2, y1, y2; - int screenoffset; - - if (pos[0] < pos[2]) { - x1 = pos[0]; - x2 = pos[2]; - } else { - x1 = pos[2]; - x2 = pos[0]; - } - - if (pos[1] < pos[3]) { - y1 = pos[1]; - y2 = pos[3]; - } else { - y1 = pos[3]; - y2 = pos[1]; - } - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexP( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to lock the access mutex"); - } - - /* - * lock the screen for drawing - */ - if (SDL_MUSTLOCK( NT_NAME( disp_nt))) { - if (SDL_LockSurface( NT_NAME( disp_nt)) < 0) { - SAC_RuntimeError( "Failed to lock the SDL Display"); - } - } - - for (yaxis = y1; yaxis < y2; yaxis ++) { - screenoffset = yaxis * disp->pitch / 4; - for (xaxis = x1; xaxis < x2 ; xaxis ++) { - Uint32 *bptr = (Uint32 *) disp->pixels - + screenoffset + xaxis; - - *bptr = ~(*bptr); - } - } - - /* - * unlock it - */ - if (SDL_MUSTLOCK( NT_NAME( disp_nt))) { - SDL_UnlockSurface( NT_NAME( disp_nt)); - } - - /* - * accessing the display needs to be mutually exclusive - */ - if (SDL_mutexV( SDLsac_mutex)==-1){ - SAC_RuntimeError( "Failed to unlock the access mutex"); - } -} - -static -int EventHandler( void *screen) -{ - SDL_Event event; - int done = 0; - - while ( !done) { - if (SDL_WaitEvent( &event) == 1) { - switch (event.type) { - case SDL_QUIT: - /* someone clicked the close button on the window */ - SDL_Quit(); - exit(10); - break; - - case SDL_USEREVENT_DRAW: -#ifdef UPDATE_VIA_SEMAPHORE - SDL_SemPost( SDLsac_updatesem); -#else /* UPDATE_VIA_SEMAPHORE */ - UpdateScreen( (SDL_Surface *) event.user.data1); -#endif /* UPDATE_VIA_SEMAPHORE */ - break; - - case SDL_USEREVENT_QUIT: - done = 1; - break; - - case SDL_MOUSEBUTTONDOWN: - if ((event.button.button == 1) && (SDLsac_selmode == SEL_top)) { - SDLsac_selmode = SEL_bottom; - SDLsac_selection[0] = event.button.x; - SDLsac_selection[1] = event.button.y; - SDLsac_selection[2] = event.button.x; - SDLsac_selection[3] = event.button.y; - } - break; - - case SDL_MOUSEBUTTONUP: - if ((event.button.button == 1) && (SDLsac_selmode == SEL_bottom)) { - SDLsac_selmode = SEL_none; - SDLsac_selection[2] = event.button.x; - SDLsac_selection[3] = event.button.y; - - SDL_SemPost( SDLsac_selectsem); - } - if ((event.button.button == 2) && (SDLsac_selmode != SEL_none)) { - SDLsac_selmode = SEL_none; - SDLsac_selection[0] = -1; - SDLsac_selection[1] = -1; - SDLsac_selection[2] = -1; - SDLsac_selection[3] = -1; - - SDL_SemPost( SDLsac_selectsem); - } - break; - - case SDL_MOUSEMOTION: - if (SDLsac_selmode == SEL_bottom) { - InvertRect( (SDLdisplay) screen, SDLsac_selection); - - SDLsac_selection[2] = event.motion.x; - SDLsac_selection[3] = event.motion.y; - - InvertRect( (SDLdisplay) screen, SDLsac_selection); - } - break; - - default: - break; - } - } - } - - return 0; -} - -static -Uint32 TimerHandler(Uint32 interval, void *param) { - SDL_Event event; -#ifdef ADAPTIVE_MODE - int eventqueue; -#endif - -#ifdef ADAPTIVE_MODE -#ifdef UPDATE_VIA_SEMAPHORE - eventqueue = SDL_SemValue( SDLsac_updatesem); -#else /* UPDATE_VIA_SEMAPHORE */ - eventqueue = SDL_PeepEvents( &event, - 1, - SDL_PEEKEVENT, - SDL_EVENTMASK( SDL_USEREVENT_DRAW)); -#endif /* UPDATE_VIA_SEMAPHORE */ - - if (eventqueue == 1) { - /* an event overtook us, so we are too fast */ - interval *= 2; - } else if (interval > MIN_UPDATE_INTERVAL + 10) { - /* nothing waiting, we can speed up :-) */ - interval -= 10; - } -#endif - - event.type = SDL_USEREVENT_DRAW; - event.user.code = 0; - event.user.data1 = param; - event.user.data2 = NULL; - - SDL_PushEvent(&event); - - return(interval); -} - - -void SAC_SDL_initDisplay( SAC_ND_PARAM_out_nodesc( disp_nt, SDLdisplay), - SAC_ND_PARAM_in( shp_nt, int), - SAC_ND_PARAM_in( async_nt, bool)) -{ - SAC_ND_DECL__DATA( disp_nt, SDLdisplay, ) - - // XXX this is a quick fix to resolve an issue that some users have experienced - // when running a SAC-SDL application over SSH (X-forwarded)... - XInitThreads (); - - if (SDL_Init( SDL_INIT_VIDEO | SDL_INIT_TIMER) < 0) { - SAC_RuntimeError( "Failed to init SDL System: %s", SDL_GetError()); - } - - SAC_ND_A_FIELD( disp_nt) = - SDL_SetVideoMode( SAC_ND_A_FIELD( shp_nt)[1], - SAC_ND_A_FIELD( shp_nt)[0], - 32, SDL_SWSURFACE); - - if (SAC_ND_A_FIELD( disp_nt) == NULL) { - SAC_RuntimeError( "Failed to init SDL Display: %s", SDL_GetError()); - } - - SDL_WM_SetCaption( SDL_SAC_DEFAULT_HEADING, NULL); - SDL_ShowCursor( SDL_DISABLE); - - SDLsac_isasync = SAC_ND_A_FIELD( async_nt); - - /* - * a shiny mutex - */ - SDLsac_mutex = SDL_CreateMutex(); - - /* - * semaphore for selection mode - */ - SDLsac_selectsem = SDL_CreateSemaphore( 0); - if (SDLsac_selectsem == NULL) { - SAC_RuntimeError( "Failed to init selection semaphore"); - } - - if( SDLsac_isasync) { -#ifdef UPDATE_VIA_SEMAPHORE - /* - * create a semaphore - */ - SDLsac_updatesem = SDL_CreateSemaphore( 0); - if (SDLsac_updatesem == NULL) { - SAC_RuntimeError( "Failed to init update semaphore"); - } - - /* - * create the update thread - */ - SDLsac_updater = SDL_CreateThread( UpdateScreen, SAC_ND_A_FIELD( disp_nt)); -#endif /* UPDATE_VIA_SEMAPHORE */ - - /* - * register an event handler - */ - SDLsac_eventhandler = SDL_CreateThread( EventHandler, - SAC_ND_A_FIELD( disp_nt)); - - /* - * start a display update timer - */ - SDLsac_timer = SDL_AddTimer( START_UPDATE_INTERVAL, - TimerHandler, - SAC_ND_A_FIELD( disp_nt)); - if ( SDLsac_timer == NULL) { - SAC_RuntimeError( "Failed to init update timer"); - } - } - - * SAC_NAMEP( SAC_ND_A_FIELD( disp_nt)) = SAC_ND_A_FIELD( disp_nt); - - SAC_ND_DEC_RC_FREE( shp_nt, 1, ) -} diff --git a/src/src/SDL2/SDL2data.h b/src/src/SDL2/SDL2data.h deleted file mode 100644 index b8ecaa3..0000000 --- a/src/src/SDL2/SDL2data.h +++ /dev/null @@ -1,91 +0,0 @@ -#ifndef SDL2DATA_H -#define SDL2DATA_H - -/* Macros for min/max from . */ -#define MIN(a,b) (((a)<(b))?(a):(b)) -#define MAX(a,b) (((a)>(b))?(a):(b)) - -/* Absolute difference between two scalars. */ -#define DELTA(a,b) (((a) > (b)) ? ((a) - (b)) : ((b) - (a))) - -/* Restrict scalar 'a' to a range with lower boundary 'b' and upper 'c'. */ -#define LIMIT(a,b,c) ((a) = ((a) < (b)) ? (b) : ((a) > (c)) ? (c) : (a)) - -/* Swap two values. */ -#define SWAP2(type,v1,v2) do{type _ = (v1); (v1) = (v2); (v2) = _;}while(0) - -/* semaphores */ - -#include - -#define SEM_SHARE_THREAD 0 -#define SEM_SHARE_PROC 1 -#define SEM_INIT_LOCKED 0 -#define SEM_INIT_UNLOCKED 1 - -/* Simple DirectMedia Layer */ - -#define BITS_PER_PIXEL 32 -#define BYTES_PER_PIXEL 4 -#define DEFAULT_VID_MOD (SDL_SWSURFACE) -#define RGB(r,g,b) ((Uint32)(r)<<16)|((Uint32)(g)<<8)|((Uint32)(b)) - -/* SDL gives USEREVENT+0 to USEREVENT+7 for users to define: */ -#define SDL2_CREATE_EVENT (SDL_USEREVENT + 1) -#define SDL2_TEARDOWN_EVENT (SDL_USEREVENT + 2) -#define SDL2_UPDATE_EVENT (SDL_USEREVENT + 3) -#define SDL2_UPDATE_ASYNC_EVENT (SDL_USEREVENT + 4) - -/* SDL2 structure */ - -#define SDL2_MAGIC_NUMBER 0x31415926 - -typedef struct SDL2 SDL2; -struct SDL2 { - unsigned int magic; - unsigned int debug; - sem_t* lock; - sem_t* sem; - SDL_Surface* surf; - SDL2* parent; - SDL2* root; - int x; - int y; - int width; - int height; -}; - -#define SDL2_MAGIC(s) ((s)->magic) -#define SDL2_DEBUG(s) ((s)->debug) -#define SDL2_LOCK(s) ((s)->lock) -#define SDL2_SEM(s) ((s)->sem) -#define SDL2_SURF(s) ((s)->surf) -#define SDL2_SURF_WIDTH(s) ((s)->surf->w) -#define SDL2_SURF_HEIGHT(s) ((s)->surf->h) -#define SDL2_PITCH(s) ((s)->surf->pitch) -#define SDL2_PIXELS(s) ((s)->surf->pixels) -#define SDL2_PARENT(s) ((s)->parent) -#define SDL2_ROOT(s) ((s)->root) -#define SDL2_DISP_X(s) ((s)->x) -#define SDL2_DISP_Y(s) ((s)->y) -#define SDL2_DISP_WIDTH(s) ((s)->width) -#define SDL2_DISP_HEIGHT(s) ((s)->height) -#define SDL2_PARENT_X(s) SDL2_DISP_X(SDL2_PARENT(s)) -#define SDL2_PARENT_Y(s) SDL2_DISP_Y(SDL2_PARENT(s)) -#define SDL2_PARENT_WIDTH(s) SDL2_DISP_WIDTH(SDL2_PARENT(s)) -#define SDL2_PARENT_HEIGHT(s) SDL2_DISP_HEIGHT(SDL2_PARENT(s)) - -#define SDL2_CHECK(s) (SDL2_MAGIC(s) == SDL2_MAGIC_NUMBER) -#define SDL2_ISROOT(s) (SDL2_PARENT(s) == NULL) - -/* Window manager frame titles */ - -#define SAC_SDL2_DEFAULT_HEADING "SaC SDL Display" -#define SAC_SDL2_SELECT_HEADING "Click and drag to select an area, " \ - "button-two click to cancel..." - -/* Colors */ -extern Uint32 SAC_SDL2_background_rgb; -extern Uint32 SAC_SDL2_foreground_rgb; - -#endif diff --git a/src/src/SDL2/SDL2proto.h b/src/src/SDL2/SDL2proto.h deleted file mode 100644 index 59a8d94..0000000 --- a/src/src/SDL2/SDL2proto.h +++ /dev/null @@ -1,147 +0,0 @@ -#ifndef SDL2PROTO_H -#define SDL2PROTO_H - -/* close.c */ - - -/* - * Close a display or a sub-window. - */ -void SAC_SDL2_close( SDL2* disp); - -/* color.c */ - -void SAC_SDL2_set_background( const int color[3]); -void SAC_SDL2_get_background( SAC_ND_PARAM_out_nodesc( aks_out_nt, int)); -void SAC_SDL2_set_foreground( const int color[3]); -void SAC_SDL2_get_foreground( SAC_ND_PARAM_out_nodesc( aks_out_nt, int)); -void SAC_SDL2_get_color( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), char* name); - -/* data.c */ - -SDL2* SAC_SDL2_alloc_disp( int width, int height); -SDL2* SAC_SDL2_copy_disp( SDL2* parent, int x, int y, int w, int h); -void SAC_SDL2_free_disp( SDL2* disp); -SDL2* SAC_SDL2_null( void); -int SAC_SDL2_isnull( SDL2* disp); -const char* When( SDL2* disp); - -/* display.c */ - -void SAC_SDL2_enable_fullscreen( int enable); -void SAC_SDL2_enable_noframe( int enable); -void SAC_SDL2_create_display_event( SDL_Event* event); -void SAC_SDL2_display( SDL2** disp_ptr, - SAC_ND_PARAM_in( shp_nt, int)); - -/* draw.c */ - -void SAC_SDL2_draw( SDL2* disp, - SAC_ND_PARAM_in( ar_nt, int)); -void SAC_SDL2_draw2( SDL2* disp, SAC_ND_PARAM_in( ar_nt, int), int offsets[2]); - -/* event.c */ - -void SAC_SDL2_event_loop( SDL2* disp); - -/* extent.c */ - -void SAC_SDL2_extent( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), SDL2* disp); - -/* font.c */ - -void SAC_SDL2_text( SDL2* disp, char* text, int offsets[2], int async); -void SAC_SDL2_text_extent( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), char* text); - -/* init.c */ - -void SAC_SDL2_check( SDL2* disp); -int SAC_SDL2_init( SDL2* disp); -void SAC_SDL2_stop( SDL2* disp); - -/* invert.c */ - -void SAC_SDL2_invert_rect( SDL2* disp, const int *pos, const int update); -void SAC_SDL2_invert2( SDL2* disp, const int offsets[2], const int sizes[2]); - -/* line.c */ - -void SAC_SDL2_line( SDL2* disp, const int P1[2], const int P2[2], int async); -void SAC_SDL2_draw_a_line( SDL2* disp, int x1, int y1, int x2, int y2, - Uint32 rgb, int update, int async); - -/* mouse.c */ - -void SAC_SDL2_start_selection( SDL2* disp); -int SAC_SDL2_get_selection( int *sel); -void SAC_SDL2_mouse_down_event( SDL_Event* event); -void SAC_SDL2_mouse_up_event( SDL_Event* event); -void SAC_SDL2_mouse_motion_event( SDL_Event* event); - -/* names.c */ - -const char* SAC_SDL2_event_name(int evno); - -/* pixel.c */ - -void SAC_SDL2_draw_a_pixel( SDL2* disp, int x, int y, Uint32 rgb); -void SAC_SDL2_pixel( SDL2* disp, SAC_ND_PARAM_in( shp_nt, int), SAC_ND_PARAM_in( color_nt, int)); - -/* rect.c */ - -void SAC_SDL2_draw_rect( SDL2* disp, const int offsets[2], const int sizes[2], - int async); -void SAC_SDL2_fill_rect( SDL2* disp, const int offsets[2], const int sizes[2], - int async); -void SAC_SDL2_fill_disp( SDL2* disp, int async); - -/* resize.c */ - -void SAC_SDL2_resize( SDL2* disp, - SAC_ND_PARAM_in( shp_nt, int)); - -/* select.c */ - -void SAC_SDL2_select( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), SDL2* disp); - -/* sem.c */ - -void SAC_SDL2_sem_init( sem_t *sem); -sem_t* SAC_SDL2_sem_alloc(void); -void SAC_SDL2_sem_free( sem_t* sem); -void SAC_SDL2_sem_post( sem_t* sem); -void SAC_SDL2_sem_wait( sem_t* sem); -void SAC_SDL2_post( SDL2* disp); -void SAC_SDL2_wait( SDL2* disp); -void SAC_SDL2_lock( SDL2* disp); -void SAC_SDL2_unlock( SDL2* disp); - -/* setup.c */ - -int SAC_SDL2_setup( SDL2* disp); -void SAC_SDL2_teardown( SDL2* disp); - -/* title.c */ - -void SAC_SDL2_heading( const char* heading); -void SAC_SDL2_default_heading( void); -void SAC_SDL2_select_heading( void); -void SAC_SDL2_cursor( int enable); - -/* update.c */ - -void SAC_SDL2_update_display_event( SDL_Event* event); - -/* - * Receive coordinates in true surface area. - */ -void SAC_SDL2_update_rect( SDL2* disp, int x, int y, int w, int h, int async); -void SAC_SDL2_update( SDL2* disp, int async); -void SAC_SDL2_update2( SDL2* disp, int offsets[2], int sizes[2], int async); - -/* window.c */ - -SDL2* SAC_SDL2_window( SDL2* disp, int offsets[2], int sizes[2]); - - -#endif diff --git a/src/src/SDL2/SDL2sac.h b/src/src/SDL2/SDL2sac.h deleted file mode 100644 index a984baa..0000000 --- a/src/src/SDL2/SDL2sac.h +++ /dev/null @@ -1,19 +0,0 @@ -#ifndef _SDL2SAC_H_ -#define _SDL2SAC_H_ - -#include "sac.h" -#include "SDL.h" -#include "SDL_thread.h" -#include "SDL2data.h" - -#define disp_nt (disp, T_OLD((SCL, (HID, (NUQ,))))) -#define shp_nt (shp, T_OLD((AKS, (NHD, (NUQ,))))) -#define ar_nt (ar, T_OLD((AKD, (NHD, (NUQ,))))) -#define color_nt (col, T_OLD((AKS, (NHD, (NUQ,))))) -#define async_nt (async, T_OLD((SCL, (NHD, (NUQ,))))) -#define aks_out_nt (aks_out, T_OLD((AKS, (NHD, (NUQ,))))) -#define aks_nt (aks, T_OLD((AKS, (NHD, (NUQ,))))) - -#include "SDL2proto.h" - -#endif diff --git a/src/src/SDL2/close.c b/src/src/SDL2/close.c deleted file mode 100644 index 801417c..0000000 --- a/src/src/SDL2/close.c +++ /dev/null @@ -1,25 +0,0 @@ -#include "SDL2sac.h" - -/* - * Close a display or a sub-window. - */ -void SAC_SDL2_close( SDL2* disp) -{ - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_close: %p\n", When( disp), (void *)disp); - } - - if (SDL2_ISROOT( disp)) { - SAC_SDL2_lock( disp); - SAC_SDL2_stop( disp); - SAC_SDL2_free_disp( disp); - } - else { - SDL2* parent = SDL2_PARENT( disp); - SAC_SDL2_lock( parent); - SAC_SDL2_free_disp( disp); - SAC_SDL2_unlock( parent); - } -} - diff --git a/src/src/SDL2/color.c b/src/src/SDL2/color.c deleted file mode 100644 index 9efb604..0000000 --- a/src/src/SDL2/color.c +++ /dev/null @@ -1,117 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_set_background( const int color[3]) -{ - const unsigned char r = color[0]; - const unsigned char g = color[1]; - const unsigned char b = color[2]; - - SAC_SDL2_background_rgb = RGB( r, g, b); -} - -void SAC_SDL2_get_background( SAC_ND_PARAM_out_nodesc( aks_out_nt, int)) -{ - SAC_ND_DECL__DATA( aks_nt, int, ); - const Uint32 rgb = SAC_SDL2_background_rgb; - - SAC_ND_A_FIELD( aks_nt) = SAC_MALLOC( sizeof( int) * 3); - SAC_ND_A_FIELD( aks_nt)[2] = rgb & 0xFF; - SAC_ND_A_FIELD( aks_nt)[1] = rgb >> 8 & 0xFF; - SAC_ND_A_FIELD( aks_nt)[0] = rgb >> 16 & 0xFF; - - SAC_ND_RET_out__NODESC( aks_out_nt, aks_nt); -} - -void SAC_SDL2_set_foreground( const int color[3]) -{ - const unsigned char r = color[0]; - const unsigned char g = color[1]; - const unsigned char b = color[2]; - - SAC_SDL2_foreground_rgb = RGB( r, g, b); -} - -void SAC_SDL2_get_foreground( SAC_ND_PARAM_out_nodesc( aks_out_nt, int)) -{ - SAC_ND_DECL__DATA( aks_nt, int, ); - const Uint32 rgb = SAC_SDL2_foreground_rgb; - - SAC_ND_A_FIELD( aks_nt) = SAC_MALLOC( sizeof( int) * 3); - SAC_ND_A_FIELD( aks_nt)[2] = rgb & 0xFF; - SAC_ND_A_FIELD( aks_nt)[1] = rgb >> 8 & 0xFF; - SAC_ND_A_FIELD( aks_nt)[0] = rgb >> 16 & 0xFF; - - SAC_ND_RET_out__NODESC( aks_out_nt, aks_nt); -} - -void SAC_SDL2_get_color( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), char* name) -{ - SAC_ND_DECL__DATA( aks_nt, int, ); - unsigned char r = 255; - unsigned char g = 255; - unsigned char b = 255; - size_t namelen = strlen( name); - - if (*name == '#') { - if (namelen == 4) { - unsigned rgb; - if (sscanf( name + 1, "%x", &rgb) == 1) { - r = rgb >> 8 & 0xF; - g = rgb >> 4 & 0xF; - b = rgb >> 0 & 0xF; - r = r * 16 + r; - g = g * 16 + g; - b = b * 16 + b; - } - } - else if (namelen == 7) { - unsigned rgb; - if (sscanf( name + 1, "%x", &rgb) == 1) { - r = rgb >> 16 & 0xFF; - g = rgb >> 8 & 0xFF; - b = rgb >> 0 & 0xFF; - } - } - } - else { - static const char* files[] = { - "/usr/share/X11/rgb.txt", - "/usr/lib/X11/rgb.txt", - "/etc/X11/rgb.txt", - "/usr/X11R6/lib/X11/rgb.txt", - }; - FILE *fp = NULL; - int i; - for (i = 0; i < sizeof files / sizeof(files[0]); ++i) { - if ((fp = fopen( files[i], "r")) != NULL) { - break; - } - } - if (fp != NULL) { - char buf[128]; - char str[128]; - while (fgets( buf, sizeof buf, fp)) { - unsigned u, v, w; - if (sscanf( buf, " %u %u %u %[0-9A-Za-z ]", &u, &v, &w, str) == 4) { - if ( ! strcmp( name, str)) { - r = u; - g = v; - b = w; - break; - } - } - } - fclose( fp); - } - } - - // printf("r = %d, g = %d, b = %d\n", r, g, b); - - SAC_ND_A_FIELD( aks_nt) = SAC_MALLOC( sizeof( int) * 3); - SAC_ND_A_FIELD( aks_nt)[0] = r; - SAC_ND_A_FIELD( aks_nt)[1] = g; - SAC_ND_A_FIELD( aks_nt)[2] = b; - - SAC_ND_RET_out__NODESC( aks_out_nt, aks_nt); -} - diff --git a/src/src/SDL2/data.c b/src/src/SDL2/data.c deleted file mode 100644 index 1c64ca4..0000000 --- a/src/src/SDL2/data.c +++ /dev/null @@ -1,98 +0,0 @@ -#include "SDL2sac.h" - -Uint32 SAC_SDL2_background_rgb = RGB( 0, 0, 0); -Uint32 SAC_SDL2_foreground_rgb = RGB( 255, 255, 255); - -static int get_debug_level(void) -{ - const char* p = getenv("SDL2_DEBUG"); - unsigned level = 0; - - if (p && *p && sscanf(p, " %u", &level) <= 0) { - level = 1; - } - return (int) level; -} - -SDL2* SAC_SDL2_alloc_disp( int width, int height) -{ - SDL2* disp; - - disp = (SDL2 *) SAC_MALLOC( sizeof( *disp)); - SDL2_DEBUG( disp) = get_debug_level(); - SDL2_SURF( disp) = NULL; - SDL2_LOCK( disp) = SAC_SDL2_sem_alloc(); - SDL2_SEM( disp) = SAC_SDL2_sem_alloc(); - SDL2_PARENT( disp) = NULL; - SDL2_ROOT( disp) = disp; - SDL2_DISP_X( disp) = 0; - SDL2_DISP_Y( disp) = 0; - SDL2_DISP_WIDTH( disp) = width; - SDL2_DISP_HEIGHT( disp) = height; - - SDL2_MAGIC( disp) = SDL2_MAGIC_NUMBER; - - return disp; -} - -SDL2* SAC_SDL2_copy_disp( SDL2* parent, int x, int y, int w, int h) -{ - SDL2* disp; - - disp = (SDL2 *) SAC_MALLOC( sizeof( *disp)); - SDL2_DEBUG( disp) = SDL2_DEBUG( parent); - SDL2_SURF( disp) = SDL2_SURF( parent); - SDL2_LOCK( disp) = SDL2_LOCK( parent); - SDL2_SEM( disp) = SDL2_SEM( parent); - SDL2_PARENT( disp) = parent; - SDL2_ROOT( disp) = SDL2_ROOT( parent); - SDL2_DISP_X( disp) = SDL2_DISP_X( parent) + x; - SDL2_DISP_Y( disp) = SDL2_DISP_Y( parent) + y; - SDL2_DISP_WIDTH( disp) = w; - SDL2_DISP_HEIGHT( disp) = h; - - SDL2_MAGIC( disp) = SDL2_MAGIC( parent); - - return disp; -} - -void SAC_SDL2_free_disp( SDL2* disp) -{ - SDL2_MAGIC( disp) = 0; - SDL2_SURF( disp) = NULL; - - if (SDL2_ISROOT( disp)) { - SAC_SDL2_sem_free( SDL2_LOCK( disp)); - SDL2_LOCK( disp) = NULL; - - SAC_SDL2_sem_free( SDL2_SEM( disp)); - SDL2_SEM( disp) = NULL; - } - - free( disp); -} - -SDL2* SAC_SDL2_null( void) -{ - return NULL; -} - -int SAC_SDL2_isnull( SDL2* disp) -{ - return disp == NULL; -} - -const char* When( SDL2* disp) -{ - static char buf[30]; - Uint32 ticks = SDL_GetTicks(); - - if (ticks < 1000*1000) { - snprintf(buf, sizeof buf, "%3u.%03u: ", ticks / 1000, ticks % 1000); - } else { - strcpy(buf, " "); - } - - return buf; -} - diff --git a/src/src/SDL2/display.c b/src/src/SDL2/display.c deleted file mode 100644 index 594d425..0000000 --- a/src/src/SDL2/display.c +++ /dev/null @@ -1,78 +0,0 @@ -#include "SDL2sac.h" - -static Uint32 SAC_SDL2_fullscreen_flag; -static Uint32 SAC_SDL2_noframe_flag; - -void SAC_SDL2_enable_fullscreen( int enable) -{ - SAC_SDL2_fullscreen_flag = enable ? SDL_FULLSCREEN : 0; -} - -void SAC_SDL2_enable_noframe( int enable) -{ - SAC_SDL2_noframe_flag = enable ? SDL_NOFRAME : 0; -} - -void SAC_SDL2_create_display_event( SDL_Event* event) -{ - SDL_Rect* rect = (SDL_Rect *) event->user.data1; - SDL2* disp = (SDL2 *) event->user.data2; - Uint32 flags = DEFAULT_VID_MOD | SAC_SDL2_fullscreen_flag | - SAC_SDL2_noframe_flag; - - SDL2_SURF( disp) = SDL_SetVideoMode( rect->w, rect->h, BITS_PER_PIXEL, flags); - if ( SDL2_SURF( disp) == NULL) { - SAC_RuntimeError( "SAC_SDL2_display: failed SDL_SetVideoMode: %s", - SDL_GetError()); - } - else { - SAC_SDL2_default_heading(); - SAC_SDL2_cursor( 0); - } - - SAC_SDL2_post( disp); -} - -void SAC_SDL2_display( SDL2** disp_ptr, - SAC_ND_PARAM_in( shp_nt, int)) -{ - const int width = SAC_ND_A_FIELD( shp_nt)[1]; - const int height = SAC_ND_A_FIELD( shp_nt)[0]; - SDL_Event event; - SDL_Rect rect; - SDL2* disp = NULL; - - if (getenv("SDL2_DEBUG")) { - printf("%sSAC_SDL2_display: w=%d, h=%d\n", When( disp), width, height); - } - - if ( width < 0 || width > SHRT_MAX || height < 0 || height > SHRT_MAX) - { - SAC_RuntimeError( "SAC_SDL2_display: invalid dimensions: [%d,%d]\n", - width, height); - } - else { - disp = SAC_SDL2_alloc_disp( width, height); - if ( SAC_SDL2_init( disp) == 0) { - event.type = SDL2_CREATE_EVENT; - rect.w = width; - rect.h = height; - event.user.data1 = ▭ - event.user.data2 = disp; - SDL_PushEvent( &event); - SAC_SDL2_wait( disp); - SDL2_DISP_WIDTH( disp) = SDL2_SURF_WIDTH( disp); - SDL2_DISP_HEIGHT( disp) = SDL2_SURF_HEIGHT( disp); - SAC_SDL2_unlock( disp); - } - else { - SAC_SDL2_free_disp( disp); - disp = NULL; - } - } - - *disp_ptr = disp; - - SAC_ND_DEC_RC_FREE( shp_nt, 1, ) -} - diff --git a/src/src/SDL2/draw.c b/src/src/SDL2/draw.c deleted file mode 100644 index 7352554..0000000 --- a/src/src/SDL2/draw.c +++ /dev/null @@ -1,106 +0,0 @@ -#include "SDL2sac.h" - -static void copy_rect( SDL2* disp, const int* color, - const int xoffset, const int yoffset, - const int width, const int height) -{ - const int pitch = SDL2_PITCH( disp) / BYTES_PER_PIXEL; - Uint32* videomem = (Uint32 *) SDL2_PIXELS( disp); - int x, y; - - for (y = 0; y < height; ++y) { - Uint32* dest = videomem + xoffset + ((y + yoffset) * pitch); - const int* src = color + (y * width * 3); - - for (x = 0; x < width; ++x) { - const unsigned char r = *src++; - const unsigned char g = *src++; - const unsigned char b = *src++; - *dest++ = RGB(r,g,b); - } - } -} - -void SAC_SDL2_draw( SDL2* disp, - SAC_ND_PARAM_in( ar_nt, int)) -{ - const int width = SAC_ND_A_DESC_SHAPE( ar_nt, 1); - const int height = SAC_ND_A_DESC_SHAPE( ar_nt, 0); - int* color = SAC_ND_A_FIELD( ar_nt); - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_draw %d,%d\n", When( disp), width, height); - } - - SAC_SDL2_lock( disp); - - if ( width != SDL2_DISP_WIDTH( disp) || - height != SDL2_DISP_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_draw: Array [%d,%d] != display [%d,%d]\n", - width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else { - copy_rect( disp, color, - SDL2_DISP_X( disp), SDL2_DISP_Y( disp), - width, height); - SAC_SDL2_update_rect( disp, - SDL2_DISP_X( disp), SDL2_DISP_Y( disp), - width, height, - false); - } - - SAC_SDL2_unlock( disp); - - SAC_ND_DEC_RC_FREE( ar_nt, 1, ) -} - -void SAC_SDL2_draw2( SDL2* disp, SAC_ND_PARAM_in( ar_nt, int), int offsets[2]) -{ - int* color = SAC_ND_A_FIELD( ar_nt); - const int width = SAC_ND_A_DESC_SHAPE( ar_nt, 1); - const int height = SAC_ND_A_DESC_SHAPE( ar_nt, 0); - const int xoffset = offsets[1]; - const int yoffset = offsets[0]; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_draw2 [%d,%d]:[%d,%d] on [%d,%d]\n", - When( disp), - xoffset, yoffset, - width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - - SAC_SDL2_lock( disp); - - if ( xoffset < 0 || yoffset < 0 || - width < 0 || height < 0 || - xoffset + width > SDL2_DISP_WIDTH( disp) || - yoffset + height > SDL2_DISP_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_draw2: Offset [%d,%d] + array [%d,%d] " - "exceeds display [%d,%d]\n", - xoffset, yoffset, - width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else { - copy_rect( disp, color, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset, - width, height); - SAC_SDL2_update_rect( disp, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset, - width, height, - false); - } - - SAC_SDL2_unlock( disp); - - SAC_ND_DEC_RC_FREE( ar_nt, 1, ) -} - diff --git a/src/src/SDL2/event.c b/src/src/SDL2/event.c deleted file mode 100644 index cd94a46..0000000 --- a/src/src/SDL2/event.c +++ /dev/null @@ -1,87 +0,0 @@ -#include "SDL2sac.h" - -static int do_event( SDL_Event* event, SDL2* disp) -{ - int done = 0; - - if (event->type != SDL_MOUSEMOTION && - event->type != SDL_ACTIVEEVENT) - { - if (SDL2_DEBUG( disp)) { - printf("%sSDL2 got event: %s\n", When( NULL), - SAC_SDL2_event_name( event->type)); - } - } - switch (event->type) { - case SDL_ACTIVEEVENT: - if (SDL2_DEBUG( disp)) { - printf("%sSDL2 active event: %s, %s\n", When( NULL), - event->active.gain ? "gain" : "loss", - event->active.state == SDL_APPMOUSEFOCUS ? "mouse " : - event->active.state == SDL_APPINPUTFOCUS ? "input " : - event->active.state == SDL_APPACTIVE ? "active" : - "unknown"); - } - break; - - case SDL_QUIT: - SDL_Quit(); - exit(0); - break; - - case SDL_KEYDOWN: - break; - - case SDL_KEYUP: - break; - - case SDL_VIDEORESIZE: - break; - - case SDL_MOUSEBUTTONDOWN: - SAC_SDL2_mouse_down_event( event); - break; - - case SDL_MOUSEBUTTONUP: - SAC_SDL2_mouse_up_event( event); - break; - - case SDL_MOUSEMOTION: - SAC_SDL2_mouse_motion_event( event); - break; - - case SDL_VIDEOEXPOSE: - break; - - case SDL2_CREATE_EVENT: - SAC_SDL2_create_display_event( event); - break; - - case SDL2_TEARDOWN_EVENT: - done = 1; - break; - - case SDL2_UPDATE_EVENT: - case SDL2_UPDATE_ASYNC_EVENT: - SAC_SDL2_update_display_event( event); - break; - - default: - SAC_RuntimeError( "SDL2_event_loop: unknown event no %d\n", event->type); - } - - return done; -} - -void SAC_SDL2_event_loop( SDL2* disp) -{ - SDL_Event event; - int done = 0; - - while ( ! done) { - if (SDL_WaitEvent( &event) == 1) { - done = do_event( &event, disp); - } - } -} - diff --git a/src/src/SDL2/extent.c b/src/src/SDL2/extent.c deleted file mode 100644 index fcfce1f..0000000 --- a/src/src/SDL2/extent.c +++ /dev/null @@ -1,21 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_extent( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), SDL2* disp) -{ - SAC_ND_DECL__DATA( aks_nt, int, ); - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_extent: %p\n", When( disp), (void *)disp); - } - - /* - * create result and write back with [Y,X] as result - */ - SAC_ND_A_FIELD( aks_nt) = SAC_MALLOC( sizeof( int) * 2); - SAC_ND_A_FIELD( aks_nt)[1] = SDL2_DISP_WIDTH( disp); - SAC_ND_A_FIELD( aks_nt)[0] = SDL2_DISP_HEIGHT( disp); - - SAC_ND_RET_out__NODESC( aks_out_nt, aks_nt); -} - diff --git a/src/src/SDL2/font.c b/src/src/SDL2/font.c deleted file mode 100644 index 2f331ed..0000000 --- a/src/src/SDL2/font.c +++ /dev/null @@ -1,125 +0,0 @@ -#include "SDL2sac.h" -#include "fontstruct.h" -#include "fontdata.h" - -void SAC_SDL2_text( SDL2* disp, char* text, int offsets[2], int async) -{ - const int xoffset = offsets[1]; - const int yoffset = offsets[0]; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_text: '%s' on [%d,%d]:[%d,%d]\n", - When( disp), text, xoffset, yoffset, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - - SAC_SDL2_lock( disp); - - if ( xoffset < 0 || yoffset < 0 || - xoffset >= SDL2_DISP_WIDTH( disp) || - yoffset >= SDL2_DISP_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_text: Offset [%d,%d] exceeds display [%d,%d]\n", - xoffset, yoffset, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else { - const int xdisp = SDL2_DISP_X( disp); - const int ydisp = SDL2_DISP_Y( disp); - const int xend = SDL2_DISP_X( disp) + SDL2_DISP_WIDTH( disp); - const int yend = SDL2_DISP_Y( disp) + SDL2_DISP_HEIGHT( disp); - const int rgb = SAC_SDL2_foreground_rgb; - int x = xdisp + xoffset; - int y = ydisp + yoffset; - int xmin = x; - int xmax = x; - int ymin = y - font.ascent; - int ymax = y + font.descent; - int i; - for (i = 0; text[i]; ++i) { - unsigned char c = text[i]; - if (c == '\n') { - x = xdisp + xoffset; - y += font.ascent + font.descent; - ymax = y + font.descent; - } - else if (c == '\r') { - x = xdisp + xoffset; - } - else if (c == '\t') { - if (' ' >= font.first && c <= font.last) { - const int tab = 8 * font.chars[' ' - font.first].width; - x += tab; - x -= (x - xdisp - xoffset) % tab; - } - } - else if (c >= font.first && c <= font.last) { - const struct fontchar *f = &font.chars[c - font.first]; - int bit = f->firstbit; - int bear, row; - for (row = f->ascent; row > -f->descent; --row) { - for (bear = f->lbearing; bear < f->rbearing; ++bear) { - if (getbit( fontbits, bit)) { - if (x >= xdisp && x < xend && y >= ydisp && y < yend) { - SAC_SDL2_draw_a_pixel( disp, x + bear, y - row, rgb); - } - } - ++bit; - } - } - x += f->width; - if (xmax < x) { - xmax = x; - } - } - } - LIMIT(xmax, xdisp, xend - 1); - LIMIT(ymax, ydisp, yend - 1); - SAC_SDL2_update_rect( disp, xmin, ymin, xmax - xmin, ymax - ymin, async); - } - - SAC_SDL2_unlock( disp); -} - -void SAC_SDL2_text_extent( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), char* text) -{ - SAC_ND_DECL__DATA( aks_nt, int, ); - - int x = 0; - int xmax = x; - int ymin = -font.ascent; - int ymax = font.descent; - int i; - for (i = 0; text[i]; ++i) { - const unsigned char c = text[i]; - if (c == '\n') { - x = 0; - ymax += font.ascent + font.descent; - } - else if (c == '\r') { - x = 0; - } - else if (c == '\t') { - if (' ' >= font.first && c <= font.last) { - const int tab = 8 * font.chars[' ' - font.first].width; - x += tab - x % tab; - } - } - else if (c >= font.first && c <= font.last) { - x += font.chars[c - font.first].width; - if (xmax < x) { - xmax = x; - } - } - } - - SAC_ND_A_FIELD( aks_nt) = SAC_MALLOC( sizeof( int) * 4); - SAC_ND_A_FIELD( aks_nt)[1] = 0; - SAC_ND_A_FIELD( aks_nt)[3] = xmax; - SAC_ND_A_FIELD( aks_nt)[0] = ymin; - SAC_ND_A_FIELD( aks_nt)[2] = ymax; - - SAC_ND_RET_out__NODESC( aks_out_nt, aks_nt); -} - diff --git a/src/src/SDL2/fontdata.h b/src/src/SDL2/fontdata.h deleted file mode 100644 index f603d7c..0000000 --- a/src/src/SDL2/fontdata.h +++ /dev/null @@ -1,369 +0,0 @@ -#ifndef SAC_SDL2_FONT_DATA_H -#define SAC_SDL2_FONT_DATA_H - -static struct fontchar fontchars[256] = { - { 11, 13, 0, 1, 10, 117, 0 }, /* 0 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 1 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 2 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 3 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 4 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 5 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 6 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 7 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 8 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 9 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 10 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 11 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 12 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 13 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 14 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 15 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 16 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 17 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 18 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 19 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 20 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 21 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 22 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 23 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 24 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 25 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 26 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 27 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 28 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 29 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 30 : ' ' */ - { 0, 0, 0, 0, 0, 0, 117 }, /* 31 : ' ' */ - { 11, 1, 0, 0, 1, 1, 117 }, /* 32 : ' ' */ - { 11, 13, 0, 5, 7, 26, 118 }, /* 33 : '!' */ - { 11, 14, -10, 3, 9, 24, 144 }, /* 34 : '"' */ - { 11, 13, 0, 0, 11, 143, 168 }, /* 35 : '#' */ - { 11, 14, 1, 2, 10, 120, 311 }, /* 36 : '$' */ - { 11, 13, 0, 0, 11, 143, 431 }, /* 37 : '%' */ - { 11, 13, 0, 0, 11, 143, 574 }, /* 38 : '&' */ - { 11, 14, -10, 4, 6, 8, 717 }, /* 39 : ''' */ - { 11, 14, 2, 3, 10, 112, 725 }, /* 40 : '(' */ - { 11, 14, 2, 1, 8, 112, 837 }, /* 41 : ')' */ - { 11, 14, -7, 2, 9, 49, 949 }, /* 42 : '*' */ - { 11, 10, -1, 1, 10, 81, 998 }, /* 43 : '+' */ - { 11, 3, 2, 4, 7, 15, 1079 }, /* 44 : ',' */ - { 11, 6, -5, 1, 10, 9, 1094 }, /* 45 : '-' */ - { 11, 3, 0, 4, 7, 9, 1103 }, /* 46 : '.' */ - { 11, 14, 2, 1, 10, 144, 1112 }, /* 47 : '/' */ - { 11, 13, 0, 1, 10, 117, 1256 }, /* 48 : '0' */ - { 11, 13, 0, 2, 7, 65, 1373 }, /* 49 : '1' */ - { 11, 13, 0, 1, 9, 104, 1438 }, /* 50 : '2' */ - { 11, 13, 0, 1, 9, 104, 1542 }, /* 51 : '3' */ - { 11, 13, 0, 1, 11, 130, 1646 }, /* 52 : '4' */ - { 11, 13, 0, 2, 10, 104, 1776 }, /* 53 : '5' */ - { 11, 13, 0, 1, 10, 117, 1880 }, /* 54 : '6' */ - { 11, 13, 0, 1, 10, 117, 1997 }, /* 55 : '7' */ - { 11, 13, 0, 1, 10, 117, 2114 }, /* 56 : '8' */ - { 11, 13, 0, 1, 10, 117, 2231 }, /* 57 : '9' */ - { 11, 10, 0, 4, 7, 30, 2348 }, /* 58 : ':' */ - { 11, 10, 2, 4, 7, 36, 2378 }, /* 59 : ';' */ - { 11, 10, -1, 0, 10, 90, 2414 }, /* 60 : '<' */ - { 11, 7, -3, 1, 10, 36, 2504 }, /* 61 : '=' */ - { 11, 10, -1, 1, 11, 90, 2540 }, /* 62 : '>' */ - { 11, 13, 0, 1, 9, 104, 2630 }, /* 63 : '?' */ - { 11, 13, 0, 1, 11, 130, 2734 }, /* 64 : '@' */ - { 11, 13, 0, 1, 11, 130, 2864 }, /* 65 : 'A' */ - { 11, 13, 0, 2, 10, 104, 2994 }, /* 66 : 'B' */ - { 11, 13, 0, 1, 10, 117, 3098 }, /* 67 : 'C' */ - { 11, 13, 0, 1, 10, 117, 3215 }, /* 68 : 'D' */ - { 11, 13, 0, 2, 10, 104, 3332 }, /* 69 : 'E' */ - { 11, 13, 0, 2, 10, 104, 3436 }, /* 70 : 'F' */ - { 11, 13, 0, 1, 10, 117, 3540 }, /* 71 : 'G' */ - { 11, 13, 0, 1, 10, 117, 3657 }, /* 72 : 'H' */ - { 11, 13, 0, 2, 10, 104, 3774 }, /* 73 : 'I' */ - { 11, 13, 0, 2, 9, 91, 3878 }, /* 74 : 'J' */ - { 11, 13, 0, 1, 11, 130, 3969 }, /* 75 : 'K' */ - { 11, 13, 0, 2, 10, 104, 4099 }, /* 76 : 'L' */ - { 11, 13, 0, 1, 11, 130, 4203 }, /* 77 : 'M' */ - { 11, 13, 0, 1, 10, 117, 4333 }, /* 78 : 'N' */ - { 11, 13, 0, 1, 11, 130, 4450 }, /* 79 : 'O' */ - { 11, 13, 0, 2, 10, 104, 4580 }, /* 80 : 'P' */ - { 11, 13, 3, 1, 11, 160, 4684 }, /* 81 : 'Q' */ - { 11, 13, 0, 2, 10, 104, 4844 }, /* 82 : 'R' */ - { 11, 13, 0, 2, 10, 104, 4948 }, /* 83 : 'S' */ - { 11, 13, 0, 1, 11, 130, 5052 }, /* 84 : 'T' */ - { 11, 13, 0, 1, 10, 117, 5182 }, /* 85 : 'U' */ - { 11, 13, 0, 1, 11, 130, 5299 }, /* 86 : 'V' */ - { 11, 13, 0, 0, 11, 143, 5429 }, /* 87 : 'W' */ - { 11, 13, 0, 1, 10, 117, 5572 }, /* 88 : 'X' */ - { 11, 13, 0, 1, 11, 130, 5689 }, /* 89 : 'Y' */ - { 11, 13, 0, 1, 10, 117, 5819 }, /* 90 : 'Z' */ - { 11, 14, 2, 3, 9, 96, 5936 }, /* 91 : '[' */ - { 11, 14, 2, 1, 10, 144, 6032 }, /* 92 : '\' */ - { 11, 14, 2, 2, 8, 96, 6176 }, /* 93 : ']' */ - { 11, 12, -2, 1, 10, 90, 6272 }, /* 94 : '^' */ - { 11, 0, 1, 0, 11, 11, 6362 }, /* 95 : '_' */ - { 11, 13, -11, 3, 7, 8, 6373 }, /* 96 : '`' */ - { 11, 10, 0, 1, 10, 90, 6381 }, /* 97 : 'a' */ - { 11, 14, 0, 1, 10, 126, 6471 }, /* 98 : 'b' */ - { 11, 10, 0, 1, 10, 90, 6597 }, /* 99 : 'c' */ - { 11, 14, 0, 1, 10, 126, 6687 }, /* 100 : 'd' */ - { 11, 10, 0, 1, 10, 90, 6813 }, /* 101 : 'e' */ - { 11, 14, 0, 1, 10, 126, 6903 }, /* 102 : 'f' */ - { 11, 10, 3, 1, 10, 117, 7029 }, /* 103 : 'g' */ - { 11, 14, 0, 2, 10, 112, 7146 }, /* 104 : 'h' */ - { 11, 14, 0, 2, 7, 70, 7258 }, /* 105 : 'i' */ - { 11, 14, 3, 1, 8, 119, 7328 }, /* 106 : 'j' */ - { 11, 14, 0, 2, 11, 126, 7447 }, /* 107 : 'k' */ - { 11, 14, 0, 2, 7, 70, 7573 }, /* 108 : 'l' */ - { 11, 10, 0, 1, 11, 100, 7643 }, /* 109 : 'm' */ - { 11, 10, 0, 2, 10, 80, 7743 }, /* 110 : 'n' */ - { 11, 10, 0, 1, 10, 90, 7823 }, /* 111 : 'o' */ - { 11, 10, 3, 1, 10, 117, 7913 }, /* 112 : 'p' */ - { 11, 10, 3, 1, 10, 117, 8030 }, /* 113 : 'q' */ - { 11, 10, 0, 3, 10, 70, 8147 }, /* 114 : 'r' */ - { 11, 10, 0, 2, 9, 70, 8217 }, /* 115 : 's' */ - { 11, 12, 0, 1, 10, 108, 8287 }, /* 116 : 't' */ - { 11, 10, 0, 1, 9, 80, 8395 }, /* 117 : 'u' */ - { 11, 10, 0, 2, 10, 80, 8475 }, /* 118 : 'v' */ - { 11, 10, 0, 1, 11, 100, 8555 }, /* 119 : 'w' */ - { 11, 10, 0, 2, 10, 80, 8655 }, /* 120 : 'x' */ - { 11, 10, 3, 2, 10, 104, 8735 }, /* 121 : 'y' */ - { 11, 10, 0, 2, 10, 80, 8839 }, /* 122 : 'z' */ - { 11, 14, 2, 2, 10, 128, 8919 }, /* 123 : '{' */ - { 11, 14, 2, 5, 7, 32, 9047 }, /* 124 : '|' */ - { 11, 14, 2, 1, 9, 128, 9079 }, /* 125 : '}' */ - { 11, 7, -4, 1, 10, 27, 9207 }, /* 126 : '~' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 127 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 128 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 129 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 130 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 131 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 132 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 133 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 134 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 135 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 136 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 137 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 138 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 139 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 140 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 141 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 142 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 143 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 144 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 145 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 146 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 147 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 148 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 149 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 150 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 151 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 152 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 153 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 154 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 155 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 156 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 157 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 158 : ' ' */ - { 0, 0, 0, 0, 0, 0, 9234 }, /* 159 : ' ' */ - { 11, 1, 0, 0, 1, 1, 9234 }, /* 160 : ' ' */ - { 11, 10, 3, 5, 7, 26, 9235 }, /* 161 : '¡' */ - { 11, 13, 1, 2, 10, 112, 9261 }, /* 162 : '¢' */ - { 11, 13, 0, 2, 10, 104, 9373 }, /* 163 : '£' */ - { 11, 13, 0, -1, 10, 143, 9477 }, /* 164 : '¤' */ - { 11, 13, 0, 1, 11, 130, 9620 }, /* 165 : '¥' */ - { 11, 16, 0, 2, 10, 128, 9750 }, /* 166 : '¦' */ - { 11, 13, 2, 2, 10, 120, 9878 }, /* 167 : '§' */ - { 11, 13, 0, 2, 9, 91, 9998 }, /* 168 : '¨' */ - { 11, 13, 0, 1, 10, 117, 10089 }, /* 169 : '©' */ - { 11, 13, -5, 2, 10, 64, 10206 }, /* 170 : 'ª' */ - { 11, 9, -1, 1, 10, 72, 10270 }, /* 171 : '«' */ - { 11, 7, -3, 1, 10, 36, 10342 }, /* 172 : '¬' */ - { 11, 6, -5, 3, 8, 5, 10378 }, /* 173 : '­' */ - { 11, 13, -5, 2, 10, 64, 10383 }, /* 174 : '®' */ - { 11, 13, -12, 4, 7, 3, 10447 }, /* 175 : '¯' */ - { 11, 14, -9, 3, 8, 25, 10450 }, /* 176 : '°' */ - { 11, 10, -2, 1, 10, 72, 10475 }, /* 177 : '±' */ - { 11, 13, -5, 2, 9, 56, 10547 }, /* 178 : '²' */ - { 11, 13, -5, 2, 9, 56, 10603 }, /* 179 : '³' */ - { 11, 16, 0, 1, 10, 144, 10659 }, /* 180 : '´' */ - { 11, 10, 3, 2, 10, 104, 10803 }, /* 181 : 'µ' */ - { 11, 13, 2, 1, 9, 120, 10907 }, /* 182 : '¶' */ - { 11, 7, -4, 4, 7, 9, 11027 }, /* 183 : '·' */ - { 11, 13, 0, 2, 10, 104, 11036 }, /* 184 : '¸' */ - { 11, 13, -5, 2, 8, 48, 11140 }, /* 185 : '¹' */ - { 11, 13, -5, 1, 10, 72, 11188 }, /* 186 : 'º' */ - { 11, 9, -1, 1, 10, 72, 11260 }, /* 187 : '»' */ - { 11, 13, 0, 1, 11, 130, 11332 }, /* 188 : '¼' */ - { 11, 10, 0, 0, 11, 110, 11462 }, /* 189 : '½' */ - { 11, 16, 0, 1, 11, 160, 11572 }, /* 190 : '¾' */ - { 11, 10, 3, 2, 10, 104, 11732 }, /* 191 : '¿' */ - { 11, 16, 0, 1, 11, 160, 11836 }, /* 192 : 'À' */ - { 11, 16, 0, 1, 11, 160, 11996 }, /* 193 : 'Á' */ - { 11, 16, 0, 1, 11, 160, 12156 }, /* 194 : 'Â' */ - { 11, 16, 0, 1, 11, 160, 12316 }, /* 195 : 'Ã' */ - { 11, 16, 0, 1, 11, 160, 12476 }, /* 196 : 'Ä' */ - { 11, 15, 0, 1, 11, 150, 12636 }, /* 197 : 'Å' */ - { 11, 13, 0, 1, 11, 130, 12786 }, /* 198 : 'Æ' */ - { 11, 13, 3, 1, 10, 144, 12916 }, /* 199 : 'Ç' */ - { 11, 16, 0, 2, 10, 128, 13060 }, /* 200 : 'È' */ - { 11, 16, 0, 2, 10, 128, 13188 }, /* 201 : 'É' */ - { 11, 16, 0, 2, 10, 128, 13316 }, /* 202 : 'Ê' */ - { 11, 16, 0, 2, 10, 128, 13444 }, /* 203 : 'Ë' */ - { 11, 16, 0, 2, 10, 128, 13572 }, /* 204 : 'Ì' */ - { 11, 16, 0, 2, 10, 128, 13700 }, /* 205 : 'Í' */ - { 11, 16, 0, 2, 10, 128, 13828 }, /* 206 : 'Î' */ - { 11, 16, 0, 2, 10, 128, 13956 }, /* 207 : 'Ï' */ - { 11, 13, 0, 0, 10, 130, 14084 }, /* 208 : 'Ð' */ - { 11, 16, 0, 1, 10, 144, 14214 }, /* 209 : 'Ñ' */ - { 11, 16, 0, 1, 11, 160, 14358 }, /* 210 : 'Ò' */ - { 11, 16, 0, 1, 11, 160, 14518 }, /* 211 : 'Ó' */ - { 11, 16, 0, 1, 11, 160, 14678 }, /* 212 : 'Ô' */ - { 11, 16, 0, 1, 11, 160, 14838 }, /* 213 : 'Õ' */ - { 11, 16, 0, 1, 11, 160, 14998 }, /* 214 : 'Ö' */ - { 11, 9, -2, 2, 9, 49, 15158 }, /* 215 : '×' */ - { 11, 13, 0, 1, 11, 130, 15207 }, /* 216 : 'Ø' */ - { 11, 16, 0, 1, 10, 144, 15337 }, /* 217 : 'Ù' */ - { 11, 16, 0, 1, 10, 144, 15481 }, /* 218 : 'Ú' */ - { 11, 16, 0, 1, 10, 144, 15625 }, /* 219 : 'Û' */ - { 11, 16, 0, 1, 10, 144, 15769 }, /* 220 : 'Ü' */ - { 11, 16, 0, 1, 11, 160, 15913 }, /* 221 : 'Ý' */ - { 11, 13, 0, 2, 10, 104, 16073 }, /* 222 : 'Þ' */ - { 11, 14, 0, 1, 10, 126, 16177 }, /* 223 : 'ß' */ - { 11, 13, 0, 1, 10, 117, 16303 }, /* 224 : 'à' */ - { 11, 13, 0, 1, 10, 117, 16420 }, /* 225 : 'á' */ - { 11, 13, 0, 1, 10, 117, 16537 }, /* 226 : 'â' */ - { 11, 13, 0, 1, 10, 117, 16654 }, /* 227 : 'ã' */ - { 11, 13, 0, 1, 10, 117, 16771 }, /* 228 : 'ä' */ - { 11, 13, 0, 1, 10, 117, 16888 }, /* 229 : 'å' */ - { 11, 10, 0, 1, 11, 100, 17005 }, /* 230 : 'æ' */ - { 11, 10, 3, 1, 10, 117, 17105 }, /* 231 : 'ç' */ - { 11, 13, 0, 1, 10, 117, 17222 }, /* 232 : 'è' */ - { 11, 13, 0, 1, 10, 117, 17339 }, /* 233 : 'é' */ - { 11, 13, 0, 1, 10, 117, 17456 }, /* 234 : 'ê' */ - { 11, 13, 0, 1, 10, 117, 17573 }, /* 235 : 'ë' */ - { 11, 13, 0, 2, 7, 65, 17690 }, /* 236 : 'ì' */ - { 11, 13, 0, 2, 8, 78, 17755 }, /* 237 : 'í' */ - { 11, 13, 0, 2, 8, 78, 17833 }, /* 238 : 'î' */ - { 11, 13, 0, 1, 7, 78, 17911 }, /* 239 : 'ï' */ - { 11, 14, 0, 1, 10, 126, 17989 }, /* 240 : 'ð' */ - { 11, 13, 0, 2, 10, 104, 18115 }, /* 241 : 'ñ' */ - { 11, 13, 0, 1, 10, 117, 18219 }, /* 242 : 'ò' */ - { 11, 13, 0, 1, 10, 117, 18336 }, /* 243 : 'ó' */ - { 11, 13, 0, 1, 10, 117, 18453 }, /* 244 : 'ô' */ - { 11, 13, 0, 1, 10, 117, 18570 }, /* 245 : 'õ' */ - { 11, 13, 0, 1, 10, 117, 18687 }, /* 246 : 'ö' */ - { 11, 10, -1, 1, 10, 81, 18804 }, /* 247 : '÷' */ - { 11, 10, 0, 1, 10, 90, 18885 }, /* 248 : 'ø' */ - { 11, 13, 0, 1, 9, 104, 18975 }, /* 249 : 'ù' */ - { 11, 13, 0, 1, 9, 104, 19079 }, /* 250 : 'ú' */ - { 11, 13, 0, 1, 9, 104, 19183 }, /* 251 : 'û' */ - { 11, 13, 0, 1, 9, 104, 19287 }, /* 252 : 'ü' */ - { 11, 13, 3, 2, 10, 128, 19391 }, /* 253 : 'ý' */ - { 11, 13, 3, 1, 10, 144, 19519 }, /* 254 : 'þ' */ - { 11, 13, 3, 2, 10, 128, 19663 }, /* 255 : 'ÿ' */ -}; -static struct font font = { 16, 3, 0, 255, fontchars }; -static unsigned int fontbits[619] = { - 0x04040155, 0x40401010, 0x04010100, 0xffd55004, 0x3cf3f0bf, 0x19833047, - 0x7fe220cc, 0x19833044, 0x198223ff, 0x080660cc, 0x8989e93e, 0x3c1e0f0b, - 0x25e46474, 0x6c07041f, 0x89114228, 0x075c16c4, 0x5112246d, 0x1c06c288, - 0x0660cc0f, 0x0380b033, 0x58d99b36, 0xbb1c3186, 0x8c0ff871, 0x830c1861, - 0x183060c1, 0x0c0c0c18, 0xc0c0c078, 0x18306060, 0x60c3060c, 0x8100c618, - 0x3611de48, 0x10080411, 0x0087fc20, 0xff840201, 0x00ffffde, 0x06020301, - 0x18080c04, 0x20301018, 0x80c04060, 0x098c7c00, 0xf0783c1a, 0x0783c1e0, - 0x07c6320b, 0xc6318c7f, 0xb18c6318, 0x303038df, 0x060c1830, 0xffc0c183, - 0x3038dfbf, 0x180f1830, 0xf0303030, 0xe0301fb8, 0x320d83c0, 0xcc3318cc, - 0x0303ffff, 0xffff300c, 0x1f010101, 0xc0c0e078, 0x787ee3c0, 0x3018199c, - 0xc1b1cf60, 0x761f0783, 0x7fffe7c6, 0xc0606060, 0x018180c0, 0x0c060303, - 0x783631f0, 0x7c2f21f0, 0x3c1f0dcc, 0x3e1f18d8, 0x1e0f86e6, 0x6f38d83c, - 0x8d8080c0, 0x0003f1f1, 0x0000fff0, 0xc0c01efc, 0x01c1c1c1, 0x1c01c01c, - 0x0001ffc0, 0x03803ff8, 0x38038038, 0x30383838, 0x3038df80, 0x03061830, - 0x00000303, 0x8c3c0303, 0x665f2619, 0x59966599, 0xc01bb27e, 0xc0307c00, - 0xc81a0780, 0x610c4330, 0xf03609fe, 0x8dff03c0, 0x8f0f0f0f, 0x0f0d8cfd, - 0xe1ff8f0f, 0xc0c06c63, 0x06030180, 0x8060300c, 0xe31fbe31, 0x3c1e0d86, - 0xc1e0f078, 0xf9cd86c3, 0x30303ff0, 0x37f03030, 0x30303030, 0x303ffff0, - 0xf0303030, 0x30303037, 0x8f803030, 0x030301b1, 0x3c180c06, 0xc661b0d8, - 0x1e0f07f8, 0xe0f0783c, 0x0f0783ff, 0xf0783c1e, 0x0606063f, 0x06060606, - 0xc6060606, 0x060c1fbf, 0x3060c183, 0x3d8e1c18, 0x8c661b06, 0xe0783619, - 0x18660d81, 0x06c19863, 0x1818181e, 0x18181818, 0x18181818, 0xf0f83ff8, - 0xba6f0fc3, 0xce9ba6e9, 0x2388e739, 0xc1e0780e, 0x66330d83, 0x6c36198c, - 0x0381e0f0, 0x618cc1e2, 0xf03c0d86, 0x6c0f03c0, 0xe0cc6198, 0x3c3e37f1, - 0xf63c3c3c, 0x30303031, 0x33078030, 0xf0361986, 0x3c0f03c0, 0x318661b0, - 0xc0180783, 0x3733fe01, 0xf3363636, 0x333331b0, 0x67cc3c36, 0xe070303c, - 0x0c0e0781, 0xf3e63c0c, 0xc0300c3f, 0x300c0300, 0x0c0300c0, 0xc300c030, - 0x0783c1e0, 0x783c1e0f, 0xc6c1e0f0, 0x7818e1dc, 0x320d81e0, 0x184630c8, - 0x2c0b0461, 0x80618060, 0x98e31c03, 0x7b2e64cd, 0xdc7bcb59, 0x18630c61, - 0x61b07833, 0xe0704c63, 0xd8c641c0, 0x0783c1b0, 0x4630d81e, 0x0602c198, - 0x01806018, 0xf8601806, 0x30301fff, 0x30303030, 0xc0603030, 0x30ffffff, - 0x0c30c30c, 0xc30c30c3, 0x0601fc30, 0x80403008, 0x300c0201, 0x02018040, - 0x8060100c, 0x30c30c3f, 0x0c30c30c, 0xff0c30c3, 0x60a07010, 0xb198c443, - 0xff0783c1, 0x398f98ff, 0x19f8c060, 0x9cec361b, 0x060301e7, 0x6e71d80c, - 0x83c1e0d8, 0xb73b0f07, 0x03639f03, 0x180c0603, 0x3e31c060, 0x030180c0, - 0xf0dcedc6, 0x0783c1e0, 0x9b8e761b, 0x83c1b18f, 0x70180fff, 0xf03f31c0, - 0xc0603030, 0x06031ff0, 0x6030180c, 0xb70180c0, 0x0783c373, 0x9c6c1e0f, - 0xc6c06037, 0x0c0c0cf8, 0x0f9dec0c, 0x0f0f0f0f, 0x630f0f0f, 0x18c7c00c, - 0xc6318c63, 0xc0003060, 0x60c18307, 0x060c1830, 0x019f6183, 0x180c0603, - 0x86c66636, 0x8c661b07, 0x63f83619, 0x18c6318c, 0xde318c63, 0x6799eeed, - 0x99e6799e, 0xe6799e67, 0xe1e1f3bd, 0xe1e1e1e1, 0xee1c61e1, 0x3c1e0d8c, - 0x7731b078, 0x1b9c7638, 0xe0f07836, 0xedcec3c1, 0x00603018, 0x0786e76e, - 0xd83c1e0f, 0x80dc73b0, 0xef9e0301, 0x60c1c38f, 0x7c0c1830, 0xc3c1c1e3, - 0x3ec78383, 0xfc30180c, 0x030180c7, 0x30180c06, 0x1e1e1fc0, 0x1e1e1e1e, - 0x1ef73e1e, 0x32361e1e, 0xc1616333, 0xe67818c0, 0xcbb26799, 0x61d8f72e, - 0x61e19986, 0x1c0e1633, 0xe1e1b31a, 0x2361e1e1, 0x1e163333, 0x06040c0c, - 0x70607f86, 0x870e1c38, 0x7c7f8183, 0x0c040606, 0x08078808, 0x06040c08, - 0xfffc0606, 0x0fffffff, 0x0c081818, 0x04780404, 0x18080c04, 0x870f9818, - 0xe879c339, 0x02021fff, 0x6262dacf, 0xc2626262, 0x02020f9a, 0x8181990e, - 0x8187e181, 0xffe04081, 0xc6307c1f, 0xc3fe0600, 0x87fc0600, 0x00c01801, - 0xf037c18c, 0xc23186c0, 0xf030160c, 0x303f0303, 0x1a0300c0, 0xf19f000c, - 0x0781c0c0, 0x3030381e, 0xdf8f98f0, 0x8781c0f1, 0xb1f0f8de, 0xf0381e17, - 0x030d1fb8, 0x07078df0, 0x1e0e0f0f, 0x131870fb, 0xc160b394, 0xe60b0582, - 0x870c6414, 0xdf9818cf, 0x3b9cd8d8, 0x66666666, 0x0cc330cc, 0x00807ff3, - 0xa11e7e01, 0x52ced2ce, 0x18bb9e21, 0x010083a3, 0x10087fc2, 0x8df7fc00, - 0xe0c738c1, 0xc18df7ff, 0xec78303c, 0xc0030343, 0x8180ffff, 0x81818181, - 0x03018181, 0x1e1ffffe, 0x1e1e1e1e, 0xff3e1e1e, 0xf018181e, 0xf4fcfcff, - 0x848484e4, 0x84848484, 0x4ffc8484, 0x0ff00183, 0xc3870e0c, 0xf03070e1, - 0xc30c3ccf, 0xc7cfcc30, 0x83c1e0d8, 0x33e31b07, 0xcc330cc3, 0x99999998, - 0x661b3f81, 0x18c63198, 0x86318fe3, 0x81b06619, 0x6cccef3f, 0x7f8f31e6, - 0x8330630c, 0x048739b9, 0x3c0c0012, 0x308c61b0, 0x300c0583, 0x0c0300c0, - 0x0300c030, 0x03000003, 0x30618303, 0x87ec7030, 0xc0001803, 0x681e0300, - 0x310cc320, 0xd827f984, 0x0c0f03c0, 0xc0000607, 0x681e0300, 0x310cc320, - 0xd827f984, 0x0c0f03c0, 0xc0001a03, 0x681e0300, 0x310cc320, 0xd827f984, - 0x0c0f03c0, 0xc0001a0b, 0x681e0300, 0x310cc320, 0xd827f984, 0x8c0f03c0, - 0xc0001204, 0x681e0300, 0x310cc320, 0xd827f984, 0x0c0f03c0, 0xc0301203, - 0xc81a0780, 0x610c4330, 0xf03609fe, 0x0f8303c0, 0xa0681c07, 0x66f90641, - 0x18c621f8, 0x8f8f8c63, 0x030301b1, 0x30180c06, 0xc60180c0, 0xc18060f8, - 0xf00301c1, 0x3030303f, 0x3037f030, 0xf0303030, 0xf000c38f, 0x3030303f, - 0x3037f030, 0xf0303030, 0xf003418f, 0x3030303f, 0x3037f030, 0xf0303030, - 0xf002424f, 0x3030303f, 0x3037f030, 0xf0303030, 0xf00301cf, 0x8181818f, - 0x81818181, 0xf1818181, 0xf000c38f, 0x8181818f, 0x81818181, 0xf1818181, - 0xf003418f, 0x8181818f, 0x81818181, 0xf1818181, 0xf002424f, 0x8181818f, - 0x81818181, 0xf1818181, 0x867187ef, 0xc1b06c19, 0xb06c1b3f, 0xe3998661, - 0x00342c03, 0xd83c1e06, 0x98c66330, 0x0f06c361, 0x0e20381e, 0x07800060, - 0x36198633, 0x0f03c0f0, 0x8661b03c, 0x1c078331, 0x07800018, 0x36198633, - 0x0f03c0f0, 0x8661b03c, 0x0c078331, 0x07800068, 0x36198633, 0x0f03c0f0, - 0x8661b03c, 0x2c078331, 0x07800068, 0x36198633, 0x0f03c0f0, 0x8661b03c, - 0x12078331, 0x07800048, 0x36198633, 0x0f03c0f0, 0x8661b03c, 0xd0c78331, - 0x647041c4, 0x35993c61, 0x47a1b0cc, 0x85e2791e, 0x99ac330d, 0x0180703c, - 0xe0f07830, 0x0f0783c1, 0xb0783c1e, 0xe0387731, 0x78300060, 0x83c1e0f0, - 0x3c1e0f07, 0x7731b078, 0x01a06038, 0xe0f07830, 0x0f0783c1, 0xb0783c1e, - 0x88387731, 0x78300110, 0x83c1e0f0, 0x3c1e0f07, 0x7731b078, 0x00c0c038, - 0x36078180, 0xb066118c, 0x18060180, 0x06018060, 0x06060618, 0x8787c6fe, - 0x063ec787, 0x88780606, 0xc2623319, 0xc6731d86, 0x783c1f0d, 0x300e1cd0, - 0x0731f000, 0x633f180c, 0xf39d86c3, 0x0003070c, 0x0180e63e, 0xd86c67e3, - 0x619e73b0, 0xc7c001a0, 0xfc60301c, 0x761b0d8c, 0x1a1633ce, 0x0398f800, - 0xb19f8c06, 0x79cec361, 0x00028146, 0x80c0731f, 0x6c3633f1, 0x30cf39d8, - 0x63e0c090, 0x7e30180e, 0x3b0d86c6, 0x99bbd9e7, 0xffd98661, 0x61986619, - 0x39f0e36f, 0xc0603036, 0x1c060180, 0x060183e3, 0x00180707, 0x3c1b18f8, - 0x0180fff8, 0x83f31c07, 0x1f000183, 0xff078363, 0x80e0301f, 0xd0307e63, - 0x6c63e000, 0x03ffe0f0, 0xcc701c06, 0x000a050f, 0x1e0d8c7c, 0x80c07ffc, - 0x39f98e03, 0x18c63e0c, 0xc6318c63, 0x30c3e019, 0x0c30c30c, 0xf81a30c3, - 0x30c30c30, 0x9230c30c, 0x86187e04, 0x61861861, 0x183700f8, 0x73e1806c, - 0xe0f0786e, 0xe1dcc6c1, 0xd800d160, 0x1e1e1f3b, 0x1e1e1e1e, 0x0300e61e, - 0xc6770e00, 0x3c1e0f06, 0x1c3b98d8, 0xc0003070, 0xe0d8cee1, 0x1b0783c1, - 0x06038773, 0xdc38001a, 0x783c1b19, 0xee6360f0, 0x01a16070, 0x633b8700, - 0x1e0f0783, 0x0e1dcc6c, 0xe0002814, 0xf06c6770, 0x8d83c1e0, 0x0101c3b9, - 0xff000002, 0x00800001, 0x633ba701, 0x5e4f27a3, 0x0e5dcc6c, 0xe180180e, - 0xe1e1e1e1, 0x73e1e1e1, 0x800c386f, 0xe1e1e1e1, 0xe1e1e1e1, 0x1a0c6f73, - 0xe1e1e180, 0xe1e1e1e1, 0x126f73e1, 0xe1e18012, 0xe1e1e1e1, 0x6f73e1e1, - 0xe1800c38, 0x332361e1, 0x0c1e1633, 0x8606040c, 0xec060301, 0xf06c3738, - 0x8783c1e0, 0x6031db9d, 0x121200c0, 0x61e1e180, 0x16333323, 0x040c0c1e, - 0x00000606, }; - -#endif diff --git a/src/src/SDL2/fontstruct.h b/src/src/SDL2/fontstruct.h deleted file mode 100644 index d3f0408..0000000 --- a/src/src/SDL2/fontstruct.h +++ /dev/null @@ -1,43 +0,0 @@ -#ifndef SAC_SDL2_FONT_STRUCT_H -#define SAC_SDL2_FONT_STRUCT_H - -struct fontchar { - unsigned short width; - short ascent; - short descent; - short lbearing; - short rbearing; - unsigned short numbits; - unsigned int firstbit; -}; - -struct font { - short ascent; - short descent; - unsigned short first; - unsigned short last; - struct fontchar* chars; -}; - -typedef unsigned int fontbits_t; - -static inline unsigned getbit(fontbits_t* fontbits, unsigned bit) -{ - const unsigned word = bit / (8 * sizeof(fontbits_t)); - const unsigned flag = bit % (8 * sizeof(fontbits_t)); - return fontbits[word] & (1U << flag); -} -static inline unsigned setbit(fontbits_t* fontbits, unsigned bit) -{ - const unsigned word = bit / (8 * sizeof(fontbits_t)); - const unsigned flag = bit % (8 * sizeof(fontbits_t)); - return fontbits[word] |= (1U << flag); -} -static inline unsigned clrbit(fontbits_t* fontbits, unsigned bit) -{ - const unsigned word = bit / (8 * sizeof(fontbits_t)); - const unsigned flag = bit % (8 * sizeof(fontbits_t)); - return fontbits[word] &= ~(1U << flag); -} - -#endif diff --git a/src/src/SDL2/init.c b/src/src/SDL2/init.c deleted file mode 100644 index dc14bb7..0000000 --- a/src/src/SDL2/init.c +++ /dev/null @@ -1,53 +0,0 @@ -#include "SDL2sac.h" - -enum SDL2_init_states { - NotInited, - Started, - Completed, -}; - -static volatile int inited; - -void SAC_SDL2_check( SDL2* disp) -{ - if (inited != Completed) { - SAC_RuntimeError( "SAC_SDL2_check: SDL2 module is not initialized"); - } - if ( ! disp || ! SDL2_CHECK( disp)) { - SAC_RuntimeError( "SAC_SDL2_check: invalid SDL2 display structure"); - } -} - -int SAC_SDL2_init( SDL2* disp) -{ - int r = 0; - - if (inited == NotInited && ++inited == Started) { - if (SAC_SDL2_setup( disp)) { - SAC_RuntimeError( "SAC_SDL2_init: failed to init SDL: %s\n", - SDL_GetError()); - r = -1; - inited = NotInited; - } else { - inited = Completed; - } - } - else { - SAC_RuntimeError( "SAC_SDL2_init: called twice (%d)\n", inited + 1); - } - - return r; -} - -void SAC_SDL2_stop( SDL2* disp) -{ - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_stop()\n", When( disp)); - } - - if (inited == Completed) { - SAC_SDL2_teardown( disp); - inited = NotInited; - } -} - diff --git a/src/src/SDL2/invert.c b/src/src/SDL2/invert.c deleted file mode 100644 index df35396..0000000 --- a/src/src/SDL2/invert.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_invert_rect( SDL2* disp, const int *pos, const int update) -{ - const int pitch = SDL2_PITCH( disp) / BYTES_PER_PIXEL; - Uint32* videomem = (Uint32 *) SDL2_PIXELS( disp); - int y, x; - int x1, x2, y1, y2; - Uint32* bptr; - - x1 = MIN(pos[0], pos[2]); - x2 = MAX(pos[0], pos[2]); - y1 = MIN(pos[1], pos[3]); - y2 = MAX(pos[1], pos[3]); - - for (y = y1; y <= y2; ++y) { - bptr = videomem + x1 + y * pitch; - for (x = x1; x <= x2 ; ++x, ++bptr) { - *bptr = (0xFFFFFF & ~(*bptr)); - } - } - - if (update) { - SDL_UpdateRect( SDL2_SURF( disp), x1, y1, x2 - x1 + 1, y2 - y1 + 1); - } -} - -void SAC_SDL2_invert2( SDL2* disp, const int offsets[2], const int sizes[2]) -{ - const int width = sizes[1]; - const int height = sizes[0]; - const int xoffset = offsets[1]; - const int yoffset = offsets[0]; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_invert2: [%d,%d]:[%d,%d] on [%d,%d]\n", - When( disp), xoffset, yoffset, width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - - SAC_SDL2_lock( disp); - - if ( xoffset < 0 || yoffset < 0 || - width < 0 || height < 0 || - xoffset + width > SDL2_DISP_WIDTH( disp) || - yoffset + height > SDL2_DISP_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_invert2: Invalid offset [%d,%d] + size [%d,%d] " - "on display [%d,%d]\n", - xoffset, yoffset, width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else { - int pos[4]; - pos[0] = xoffset + SDL2_DISP_X( disp); - pos[1] = yoffset + SDL2_DISP_Y( disp); - pos[2] = pos[0] + width - 1; - pos[3] = pos[1] + height - 1; - SAC_SDL2_invert_rect( disp, pos, false); - SAC_SDL2_update_rect( disp, pos[0], pos[1], width, height, false); - } - - SAC_SDL2_unlock( disp); -} - diff --git a/src/src/SDL2/line.c b/src/src/SDL2/line.c deleted file mode 100644 index c15b756..0000000 --- a/src/src/SDL2/line.c +++ /dev/null @@ -1,129 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_line( SDL2* disp, const int P1[2], const int P2[2], int async) -{ - const int width = SDL2_DISP_WIDTH( disp); - const int height = SDL2_DISP_HEIGHT( disp); - int x1 = P1[1]; - int y1 = P1[0]; - int x2 = P2[1]; - int y2 = P2[0]; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_line: [%d,%d] to [%d,%d] on [%d,%d]\n", - When( disp), x1, y1, x2, y2, - width, height); - } - - SAC_SDL2_lock( disp); - - if ( x1 < 0 || x2 < 0 || y1 < 0 || y2 < 0 || - x1 >= width || x2 >= width || y1 >= height || y2 >= height) - { - SAC_RuntimeError( "SAC_SDL2_line: [%d,%d] to [%d,%d] exceeds [%d,%d]\n", - x1, y1, x2, y2, width, height); - } - else { - SAC_SDL2_draw_a_line( disp, - SDL2_DISP_X( disp) + x1, - SDL2_DISP_Y( disp) + y1, - SDL2_DISP_X( disp) + x2, - SDL2_DISP_Y( disp) + y2, - SAC_SDL2_foreground_rgb, - true, - async); - } - - SAC_SDL2_unlock( disp); -} - -void SAC_SDL2_draw_a_line( SDL2* disp, int x1, int y1, int x2, int y2, - Uint32 rgb, int update, int async) -{ - const int pitch = SDL2_PITCH( disp) / BYTES_PER_PIXEL; - Uint32* videomem = (Uint32 *) SDL2_PIXELS( disp); - - int x; - int y; - int xinc; - int yinc; - int deltax; - int deltay; - int denom; - int numer; - - deltax = DELTA( x1, x2); - deltay = DELTA( y1, y2); - - if (deltax >= deltay) - { - if (x1 > x2) { - SWAP2( int, x1, x2); - SWAP2( int, y1, y2); - } - - if (deltay == 0) { - for (x = x1; x <= x2; ++x) - { - videomem[x + y1 * pitch] = rgb; - } - } - else { - denom = deltax; - numer = deltax / 2; - y = y1; - yinc = (y1 <= y2) ? 1 : -1; - - for (x = x1; x <= x2; ++x) - { - videomem[x + y * pitch] = rgb; - numer += deltay; - if (numer >= denom) - { - numer -= denom; - y += yinc; - } - } - } - } - else - { - if (y1 > y2) { - SWAP2( int, x1, x2); - SWAP2( int, y1, y2); - } - - if (deltax == 0) { - for (y = y1; y <= y2; ++y) - { - videomem[x1 + y * pitch] = rgb; - } - } - else { - denom = deltay; - numer = deltay / 2; - x = x1; - xinc = (x1 <= x2) ? 1 : -1; - - for (y = y1; y <= y2; ++y) - { - videomem[x + y * pitch] = rgb; - numer += deltax; - if (numer >= denom) - { - numer -= denom; - x += xinc; - } - } - } - } - - if (update) { - SAC_SDL2_update_rect( disp, - MIN( x1, x2), MIN( y1, y2), - deltax + 1, deltay + 1, - async); - } -} - diff --git a/src/src/SDL2/mouse.c b/src/src/SDL2/mouse.c deleted file mode 100644 index 159271d..0000000 --- a/src/src/SDL2/mouse.c +++ /dev/null @@ -1,138 +0,0 @@ -#include "SDL2sac.h" - -enum SelectMode { - SelNone = 0, - SelStart, - SelDown, - SelDone, -}; -static enum SelectMode sel_mode; -static SDL2* sel_disp; -static int selection[4]; - -static void change_mode( enum SelectMode new_mode) -{ - if (SDL2_DEBUG( sel_disp)) { - printf("%sChanging select mode from %d to %d.\n", - When( sel_disp), sel_mode, new_mode); - } - sel_mode = new_mode; -} - -void SAC_SDL2_start_selection( SDL2* disp) -{ - sel_disp = disp; - change_mode( SelStart); -} - -int SAC_SDL2_get_selection( int *sel) -{ - if ( sel_mode == SelDone) { - sel[0] = MIN(selection[0], selection[2]); - sel[2] = MAX(selection[0], selection[2]); - sel[1] = MIN(selection[1], selection[3]); - sel[3] = MAX(selection[1], selection[3]); - } else { - sel[0] = sel[1] = sel[2] = sel[3] = -1; - } - - return (sel_mode == SelDone); -} - -static void invert(void) -{ - SAC_SDL2_invert_rect( sel_disp, selection, true); -} - -static int next_event_type(void) -{ - int r; - int kind; - SDL_Event event; - - kind = -1; - r = SDL_PeepEvents( &event, 1, SDL_PEEKEVENT, SDL_MOUSEEVENTMASK); - if (r == 1) { - kind = event.type; - } - - return kind; -} - -void SAC_SDL2_mouse_down_event( SDL_Event* event) -{ - if (sel_mode == SelStart || sel_mode == SelDown) { - if (SDL2_DEBUG( sel_disp)) { - printf("%sSAC_SDL2_mouse_down: button %d, mode %d\n", When( sel_disp), - event->button.button, sel_mode); - } - } - if ((event->button.button == 1) && (sel_mode == SelStart)) - { - change_mode( SelDown); - LIMIT(event->button.x, SDL2_DISP_X( sel_disp), - SDL2_DISP_X( sel_disp) + SDL2_DISP_WIDTH( sel_disp) - 1); - LIMIT(event->button.y, SDL2_DISP_Y( sel_disp), - SDL2_DISP_Y( sel_disp) + SDL2_DISP_HEIGHT( sel_disp) - 1); - selection[0] = event->button.x; - selection[1] = event->button.y; - selection[2] = event->button.x; - selection[3] = event->button.y; - invert(); - } -} - -void SAC_SDL2_mouse_up_event( SDL_Event* event) -{ - if (sel_mode == SelDown || sel_mode == SelStart) { - if (SDL2_DEBUG( sel_disp)) { - printf("%sSAC_SDL2_mouse_up: button %d, mode %d\n", When( sel_disp), - event->button.button, sel_mode); - } - } - if ((event->button.button == 1) && (sel_mode == SelDown)) - { - invert(); - change_mode( SelDone); - LIMIT(event->button.x, SDL2_DISP_X( sel_disp), - SDL2_DISP_X( sel_disp) + SDL2_DISP_WIDTH( sel_disp) - 1); - LIMIT(event->button.y, SDL2_DISP_Y( sel_disp), - SDL2_DISP_Y( sel_disp) + SDL2_DISP_HEIGHT( sel_disp) - 1); - selection[2] = event->button.x; - selection[3] = event->button.y; - SAC_SDL2_post( sel_disp); - } - if ((event->button.button == 2) && - (sel_mode == SelDown || sel_mode == SelStart)) - { - if (sel_mode == SelDown) { - invert(); - } - change_mode( SelNone); - SAC_SDL2_post( sel_disp); - } -} - -void SAC_SDL2_mouse_motion_event( SDL_Event* event) -{ - if (sel_mode == SelDown && next_event_type() != SDL_MOUSEMOTION) - { - if (SDL2_DEBUG( sel_disp)) { - printf("%sSAC_SDL2_mouse_motion: %d,%d, mode %d\n", When( sel_disp), - event->motion.x, event->motion.y, sel_mode); - } - - LIMIT(event->button.x, SDL2_DISP_X( sel_disp), - SDL2_DISP_X( sel_disp) + SDL2_DISP_WIDTH( sel_disp) - 1); - LIMIT(event->button.y, SDL2_DISP_Y( sel_disp), - SDL2_DISP_Y( sel_disp) + SDL2_DISP_HEIGHT( sel_disp) - 1); - if (event->motion.x != selection[2] || event->motion.y != selection[3]) - { - invert(); - selection[2] = event->motion.x; - selection[3] = event->motion.y; - invert(); - } - } -} - diff --git a/src/src/SDL2/names.c b/src/src/SDL2/names.c deleted file mode 100644 index d956565..0000000 --- a/src/src/SDL2/names.c +++ /dev/null @@ -1,44 +0,0 @@ -#include "SDL2sac.h" - -static const char* SAC_SDL2_event_names[] = { - /* 0 */ "noevent", - /* 1 */ "activeevent", - /* 2 */ "keydown", - /* 3 */ "keyup", - /* 4 */ "mousemotion", - /* 5 */ "mousebuttondown", - /* 6 */ "mousebuttonup", - /* 7 */ "joyaxismotion", - /* 8 */ "joyballmotion", - /* 9 */ "joyhatmotion", - /* 10 */ "joybuttondown", - /* 11 */ "joybuttonup", - /* 12 */ "quit", - /* 13 */ "syswmevent", - /* 14 */ "event_reserveda", - /* 15 */ "event_reservedb", - /* 16 */ "videoresize", - /* 17 */ "videoexpose", - /* 18 */ "event_reserved2", - /* 19 */ "event_reserved3", - /* 20 */ "event_reserved4", - /* 21 */ "event_reserved5", - /* 22 */ "event_reserved6", - /* 23 */ "event_reserved7", - /* 24 */ "userevent", - /* 25 */ "create_event", - /* 26 */ "teardown_event", - /* 27 */ "update_event", - /* 28 */ "update_async_event", -}; - -const char* SAC_SDL2_event_name(int evno) -{ - size_t count = sizeof(SAC_SDL2_event_names) / sizeof(const char *); - - if (evno < 0 || evno >= count) { - SAC_RuntimeError( "SDL2_event_name: unknown event number %d", evno); - } - return SAC_SDL2_event_names[evno]; -} - diff --git a/src/src/SDL2/pixel.c b/src/src/SDL2/pixel.c deleted file mode 100644 index 37796ce..0000000 --- a/src/src/SDL2/pixel.c +++ /dev/null @@ -1,42 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_draw_a_pixel( SDL2* disp, int x, int y, Uint32 rgb) -{ - const int pitch = SDL2_PITCH( disp) / BYTES_PER_PIXEL; - Uint32* videomem = (Uint32 *) SDL2_PIXELS( disp); - - videomem[x + y * pitch] = rgb; -} - -void SAC_SDL2_pixel( SDL2* disp, SAC_ND_PARAM_in( shp_nt, int), SAC_ND_PARAM_in( color_nt, int)) -{ - const int pitch = SDL2_PITCH( disp) / BYTES_PER_PIXEL; - Uint32* videomem = (Uint32 *) SDL2_PIXELS( disp); - const int x = SAC_ND_A_FIELD( shp_nt)[1]; - const int y = SAC_ND_A_FIELD( shp_nt)[0]; - const int* color = SAC_ND_A_FIELD( color_nt); - const unsigned char r = color[0]; - const unsigned char g = color[1]; - const unsigned char b = color[2]; - - if (SDL2_DEBUG( disp) >= 3) { - printf("%sSAC_SDL_pixel [%d,%d] %d,%d,%d\n", When( disp), x, y, r, g, b); - } - - SAC_SDL2_check( disp); - - if ( ((unsigned) x >= SDL2_DISP_WIDTH( disp)) || - ((unsigned) y >= SDL2_DISP_HEIGHT( disp)) ) { - SAC_RuntimeError( "SAC_SDL_pixel: Pixel [%d,%d] exceeds display [%d,%d]\n", - x, y, SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else { - const int xoffset = SDL2_DISP_X( disp) + x; - const int yoffset = SDL2_DISP_Y( disp) + y; - videomem[xoffset + yoffset * pitch] = RGB(r,g,b); - } - - SAC_ND_DEC_RC_FREE( shp_nt, 1, ) - SAC_ND_DEC_RC_FREE( color_nt, 1, ) -} - diff --git a/src/src/SDL2/rect.c b/src/src/SDL2/rect.c deleted file mode 100644 index 7ac0a43..0000000 --- a/src/src/SDL2/rect.c +++ /dev/null @@ -1,163 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_draw_rect( SDL2* disp, const int offsets[2], const int sizes[2], - int async) -{ - const int width = sizes[1]; - const int height = sizes[0]; - const int xoffset = offsets[1]; - const int yoffset = offsets[0]; - const Uint32 rgb = SAC_SDL2_foreground_rgb; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_draw_rect: [%d,%d]:[%d,%d] on [%d,%d]\n", - When( disp), xoffset, yoffset, width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - - SAC_SDL2_lock( disp); - - if ( xoffset < 0 || yoffset < 0 || - width < 0 || height < 0 || - xoffset + width > SDL2_DISP_WIDTH( disp) || - yoffset + height > SDL2_DISP_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_draw_rect: Invalid offset [%d,%d] + " - "size [%d,%d] on display [%d,%d]\n", - xoffset, yoffset, width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else if (width > 1) { - if (height > 1) { - const int x = SDL2_DISP_X( disp) + xoffset; - const int y = SDL2_DISP_Y( disp) + yoffset; - SAC_SDL2_draw_a_line( disp, x, y, x + width - 1, y, rgb, true, true); - SAC_SDL2_draw_a_line( disp, x, y + 1, x, y + height - 1, rgb, true, true); - if (width > 2) { - SAC_SDL2_draw_a_line( disp, - x + 1, y + height - 1, - x + width - 1, y + height - 1, - rgb, true, true); - } - SAC_SDL2_draw_a_line( disp, - x + width - 1, y + 1, - x + width - 1, y + height - 1, - rgb, true, async); - } - else if (height == 1) { - SAC_SDL2_draw_a_line( disp, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset, - SDL2_DISP_X( disp) + xoffset + width - 1, - SDL2_DISP_Y( disp) + yoffset, - rgb, true, async); - } - } - else if (width == 1) { - if (height > 1) { - SAC_SDL2_draw_a_line( disp, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset + height - 1, - rgb, true, async); - } - else if (height == 1) { - SAC_SDL2_draw_a_pixel( disp, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset, - SAC_SDL2_foreground_rgb); - SAC_SDL2_update_rect( disp, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset, - 1, 1, true); - } - } - - SAC_SDL2_unlock( disp); -} - -static void fill_a_rect( SDL2* disp, int xoff, int yoff, int wid, int hei, int async) -{ - const Uint32 rgb = SAC_SDL2_foreground_rgb; - const int pitch = SDL2_PITCH( disp) / BYTES_PER_PIXEL; - Uint32* videomem = (Uint32 *) SDL2_PIXELS( disp); - Uint32* bptr; - int x, y; - - if (SDL2_DEBUG( disp)) { - printf("%sfill_a_rect: [%d,%d]:[%d,%d], %d, 0x%x\n", - When( disp), xoff, yoff, wid, hei, async, rgb); - } - - for (y = 0; y < hei; ++y) { - bptr = &videomem[xoff + ((y + yoff) * pitch)]; - for (x = 0; x < wid; ++x, ++bptr) { - *bptr = rgb; - } - } - - SAC_SDL2_update_rect( disp, xoff, yoff, wid, hei, async); -} - -void SAC_SDL2_fill_rect( SDL2* disp, const int offsets[2], const int sizes[2], - int async) -{ - const int width = sizes[1]; - const int height = sizes[0]; - const int xoffset = offsets[1]; - const int yoffset = offsets[0]; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_fill_rect: [%d,%d]:[%d,%d] on display [%d,%d]:[%d,%d]\n", - When( disp), xoffset, yoffset, width, height, - SDL2_DISP_X( disp), SDL2_DISP_Y( disp), - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - - SAC_SDL2_lock( disp); - - if ( xoffset < 0 || yoffset < 0 || - width < 0 || height < 0 || - xoffset + width > SDL2_DISP_WIDTH( disp) || - yoffset + height > SDL2_DISP_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_fill_rect: Invalid offset [%d,%d] + " - "size [%d,%d] on display [%d,%d]:[%d,%d]\n", - xoffset, yoffset, width, height, - SDL2_DISP_X( disp), SDL2_DISP_Y( disp), - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else { - fill_a_rect( disp, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset, - width, height, async); - } - SAC_SDL2_unlock( disp); -} - -void SAC_SDL2_fill_disp( SDL2* disp, int async) -{ - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_fill_disp: [%d,%d]:[%d,%d]\n", - When( disp), - SDL2_DISP_X( disp), SDL2_DISP_Y( disp), - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - - SAC_SDL2_lock( disp); - - fill_a_rect( disp, - SDL2_DISP_X( disp), - SDL2_DISP_Y( disp), - SDL2_DISP_WIDTH( disp), - SDL2_DISP_HEIGHT( disp), - async); - - SAC_SDL2_unlock( disp); -} - diff --git a/src/src/SDL2/resize.c b/src/src/SDL2/resize.c deleted file mode 100644 index f38bfae..0000000 --- a/src/src/SDL2/resize.c +++ /dev/null @@ -1,56 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_resize( SDL2* disp, - SAC_ND_PARAM_in( shp_nt, int)) -{ - const int width = SAC_ND_A_FIELD( shp_nt)[1]; - const int height = SAC_ND_A_FIELD( shp_nt)[0]; - SDL_Event event; - SDL_Rect rect; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_resize: w=%d, h=%d\n", When( disp), width, height); - } - - SAC_SDL2_lock( disp); - - if ( width < 0 || width > SHRT_MAX || height < 0 || height > SHRT_MAX) - { - SAC_RuntimeError( "SAC_SDL2_resize: invalid dimensions: [%d,%d]\n", - width, height); - } - else if (SDL2_ISROOT( disp)) - { - event.type = SDL2_CREATE_EVENT; - rect.w = width; - rect.h = height; - event.user.data1 = ▭ - event.user.data2 = disp; - SDL_PushEvent( &event); - SAC_SDL2_wait( disp); - } - else if (width < 1 || height < 1 || - SDL2_DISP_X( disp) + width > - SDL2_PARENT_X( disp) + SDL2_PARENT_WIDTH( disp) || - SDL2_DISP_Y( disp) + height > - SDL2_PARENT_Y( disp) + SDL2_PARENT_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_resize: Invalid resize [%d,%d] at [%d,%d] " - "on parent space [%d,%d]\n", - width, height, - SDL2_DISP_X( disp) - SDL2_PARENT_X( disp), - SDL2_DISP_Y( disp) - SDL2_PARENT_Y( disp), - SDL2_PARENT_WIDTH( disp), - SDL2_PARENT_HEIGHT( disp)); - } - else { - SDL2_DISP_WIDTH( disp) = width; - SDL2_DISP_HEIGHT( disp) = height; - } - - SAC_SDL2_unlock( disp); - - SAC_ND_DEC_RC_FREE( shp_nt, 1, ) -} - diff --git a/src/src/SDL2/select.c b/src/src/SDL2/select.c deleted file mode 100644 index ce6f982..0000000 --- a/src/src/SDL2/select.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_select( SAC_ND_PARAM_out_nodesc( aks_out_nt, int), SDL2* disp) -{ - SAC_ND_DECL__DATA( aks_nt, int, ); - int sel[4]; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL_select\n", When( disp)); - } - - SAC_SDL2_lock( disp); - - SAC_SDL2_select_heading(); - SAC_SDL2_cursor( 1); - - SAC_SDL2_start_selection( disp); - SAC_SDL2_wait( disp); - - SAC_SDL2_default_heading(); - SAC_SDL2_cursor( 0); - - SAC_SDL2_get_selection( sel); - - /* - * write back result, ensure that we have [topleft, bottomright] and - * [Y,X] coordinates - */ - SAC_ND_A_FIELD( aks_nt) = SAC_MALLOC( sizeof( int) * 4); - SAC_ND_A_FIELD( aks_nt)[1] = MIN(sel[0], sel[2]); - SAC_ND_A_FIELD( aks_nt)[3] = MAX(sel[0], sel[2]); - SAC_ND_A_FIELD( aks_nt)[0] = MIN(sel[1], sel[3]); - SAC_ND_A_FIELD( aks_nt)[2] = MAX(sel[1], sel[3]); - - SAC_SDL2_unlock( disp); - - SAC_ND_RET_out__NODESC( aks_out_nt, aks_nt); -} diff --git a/src/src/SDL2/sem.c b/src/src/SDL2/sem.c deleted file mode 100644 index 8ca8c33..0000000 --- a/src/src/SDL2/sem.c +++ /dev/null @@ -1,92 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_sem_init( sem_t *sem) -{ - int r = sem_init( sem, SEM_SHARE_THREAD, SEM_INIT_LOCKED); - if (r) { - SAC_RuntimeError( "SAC_SDL2_sem_alloc: sem_init failed: %d: %m\n", r); - } -} - -sem_t* SAC_SDL2_sem_alloc(void) -{ - sem_t* sem = (sem_t *) SAC_MALLOC( sizeof( sem_t)); - SAC_SDL2_sem_init( sem); - return sem; -} - -void SAC_SDL2_sem_free( sem_t* sem) -{ - int r = sem_destroy( sem); - if (r) { - SAC_RuntimeError( "SAC_SDL2_sem_free: sem_destroy failed: %d: %m\n", r); - } - free( sem); -} - -void SAC_SDL2_sem_post( sem_t* sem) -{ - int r; - - r = sem_post( sem); - if (r) { - SAC_RuntimeError( "SDL2_sem_post: sem_post failed: %d: %m\n", r); - } -} - -void SAC_SDL2_sem_wait( sem_t* sem) -{ - int r; - - r = sem_wait( sem); - if (r) { - SAC_RuntimeError( "SDL2_sem_wait: sem_wait failed: %d: %m\n", r); - } -} - -void SAC_SDL2_post( SDL2* disp) -{ - sem_t *sem = SDL2_SEM( disp); - - if (SDL2_DEBUG( disp) >= 2) { - printf("%spost\n", When( disp)); - } - SAC_SDL2_sem_post( sem); -} - -void SAC_SDL2_wait( SDL2* disp) -{ - sem_t *sem = SDL2_SEM( disp); - - if (SDL2_DEBUG( disp) >= 2) { - printf("%swait...\n", When( disp)); - } - SAC_SDL2_sem_wait( sem); - if (SDL2_DEBUG( disp) >= 2) { - printf("%swaited.\n", When( disp)); - } -} - -void SAC_SDL2_lock( SDL2* disp) -{ - sem_t *sem = SDL2_LOCK( disp); - - if (SDL2_DEBUG( disp) >= 2) { - printf("%slock...\n", When( disp)); - } - SAC_SDL2_sem_wait( sem); - if (SDL2_DEBUG( disp) >= 2) { - printf("%slocked.\n", When( disp)); - } -} - -void SAC_SDL2_unlock( SDL2* disp) -{ - sem_t *sem = SDL2_LOCK( disp); - - if (SDL2_DEBUG( disp) >= 2) { - printf("%sunlock\n", When( disp)); - } - SAC_SDL2_sem_post( sem); -} - diff --git a/src/src/SDL2/setup.c b/src/src/SDL2/setup.c deleted file mode 100644 index 9fb5018..0000000 --- a/src/src/SDL2/setup.c +++ /dev/null @@ -1,88 +0,0 @@ -#include "SDL2sac.h" -#include - -static pthread_t SAC_SDL2_thread_id; - - - /* Arguments for event loop thread. */ - typedef struct thread_args { - int* init_result_ptr; - SDL2* disp; - } thread_args_t; - - -static void* SAC_SDL2_thread( void *vp) -{ - thread_args_t* ta = (thread_args_t *) vp; - SDL2* disp = ta->disp; - int* result = ta->init_result_ptr; - int r; - - if (SDL2_DEBUG( disp)) { - printf( "%sSDL2_thread starts\n", When( disp)); - } - - r = SDL_Init( SDL_INIT_VIDEO | SDL_INIT_NOPARACHUTE); - *result = r; - SAC_SDL2_post( disp); - if (r == 0) { - SAC_SDL2_event_loop( disp); - SDL_Quit(); - } - - if (SDL2_DEBUG( disp)) { - printf( "%sSDL2_thread ends\n", When( disp)); - } - - return NULL; -} - -int SAC_SDL2_setup( SDL2* disp) -{ - pthread_attr_t attr; - int r; - int sdl_init_result; - thread_args_t ta; - - ta.disp = disp; - ta.init_result_ptr = &sdl_init_result; - - r = pthread_attr_init( &attr); - if (r) { - SAC_RuntimeError( "SAC_SDL2_setup: pthread_attr_create failed: %d: %m\n", r); - } - r = pthread_attr_setscope( &attr, PTHREAD_SCOPE_SYSTEM); - if (r) { - SAC_RuntimeError( "SAC_SDL2_setup: pthread_attr_setscope failed: %d: %m\n", r); - } - r = pthread_attr_setdetachstate( &attr, PTHREAD_CREATE_JOINABLE); - if (r) { - SAC_RuntimeError( "SAC_SDL2_setup: pthread_attr_setdetach failed: %d: %m\n", r); - } - r = pthread_create( &SAC_SDL2_thread_id, NULL, SAC_SDL2_thread, &ta); - if (r) { - SAC_RuntimeError( "SAC_SDL2_setup: pthread_create failed: %d: %m\n", r); - } - - pthread_attr_destroy( &attr); - - SAC_SDL2_wait( disp); - - return sdl_init_result; -} - -void SAC_SDL2_teardown( SDL2* disp) -{ - int r; - SDL_Event event; - - event.type = SDL2_TEARDOWN_EVENT; - event.user.data2 = disp; - SDL_PushEvent( &event); - - r = pthread_join( SAC_SDL2_thread_id, NULL); - if (r) { - SAC_RuntimeError( "SAC_SDL2_teardown: pthread_join failed: %d: %m\n", r); - } -} - diff --git a/src/src/SDL2/title.c b/src/src/SDL2/title.c deleted file mode 100644 index c8abbb7..0000000 --- a/src/src/SDL2/title.c +++ /dev/null @@ -1,45 +0,0 @@ -#include "SDL2sac.h" - -static const char* get_argv0(void) -{ - int ac; - char** av; - char* s; - char* h; - size_t len; - - SAC_COMMANDLINE_GET( ac, av); - s = av[0]; - - /* try to skip 's' past the home directory component */ - h = getenv("HOME"); - if (h) { - len = strlen( h); - if ( ! strncmp( h, s, len) && s[len] == '/') { - s += len + 1; - } - } - - return s; -} - -void SAC_SDL2_heading( const char* heading) -{ - SDL_WM_SetCaption( heading, NULL); -} - -void SAC_SDL2_default_heading( void) -{ - SDL_WM_SetCaption( get_argv0(), NULL); -} - -void SAC_SDL2_select_heading( void) -{ - SDL_WM_SetCaption( SAC_SDL2_SELECT_HEADING, NULL); -} - -void SAC_SDL2_cursor( int enable) -{ - SDL_ShowCursor( enable); -} - diff --git a/src/src/SDL2/update.c b/src/src/SDL2/update.c deleted file mode 100644 index 9217730..0000000 --- a/src/src/SDL2/update.c +++ /dev/null @@ -1,86 +0,0 @@ -#include "SDL2sac.h" - -void SAC_SDL2_update_display_event( SDL_Event* event) -{ - SDL_Rect* rect = (SDL_Rect *) &event->user.code; - SDL2* disp = event->user.data2; - - SDL_UpdateRect( SDL2_SURF( disp), rect->x, rect->y, rect->w, rect->h); - if (event->type == SDL2_UPDATE_EVENT) { - SAC_SDL2_post( disp); - } -} - -/* - * Receive coordinates in true surface area. - */ -void SAC_SDL2_update_rect( SDL2* disp, int x, int y, int w, int h, int async) -{ - SDL_Event event; - SDL_Rect* rect_ptr; - - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_update_rect: [%d,%d]:[%d,%d] %s\n", - When( disp), x, y, w, h, async ? "async" : "sync"); - } - event.type = async ? SDL2_UPDATE_ASYNC_EVENT : SDL2_UPDATE_EVENT; - rect_ptr = (SDL_Rect *) &event.user.code; - rect_ptr->x = x; - rect_ptr->y = y; - rect_ptr->w = w; - rect_ptr->h = h; - event.user.data2 = disp; - SDL_PushEvent( &event); - if ( ! async) { - SAC_SDL2_wait( disp); - } -} - -void SAC_SDL2_update( SDL2* disp, int async) -{ - int offsets[2]; - int sizes[2]; - - SAC_SDL2_check( disp); - offsets[1] = 0; - offsets[0] = 0; - sizes[1] = SDL2_DISP_WIDTH( disp); - sizes[0] = SDL2_DISP_HEIGHT( disp); - SAC_SDL2_update2( disp, offsets, sizes, async); -} - -void SAC_SDL2_update2( SDL2* disp, int offsets[2], int sizes[2], int async) -{ - const int width = sizes[1]; - const int height = sizes[0]; - const int xoffset = offsets[1]; - const int yoffset = offsets[0]; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_update2: [%d,%d]:[%d,%d] on [%d,%d]\n", - When( disp), xoffset, yoffset, width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - - SAC_SDL2_lock( disp); - - if ( xoffset < 0 || yoffset < 0 || - xoffset + width > SDL2_DISP_WIDTH( disp) || - yoffset + height > SDL2_DISP_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_update2: Offset [%d,%d] + array [%d,%d] " - "exceeds display [%d,%d]\n", - xoffset, yoffset, width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else { - SAC_SDL2_update_rect( disp, - SDL2_DISP_X( disp) + xoffset, - SDL2_DISP_Y( disp) + yoffset, - width, height, async); - } - - SAC_SDL2_unlock( disp); -} - diff --git a/src/src/SDL2/window.c b/src/src/SDL2/window.c deleted file mode 100644 index f9d6842..0000000 --- a/src/src/SDL2/window.c +++ /dev/null @@ -1,41 +0,0 @@ -#include "SDL2sac.h" - -SDL2* SAC_SDL2_window( SDL2* disp, int offsets[2], int sizes[2]) -{ - const int width = sizes[1]; - const int height = sizes[0]; - const int xoffset = offsets[1]; - const int yoffset = offsets[0]; - SDL2* window = NULL; - - SAC_SDL2_check( disp); - if (SDL2_DEBUG( disp)) { - printf("%sSAC_SDL2_window: [%d,%d]:[%d,%d] on [%d,%d]\n", - When( disp), - xoffset, yoffset, - width, height, - SDL2_DISP_WIDTH( disp), - SDL2_DISP_HEIGHT( disp)); - } - - SAC_SDL2_lock( disp); - - if ( xoffset < 0 || yoffset < 0 || - width < 1 || height < 1 || - xoffset + width > SDL2_DISP_WIDTH( disp) || - yoffset + height > SDL2_DISP_HEIGHT( disp)) - { - SAC_RuntimeError( "SAC_SDL2_window: Invalid offset [%d,%d] + size [%d,%d] " - "on display [%d,%d]\n", - xoffset, yoffset, width, height, - SDL2_DISP_WIDTH( disp), SDL2_DISP_HEIGHT( disp)); - } - else { - window = SAC_SDL2_copy_disp( disp, xoffset, yoffset, width, height); - } - - SAC_SDL2_unlock( disp); - - return window; -} - diff --git a/src/src/sdl3.c b/src/src/sdl3.c new file mode 100644 index 0000000..1ab7d13 --- /dev/null +++ b/src/src/sdl3.c @@ -0,0 +1,41 @@ +#include + +#include "sac.h" + +typedef struct SDLdisplay { + SDL_Window *window; + SDL_Surface *surf; +} SDLdisplay; + +SDLdisplay initDisplay(int w, int h) +{ + SDLdisplay disp; + + if (!SDL_Init(SDL_INIT_VIDEO)) + { + SAC_RuntimeError("SDL_Init failed: %s", SDL_GetError()); + } + + SDL_Delay(2000); + + disp.window = SDL_CreateWindow("SDL3", w, h, 0); + if(disp.window == NULL) + { + SAC_RuntimeError("SDL_CreateWindow failed: %s", SDL_GetError()); + } + + SDL_Delay(2000); + + disp.surf = SDL_GetWindowSurface(disp.window); + + SDL_Delay(2000); + + return disp; +} + +void closeDisplay(SDLdisplay disp) +{ + SDL_DestroySurface(disp.surf); + SDL_DestroyWindow(disp.window); + SDL_Quit(); +} From 19e02ebd328ada6d788ef7527ae84f8fb00188e2 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Fri, 7 Nov 2025 16:00:19 +0100 Subject: [PATCH 02/18] it works standalone, but not from sac. ugh --- .github/workflows/main.yml | 2 +- src/SDLdisplay.sac | 14 +++-- src/example.sac | 7 +-- src/src/sdl3.c | 101 ++++++++++++++++++++++++++++++------- 4 files changed, 98 insertions(+), 26 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 45298f8..00adc3a 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,6 @@ name: Build On Changes -on: [push, pull_request] +on: [pull_request] env: BASE_URL: https://gitlab.sac-home.org/sac-group/sac-packages/-/raw/master/latest/weekly diff --git a/src/SDLdisplay.sac b/src/SDLdisplay.sac index e782a1a..ec79525 100644 --- a/src/SDLdisplay.sac +++ b/src/SDLdisplay.sac @@ -1,14 +1,18 @@ -class SDLdisplay; - -external classtype; +module SDLdisplay; export all; -external SDLdisplay initDisplay(int w, int h); +external void initDisplay(int w, int h); + #pragma effect World::TheWorld + #pragma linkobj "src/sdl3.o" + #pragma linkwith "SDL3" + +external void drawPixel(int x, int y, int r, int g, int b); #pragma effect World::TheWorld #pragma linkobj "src/sdl3.o" #pragma linkwith "SDL3" -external void closeDisplay(SDLdisplay disp); +external void closeDisplay(); + #pragma effect World::TheWorld #pragma linkobj "src/sdl3.o" #pragma linkwith "SDL3" diff --git a/src/example.sac b/src/example.sac index 02eed0e..d7ea406 100644 --- a/src/example.sac +++ b/src/example.sac @@ -3,9 +3,10 @@ use StdIO: all; int main() { printf("Hello, world!\n"); - disp = initDisplay(640, 480); + initDisplay(640, 480); printf("Created window\n"); - closeDisplay(disp); - printf("Closed window\n"); + drawPixel(50,50, 255,255,255); + drawPixel(60,60, 0,0,0); + closeDisplay(); return 0; } diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 1ab7d13..6a1488c 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -1,41 +1,108 @@ +#include +#include #include +#include -#include "sac.h" +//#include "sac.h" -typedef struct SDLdisplay { - SDL_Window *window; - SDL_Surface *surf; -} SDLdisplay; +SDL_Window *window = NULL; +SDL_Surface *surface = NULL; +SDL_Mutex *mutex = NULL; -SDLdisplay initDisplay(int w, int h) +// typedef struct SDLdisplay { +// SDL_Window *window; +// SDL_Renderer *renderer; +// SDL_Surface *surface; +// SDL_Mutex *mutex; +// } SDLdisplay; + +void initDisplay(int w, int h) { - SDLdisplay disp; + assert(window == NULL); + assert(surface == NULL); + assert(mutex == NULL); if (!SDL_Init(SDL_INIT_VIDEO)) { - SAC_RuntimeError("SDL_Init failed: %s", SDL_GetError()); + printf("SDL_Init failed: %s\n", SDL_GetError()); } - SDL_Delay(2000); + printf("a\n"); + window = SDL_CreateWindow("SDL3", w, h, 0); + if(window == NULL) + { + printf("SDL_CreateWindow failed: %s\n", SDL_GetError()); + } - disp.window = SDL_CreateWindow("SDL3", w, h, 0); - if(disp.window == NULL) + printf("b\n"); + + assert(window != NULL); + surface = SDL_GetWindowSurface(window); + if(surface == NULL) { - SAC_RuntimeError("SDL_CreateWindow failed: %s", SDL_GetError()); + printf("SDL_GetWindowSurface failed: %s\n", SDL_GetError()); } + SDL_ClearSurface(surface, 0., 0., 120., 255.); + SDL_UpdateWindowSurface(window); + + printf("c\n"); + + + SDL_Delay(2000); - disp.surf = SDL_GetWindowSurface(disp.window); + mutex = SDL_CreateMutex(); + if(mutex == NULL) + { + printf("SDL_CreateMutex failed: %s\n", SDL_GetError()); + } SDL_Delay(2000); +} + +void drawPixel(int x, int y, int r, int g, int b) +{ + printf("drawing pixel at %d %d\n", x, y); + + SDL_LockMutex(mutex); + + if (SDL_MUSTLOCK(surface)) { + if (!SDL_LockSurface(surface)) { + printf("SDL_LockSurface failed: %s\n", SDL_GetError()); + } + } - return disp; + int yoffset = x * (surface->pitch / 4); + int xoffset = y; + + Uint32 *bptr = (Uint32 *) (surface->pixels) + xoffset + yoffset; + *bptr = r << 16 | g << 8 | b; + + if (SDL_MUSTLOCK(surface)) { + SDL_UnlockSurface(surface); + } + + SDL_UpdateWindowSurface(window); + + SDL_UnlockMutex(mutex); } -void closeDisplay(SDLdisplay disp) + +void closeDisplay(void) { - SDL_DestroySurface(disp.surf); - SDL_DestroyWindow(disp.window); + printf("SDL_Quit\n"); SDL_Quit(); } + +#if 0 +int main() +{ + initDisplay(640, 480); + printf("Created window\n"); + drawPixel(50,50, 255,255,255); + drawPixel(60,60, 0,0,0); + closeDisplay(); + return 0; +} +#endif From 82c2d36768899f4bedb5393c9d4d7e207807c1fb Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Wed, 19 Nov 2025 17:29:42 +0100 Subject: [PATCH 03/18] get a simple example working again --- CMakeLists.txt | 1 + README.md | 5 ++ src/SDLdisplay.sac | 14 +++-- src/example.sac | 17 ++++-- src/src/sdl3.c | 143 +++++++++++++++++++++++---------------------- 5 files changed, 101 insertions(+), 79 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d714510..80aa5fd 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -14,6 +14,7 @@ LIST (APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-common") INCLUDE ("cmake-common/check-sac2c.cmake") INCLUDE ("cmake-common/misc-macros.cmake") +SET (SDL_BUILDING_LIBRARY ON) FIND_PACKAGE (SDL3 REQUIRED) FIND_PACKAGE (X11 REQUIRED) diff --git a/README.md b/README.md index 69c303b..8e78d36 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,11 @@ SAC SDL Module ============== +Note +---- + +Due to a bug in the private head manager, requires the `-noPHM` flag. + About ----- diff --git a/src/SDLdisplay.sac b/src/SDLdisplay.sac index ec79525..49fdc04 100644 --- a/src/SDLdisplay.sac +++ b/src/SDLdisplay.sac @@ -1,18 +1,24 @@ -module SDLdisplay; +class SDLdisplay; + +external classtype; export all; -external void initDisplay(int w, int h); +external SDLdisplay initDisplay(int w, int h); #pragma effect World::TheWorld #pragma linkobj "src/sdl3.o" #pragma linkwith "SDL3" + #pragma linksign [0,1,2] -external void drawPixel(int x, int y, int r, int g, int b); +external SDLdisplay drawScreen(SDLdisplay ctx, int[w,h,3] pixels); #pragma effect World::TheWorld #pragma linkobj "src/sdl3.o" #pragma linkwith "SDL3" + #pragma linksign [1,1,2] + #pragma sacarg [2] -external void closeDisplay(); +external void closeDisplay(SDLdisplay ctx); #pragma effect World::TheWorld #pragma linkobj "src/sdl3.o" #pragma linkwith "SDL3" + #pragma linksign [1] diff --git a/src/example.sac b/src/example.sac index d7ea406..a660f2b 100644 --- a/src/example.sac +++ b/src/example.sac @@ -1,12 +1,17 @@ +use Array: all; use SDLdisplay: all; use StdIO: all; int main() { - printf("Hello, world!\n"); - initDisplay(640, 480); - printf("Created window\n"); - drawPixel(50,50, 255,255,255); - drawPixel(60,60, 0,0,0); - closeDisplay(); + printf("initDisplay\n"); + ctx = initDisplay(640, 480); + + printf("drawPixel\n"); + pixels = reshape([640,480,3], iota(640*480*3) % 256); + ctx = drawScreen(ctx, pixels); + + printf("closeDisplay\n"); + closeDisplay(ctx); + printf("Done\n"); return 0; } diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 6a1488c..3bb2ba4 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -1,108 +1,113 @@ #include #include +#include #include -#include +#include -//#include "sac.h" +#include "sac.h" +#include "sacinterface.h" -SDL_Window *window = NULL; -SDL_Surface *surface = NULL; -SDL_Mutex *mutex = NULL; +typedef struct SDLcontext { + int width, height; + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Texture *texture; + SDL_Mutex *mutex; +} SDLcontext; -// typedef struct SDLdisplay { -// SDL_Window *window; -// SDL_Renderer *renderer; -// SDL_Surface *surface; -// SDL_Mutex *mutex; -// } SDLdisplay; - -void initDisplay(int w, int h) +SDLcontext *initDisplay(int width, int height) { - assert(window == NULL); - assert(surface == NULL); - assert(mutex == NULL); + SDLcontext *ctx = (SDLcontext *)malloc(sizeof(SDLcontext)); + ctx->width = width; + ctx->height = height; + + // Fix for using SDL with X-forwarding over SSH + XInitThreads(); if (!SDL_Init(SDL_INIT_VIDEO)) { - printf("SDL_Init failed: %s\n", SDL_GetError()); + SAC_RuntimeError("SDL_Init failed: %s", SDL_GetError()); } - printf("a\n"); - window = SDL_CreateWindow("SDL3", w, h, 0); - if(window == NULL) + if(!SDL_CreateWindowAndRenderer("SaC SDL3", width, height, 0, &ctx->window, &ctx->renderer)) { - printf("SDL_CreateWindow failed: %s\n", SDL_GetError()); + SAC_RuntimeError("SDL_CreateWindowAndRenderer failed: %s", SDL_GetError()); } - printf("b\n"); - - assert(window != NULL); - surface = SDL_GetWindowSurface(window); - if(surface == NULL) + ctx->texture = SDL_CreateTexture(ctx->renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, width, height); + if(ctx->texture == NULL) { - printf("SDL_GetWindowSurface failed: %s\n", SDL_GetError()); + SAC_RuntimeError("SDL_CreateTexture failed: %s", SDL_GetError()); } - SDL_ClearSurface(surface, 0., 0., 120., 255.); - SDL_UpdateWindowSurface(window); - - printf("c\n"); - + uint32_t *pixels = (uint32_t *)malloc(width * height * sizeof(uint32_t)); + for (int y = 0; y < height; y++) { + for (int x = 0; x < width; x++) { + uint8_t r = (x % 2) * 255; + uint8_t g = (y % 2) * 255; + uint8_t b = ((x + y) % 2) * 255; + uint8_t a = 255; + pixels[x + y * width] = (r << 0) | (g << 8) | (b << 16) | (a << 24); + } + } + SDL_UpdateTexture(ctx->texture, NULL, pixels, width * sizeof(uint32_t)); + free(pixels); - SDL_Delay(2000); + SDL_RenderClear(ctx->renderer); + SDL_RenderTexture(ctx->renderer, ctx->texture, NULL, NULL); + SDL_RenderPresent(ctx->renderer); - mutex = SDL_CreateMutex(); - if(mutex == NULL) + ctx->mutex = SDL_CreateMutex(); + if(ctx->mutex == NULL) { printf("SDL_CreateMutex failed: %s\n", SDL_GetError()); } - SDL_Delay(2000); + SAC_Print ("Created %dx%d SDL3 display\n", width, height); + return ctx; } -void drawPixel(int x, int y, int r, int g, int b) +void drawScreen(SDLcontext *ctx, SACarg *sa_pixels) { - printf("drawing pixel at %d %d\n", x, y); - - SDL_LockMutex(mutex); - - if (SDL_MUSTLOCK(surface)) { - if (!SDL_LockSurface(surface)) { - printf("SDL_LockSurface failed: %s\n", SDL_GetError()); + assert(SACARGgetDim(sa_pixels) == 3); + assert(SACARGgetShape(sa_pixels, 0) == ctx->width); + assert(SACARGgetShape(sa_pixels, 1) == ctx->height); + assert(SACARGgetShape(sa_pixels, 2) == 3); + + SDL_LockMutex(ctx->mutex); + + const int *sa_pixel_data = SACARGgetSharedData(SACTYPE__MAIN__int, sa_pixels); + + uint32_t *pixels = (uint32_t *)malloc(ctx->width * ctx->height * sizeof(uint32_t)); + for (int i = 0, y = 0; y < ctx->height; y++) { + for (int x = 0; x < ctx->width; x++, i++) { + uint8_t r = sa_pixel_data[3 * i + 0]; + uint8_t g = sa_pixel_data[3 * i + 1]; + uint8_t b = sa_pixel_data[3 * i + 2]; + uint8_t a = 255; + pixels[i] = (r << 0) | (g << 8) | (b << 16) | (a << 24); } } - int yoffset = x * (surface->pitch / 4); - int xoffset = y; - - Uint32 *bptr = (Uint32 *) (surface->pixels) + xoffset + yoffset; - *bptr = r << 16 | g << 8 | b; + SDL_UpdateTexture(ctx->texture, NULL, pixels, ctx->width * sizeof(uint32_t)); + free(pixels); - if (SDL_MUSTLOCK(surface)) { - SDL_UnlockSurface(surface); - } + SDL_RenderClear(ctx->renderer); + SDL_RenderTexture(ctx->renderer, ctx->texture, NULL, NULL); + SDL_RenderPresent(ctx->renderer); - SDL_UpdateWindowSurface(window); + SDL_Delay(5000); - SDL_UnlockMutex(mutex); + SDL_UnlockMutex(ctx->mutex); } - -void closeDisplay(void) +void closeDisplay(SDLcontext *ctx) { - printf("SDL_Quit\n"); + printf("Closing %dx%d SDL3 display\n", ctx->width, ctx->height); + SDL_DestroyMutex(ctx->mutex); + SDL_DestroyTexture(ctx->texture); + SDL_DestroyRenderer(ctx->renderer); + SDL_DestroyWindow(ctx->window); SDL_Quit(); } - -#if 0 -int main() -{ - initDisplay(640, 480); - printf("Created window\n"); - drawPixel(50,50, 255,255,255); - drawPixel(60,60, 0,0,0); - closeDisplay(); - return 0; -} -#endif From 0dc09d5768736ba6918477b40cbd8c604cef5a76 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Wed, 19 Nov 2025 17:37:45 +0100 Subject: [PATCH 04/18] use SDL_LockTexture --- src/src/sdl3.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 3bb2ba4..c121db7 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -52,7 +52,7 @@ SDLcontext *initDisplay(int width, int height) } SDL_UpdateTexture(ctx->texture, NULL, pixels, width * sizeof(uint32_t)); - free(pixels); + //free(pixels); SDL_RenderClear(ctx->renderer); SDL_RenderTexture(ctx->renderer, ctx->texture, NULL, NULL); @@ -79,7 +79,13 @@ void drawScreen(SDLcontext *ctx, SACarg *sa_pixels) const int *sa_pixel_data = SACARGgetSharedData(SACTYPE__MAIN__int, sa_pixels); - uint32_t *pixels = (uint32_t *)malloc(ctx->width * ctx->height * sizeof(uint32_t)); + uint32_t *pixels; + int pitch; + if (!SDL_LockTexture(ctx->texture, NULL, (void **)&pixels, &pitch)) { + SAC_RuntimeError("SDL_LockTexture failed: %s", SDL_GetError()); + } + assert(pitch == ctx->width * sizeof(uint32_t)); + for (int i = 0, y = 0; y < ctx->height; y++) { for (int x = 0; x < ctx->width; x++, i++) { uint8_t r = sa_pixel_data[3 * i + 0]; @@ -90,8 +96,7 @@ void drawScreen(SDLcontext *ctx, SACarg *sa_pixels) } } - SDL_UpdateTexture(ctx->texture, NULL, pixels, ctx->width * sizeof(uint32_t)); - free(pixels); + SDL_UnlockTexture(ctx->texture); SDL_RenderClear(ctx->renderer); SDL_RenderTexture(ctx->renderer, ctx->texture, NULL, NULL); From 1e758591c6751b7a1d729586521fda2400015d67 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Thu, 20 Nov 2025 13:44:00 +0100 Subject: [PATCH 05/18] draw entire arrays to the screen --- examples/mandelbrot.sac | 93 +++++++++++++++++++++++++++++++++++++++++ examples/minimal.sac | 27 ++++++++++++ src/SDLdisplay.sac | 14 +++---- src/example.sac | 17 -------- src/src/sdl3.c | 78 ++++++++++------------------------ 5 files changed, 148 insertions(+), 81 deletions(-) create mode 100644 examples/mandelbrot.sac create mode 100644 examples/minimal.sac delete mode 100644 src/example.sac diff --git a/examples/mandelbrot.sac b/examples/mandelbrot.sac new file mode 100644 index 0000000..5770a88 --- /dev/null +++ b/examples/mandelbrot.sac @@ -0,0 +1,93 @@ +use SDLdisplay: all; +use Structures: all; +use Numerical: { log2 }; + +external uint sleep(uint x); + #pragma effect World::TheWorld + #pragma linksign [0,1] + #pragma linkname "sleep" + #pragma header "" + +inline +complex[yres,xres] genComplexArray(int yres, int xres, + complex cmin, complex cmax) +{ + dR = real(cmax) - real(cmin); + dI = imag(cmax) - imag(cmin); + return { [y,x] -> cmin + toc((tod(x) / tod(xres)) * dR, + (tod(y) / tod(yres)) * dI) + | [y,x] < [yres,xres] }; +} + +inline +int, complex escapeTimeAndValue(complex c, int depth) +{ + time = 0; + z = c; + + while (time < depth && normSq(z) <= 4d) { + z = z * z + c; + time += 1; + } + + return (time, z); +} + +inline +int[2:shp], complex[2:shp] escapeTimeAndValue(complex[2:shp] arr, int depth) +{ + ts, vs = { iv -> escapeTimeAndValue(arr[iv], depth) }; + return (ts, vs); +} + +inline +double[2:shp] normalizeIterationCount(int[2:shp] ts, complex[2:shp] vs) +{ + return where(normSq(vs) <= 4d, + 0d, + tod(ts + 1) - log2(log2(norm(vs)))); +} + +inline +Color8[2:shp] intToMonochrome(int[2:shp] arr) +{ + scaled_vals = (arr * 255) / maxval(arr); + clut = genLogarithmicClut(0.4d, 0.9d, white(), black()); + return { iv -> clut[scaled_vals[iv]] }; +} + +inline +Color8[2:shp] doubleToRgb(double[2:shp] arr) +{ + scaled_vals = toi((arr * 360d) / maxval(arr)); + return Hsb2Rgb(scaled_vals, 60, 80); +} + +int main() { + XRES = 640; + YRES = 480; + DEPTH = 2048; + + ctx = initDisplay(YRES, XRES); + + cmin = toc(-2.2, 1.0); + cmax = toc( 0.8, -1.0); + arr = genComplexArray(YRES, XRES, cmin, cmax); + + ts, vs = escapeTimeAndValue(arr, DEPTH); + +#if 1 + rgb = intToMonochrome(ts); +#else + nvs = normalizeIterationCount(ts, vs); + rgb = doubleToRgb(nvs); +#endif + + rgb = Color8::toi(rgb); + ctx = drawPixels(ctx, rgb); + + _ = sleep(5ui); + + status = closeDisplay(ctx); + return status; +} diff --git a/examples/minimal.sac b/examples/minimal.sac new file mode 100644 index 0000000..b06952d --- /dev/null +++ b/examples/minimal.sac @@ -0,0 +1,27 @@ +use SDLdisplay: all; + +external uint sleep(uint x); + #pragma effect World::TheWorld + #pragma linksign [0,1] + #pragma linkname "sleep" + #pragma header "" + +int[w,h,3] makePixels(int w, int h) +{ + return { [i,j] -> [_mod_SxS_(i, 256), _mod_SxS_(j, 256), 0] + | [i,j] < [w,h] }; +} + +int main() { + XRES = 640; + YRES = 480; + + ctx = initDisplay(YRES, XRES); + pixels = makePixels(YRES, XRES); + ctx = drawPixels(ctx, pixels); + + _ = sleep(5ui); + + status = closeDisplay(ctx); + return status; +} diff --git a/src/SDLdisplay.sac b/src/SDLdisplay.sac index 49fdc04..4bbd78e 100644 --- a/src/SDLdisplay.sac +++ b/src/SDLdisplay.sac @@ -4,21 +4,21 @@ external classtype; export all; -external SDLdisplay initDisplay(int w, int h); - #pragma effect World::TheWorld +external SDLdisplay initDisplay(int h, int w); + #pragma linkname "SAC_InitDisplay" #pragma linkobj "src/sdl3.o" #pragma linkwith "SDL3" #pragma linksign [0,1,2] -external SDLdisplay drawScreen(SDLdisplay ctx, int[w,h,3] pixels); - #pragma effect World::TheWorld +external SDLdisplay drawPixels(SDLdisplay ctx, int[h,w,3] pixels); + #pragma linkname "SAC_DrawPixels" #pragma linkobj "src/sdl3.o" #pragma linkwith "SDL3" #pragma linksign [1,1,2] #pragma sacarg [2] -external void closeDisplay(SDLdisplay ctx); - #pragma effect World::TheWorld +external int closeDisplay(SDLdisplay ctx); + #pragma linkname "SAC_CloseDisplay" #pragma linkobj "src/sdl3.o" #pragma linkwith "SDL3" - #pragma linksign [1] + #pragma linksign [0,1] diff --git a/src/example.sac b/src/example.sac deleted file mode 100644 index a660f2b..0000000 --- a/src/example.sac +++ /dev/null @@ -1,17 +0,0 @@ -use Array: all; -use SDLdisplay: all; -use StdIO: all; - -int main() { - printf("initDisplay\n"); - ctx = initDisplay(640, 480); - - printf("drawPixel\n"); - pixels = reshape([640,480,3], iota(640*480*3) % 256); - ctx = drawScreen(ctx, pixels); - - printf("closeDisplay\n"); - closeDisplay(ctx); - printf("Done\n"); - return 0; -} diff --git a/src/src/sdl3.c b/src/src/sdl3.c index c121db7..8189e10 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -12,10 +12,9 @@ typedef struct SDLcontext { SDL_Window *window; SDL_Renderer *renderer; SDL_Texture *texture; - SDL_Mutex *mutex; } SDLcontext; -SDLcontext *initDisplay(int width, int height) +SDLcontext *SAC_InitDisplay(int height, int width) { SDLcontext *ctx = (SDLcontext *)malloc(sizeof(SDLcontext)); ctx->width = width; @@ -24,95 +23,60 @@ SDLcontext *initDisplay(int width, int height) // Fix for using SDL with X-forwarding over SSH XInitThreads(); - if (!SDL_Init(SDL_INIT_VIDEO)) - { + if (!SDL_Init(SDL_INIT_VIDEO)) { SAC_RuntimeError("SDL_Init failed: %s", SDL_GetError()); } - if(!SDL_CreateWindowAndRenderer("SaC SDL3", width, height, 0, &ctx->window, &ctx->renderer)) - { + if(!SDL_CreateWindowAndRenderer("SaC SDL3", width, height, 0, &ctx->window, &ctx->renderer)) { SAC_RuntimeError("SDL_CreateWindowAndRenderer failed: %s", SDL_GetError()); } - ctx->texture = SDL_CreateTexture(ctx->renderer, SDL_PIXELFORMAT_RGBA32, SDL_TEXTUREACCESS_STREAMING, width, height); - if(ctx->texture == NULL) - { + ctx->texture = SDL_CreateTexture(ctx->renderer, SDL_PIXELFORMAT_RGB24, SDL_TEXTUREACCESS_STREAMING, width, height); + if(ctx->texture == NULL) { SAC_RuntimeError("SDL_CreateTexture failed: %s", SDL_GetError()); } - uint32_t *pixels = (uint32_t *)malloc(width * height * sizeof(uint32_t)); - for (int y = 0; y < height; y++) { - for (int x = 0; x < width; x++) { - uint8_t r = (x % 2) * 255; - uint8_t g = (y % 2) * 255; - uint8_t b = ((x + y) % 2) * 255; - uint8_t a = 255; - pixels[x + y * width] = (r << 0) | (g << 8) | (b << 16) | (a << 24); - } - } - - SDL_UpdateTexture(ctx->texture, NULL, pixels, width * sizeof(uint32_t)); - //free(pixels); - SDL_RenderClear(ctx->renderer); - SDL_RenderTexture(ctx->renderer, ctx->texture, NULL, NULL); SDL_RenderPresent(ctx->renderer); - - ctx->mutex = SDL_CreateMutex(); - if(ctx->mutex == NULL) - { - printf("SDL_CreateMutex failed: %s\n", SDL_GetError()); - } - - SAC_Print ("Created %dx%d SDL3 display\n", width, height); return ctx; } -void drawScreen(SDLcontext *ctx, SACarg *sa_pixels) +void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels) { assert(SACARGgetDim(sa_pixels) == 3); - assert(SACARGgetShape(sa_pixels, 0) == ctx->width); - assert(SACARGgetShape(sa_pixels, 1) == ctx->height); + assert(SACARGgetShape(sa_pixels, 0) == ctx->height); + assert(SACARGgetShape(sa_pixels, 1) == ctx->width); assert(SACARGgetShape(sa_pixels, 2) == 3); - SDL_LockMutex(ctx->mutex); - - const int *sa_pixel_data = SACARGgetSharedData(SACTYPE__MAIN__int, sa_pixels); + const int *src_colors = SACARGgetSharedData(SACTYPE__MAIN__int, sa_pixels); - uint32_t *pixels; + uint8_t *dst_pixels; int pitch; - if (!SDL_LockTexture(ctx->texture, NULL, (void **)&pixels, &pitch)) { + if (!SDL_LockTexture(ctx->texture, NULL, (void **)&dst_pixels, &pitch)) { SAC_RuntimeError("SDL_LockTexture failed: %s", SDL_GetError()); } - assert(pitch == ctx->width * sizeof(uint32_t)); - for (int i = 0, y = 0; y < ctx->height; y++) { - for (int x = 0; x < ctx->width; x++, i++) { - uint8_t r = sa_pixel_data[3 * i + 0]; - uint8_t g = sa_pixel_data[3 * i + 1]; - uint8_t b = sa_pixel_data[3 * i + 2]; - uint8_t a = 255; - pixels[i] = (r << 0) | (g << 8) | (b << 16) | (a << 24); + for (int y = 0; y < ctx->height; y++) { + const int *src_row = src_colors + y * ctx->width * 3; + uint8_t *dst_row = dst_pixels + y * pitch; + + for (int x = 0; x < 3 * ctx->width; x += 3) { + dst_row[x + 0] = (uint8_t)(src_row[x + 0]); + dst_row[x + 1] = (uint8_t)(src_row[x + 1]); + dst_row[x + 2] = (uint8_t)(src_row[x + 2]); } } SDL_UnlockTexture(ctx->texture); - - SDL_RenderClear(ctx->renderer); SDL_RenderTexture(ctx->renderer, ctx->texture, NULL, NULL); SDL_RenderPresent(ctx->renderer); - - SDL_Delay(5000); - - SDL_UnlockMutex(ctx->mutex); } -void closeDisplay(SDLcontext *ctx) +int SAC_CloseDisplay(SDLcontext *ctx) { - printf("Closing %dx%d SDL3 display\n", ctx->width, ctx->height); - SDL_DestroyMutex(ctx->mutex); SDL_DestroyTexture(ctx->texture); SDL_DestroyRenderer(ctx->renderer); SDL_DestroyWindow(ctx->window); SDL_Quit(); + return 0; } From ba720b1d27efa6f04684305bc98667988af005ff Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Thu, 20 Nov 2025 13:56:19 +0100 Subject: [PATCH 06/18] start up event thread --- src/src/sdl3.c | 32 ++++++++++++++++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 8189e10..00d35f4 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -14,6 +14,33 @@ typedef struct SDLcontext { SDL_Texture *texture; } SDLcontext; +static void SAC_EventHandler(void *data) +{ + SDL_Window *window = (SDL_Window *)data; + bool running = true; + + while (running) { + SDL_Event event; + + if (!SDL_WaitEvent(&event)) { + SAC_RuntimeError("SDL_WaitEvent failed: %s", SDL_GetError()); + } + + switch (event.type) { + case SDL_EVENT_QUIT: + running = false; + break; + + default: + break; + } + } + + printf("SDL quit event received\n"); + SDL_DestroyWindow(window); + exit(0); +} + SDLcontext *SAC_InitDisplay(int height, int width) { SDLcontext *ctx = (SDLcontext *)malloc(sizeof(SDLcontext)); @@ -36,6 +63,11 @@ SDLcontext *SAC_InitDisplay(int height, int width) SAC_RuntimeError("SDL_CreateTexture failed: %s", SDL_GetError()); } + SDL_Thread *t = SDL_CreateThread(SAC_EventHandler, "SAC_EventHandler", (void *)ctx->window); + if (t == NULL) { + SAC_RuntimeError("SDL_CreateThread failed: %s", SDL_GetError()); + } + SDL_RenderClear(ctx->renderer); SDL_RenderPresent(ctx->renderer); return ctx; From 6d805649a88573062b78b62eb77b5ee50f723d42 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Thu, 20 Nov 2025 14:32:46 +0100 Subject: [PATCH 07/18] event handler and (more) graceful closing --- examples/mandelbrot.sac | 28 +++++++++++----------- src/SDLdisplay.sac | 6 +++++ src/src/sdl3.c | 51 +++++++++++++++++++++++++---------------- src/src/sdl3.h | 24 +++++++++++++++++++ 4 files changed, 76 insertions(+), 33 deletions(-) create mode 100644 src/src/sdl3.h diff --git a/examples/mandelbrot.sac b/examples/mandelbrot.sac index 5770a88..839624b 100644 --- a/examples/mandelbrot.sac +++ b/examples/mandelbrot.sac @@ -70,23 +70,25 @@ int main() { ctx = initDisplay(YRES, XRES); - cmin = toc(-2.2, 1.0); - cmax = toc( 0.8, -1.0); - arr = genComplexArray(YRES, XRES, cmin, cmax); + while (isRunning(ctx)) { + cmin = toc(-2.2, 1.0); + cmax = toc( 0.8, -1.0); + arr = genComplexArray(YRES, XRES, cmin, cmax); - ts, vs = escapeTimeAndValue(arr, DEPTH); + ts, vs = escapeTimeAndValue(arr, DEPTH); -#if 1 - rgb = intToMonochrome(ts); -#else - nvs = normalizeIterationCount(ts, vs); - rgb = doubleToRgb(nvs); -#endif + #if 1 + rgb = intToMonochrome(ts); + #else + nvs = normalizeIterationCount(ts, vs); + rgb = doubleToRgb(nvs); + #endif - rgb = Color8::toi(rgb); - ctx = drawPixels(ctx, rgb); + rgb = Color8::toi(rgb); + ctx = drawPixels(ctx, rgb); - _ = sleep(5ui); + _ = sleep(1ui); + } status = closeDisplay(ctx); return status; diff --git a/src/SDLdisplay.sac b/src/SDLdisplay.sac index 4bbd78e..157c620 100644 --- a/src/SDLdisplay.sac +++ b/src/SDLdisplay.sac @@ -17,6 +17,12 @@ external SDLdisplay drawPixels(SDLdisplay ctx, int[h,w,3] pixels); #pragma linksign [1,1,2] #pragma sacarg [2] +external bool isRunning(SDLdisplay &ctx); + #pragma linkname "SAC_IsRunning" + #pragma linkobj "src/sdl3.o" + #pragma linkwith "SDL3" + #pragma linksign [0,1] + external int closeDisplay(SDLdisplay ctx); #pragma linkname "SAC_CloseDisplay" #pragma linkobj "src/sdl3.o" diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 00d35f4..1c592b8 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -4,22 +4,11 @@ #include #include -#include "sac.h" -#include "sacinterface.h" +#include "sdl3.h" -typedef struct SDLcontext { - int width, height; - SDL_Window *window; - SDL_Renderer *renderer; - SDL_Texture *texture; -} SDLcontext; - -static void SAC_EventHandler(void *data) +static int SAC_EventHandler(SDLcontext *ctx) { - SDL_Window *window = (SDL_Window *)data; - bool running = true; - - while (running) { + while (ctx->running) { SDL_Event event; if (!SDL_WaitEvent(&event)) { @@ -28,7 +17,7 @@ static void SAC_EventHandler(void *data) switch (event.type) { case SDL_EVENT_QUIT: - running = false; + ctx->running = false; break; default: @@ -37,8 +26,7 @@ static void SAC_EventHandler(void *data) } printf("SDL quit event received\n"); - SDL_DestroyWindow(window); - exit(0); + return 0; } SDLcontext *SAC_InitDisplay(int height, int width) @@ -46,6 +34,7 @@ SDLcontext *SAC_InitDisplay(int height, int width) SDLcontext *ctx = (SDLcontext *)malloc(sizeof(SDLcontext)); ctx->width = width; ctx->height = height; + ctx->running = true; // Fix for using SDL with X-forwarding over SSH XInitThreads(); @@ -63,8 +52,8 @@ SDLcontext *SAC_InitDisplay(int height, int width) SAC_RuntimeError("SDL_CreateTexture failed: %s", SDL_GetError()); } - SDL_Thread *t = SDL_CreateThread(SAC_EventHandler, "SAC_EventHandler", (void *)ctx->window); - if (t == NULL) { + ctx->eventHandler = SDL_CreateThread(SAC_EventHandler, "SAC_EventHandler", ctx); + if (ctx->eventHandler == NULL) { SAC_RuntimeError("SDL_CreateThread failed: %s", SDL_GetError()); } @@ -104,11 +93,33 @@ void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels) SDL_RenderPresent(ctx->renderer); } +/// Wait for a selection of the user +/// Returns an int[2,2] of the form: [[xmin,ymin], [xmax,ymax]] +//SACarg *SAC_GetSelection(SDLcontext *ctx) +//{ +// return SACARGcreateFromPointer (SACTYPE__MAIN__int, (void *)zoomCoords, 2, 2, 2); +//} + int SAC_CloseDisplay(SDLcontext *ctx) { + SDL_Event quitEvent; + quitEvent.type = SDL_EVENT_QUIT; + if (!SDL_PushEvent(&quitEvent)) { + SAC_RuntimeError("SDL_PushEvent failed: %s", SDL_GetError()); + } + + int exitStatus; + SDL_WaitThread(ctx->eventHandler, &exitStatus); + SDL_DestroyTexture(ctx->texture); SDL_DestroyRenderer(ctx->renderer); SDL_DestroyWindow(ctx->window); SDL_Quit(); - return 0; + + return exitStatus; +} + +bool SAC_IsRunning(SDLcontext *ctx) +{ + return (ctx)->running; } diff --git a/src/src/sdl3.h b/src/src/sdl3.h new file mode 100644 index 0000000..1655311 --- /dev/null +++ b/src/src/sdl3.h @@ -0,0 +1,24 @@ +#ifndef _SACSDL3_H_ +#define _SACSDL3_H_ + +#include +#include + +#include "sac.h" +#include "sacinterface.h" + +typedef struct SDLcontext { + bool running; + int width, height; + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Texture *texture; + SDL_Thread *eventHandler; +} SDLcontext; + +extern SDLcontext *SAC_InitDisplay(int height, int width); +extern void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels); +extern int SAC_CloseDisplay(SDLcontext *ctx); +extern bool SAC_IsRunning(SDLcontext *ctx); + +#endif /* _SACSDL3_H_ */ From b62a09adc1b2850ab8adca6083dbf8448a260864 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Thu, 20 Nov 2025 14:35:00 +0100 Subject: [PATCH 08/18] event handler and (more) graceful closing --- src/src/sdl3.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 1c592b8..13ad5f6 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -102,10 +102,12 @@ void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels) int SAC_CloseDisplay(SDLcontext *ctx) { - SDL_Event quitEvent; - quitEvent.type = SDL_EVENT_QUIT; - if (!SDL_PushEvent(&quitEvent)) { - SAC_RuntimeError("SDL_PushEvent failed: %s", SDL_GetError()); + if (ctx->running) { + SDL_Event quitEvent; + quitEvent.type = SDL_EVENT_QUIT; + if (!SDL_PushEvent(&quitEvent)) { + SAC_RuntimeError("SDL_PushEvent failed: %s", SDL_GetError()); + } } int exitStatus; From f793eef5efecafc8a958828a76eddac466e659ab Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Thu, 20 Nov 2025 14:41:54 +0100 Subject: [PATCH 09/18] setup for getSelection --- examples/mandelbrot.sac | 2 +- src/SDLdisplay.sac | 7 +++++++ src/src/sdl3.c | 15 ++++++++++----- src/src/sdl3.h | 1 + 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/examples/mandelbrot.sac b/examples/mandelbrot.sac index 839624b..1c71111 100644 --- a/examples/mandelbrot.sac +++ b/examples/mandelbrot.sac @@ -87,7 +87,7 @@ int main() { rgb = Color8::toi(rgb); ctx = drawPixels(ctx, rgb); - _ = sleep(1ui); + zoom_coords, ctx = getSelection(ctx); } status = closeDisplay(ctx); diff --git a/src/SDLdisplay.sac b/src/SDLdisplay.sac index 157c620..81a6efc 100644 --- a/src/SDLdisplay.sac +++ b/src/SDLdisplay.sac @@ -17,6 +17,13 @@ external SDLdisplay drawPixels(SDLdisplay ctx, int[h,w,3] pixels); #pragma linksign [1,1,2] #pragma sacarg [2] +external int[2,2], SDLdisplay getSelection(SDLdisplay ctx); + #pragma linkname "SAC_GetSelection" + #pragma linkobj "src/sdl3.o" + #pragma linkwith "SDL3" + #pragma linksign [0,1,1] + #pragma sacarg [0] + external bool isRunning(SDLdisplay &ctx); #pragma linkname "SAC_IsRunning" #pragma linkobj "src/sdl3.o" diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 13ad5f6..3878cfd 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -94,11 +94,16 @@ void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels) } /// Wait for a selection of the user -/// Returns an int[2,2] of the form: [[xmin,ymin], [xmax,ymax]] -//SACarg *SAC_GetSelection(SDLcontext *ctx) -//{ -// return SACARGcreateFromPointer (SACTYPE__MAIN__int, (void *)zoomCoords, 2, 2, 2); -//} +/// Returns an int[2,2] of the form: [topleft, bottomright] = [[ymin,xmin], [ymax,xmax]] +SACarg *SAC_GetSelection(SDLcontext *ctx) +{ + int *zoomCoords = malloc(4 * sizeof (int)); + zoomCoords[0] = 0; + zoomCoords[1] = 0; + zoomCoords[2] = 0; + zoomCoords[3] = 0; + return SACARGcreateFromPointer (SACTYPE__MAIN__int, (void *)zoomCoords, 2, 2, 2); +} int SAC_CloseDisplay(SDLcontext *ctx) { diff --git a/src/src/sdl3.h b/src/src/sdl3.h index 1655311..691f55b 100644 --- a/src/src/sdl3.h +++ b/src/src/sdl3.h @@ -18,6 +18,7 @@ typedef struct SDLcontext { extern SDLcontext *SAC_InitDisplay(int height, int width); extern void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels); +extern SACarg *SAC_GetSelection(SDLcontext *ctx); extern int SAC_CloseDisplay(SDLcontext *ctx); extern bool SAC_IsRunning(SDLcontext *ctx); From 950d118b92c4a303f09509d0cc2915ee2de200f5 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Thu, 20 Nov 2025 15:17:32 +0100 Subject: [PATCH 10/18] selection --- examples/mandelbrot.sac | 16 ++++++++--- src/src/sdl3.c | 60 ++++++++++++++++++++++++++++++++++------- src/src/sdl3.h | 9 +++++++ 3 files changed, 71 insertions(+), 14 deletions(-) diff --git a/examples/mandelbrot.sac b/examples/mandelbrot.sac index 1c71111..b410b64 100644 --- a/examples/mandelbrot.sac +++ b/examples/mandelbrot.sac @@ -69,11 +69,11 @@ int main() { DEPTH = 2048; ctx = initDisplay(YRES, XRES); + cmin = [toc(-2.2, 1.0)]; + cmax = [toc( 0.8, -1.0)]; while (isRunning(ctx)) { - cmin = toc(-2.2, 1.0); - cmax = toc( 0.8, -1.0); - arr = genComplexArray(YRES, XRES, cmin, cmax); + arr = genComplexArray(YRES, XRES, cmin[0], cmax[0]); ts, vs = escapeTimeAndValue(arr, DEPTH); @@ -87,7 +87,15 @@ int main() { rgb = Color8::toi(rgb); ctx = drawPixels(ctx, rgb); - zoom_coords, ctx = getSelection(ctx); + zoomCoords, ctx = getSelection(ctx); + if (all(zoomCoords >= 0)) { + cmin = [arr[zoomCoords[0]]] ++ cmin; + cmax = [arr[zoomCoords[1]]] ++ cmax; + } else if (shape(cmin)[0] > 1) { + // Undo the last selection, if any + cmin = drop([1], cmin); + cmax = drop([1], cmax); + } } status = closeDisplay(ctx); diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 3878cfd..c599b41 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -20,13 +20,33 @@ static int SAC_EventHandler(SDLcontext *ctx) ctx->running = false; break; + case SDL_EVENT_MOUSE_BUTTON_DOWN: + if (event.button.button == 1 && ctx->selectionMode == SEL_from) { + ctx->selectionCoords[0] = event.button.x; + ctx->selectionCoords[1] = event.button.y; + ctx->selectionMode = SEL_to; + } + break; + + case SDL_EVENT_MOUSE_BUTTON_UP: + if (event.button.button == 1 && ctx->selectionMode == SEL_to) { + ctx->selectionCoords[2] = event.button.x; + ctx->selectionCoords[3] = event.button.y; + ctx->selectionMode = SEL_none; + SDL_SignalSemaphore(ctx->waitForSelection); + } + break; + default: break; } } - printf("SDL quit event received\n"); - return 0; + SDL_DestroyTexture(ctx->texture); + SDL_DestroyRenderer(ctx->renderer); + SDL_DestroyWindow(ctx->window); + SDL_Quit(); + exit(0); } SDLcontext *SAC_InitDisplay(int height, int width) @@ -57,6 +77,11 @@ SDLcontext *SAC_InitDisplay(int height, int width) SAC_RuntimeError("SDL_CreateThread failed: %s", SDL_GetError()); } + ctx->waitForSelection = SDL_CreateSemaphore(0); + if (ctx->waitForSelection == NULL) { + SAC_RuntimeError("SDL_CreateSemaphore failed: %s", SDL_GetError()); + } + SDL_RenderClear(ctx->renderer); SDL_RenderPresent(ctx->renderer); return ctx; @@ -93,16 +118,31 @@ void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels) SDL_RenderPresent(ctx->renderer); } -/// Wait for a selection of the user -/// Returns an int[2,2] of the form: [topleft, bottomright] = [[ymin,xmin], [ymax,xmax]] SACarg *SAC_GetSelection(SDLcontext *ctx) { - int *zoomCoords = malloc(4 * sizeof (int)); - zoomCoords[0] = 0; - zoomCoords[1] = 0; - zoomCoords[2] = 0; - zoomCoords[3] = 0; - return SACARGcreateFromPointer (SACTYPE__MAIN__int, (void *)zoomCoords, 2, 2, 2); + ctx->selectionMode = SEL_from; + + SDL_WaitSemaphore(ctx->waitForSelection); + assert(ctx->selectionMode == SEL_none); + + int *res = malloc(4 * sizeof(int)); + // Ensure coordinates are [topleft, bottomright] and each of the form [y,x] + if (ctx->selectionCoords[0] <= ctx->selectionCoords[2]) { + res[1] = ctx->selectionCoords[0]; + res[3] = ctx->selectionCoords[2]; + } else { + res[1] = ctx->selectionCoords[2]; + res[3] = ctx->selectionCoords[0]; + } + if (ctx->selectionCoords[1] <= ctx->selectionCoords[3]) { + res[0] = ctx->selectionCoords[1]; + res[2] = ctx->selectionCoords[3]; + } else { + res[0] = ctx->selectionCoords[3]; + res[2] = ctx->selectionCoords[1]; + } + + return SACARGcreateFromPointer(SACTYPE__MAIN__int, (void *)res, 2, 2, 2); } int SAC_CloseDisplay(SDLcontext *ctx) diff --git a/src/src/sdl3.h b/src/src/sdl3.h index 691f55b..1c18894 100644 --- a/src/src/sdl3.h +++ b/src/src/sdl3.h @@ -7,6 +7,12 @@ #include "sac.h" #include "sacinterface.h" +typedef enum { + SEL_none, + SEL_from, + SEL_to, +} selmode_t; + typedef struct SDLcontext { bool running; int width, height; @@ -14,6 +20,9 @@ typedef struct SDLcontext { SDL_Renderer *renderer; SDL_Texture *texture; SDL_Thread *eventHandler; + SDL_Semaphore *waitForSelection; + int selectionCoords[4]; + selmode_t selectionMode; } SDLcontext; extern SDLcontext *SAC_InitDisplay(int height, int width); From c2afe0f1c65146cb55aabce5ded29ac1dd0a2a25 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Thu, 20 Nov 2025 15:27:50 +0100 Subject: [PATCH 11/18] selection --- examples/mandelbrot.sac | 10 ++++------ src/src/sdl3.c | 14 +++++++++++--- 2 files changed, 15 insertions(+), 9 deletions(-) diff --git a/examples/mandelbrot.sac b/examples/mandelbrot.sac index b410b64..06bfe9e 100644 --- a/examples/mandelbrot.sac +++ b/examples/mandelbrot.sac @@ -1,12 +1,7 @@ use SDLdisplay: all; use Structures: all; use Numerical: { log2 }; - -external uint sleep(uint x); - #pragma effect World::TheWorld - #pragma linksign [0,1] - #pragma linkname "sleep" - #pragma header "" +use StdIO: all; inline complex[yres,xres] genComplexArray(int yres, int xres, @@ -87,12 +82,15 @@ int main() { rgb = Color8::toi(rgb); ctx = drawPixels(ctx, rgb); + printf("Waiting for selection...\n"); zoomCoords, ctx = getSelection(ctx); if (all(zoomCoords >= 0)) { + printf("Received selection [[%d,%d],[%d,%d]]\n", zoomCoords[0,0], zoomCoords[0,1], zoomCoords[1,0], zoomCoords[1,1]); cmin = [arr[zoomCoords[0]]] ++ cmin; cmax = [arr[zoomCoords[1]]] ++ cmax; } else if (shape(cmin)[0] > 1) { // Undo the last selection, if any + printf("Undo last selection\n"); cmin = drop([1], cmin); cmax = drop([1], cmax); } diff --git a/src/src/sdl3.c b/src/src/sdl3.c index c599b41..1ea7e91 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -21,7 +21,7 @@ static int SAC_EventHandler(SDLcontext *ctx) break; case SDL_EVENT_MOUSE_BUTTON_DOWN: - if (event.button.button == 1 && ctx->selectionMode == SEL_from) { + if (event.button.button == SDL_BUTTON_LEFT && ctx->selectionMode == SEL_from) { ctx->selectionCoords[0] = event.button.x; ctx->selectionCoords[1] = event.button.y; ctx->selectionMode = SEL_to; @@ -29,12 +29,21 @@ static int SAC_EventHandler(SDLcontext *ctx) break; case SDL_EVENT_MOUSE_BUTTON_UP: - if (event.button.button == 1 && ctx->selectionMode == SEL_to) { + if (event.button.button == SDL_BUTTON_LEFT && ctx->selectionMode == SEL_to) { ctx->selectionCoords[2] = event.button.x; ctx->selectionCoords[3] = event.button.y; ctx->selectionMode = SEL_none; SDL_SignalSemaphore(ctx->waitForSelection); } + // Undo selection if the right mouse button was pressed + if (event.button.button == SDL_BUTTON_RIGHT && ctx->selectionMode != SEL_none) { + ctx->selectionCoords[0] = -1; + ctx->selectionCoords[1] = -1; + ctx->selectionCoords[2] = -1; + ctx->selectionCoords[3] = -1; + ctx->selectionMode = SEL_none; + SDL_SignalSemaphore(ctx->waitForSelection); + } break; default: @@ -121,7 +130,6 @@ void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels) SACarg *SAC_GetSelection(SDLcontext *ctx) { ctx->selectionMode = SEL_from; - SDL_WaitSemaphore(ctx->waitForSelection); assert(ctx->selectionMode == SEL_none); From 13b1426f1f53cd118b3a8216e2903e727318678e Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Thu, 20 Nov 2025 16:58:47 +0100 Subject: [PATCH 12/18] tier 2 is being stupid, use tier 1 for now... --- examples/mandelbrot.sac | 91 +++++++++++++++++++++++++---------------- src/src/sdl3.c | 21 ++++++---- src/src/sdl3.h | 2 +- 3 files changed, 69 insertions(+), 45 deletions(-) diff --git a/examples/mandelbrot.sac b/examples/mandelbrot.sac index 06bfe9e..1c2364f 100644 --- a/examples/mandelbrot.sac +++ b/examples/mandelbrot.sac @@ -3,84 +3,105 @@ use Structures: all; use Numerical: { log2 }; use StdIO: all; +#define XRES 16 +#define YRES 9 +#define EXPAND 64 +#define DEPTH 1024 + inline -complex[yres,xres] genComplexArray(int yres, int xres, - complex cmin, complex cmax) +complex[h,w] genComplexArray(int h, int w, complex cmin, complex cmax) { dR = real(cmax) - real(cmin); dI = imag(cmax) - imag(cmin); - return { [y,x] -> cmin + toc((tod(x) / tod(xres)) * dR, - (tod(y) / tod(yres)) * dI) - | [y,x] < [yres,xres] }; + return { [y,x] -> cmin + toc(tod(x) * dR / tod(w), + tod(y) * dI / tod(h)) + | [y,x] < [h,w] }; } inline int, complex escapeTimeAndValue(complex c, int depth) { - time = 0; + i = 0; z = c; - while (time < depth && normSq(z) <= 4d) { + while (i < depth && normSq(z) <= 4d) { z = z * z + c; - time += 1; + i += 1; } - return (time, z); + return (i, z); } inline int[2:shp], complex[2:shp] escapeTimeAndValue(complex[2:shp] arr, int depth) { - ts, vs = { iv -> escapeTimeAndValue(arr[iv], depth) }; + ts, vs = { iv -> escapeTimeAndValue(arr[iv], depth) | iv < shp }; return (ts, vs); } inline double[2:shp] normalizeIterationCount(int[2:shp] ts, complex[2:shp] vs) { - return where(normSq(vs) <= 4d, + return where(norm(vs) <= 2d, 0d, tod(ts + 1) - log2(log2(norm(vs)))); } inline -Color8[2:shp] intToMonochrome(int[2:shp] arr) +Color8[2:shp] doubleToRgb(double[2:shp] arr) { - scaled_vals = (arr * 255) / maxval(arr); - clut = genLogarithmicClut(0.4d, 0.9d, white(), black()); - return { iv -> clut[scaled_vals[iv]] }; + min = minval(arr); + max = maxval(arr); + scaled = (arr - min) / (max - min); + + //return Hsb2Rgb(toi(scaled * 360d), 60, 80); + + scaled = toi(scaled * 255d); + clut = genLogarithmicClut( 0.4d, 0.9d, Color8::black(), Color8::red()); + return { iv -> clut[scaled[iv]] | iv < shp }; } inline -Color8[2:shp] doubleToRgb(double[2:shp] arr) +Color8[2:shp] intToMonochrome(int[2:shp] a) { - scaled_vals = toi((arr * 360d) / maxval(arr)); - return Hsb2Rgb(scaled_vals, 60, 80); + clut = genLogarithmicClut( 0.4d, 0.9d, Color8::black(), Color8::red()); + + a = (a * 255) / maxval(a); + + return { iv -> clut[ a[ iv] ] }; } -int main() { - XRES = 640; - YRES = 480; - DEPTH = 2048; +inline +Color8[2:oshp] stretchRgb(Color8[2:shp] arr, int stretch) +{ + return { iv -> arr[iv / stretch] | iv < shp * stretch }; +} - ctx = initDisplay(YRES, XRES); - cmin = [toc(-2.2, 1.0)]; - cmax = [toc( 0.8, -1.0)]; +int main() { + ctx = initDisplay(YRES*EXPAND, XRES*EXPAND); + cmin = [toc(-2.2, -1.0)]; + cmax = [toc( 0.8, 1.0)]; while (isRunning(ctx)) { - arr = genComplexArray(YRES, XRES, cmin[0], cmax[0]); + xres = XRES; + yres = YRES; + expand = EXPAND; + + do { + arr = genComplexArray(yres, xres, cmin[0], cmax[0]); - ts, vs = escapeTimeAndValue(arr, DEPTH); + ts, vs = escapeTimeAndValue(arr, DEPTH); - #if 1 - rgb = intToMonochrome(ts); - #else - nvs = normalizeIterationCount(ts, vs); - rgb = doubleToRgb(nvs); - #endif + nvs = normalizeIterationCount(ts, vs); + rgb = intToMonochrome(ts); + //rgb = doubleToRgb(nvs); + rgb = stretchRgb(rgb, expand); + ctx = drawPixels(ctx, toi(rgb)); - rgb = Color8::toi(rgb); - ctx = drawPixels(ctx, rgb); + xres *= 2; + yres *= 2; + expand /= 2; + } while (expand > 0); printf("Waiting for selection...\n"); zoomCoords, ctx = getSelection(ctx); diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 1ea7e91..66fa7b8 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -96,14 +96,14 @@ SDLcontext *SAC_InitDisplay(int height, int width) return ctx; } -void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels) +void SAC_DrawPixels(SDLcontext *ctx, SACarg *pixel_data) { - assert(SACARGgetDim(sa_pixels) == 3); - assert(SACARGgetShape(sa_pixels, 0) == ctx->height); - assert(SACARGgetShape(sa_pixels, 1) == ctx->width); - assert(SACARGgetShape(sa_pixels, 2) == 3); + assert(SACARGgetDim(pixel_data) == 3); + assert(SACARGgetShape(pixel_data, 0) == ctx->height); + assert(SACARGgetShape(pixel_data, 1) == ctx->width); + assert(SACARGgetShape(pixel_data, 2) == 3); - const int *src_colors = SACARGgetSharedData(SACTYPE__MAIN__int, sa_pixels); + const int *src_pixels = SACARGgetSharedData(SACTYPE__MAIN__int, pixel_data); uint8_t *dst_pixels; int pitch; @@ -111,17 +111,20 @@ void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels) SAC_RuntimeError("SDL_LockTexture failed: %s", SDL_GetError()); } - for (int y = 0; y < ctx->height; y++) { - const int *src_row = src_colors + y * ctx->width * 3; + for (size_t y = 0; y < ctx->height; y++) { + const int *src_row = src_pixels + y * ctx->width * 3; uint8_t *dst_row = dst_pixels + y * pitch; - for (int x = 0; x < 3 * ctx->width; x += 3) { + for (size_t x = 0; x < 3 * ctx->width; x += 3) { dst_row[x + 0] = (uint8_t)(src_row[x + 0]); dst_row[x + 1] = (uint8_t)(src_row[x + 1]); dst_row[x + 2] = (uint8_t)(src_row[x + 2]); } } + // Clearing should not be necessary since we overwrite the entire texture with non-transparent pixels + //SDL_RenderClear(ctx->renderer); + SDL_UnlockTexture(ctx->texture); SDL_RenderTexture(ctx->renderer, ctx->texture, NULL, NULL); SDL_RenderPresent(ctx->renderer); diff --git a/src/src/sdl3.h b/src/src/sdl3.h index 1c18894..894a8a3 100644 --- a/src/src/sdl3.h +++ b/src/src/sdl3.h @@ -15,7 +15,7 @@ typedef enum { typedef struct SDLcontext { bool running; - int width, height; + size_t width, height; SDL_Window *window; SDL_Renderer *renderer; SDL_Texture *texture; From 11ee307e2fa3f9cda68075a7d101f80e65933693 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Fri, 21 Nov 2025 10:02:51 +0100 Subject: [PATCH 13/18] seperate selection struct --- src/src/sdl3.c | 75 ++++++++++++++++++++++++-------------------------- src/src/sdl3.h | 10 +++++-- 2 files changed, 43 insertions(+), 42 deletions(-) diff --git a/src/src/sdl3.c b/src/src/sdl3.c index 66fa7b8..a0f7670 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -10,7 +10,6 @@ static int SAC_EventHandler(SDLcontext *ctx) { while (ctx->running) { SDL_Event event; - if (!SDL_WaitEvent(&event)) { SAC_RuntimeError("SDL_WaitEvent failed: %s", SDL_GetError()); } @@ -21,28 +20,28 @@ static int SAC_EventHandler(SDLcontext *ctx) break; case SDL_EVENT_MOUSE_BUTTON_DOWN: - if (event.button.button == SDL_BUTTON_LEFT && ctx->selectionMode == SEL_from) { - ctx->selectionCoords[0] = event.button.x; - ctx->selectionCoords[1] = event.button.y; - ctx->selectionMode = SEL_to; + if (event.button.button == SDL_BUTTON_LEFT && ctx->selection.mode == SEL_from) { + ctx->selection.coords[0] = event.button.x; + ctx->selection.coords[1] = event.button.y; + ctx->selection.mode = SEL_to; } break; case SDL_EVENT_MOUSE_BUTTON_UP: - if (event.button.button == SDL_BUTTON_LEFT && ctx->selectionMode == SEL_to) { - ctx->selectionCoords[2] = event.button.x; - ctx->selectionCoords[3] = event.button.y; - ctx->selectionMode = SEL_none; - SDL_SignalSemaphore(ctx->waitForSelection); + if (event.button.button == SDL_BUTTON_LEFT && ctx->selection.mode == SEL_to) { + ctx->selection.coords[2] = event.button.x; + ctx->selection.coords[3] = event.button.y; + ctx->selection.mode = SEL_none; + SDL_SignalSemaphore(ctx->selection.isSelecting); } // Undo selection if the right mouse button was pressed - if (event.button.button == SDL_BUTTON_RIGHT && ctx->selectionMode != SEL_none) { - ctx->selectionCoords[0] = -1; - ctx->selectionCoords[1] = -1; - ctx->selectionCoords[2] = -1; - ctx->selectionCoords[3] = -1; - ctx->selectionMode = SEL_none; - SDL_SignalSemaphore(ctx->waitForSelection); + if (event.button.button == SDL_BUTTON_RIGHT && ctx->selection.mode != SEL_none) { + ctx->selection.coords[0] = -1; + ctx->selection.coords[1] = -1; + ctx->selection.coords[2] = -1; + ctx->selection.coords[3] = -1; + ctx->selection.mode = SEL_none; + SDL_SignalSemaphore(ctx->selection.isSelecting); } break; @@ -51,9 +50,6 @@ static int SAC_EventHandler(SDLcontext *ctx) } } - SDL_DestroyTexture(ctx->texture); - SDL_DestroyRenderer(ctx->renderer); - SDL_DestroyWindow(ctx->window); SDL_Quit(); exit(0); } @@ -86,8 +82,13 @@ SDLcontext *SAC_InitDisplay(int height, int width) SAC_RuntimeError("SDL_CreateThread failed: %s", SDL_GetError()); } - ctx->waitForSelection = SDL_CreateSemaphore(0); - if (ctx->waitForSelection == NULL) { + ctx->selection = (SDLselection){ + .isSelecting = SDL_CreateSemaphore(0), + .mode = SEL_none, + .coords = {-1, -1, -1, -1}, + }; + + if (ctx->selection.isSelecting == NULL) { SAC_RuntimeError("SDL_CreateSemaphore failed: %s", SDL_GetError()); } @@ -132,25 +133,25 @@ void SAC_DrawPixels(SDLcontext *ctx, SACarg *pixel_data) SACarg *SAC_GetSelection(SDLcontext *ctx) { - ctx->selectionMode = SEL_from; - SDL_WaitSemaphore(ctx->waitForSelection); - assert(ctx->selectionMode == SEL_none); + ctx->selection.mode = SEL_from; + SDL_WaitSemaphore(ctx->selection.isSelecting); + assert(ctx->selection.mode == SEL_none); int *res = malloc(4 * sizeof(int)); // Ensure coordinates are [topleft, bottomright] and each of the form [y,x] - if (ctx->selectionCoords[0] <= ctx->selectionCoords[2]) { - res[1] = ctx->selectionCoords[0]; - res[3] = ctx->selectionCoords[2]; + if (ctx->selection.coords[0] <= ctx->selection.coords[2]) { + res[1] = ctx->selection.coords[0]; + res[3] = ctx->selection.coords[2]; } else { - res[1] = ctx->selectionCoords[2]; - res[3] = ctx->selectionCoords[0]; + res[1] = ctx->selection.coords[2]; + res[3] = ctx->selection.coords[0]; } - if (ctx->selectionCoords[1] <= ctx->selectionCoords[3]) { - res[0] = ctx->selectionCoords[1]; - res[2] = ctx->selectionCoords[3]; + if (ctx->selection.coords[1] <= ctx->selection.coords[3]) { + res[0] = ctx->selection.coords[1]; + res[2] = ctx->selection.coords[3]; } else { - res[0] = ctx->selectionCoords[3]; - res[2] = ctx->selectionCoords[1]; + res[0] = ctx->selection.coords[3]; + res[2] = ctx->selection.coords[1]; } return SACARGcreateFromPointer(SACTYPE__MAIN__int, (void *)res, 2, 2, 2); @@ -168,10 +169,6 @@ int SAC_CloseDisplay(SDLcontext *ctx) int exitStatus; SDL_WaitThread(ctx->eventHandler, &exitStatus); - - SDL_DestroyTexture(ctx->texture); - SDL_DestroyRenderer(ctx->renderer); - SDL_DestroyWindow(ctx->window); SDL_Quit(); return exitStatus; diff --git a/src/src/sdl3.h b/src/src/sdl3.h index 894a8a3..f292303 100644 --- a/src/src/sdl3.h +++ b/src/src/sdl3.h @@ -13,6 +13,12 @@ typedef enum { SEL_to, } selmode_t; +typedef struct SDLselection { + SDL_Semaphore *isSelecting; + selmode_t mode; + int coords[4]; +} SDLselection; + typedef struct SDLcontext { bool running; size_t width, height; @@ -20,9 +26,7 @@ typedef struct SDLcontext { SDL_Renderer *renderer; SDL_Texture *texture; SDL_Thread *eventHandler; - SDL_Semaphore *waitForSelection; - int selectionCoords[4]; - selmode_t selectionMode; + SDLselection selection; } SDLcontext; extern SDLcontext *SAC_InitDisplay(int height, int width); From 5d7690046d9430247e8895b7bcecd611cfc0efe5 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Fri, 21 Nov 2025 12:17:54 +0100 Subject: [PATCH 14/18] allow drawing with offset, and for variable sized input pixels --- examples/mandelbrot.sac | 4 ++-- src/SDLdisplay.sac | 7 +++++++ src/src/sdl3.c | 41 +++++++++++++++++++++++------------------ src/src/sdl3.h | 3 ++- 4 files changed, 34 insertions(+), 21 deletions(-) diff --git a/examples/mandelbrot.sac b/examples/mandelbrot.sac index 1c2364f..7a039bf 100644 --- a/examples/mandelbrot.sac +++ b/examples/mandelbrot.sac @@ -78,7 +78,7 @@ Color8[2:oshp] stretchRgb(Color8[2:shp] arr, int stretch) } int main() { - ctx = initDisplay(YRES*EXPAND, XRES*EXPAND); + ctx = initDisplay(YRES*EXPAND+100, XRES*EXPAND+100); cmin = [toc(-2.2, -1.0)]; cmax = [toc( 0.8, 1.0)]; @@ -96,7 +96,7 @@ int main() { rgb = intToMonochrome(ts); //rgb = doubleToRgb(nvs); rgb = stretchRgb(rgb, expand); - ctx = drawPixels(ctx, toi(rgb)); + ctx = drawPixelsOffset(ctx, toi(rgb), 150, 150); xres *= 2; yres *= 2; diff --git a/src/SDLdisplay.sac b/src/SDLdisplay.sac index 81a6efc..ca0ed68 100644 --- a/src/SDLdisplay.sac +++ b/src/SDLdisplay.sac @@ -10,6 +10,13 @@ external SDLdisplay initDisplay(int h, int w); #pragma linkwith "SDL3" #pragma linksign [0,1,2] +external SDLdisplay drawPixelsOffset(SDLdisplay ctx, int[h,w,3] pixels, int xOffset, int yOffset); + #pragma linkname "SAC_DrawPixelsOffset" + #pragma linkobj "src/sdl3.o" + #pragma linkwith "SDL3" + #pragma linksign [1,1,2,3,4] + #pragma sacarg [2] + external SDLdisplay drawPixels(SDLdisplay ctx, int[h,w,3] pixels); #pragma linkname "SAC_DrawPixels" #pragma linkobj "src/sdl3.o" diff --git a/src/src/sdl3.c b/src/src/sdl3.c index a0f7670..7f95630 100644 --- a/src/src/sdl3.c +++ b/src/src/sdl3.c @@ -6,6 +6,9 @@ #include "sdl3.h" +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + static int SAC_EventHandler(SDLcontext *ctx) { while (ctx->running) { @@ -97,40 +100,42 @@ SDLcontext *SAC_InitDisplay(int height, int width) return ctx; } -void SAC_DrawPixels(SDLcontext *ctx, SACarg *pixel_data) +void SAC_DrawPixelsOffset(SDLcontext *ctx, SACarg *sacPixels, int xOffset, int yOffset) { - assert(SACARGgetDim(pixel_data) == 3); - assert(SACARGgetShape(pixel_data, 0) == ctx->height); - assert(SACARGgetShape(pixel_data, 1) == ctx->width); - assert(SACARGgetShape(pixel_data, 2) == 3); + assert(SACARGgetDim(sacPixels) == 3); + assert(SACARGgetShape(sacPixels, 2) == 3); - const int *src_pixels = SACARGgetSharedData(SACTYPE__MAIN__int, pixel_data); + const int srcHeight = SACARGgetShape(sacPixels, 0); + const int srcWidth = SACARGgetShape(sacPixels, 1); + const int *srcPixels = SACARGgetSharedData(SACTYPE__MAIN__int, sacPixels); - uint8_t *dst_pixels; + uint8_t *dstPixels; int pitch; - if (!SDL_LockTexture(ctx->texture, NULL, (void **)&dst_pixels, &pitch)) { + if (!SDL_LockTexture(ctx->texture, NULL, (void **)&dstPixels, &pitch)) { SAC_RuntimeError("SDL_LockTexture failed: %s", SDL_GetError()); } - for (size_t y = 0; y < ctx->height; y++) { - const int *src_row = src_pixels + y * ctx->width * 3; - uint8_t *dst_row = dst_pixels + y * pitch; + for (size_t y = 0; y < MIN(srcHeight, ctx->height - yOffset); y++) { + const int *srcRow = srcPixels + y * srcWidth * 3; + uint8_t *dstRow = dstPixels + (yOffset + y) * pitch; - for (size_t x = 0; x < 3 * ctx->width; x += 3) { - dst_row[x + 0] = (uint8_t)(src_row[x + 0]); - dst_row[x + 1] = (uint8_t)(src_row[x + 1]); - dst_row[x + 2] = (uint8_t)(src_row[x + 2]); + for (size_t x = 0; x < 3 * MIN(srcWidth, ctx->width - xOffset); x += 3) { + dstRow[xOffset + x + 0] = (uint8_t)(srcRow[x + 0]); + dstRow[xOffset + x + 1] = (uint8_t)(srcRow[x + 1]); + dstRow[xOffset + x + 2] = (uint8_t)(srcRow[x + 2]); } } - // Clearing should not be necessary since we overwrite the entire texture with non-transparent pixels - //SDL_RenderClear(ctx->renderer); - SDL_UnlockTexture(ctx->texture); SDL_RenderTexture(ctx->renderer, ctx->texture, NULL, NULL); SDL_RenderPresent(ctx->renderer); } +void SAC_DrawPixels(SDLcontext *ctx, SACarg *sacPixels) +{ + SAC_DrawPixelsOffset(ctx, sacPixels, 0, 0); +} + SACarg *SAC_GetSelection(SDLcontext *ctx) { ctx->selection.mode = SEL_from; diff --git a/src/src/sdl3.h b/src/src/sdl3.h index f292303..fe6834f 100644 --- a/src/src/sdl3.h +++ b/src/src/sdl3.h @@ -30,7 +30,8 @@ typedef struct SDLcontext { } SDLcontext; extern SDLcontext *SAC_InitDisplay(int height, int width); -extern void SAC_DrawPixels(SDLcontext *ctx, SACarg *sa_pixels); +extern void SAC_DrawPixelsOffset(SDLcontext *ctx, SACarg *sacPixels, int xOffset, int yOffset); +extern void SAC_DrawPixels(SDLcontext *ctx, SACarg *sacPixels); extern SACarg *SAC_GetSelection(SDLcontext *ctx); extern int SAC_CloseDisplay(SDLcontext *ctx); extern bool SAC_IsRunning(SDLcontext *ctx); From 4a207952664597569c461c1e3379f6069a1044dd Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Mon, 24 Nov 2025 17:47:09 +0100 Subject: [PATCH 15/18] fix dependency checking --- CMakeLists.txt | 5 +++++ Makefile | 14 ++++++++++++++ src/CMakeLists.txt | 5 ++--- 3 files changed, 21 insertions(+), 3 deletions(-) create mode 100644 Makefile diff --git a/CMakeLists.txt b/CMakeLists.txt index 80aa5fd..807f2a2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,6 +8,7 @@ SET (DLL_BUILD_DIR "${PROJECT_BINARY_DIR}/lib") # For what targets we build modules SET (TARGETS seq seq_checks mt_pth CACHE STRING "Build for these targets") SET (SAC2C_EXEC CACHE STRING "Path to sac2c compiler") +OPTION (BUILDGENERIC "Do not use architecture-specific optimisations" OFF) # Check whether sac2c is operational LIST (APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-common") @@ -21,6 +22,10 @@ FIND_PACKAGE (X11 REQUIRED) SET (SAC2C_EXTRA_INC "-I${X11_INCLUDE_DIR}") SET (SAC2C_CPP_INC "-Xl" "-lX11" "-Xtl" "-lX11") +IF (BUILDGENERIC) + LIST (APPEND SAC2C_CPP_INC "-generic") +ENDIF () + # For every target run CMakeLists.txt in src FOREACH (TARGET IN ITEMS ${TARGETS}) ADD_SUBDIRECTORY (src src-${TARGET}) diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..d578a8c --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +SAC2C ?= sac2c +TARGETS ?= "seq;seq_checks;mt_pth" +BUILD_DIR ?= build + +.PHONY: all build clean + +all: build + +build: + cmake -DSAC2C_EXEC=$(SAC2C) -DTARGETS=$(TARGETS) -B $(BUILD_DIR) + cmake --build $(BUILD_DIR) + +clean: + $(RM) -r $(BUILD_DIR) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index b5c923f..dc77627 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -48,9 +48,8 @@ FOREACH (name ${SAC_SRC}) SET (tree "${DLL_BUILD_DIR}/tree/${TARGET_ENV}/${SBI}/lib${dst}Tree${VARIANT}${TREE_DLLEXT}") RESOLVE_SAC_DEPS_AS_TARGETS ("${name}" "-module-" target_list object_list source_list) - #LIST (APPEND deps_list ${target_list} ${object_list} ${source_list}) - LIST (APPEND deps_list ${object_list}) - MESSAGE (DEBUG "Dependencies of ${name} are: ${deps_list}") + LIST (APPEND deps_list ${target_list} ${object_list} ${source_list}) + MESSAGE (STATUS "Dependencies of ${name} are: ${deps_list}") UNSET (target_list) UNSET (object_list) UNSET (source_list) From f972c4cc583816c66f1edde229ee7c372e95a738 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Mon, 24 Nov 2025 17:54:37 +0100 Subject: [PATCH 16/18] update makefile --- .github/workflows/main.yml | 53 ++++++++++---------------------------- 1 file changed, 14 insertions(+), 39 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 00adc3a..3e7e68e 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,47 +1,22 @@ -name: Build On Changes +name: Build -on: [pull_request] - -env: - BASE_URL: https://gitlab.sac-home.org/sac-group/sac-packages/-/raw/master/latest/weekly +on: [push, pull_request] jobs: - build-ubuntu24: - runs-on: ubuntu-24.04 + build-ubuntu: + runs-on: ubuntu-latest + container: + image: sacbase/sac-compiler steps: - - name: Get HEAD and submodules - uses: actions/checkout@v2 + - uses: actions/checkout@v5 with: - fetch-depth: 0 submodules: 'recursive' - - name: Install SDL - run: | - sudo apt update - sudo apt upgrade -y - sudo apt install -y libsdl1.2-dev libsdl2-dev libsdl2-image-dev libsdl2-ttf-dev - - name: Install SaC - run: | - wget -q ${BASE_URL}/Ubl22/sac2c-basic.deb - sudo apt install ./sac2c-basic.deb - sac2c -V - - name: Install Stdlib + - name: Configure sac2c + run: cp -r /root/.sac2crc $HOME/.sac2crc + - name: Install SDL3 run: | - wget -q ${BASE_URL}/Ubl22/stdlib-basic.deb - sudo apt install ./stdlib-basic.deb - - name: Create build dir - run: | - cmake -E make_directory ${{runner.workspace}}/build - mkdir $HOME/.sac2crc - - name: Configure build-system - shell: bash - working-directory: ${{runner.workspace}}/build - run: cmake $GITHUB_WORKSPACE + apt update + apt upgrade -y + apt install -y libsdl3-dev libsdl3-image-dev libsdl3-ttf-dev - name: Build - shell: bash - working-directory: ${{runner.workspace}}/build - run: | - cmake --build . -j 4 2>&1 | tee build.log - if [ ${PIPESTATUS[0]} -ne 0 ]; then - echo "!!! ERROR detected in build !!!"; - exit 1; - fi + run: make From aeea33e5fba95fd7f4c32e509f832694d3666ff2 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Mon, 24 Nov 2025 20:38:38 +0100 Subject: [PATCH 17/18] fix dependency checking --- .github/workflows/main.yml | 5 +---- CMakeLists.txt | 12 +++++++++++- src/CMakeLists.txt | 1 - 3 files changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 3e7e68e..9760656 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -14,9 +14,6 @@ jobs: - name: Configure sac2c run: cp -r /root/.sac2crc $HOME/.sac2crc - name: Install SDL3 - run: | - apt update - apt upgrade -y - apt install -y libsdl3-dev libsdl3-image-dev libsdl3-ttf-dev + run: apt install -y libsdl3-dev libsdl3-image-dev libsdl3-ttf-dev - name: Build run: make diff --git a/CMakeLists.txt b/CMakeLists.txt index 807f2a2..93f4bc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -13,6 +13,7 @@ OPTION (BUILDGENERIC "Do not use architecture-specific optimisations" OFF) # Check whether sac2c is operational LIST (APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake-common") INCLUDE ("cmake-common/check-sac2c.cmake") +INCLUDE ("cmake-common/check-sac2c-feature-support.cmake") INCLUDE ("cmake-common/misc-macros.cmake") SET (SDL_BUILDING_LIBRARY ON) @@ -22,8 +23,17 @@ FIND_PACKAGE (X11 REQUIRED) SET (SAC2C_EXTRA_INC "-I${X11_INCLUDE_DIR}") SET (SAC2C_CPP_INC "-Xl" "-lX11" "-Xtl" "-lX11") + +# Check if sac2c suppports building generically IF (BUILDGENERIC) - LIST (APPEND SAC2C_CPP_INC "-generic") + CHECK_SAC2C_SUPPORT_FLAG ("generic" "-generic") + IF (HAVE_FLAG_generic) + LIST (APPEND SAC2C_CPP_INC "-generic") + MESSAGE (STATUS "Building with *no* system-specific optimisations") + ELSE () + MESSAGE (STATUS "Generic-build disabled as sac2c does not support this") + SET (BUILDGENERIC OFF) + ENDIF () ENDIF () # For every target run CMakeLists.txt in src diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index dc77627..55bec75 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -58,7 +58,6 @@ FOREACH (name ${SAC_SRC}) FILE (MAKE_DIRECTORY "${dir}") ADD_CUSTOM_TARGET (${TARGET}-module-${dst} DEPENDS "${mod}" "${tree}") - ADD_DEPENDENCIES (${TARGET}-all-modules ${TARGET}-module-${dst}) ADD_CUSTOM_COMMAND ( OUTPUT ${mod} ${tree} From 14588cb14aa05367b796c6341f6f9a939ad55461 Mon Sep 17 00:00:00 2001 From: Jordy Aaldering Date: Mon, 24 Nov 2025 20:40:00 +0100 Subject: [PATCH 18/18] update CI --- .github/workflows/main.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 9760656..76defec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,6 +1,6 @@ name: Build -on: [push, pull_request] +on: [pull_request] jobs: build-ubuntu: