diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 45298f8..76defec 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -1,47 +1,19 @@ -name: Build On Changes +name: Build -on: [push, pull_request] - -env: - BASE_URL: https://gitlab.sac-home.org/sac-group/sac-packages/-/raw/master/latest/weekly +on: [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 - 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 + - name: Configure sac2c + run: cp -r /root/.sac2crc $HOME/.sac2crc + - name: Install SDL3 + run: 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 diff --git a/CMakeLists.txt b/CMakeLists.txt index b18e5e4..93f4bc3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,21 +8,34 @@ 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") INCLUDE ("cmake-common/check-sac2c.cmake") +INCLUDE ("cmake-common/check-sac2c-feature-support.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") + +# Check if sac2c suppports building generically +IF (BUILDGENERIC) + 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 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/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/examples/mandelbrot.sac b/examples/mandelbrot.sac new file mode 100644 index 0000000..7a039bf --- /dev/null +++ b/examples/mandelbrot.sac @@ -0,0 +1,122 @@ +use SDLdisplay: all; +use Structures: all; +use Numerical: { log2 }; +use StdIO: all; + +#define XRES 16 +#define YRES 9 +#define EXPAND 64 +#define DEPTH 1024 + +inline +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) * dR / tod(w), + tod(y) * dI / tod(h)) + | [y,x] < [h,w] }; +} + +inline +int, complex escapeTimeAndValue(complex c, int depth) +{ + i = 0; + z = c; + + while (i < depth && normSq(z) <= 4d) { + z = z * z + c; + i += 1; + } + + return (i, z); +} + +inline +int[2:shp], complex[2:shp] escapeTimeAndValue(complex[2:shp] arr, int 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(norm(vs) <= 2d, + 0d, + tod(ts + 1) - log2(log2(norm(vs)))); +} + +inline +Color8[2:shp] doubleToRgb(double[2:shp] arr) +{ + 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] intToMonochrome(int[2:shp] a) +{ + clut = genLogarithmicClut( 0.4d, 0.9d, Color8::black(), Color8::red()); + + a = (a * 255) / maxval(a); + + return { iv -> clut[ a[ iv] ] }; +} + +inline +Color8[2:oshp] stretchRgb(Color8[2:shp] arr, int stretch) +{ + return { iv -> arr[iv / stretch] | iv < shp * stretch }; +} + +int main() { + ctx = initDisplay(YRES*EXPAND+100, XRES*EXPAND+100); + cmin = [toc(-2.2, -1.0)]; + cmax = [toc( 0.8, 1.0)]; + + while (isRunning(ctx)) { + xres = XRES; + yres = YRES; + expand = EXPAND; + + do { + arr = genComplexArray(yres, xres, cmin[0], cmax[0]); + + ts, vs = escapeTimeAndValue(arr, DEPTH); + + nvs = normalizeIterationCount(ts, vs); + rgb = intToMonochrome(ts); + //rgb = doubleToRgb(nvs); + rgb = stretchRgb(rgb, expand); + ctx = drawPixelsOffset(ctx, toi(rgb), 150, 150); + + xres *= 2; + yres *= 2; + expand /= 2; + } while (expand > 0); + + 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); + } + } + + 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/CMakeLists.txt b/src/CMakeLists.txt index 390a085..55bec75 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 @@ -77,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) @@ -88,11 +58,10 @@ 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} - 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..ca0ed68 100644 --- a/src/SDLdisplay.sac +++ b/src/SDLdisplay.sac @@ -2,92 +2,43 @@ 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; - } - - return (field[[0]], pos); -} +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 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" + #pragma linkwith "SDL3" + #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" + #pragma linkwith "SDL3" + #pragma linksign [0,1] + +external int closeDisplay(SDLdisplay ctx); + #pragma linkname "SAC_CloseDisplay" + #pragma linkobj "src/sdl3.o" + #pragma linkwith "SDL3" + #pragma linksign [0,1] 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..7f95630 --- /dev/null +++ b/src/src/sdl3.c @@ -0,0 +1,185 @@ +#include +#include +#include +#include +#include + +#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) { + SDL_Event event; + if (!SDL_WaitEvent(&event)) { + SAC_RuntimeError("SDL_WaitEvent failed: %s", SDL_GetError()); + } + + switch (event.type) { + case SDL_EVENT_QUIT: + ctx->running = false; + break; + + case SDL_EVENT_MOUSE_BUTTON_DOWN: + 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->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->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; + + default: + break; + } + } + + SDL_Quit(); + exit(0); +} + +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(); + + 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)) { + SAC_RuntimeError("SDL_CreateWindowAndRenderer failed: %s", SDL_GetError()); + } + + 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()); + } + + ctx->eventHandler = SDL_CreateThread(SAC_EventHandler, "SAC_EventHandler", ctx); + if (ctx->eventHandler == NULL) { + SAC_RuntimeError("SDL_CreateThread failed: %s", SDL_GetError()); + } + + 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()); + } + + SDL_RenderClear(ctx->renderer); + SDL_RenderPresent(ctx->renderer); + return ctx; +} + +void SAC_DrawPixelsOffset(SDLcontext *ctx, SACarg *sacPixels, int xOffset, int yOffset) +{ + assert(SACARGgetDim(sacPixels) == 3); + assert(SACARGgetShape(sacPixels, 2) == 3); + + const int srcHeight = SACARGgetShape(sacPixels, 0); + const int srcWidth = SACARGgetShape(sacPixels, 1); + const int *srcPixels = SACARGgetSharedData(SACTYPE__MAIN__int, sacPixels); + + uint8_t *dstPixels; + int pitch; + if (!SDL_LockTexture(ctx->texture, NULL, (void **)&dstPixels, &pitch)) { + SAC_RuntimeError("SDL_LockTexture failed: %s", SDL_GetError()); + } + + 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 * 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]); + } + } + + 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; + 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->selection.coords[0] <= ctx->selection.coords[2]) { + res[1] = ctx->selection.coords[0]; + res[3] = ctx->selection.coords[2]; + } else { + res[1] = ctx->selection.coords[2]; + res[3] = ctx->selection.coords[0]; + } + 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->selection.coords[3]; + res[2] = ctx->selection.coords[1]; + } + + return SACARGcreateFromPointer(SACTYPE__MAIN__int, (void *)res, 2, 2, 2); +} + +int SAC_CloseDisplay(SDLcontext *ctx) +{ + 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; + SDL_WaitThread(ctx->eventHandler, &exitStatus); + SDL_Quit(); + + 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..fe6834f --- /dev/null +++ b/src/src/sdl3.h @@ -0,0 +1,39 @@ +#ifndef _SACSDL3_H_ +#define _SACSDL3_H_ + +#include +#include + +#include "sac.h" +#include "sacinterface.h" + +typedef enum { + SEL_none, + SEL_from, + 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; + SDL_Window *window; + SDL_Renderer *renderer; + SDL_Texture *texture; + SDL_Thread *eventHandler; + SDLselection selection; +} SDLcontext; + +extern SDLcontext *SAC_InitDisplay(int height, int width); +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); + +#endif /* _SACSDL3_H_ */