diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index bae50f2..5c24d78 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -42,9 +42,17 @@ jobs: BUILD_TYPE: Release steps: - uses: actions/checkout@v3 + - name: Show CMake version + run: cmake --version - name: Install X11 dependencies on MacOS if: ${{ runner.os == 'macOS'}} run: brew install --cask xquartz + - name: Install SDL2 dependencies on MacOS + if: ${{ runner.os == 'macOS'}} + run: brew install sdl2 + - name: Install SDL dependency on Ubuntu + if: ${{ runner.os == 'Linux'}} + run: sudo apt-get update && sudo apt-get install -y libsdl2-dev - name: Create Build Environment run: cmake -E make_directory ${{github.workspace}}/build - name: Configure CMake diff --git a/.gitignore b/.gitignore index f97e0d5..e809c7c 100644 --- a/.gitignore +++ b/.gitignore @@ -17,6 +17,7 @@ cmake-build-*/** *.sparc-x/** *.sparc/** *.x86_64-x/** +*.x86_64-sdl/** *.x86_64/** *.armv7l-x/** *.armv7l/** diff --git a/CMakeLists.txt b/CMakeLists.txt index 8a1b369..952f46e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,5 +1,5 @@ -PROJECT(maiko C) CMAKE_MINIMUM_REQUIRED(VERSION 3.15) +PROJECT(maiko C) SET(CMAKE_EXPORT_COMPILE_COMMANDS ON) @@ -23,10 +23,12 @@ find_program( ) IF (CLANG_TIDY_EXE) + IF (NOT CMAKE_CROSSCOMPILING) # There are many many warnings for strcpy instances to deal with, # but suppress it for now so that other issues are more obvious # - SET(CMAKE_C_CLANG_TIDY ${CLANG_TIDY_EXE} -checks=-*,cert-*,clang-analyzer-security.*,-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-security.insecureAPI.bzero -header-filter=.*) + SET(CMAKE_C_CLANG_TIDY ${CLANG_TIDY_EXE} -checks=-*,cert-*,clang-analyzer-security.*,-clang-analyzer-security.insecureAPI.strcpy,-clang-analyzer-security.insecureAPI.bzero -header-filter=.*) + ENDIF() ENDIF() INCLUDE(CheckLibraryExists) @@ -40,6 +42,8 @@ SET(MAIKO_DEFINITIONS ) OPTION(MAIKO_DISPLAY_X11 "Use X11 for display." ON) +OPTION(MAIKO_DISPLAY_SDL "Use SDL for display." OFF) + IF(MAIKO_DISPLAY_X11) FIND_PACKAGE(X11 REQUIRED) SET(MAIKO_DISPLAY_X11_DEFINITIONS @@ -70,6 +74,22 @@ IF(MAIKO_DISPLAY_X11) inc/xscroll.h inc/xwinmandefs.h ) + MESSAGE("-- Configured for X11 display") +ENDIF() + +IF(MAIKO_DISPLAY_SDL) + FIND_PACKAGE(SDL2 REQUIRED) + SET(MAIKO_DISPLAY_SDL_DEFINITIONS + "-DSDL" + ) + SET(MAIKO_DISPLAY_SDL_LIBRARIES ${SDL2_LIBRARIES}) + SET(MAIKO_DISPLAY_SDL_SRCS + src/sdl.c + ) + SET(MAIKO_DISPLAY_SDL_HDRS + inc/sdldefs.h + ) + MESSAGE("-- Configured for SDL display") ENDIF() # according to: https://cmake.org/pipermail/cmake/2016-October/064342.html @@ -93,6 +113,7 @@ ELSEIF(NOT MAIKO_NETWORK_TYPE STREQUAL "NONE") MESSAGE(WARNING "Invalid option given for MAIKO_NETWORK_TYPE, must be one of:\nNONE, SUN_DLPI, SUN_NIT, NETHUB") ENDIF() + IF(CMAKE_SYSTEM_NAME STREQUAL "SunOS") LIST(APPEND MAIKO_DEFINITIONS "-DOS5" @@ -412,6 +433,11 @@ IF(MAIKO_DISPLAY_X11) TARGET_LINK_LIBRARIES(lde X11::X11) ENDIF() +IF(MAIKO_DISPLAY_SDL) + # Tell it that the SDL launcher is available. + TARGET_COMPILE_DEFINITIONS(lde PUBLIC ${MAIKO_DISPLAY_SDL_DEFINITIONS}) +ENDIF() + ADD_EXECUTABLE(ldeether src/ldeether.c src/dlpi.c) TARGET_COMPILE_DEFINITIONS(ldeether PUBLIC ${MAIKO_DEFINITIONS}) TARGET_INCLUDE_DIRECTORIES(ldeether PUBLIC inc) @@ -430,6 +456,25 @@ IF(MAIKO_DISPLAY_X11) TARGET_LINK_LIBRARIES(ldex ${MAIKO_LIBRARIES} ${MAIKO_DISPLAY_X11_LIBRARIES}) ENDIF() +IF(MAIKO_DISPLAY_SDL) + ADD_EXECUTABLE(ldesdl + src/main.c + vdate.c + ${MAIKO_SRCS} + ${MAIKO_HDRS} + ${MAIKO_DISPLAY_SDL_SRCS} + ${MAIKO_DISPLAY_SDL_HDRS} + ) + TARGET_COMPILE_DEFINITIONS(ldesdl PUBLIC ${MAIKO_DEFINITIONS} ${MAIKO_DISPLAY_SDL_DEFINITIONS}) + TARGET_INCLUDE_DIRECTORIES(ldesdl PUBLIC inc) + TARGET_INCLUDE_DIRECTORIES(ldesdl PRIVATE ${SDL2_INCLUDE_DIRS}) + TARGET_LINK_LIBRARIES(ldesdl ${MAIKO_LIBRARIES} ${MAIKO_DISPLAY_SDL_LIBRARIES}) +ENDIF() + +ADD_EXECUTABLE(mkvdate src/mkvdate.c) +TARGET_COMPILE_DEFINITIONS(mkvdate PUBLIC ${MAIKO_DEFINITIONS}) +TARGET_INCLUDE_DIRECTORIES(mkvdate PUBLIC inc) + ADD_EXECUTABLE(setsout src/setsout.c src/byteswap.c) TARGET_COMPILE_DEFINITIONS(setsout PUBLIC ${MAIKO_DEFINITIONS}) TARGET_INCLUDE_DIRECTORIES(setsout PUBLIC inc) diff --git a/bin/makefile-cygwin.x86_64-x b/bin/makefile-cygwin.x86_64-x old mode 100755 new mode 100644 index cce7326..f280cba --- a/bin/makefile-cygwin.x86_64-x +++ b/bin/makefile-cygwin.x86_64-x @@ -1,7 +1,7 @@ # Options for Linux, Intel x86_64 and X-Window #CC = gcc -m64 $(GCC_CFLAGS) -CC = clang -m64 $(CLANG_CFLAGS) -DMAIKO_ENABLE_NETHUB +CC = clang -m64 $(CLANG_CFLAGS) XFILES = $(OBJECTDIR)xmkicon.o \ $(OBJECTDIR)xbbt.o \ diff --git a/bin/makefile-darwin.aarch64-sdl b/bin/makefile-darwin.aarch64-sdl new file mode 100644 index 0000000..dc56a02 --- /dev/null +++ b/bin/makefile-darwin.aarch64-sdl @@ -0,0 +1,19 @@ +# Options for MacOS, x86 processor, SDL + +CC = clang $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +SDLFLAGS = -DSDL -F /Library/Frameworks + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g +DEBUGFLAGS = # -DDEBUG -DOPTRACE +DFLAGS = $(DEBUGFLAGS) $(SDLFLAGS) -DRELEASE=351 + +LDFLAGS = -F /Library/Frameworks -framework SDL2 +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-darwin.x86_64-sdl b/bin/makefile-darwin.x86_64-sdl new file mode 100644 index 0000000..94604b0 --- /dev/null +++ b/bin/makefile-darwin.x86_64-sdl @@ -0,0 +1,19 @@ +# Options for MacOS, x86 processor, SDL + +CC = clang -m64 $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +SDLFLAGS = -DSDL -F /Library/Frameworks + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g +DEBUGFLAGS = # -DDEBUG -DOPTRACE +DFLAGS = $(DEBUGFLAGS) $(SDLFLAGS) -DRELEASE=351 + +LDFLAGS = -F /Library/Frameworks -framework SDL2 +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-freebsd.386-sdl b/bin/makefile-freebsd.386-sdl new file mode 100644 index 0000000..8a843a6 --- /dev/null +++ b/bin/makefile-freebsd.386-sdl @@ -0,0 +1,18 @@ +# Options for FreeBSD, Intel 386/486 and SDL + +CC = clang -m32 $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +SDLFLAGS = -DSDL -I/usr/local/include + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g +DFLAGS = $(SDLFLAGS) -DRELEASE=351 + +LDFLAGS = -L/usr/local/lib -lSDL2 -lm +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-freebsd.aarch64-sdl b/bin/makefile-freebsd.aarch64-sdl new file mode 100644 index 0000000..01f967b --- /dev/null +++ b/bin/makefile-freebsd.aarch64-sdl @@ -0,0 +1,18 @@ +# Options for FreeBSD, ARM64 and SDL + +CC = clang -m64 $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +SDLFLAGS = -DSDL -I/usr/local/include + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g +DFLAGS = $(SDLFLAGS) -DRELEASE=351 + +LDFLAGS = -L/usr/local/lib -lSDL2 -lm +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-freebsd.x86_64-sdl b/bin/makefile-freebsd.x86_64-sdl new file mode 100644 index 0000000..8087150 --- /dev/null +++ b/bin/makefile-freebsd.x86_64-sdl @@ -0,0 +1,18 @@ +# Options for FreeBSD, Intel x86_64 and X-Windows + +CC = clang -m64 $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +SDLFLAGS = -DSDL -I/usr/local/include + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g +DFLAGS = $(SDLFLAGS) -DRELEASE=351 + +LDFLAGS = -L/usr/local/lib -lSDL2 -lm +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-linux.386-sdl b/bin/makefile-linux.386-sdl new file mode 100644 index 0000000..da04d80 --- /dev/null +++ b/bin/makefile-linux.386-sdl @@ -0,0 +1,19 @@ +# Options for Linux, Intel 386/486 and SDL + +CC = gcc -m32 $(GCC_CFLAGS) +# CC = clang $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +XFLAGS = -DSDL + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g3 +DFLAGS = $(XFLAGS) -DRELEASE=351 + +LDFLAGS = -lm -lSDL2 +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-linux.386-x b/bin/makefile-linux.386-x index b25198d..5250683 100644 --- a/bin/makefile-linux.386-x +++ b/bin/makefile-linux.386-x @@ -1,7 +1,8 @@ # Options for Linux, Intel 386/486 and X-Window -#CC = gcc -m32 $(GCC_CFLAGS) -CC = clang -m32 $(CLANG_CFLAGS) +CC = gcc -m32 $(GCC_CFLAGS) +# CC = clang -m32 $(CLANG_CFLAGS) + XFILES = $(OBJECTDIR)xmkicon.o \ $(OBJECTDIR)xbbt.o \ $(OBJECTDIR)dspif.o \ @@ -12,7 +13,6 @@ XFILES = $(OBJECTDIR)xmkicon.o \ $(OBJECTDIR)xrdopt.o \ $(OBJECTDIR)xwinman.o - XFLAGS = -DXWINDOW # OPTFLAGS is normally -O2. diff --git a/bin/makefile-linux.aarch64-sdl b/bin/makefile-linux.aarch64-sdl new file mode 100644 index 0000000..337b14d --- /dev/null +++ b/bin/makefile-linux.aarch64-sdl @@ -0,0 +1,19 @@ +# Options for Linux, ARM64 and SDL + +CC = gcc $(GCC_CFLAGS) +#CC = clang $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +SDLFLAGS = -DSDL + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g3 +DFLAGS = $(SDLFLAGS) -DRELEASE=351 + +LDFLAGS = -lSDL2 -lm +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-linux.armv7l-sdl b/bin/makefile-linux.armv7l-sdl new file mode 100644 index 0000000..f2b844c --- /dev/null +++ b/bin/makefile-linux.armv7l-sdl @@ -0,0 +1,19 @@ +# Options for Linux, ARMv7 and SDL + +CC = gcc $(GCC_CFLAGS) +#CC = clang $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +XFLAGS = -DSDL + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g3 +DFLAGS = $(XFLAGS) -DRELEASE=351 + +LDFLAGS = -lm -lSDL2 +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-linux.x86_64-sdl b/bin/makefile-linux.x86_64-sdl new file mode 100644 index 0000000..64819dc --- /dev/null +++ b/bin/makefile-linux.x86_64-sdl @@ -0,0 +1,19 @@ +# Options for Linux, Intel x86_64 and SDL + +CC = gcc -m64 $(GCC_CFLAGS) +# CC = clang -m64 $(CLANG_CFLAGS) + +XFILES = $(OBJECTDIR)sdl.o + +XFLAGS = -DSDL + +# OPTFLAGS is normally -O2. +OPTFLAGS = -O2 -g3 +DFLAGS = $(XFLAGS) -DRELEASE=351 + +LDFLAGS = -lm -lSDL2 +LDELDFLAGS = + +OBJECTDIR = ../$(RELEASENAME)/ + +default : ../$(OSARCHNAME)/lde ../$(OSARCHNAME)/ldesdl diff --git a/bin/makefile-linux.x86_64-x b/bin/makefile-linux.x86_64-x index cce7326..64c3eb0 100644 --- a/bin/makefile-linux.x86_64-x +++ b/bin/makefile-linux.x86_64-x @@ -1,7 +1,7 @@ # Options for Linux, Intel x86_64 and X-Window -#CC = gcc -m64 $(GCC_CFLAGS) -CC = clang -m64 $(CLANG_CFLAGS) -DMAIKO_ENABLE_NETHUB +CC = gcc -m64 $(GCC_CFLAGS) +# CC = clang -m64 $(CLANG_CFLAGS) XFILES = $(OBJECTDIR)xmkicon.o \ $(OBJECTDIR)xbbt.o \ diff --git a/bin/makefile-tail b/bin/makefile-tail index 4036904..508e998 100644 --- a/bin/makefile-tail +++ b/bin/makefile-tail @@ -996,6 +996,9 @@ $(OBJECTDIR)xwinman.o: $(SRCDIR)xwinman.c $(REQUIRED-INCS) \ $(INCDIR)xlspwindefs.h $(INCDIR)xscrolldefs.h $(CC) $(RFLAGS) $(SRCDIR)xwinman.c -o $(OBJECTDIR)xwinman.o +$(OBJECTDIR)sdl.o: $(SRCDIR)sdl.c $(REQUIRED-INCS) + $(CC) $(RFLAGS) $(SRCDIR)sdl.c -o $(OBJECTDIR)sdl.o + $(OBJECTDIR)foreign.o: $(SRCDIR)foreign.c $(REQUIRED-INCS) \ $(INCDIR)/foreigndefs.h $(CC) $(RFLAGS) $(SRCDIR)foreign.c -o $(OBJECTDIR)foreign.o diff --git a/bin/makeright b/bin/makeright index 9f2ab0c..1fde522 100755 --- a/bin/makeright +++ b/bin/makeright @@ -71,6 +71,9 @@ case "$display" in x) releasename=${osversion}.${architecture}-${display} ldename=ldex ;; + sdl) releasename=${osversion}.${architecture}-${display} + ldename=ldesdl + ;; *) echo "display-option: $display is not supported." exit ;; diff --git a/inc/display.h b/inc/display.h index 5cee6ff..59c0509 100755 --- a/inc/display.h +++ b/inc/display.h @@ -43,6 +43,10 @@ extern DLword *DISP_MAX_Address; #define DISPLAYBUFFER #endif /* XWINDOW */ +#ifdef SDL +#define DISPLAYBUFFER +#endif /* SDL */ + #ifdef DOS #define DISPLAYBUFFER #endif /* DOS */ diff --git a/inc/sdldefs.h b/inc/sdldefs.h new file mode 100644 index 0000000..e1a0c18 --- /dev/null +++ b/inc/sdldefs.h @@ -0,0 +1,11 @@ +#ifndef SDLDEFS_H +#define SDLDEFS_H 1 + +void sdl_notify_damage(int x, int y, int w, int h); +void sdl_setCursor(int hot_x, int hot_y); +void sdl_bitblt_to_screen(int x, int y, int w, int h); +void sdl_set_invert(int flag); +void sdl_setMousePosition(int x, int y); +void process_SDLevents(); +int init_SDL(char *windowtitle, int w, int h, int s); +#endif diff --git a/src/bbtsub.c b/src/bbtsub.c index f8c5d12..e32c901 100644 --- a/src/bbtsub.c +++ b/src/bbtsub.c @@ -470,6 +470,10 @@ do_it_now: if (in_display_segment(dstbase)) flush_display_region(dx, dty, w, h); #endif /* XWINDOW */ +#ifdef SDL + if (in_display_segment(dstbase)) flush_display_region(dx, dty, w, h); +#endif /* XWINDOW */ + #ifdef DOS /* Copy the changed section of display bank to the frame buffer */ if (in_display_segment(dstbase)) { @@ -823,6 +827,10 @@ do_it_now: if (in_display_segment(dstbase)) flush_display_region(dlx, dty, width, height); #endif /* XWINDOW */ +#ifdef SDL + if (in_display_segment(dstbase)) flush_display_region(dlx, dty, width, height); +#endif /* SDL */ + #ifdef DOS /* Copy the changed section of display bank to the frame buffer */ if (in_display_segment(dstbase)) { @@ -1070,6 +1078,10 @@ do_it_now: if (in_display_segment(dstbase)) flush_display_region(left, dty, width, height); #endif /* XWINDOW */ +#ifdef SDL + if (in_display_segment(dstbase)) flush_display_region(left, dty, width, height); +#endif /* SDL */ + #ifdef DOS /* Copy the changed section of display bank to the frame buffer */ if (in_display_segment(dstbase)) { @@ -1199,6 +1211,10 @@ void bltchar(LispPTR *args) if (in_display_segment(dstbase)) flush_display_lineregion(dx, dstbase, w, h); #endif /* XWINDOW */ +#ifdef SDL + if (in_display_segment(dstbase)) flush_display_lineregion(dx, dstbase, w, h); +#endif /* SDL */ + #ifdef DOS if (in_display_segment(dstbase)) flush_display_lineregion(dx, dstbase, w, h); #endif /* DOS */ @@ -1415,6 +1431,9 @@ void newbltchar(LispPTR *args) { #ifdef XWINDOW if (in_display_segment(dstbase)) flush_display_lineregion(dx, dstbase, w, h); #endif /* XWINDOW */ +#ifdef SDL + if (in_display_segment(dstbase)) flush_display_lineregion(dx, dstbase, w, h); +#endif /* SDL */ #ifdef DOS if (in_display_segment(dstbase)) flush_display_lineregion(dx, dstbase, w, h); #endif /* DOS */ diff --git a/src/draw.c b/src/draw.c index 09b314f..1b5fdac 100644 --- a/src/draw.c +++ b/src/draw.c @@ -20,6 +20,7 @@ #include // for ptrdiff_t #include // for abs #include "adr68k.h" // for NativeAligned2FromLAddr +#include "bitblt.h" // for MOUSEXR, MOUSEYH #include "display.h" // for DISPLAYBUFFER, DisplayRegion68k, in_display... #include "drawdefs.h" // for N_OP_drawline #include "emlglob.h" diff --git a/src/dspsubrs.c b/src/dspsubrs.c index cf1c516..69fc3d2 100644 --- a/src/dspsubrs.c +++ b/src/dspsubrs.c @@ -18,9 +18,11 @@ #include "lispemul.h" // for LispPTR, DLword, ATOM_T, NIL #include "lispmap.h" // for S_POSITIVE #include "lsptypes.h" // for GETWORD -#ifdef XWINDOW +#if defined(XWINDOW) #include "xcursordefs.h" // for Set_XCursor #include "xlspwindefs.h" // for lisp_Xvideocolor, set_Xmouseposition +#elif defined(SDL) +#include "sdldefs.h" #endif extern int DebugDSP; @@ -69,6 +71,13 @@ LispPTR DSP_VideoColor(LispPTR *args) /* args[0] : black flag */ return ATOM_T; else return NIL; +#elif defined(SDL) + invert = args[0] & 0xFFFF; + sdl_set_invert(invert); + if (invert) + return ATOM_T; + else + return NIL; #else return NIL; #endif @@ -92,9 +101,11 @@ void DSP_Cursor(LispPTR *args, int argnum) extern int LastCursorX, LastCursorY; -#ifdef XWINDOW +#if defined(XWINDOW) /* For X-Windows, set the cursor to the given location. */ Set_XCursor((int)(args[0] & 0xFFFF), (int)(args[1] & 0xFFFF)); +#elif defined(SDL) + sdl_setCursor((int)(args[0] & 0xFFFF), (int)(args[1] & 0xFFFF)); #endif /* XWINDOW */ } @@ -114,6 +125,11 @@ void DSP_SetMousePos(LispPTR *args) if (Mouse_Included) set_Xmouseposition((int)(GetSmalldata(args[0])), (int)(GetSmalldata(args[1]))); #endif /* XWINDOW */ +#ifdef SDL + int x = (int)(GetSmalldata(args[0])); + int y = (int)(GetSmalldata(args[1])); + sdl_setMousePosition(x, y); +#endif /* SDL */ } /**************************************************** @@ -174,8 +190,10 @@ void flip_cursor(void) { #endif -#ifdef XWINDOW +#if defined(XWINDOW) /* JDS 011213: 15- cur y, as function does same! */ Set_XCursor(Current_Hot_X, 15 - Current_Hot_Y); +#elif defined(SDL) + sdl_setCursor(0, 0); // TODO: keep track of the current hot_x and hot_y #endif /* XWINDOW */ } diff --git a/src/initdsp.c b/src/initdsp.c index 86c0335..05466af 100644 --- a/src/initdsp.c +++ b/src/initdsp.c @@ -56,6 +56,7 @@ extern DspInterface currentdsp; int FrameBufferFd = -1; +extern int sdl_displaywidth, sdl_displayheight, sdl_pixelscale; extern unsigned displaywidth, displayheight, DisplayRasterWidth, DisplayType, DisplayByteSize; unsigned displaywidth, displayheight, DisplayRasterWidth, DisplayType, DisplayByteSize; DLword *DisplayRegion68k; /* 68k addr of #{}22,0 */ @@ -78,6 +79,10 @@ extern DLword *ColorDisplayRegion68k; extern int MonoOrColor; #endif /* COLOR */ +#ifdef SDL +extern void sdl_notify_damage(int, int, int, int); +#endif /* SDL */ + #ifdef XWINDOW DLword *DisplayRegion68k_end_addr; extern int *Xdisplay; /* DAANGER -jarl nilsson 27-apr-92 */ @@ -169,7 +174,10 @@ void init_display2(DLword *display_addr, unsigned display_max) displaywidth = currentdsp->Display.width; displayheight = currentdsp->Display.height; #endif /* XWINDOW */ - +#if (defined(SDL)) + displaywidth = sdl_displaywidth; + displayheight = sdl_displayheight; +#endif /* SDL */ DisplayRasterWidth = displaywidth / BITSPER_DLWORD; if ((displaywidth * displayheight) > display_max) { displayheight = display_max / displaywidth; } @@ -183,7 +191,9 @@ void init_display2(DLword *display_addr, unsigned display_max) DisplayType = SUN2BW; DisplayRegion68k_end_addr = DisplayRegion68k + DisplayRasterWidth * displayheight; #endif /* XWINDOW */ - +#ifdef SDL + DisplayType = SUN2BW; +#endif /* SDL */ init_cursor(); DisplayByteSize = ((displaywidth * displayheight / 8 + ((unsigned)getpagesize() - 1)) & (unsigned)-getpagesize()); @@ -255,7 +265,9 @@ in_display_segment(baseaddr) /************************************************************************/ void flush_display_buffer(void) { - +#ifdef SDL + sdl_notify_damage(0, 0, sdl_displaywidth, sdl_displayheight); +#endif #ifdef XWINDOW (currentdsp->bitblt_to_screen)(currentdsp, DisplayRegion68k, currentdsp->Visible.x, currentdsp->Visible.y, currentdsp->Visible.width, @@ -283,7 +295,10 @@ void flush_display_buffer(void) { /************************************************************************/ void flush_display_region(int x, int y, int w, int h) { - + // printf("flush_display_region %d %d %d %d\n", x, y, w, h); +#ifdef SDL + sdl_notify_damage(x, y, w, h); +#endif #if (defined(XWINDOW) || defined(DOS)) TPRINT(("Enter flush_display_region x=%d, y=%d, w=%d, h=%d\n", x, y, w, h)); (currentdsp->bitblt_to_screen)(currentdsp, DisplayRegion68k, x, y, w, h); @@ -326,7 +341,10 @@ void flush_display_lineregion(UNSIGNED x, DLword *ybase, int w, int h) { int y; y = ((DLword *)ybase - DisplayRegion68k) / DLWORD_PERLINE; - + // printf("flush_display_lineregion %d %d %d %d\n", x, y, w, h); +#ifdef SDL + sdl_notify_damage(x, y, w, h); +#endif #if (defined(XWINDOW) || defined(DOS)) TPRINT(("Enter flush_display_lineregion x=%p, y=%d, w=%d, h=%d\n", (void *)x, y, w, h)); (currentdsp->bitblt_to_screen)(currentdsp, DisplayRegion68k, x, y, w, h); @@ -357,7 +375,10 @@ void flush_display_ptrregion(DLword *ybase, UNSIGNED bitoffset, int w, int h) baseoffset = (((DLword *)ybase) - DisplayRegion68k); y = baseoffset / DLWORD_PERLINE; x = bitoffset + (BITSPERWORD * (baseoffset - (DLWORD_PERLINE * y))); - + // printf("flush_display_ptrregion %d %d %d %d\n", x, y, w, h); +#ifdef SDL + sdl_notify_damage(x, y, w, h); +#endif #if (defined(XWINDOW) || defined(DOS)) TPRINT(("Enter flush_display_ptrregion\n x=%d, y=%d, w=%d, h=%d\n", x, y, w, h)); (currentdsp->bitblt_to_screen)(currentdsp, DisplayRegion68k, x, y, w, h); diff --git a/src/initkbd.c b/src/initkbd.c index e250b78..39612f3 100644 --- a/src/initkbd.c +++ b/src/initkbd.c @@ -283,6 +283,7 @@ void set_kbd_iopointers(void) { #define KB_HP9000 (10 + MIN_KEYTYPE) /* TODO: Can we remove this? */ #define KB_X (11 + MIN_KEYTYPE) #define KB_DOS (12 + MIN_KEYTYPE) +#define KB_SDL (13 + MIN_KEYTYPE) /* KB_SUN4 not defined in older OS versions */ #ifndef KB_SUN4 @@ -424,8 +425,10 @@ void keyboardtype(int fd) int i; char *key; +#if defined(OS4) for (i = 0; i < 5000; i++) { /* IDLE LOOP */ } /* because of a SunOS bug */ +#endif /* clear the keyboard field in devconfig */ InterfacePage->devconfig &= 0xfff8; @@ -442,6 +445,8 @@ void keyboardtype(int fd) type = KB_X; #elif DOS type = KB_DOS; +#elif SDL + type = KB_SDL; #endif /* XWINDOW */ } /* if end */ else { @@ -455,6 +460,8 @@ void keyboardtype(int fd) type = KB_JLE; else if (strcmp("X", key) == 0 || strcmp("x", key) == 0) type = KB_X; + else if (strcmp("sdl", key) == 0) + type = KB_SDL; else type = KB_SUN3; /* default */ } @@ -491,7 +498,11 @@ void keyboardtype(int fd) InterfacePage->devconfig |= KB_SUN3 - MIN_KEYTYPE; /* 10 */ break; #endif /* XWINDOW */ - +#ifdef SDL + case KB_SDL: + InterfacePage->devconfig |= KB_SUN3 - MIN_KEYTYPE; /* 10 */ + break; +#endif /* SDL */ #ifdef DOS case KB_DOS: SUNLispKeyMap = DOSLispKeyMap_101; diff --git a/src/keyevent.c b/src/keyevent.c index b57e2ee..ecc60b3 100644 --- a/src/keyevent.c +++ b/src/keyevent.c @@ -45,6 +45,7 @@ void Mouse_hndlr(void); /* Fields mouse events from driver */ #include "adr68k.h" #include "address.h" #include "stack.h" +#include "initdspdefs.h" #include "keyboard.h" #include "display.h" #include "lsptypes.h" @@ -55,7 +56,9 @@ void Mouse_hndlr(void); /* Fields mouse events from driver */ #include "keyeventdefs.h" #include "osmsgdefs.h" +#ifdef XWINDOW #include "xwinmandefs.h" +#endif #if defined(MAIKO_ENABLE_ETHERNET) || defined(MAIKO_ENABLE_NETHUB) #include "etherdefs.h" diff --git a/src/ldeboot.c b/src/ldeboot.c index a01f612..6e18927 100644 --- a/src/ldeboot.c +++ b/src/ldeboot.c @@ -12,12 +12,15 @@ #include #include +#include // for PATH_MAX #include #include #include #include #include +#include "unixfork.h" + #if defined(sun) && !defined(OS5) #define USESUNSCREEN #else @@ -26,23 +29,25 @@ #ifdef USESUNSCREEN #include +#ifndef FBTYPE_SUNFAST_COLOR +#define FBTYPE_SUNFAST_COLOR 12 +#endif #define LDEMONO "ldesingle" #define LDECOLOR "ldemulti" #define LDETRUECOLOR "ldetruecolor" -#define FBTYPE_SUNFAST_COLOR 12 #endif /* USESUNSCREEN */ -#include "unixfork.h" - #ifdef XWINDOW #include #include #define LDEX "ldex" #endif /* XWINDOW */ - +#ifdef SDL +#define LDESDL "ldesdl" +#endif /************************************************************************/ /* */ @@ -52,10 +57,13 @@ /* */ /************************************************************************/ -int main(int argc, char *argv[]) -{ +int main(int argc, char *argv[]) { int i; - char filetorun[30] = {0}; + char *filetorun = NULL; + char filetorunpath[PATH_MAX]; + char *dirsepp = NULL; + char *displayName = (char *)NULL; + int doFork = 1; #ifdef USESUNSCREEN int FrameBufferFd; struct fbtype my_screen; @@ -63,142 +71,142 @@ int main(int argc, char *argv[]) struct fbgattr FBattr; #endif /* USESUNSCREEN */ -/* Kickstart program for the Lisp Development Environment (LDE). - Display Device emulator - CG3, CG6 lde.multi - BW2, CG2, CG4, CG9 lde.single + /* Kickstart program for the Lisp Development Environment (LDE). + Display Device emulator + CG3, CG6 lde.multi + BW2, CG2, CG4, CG9 lde.single - FB-TYPE REAL-TYPE - BW2 2 x - CG2 3 3 - CG3 8 6 - CG4 2 8 - CG6 8 12 - CG8 6 7 - CG9(GP1) 4 4 ;gpconfig -f -b - CG9(GP1) 2 13 ;gpconfig gpone0 -f -b cgtwo0 - ;We assume This config for GXP model + FB-TYPE REAL-TYPE + BW2 2 x + CG2 3 3 + CG3 8 6 + CG4 2 8 + CG6 8 12 + CG8 6 7 + CG9(GP1) 4 4 ;gpconfig -f -b + CG9(GP1) 2 13 ;gpconfig gpone0 -f -b cgtwo0 + ;We assume This config for GXP model + */ + + /* look for a -display argument that could tell us X11 vs SDL for display + */ + for (i = 1; i < argc; i++) { + if ((strcmp(argv[i], "-d") == 0) || (strcmp(argv[i], "-display") == 0)) { + if (i == argc - 1) { + fprintf(stderr, "Missing argument to -display option.\n"); + exit(1); + } + displayName = argv[++i]; + } + } + + /* Unless prevented by -NF option, fork the process, while small, to handle + * process communications and subsequent forks */ -#ifdef XWINDOW - /* If X-Server exists on the host specified in -display option - or environment variable DISPLAY, ldex is started. Otherwise - ldesingle or ldemulti. - */ - { - char *Display_Name = (char *)NULL; - Display *Xdisplay = (Display *)NULL; - char *pos; - - for (i = 1; i < argc; i++) { - if ((strcmp(argv[i], "-d") == 0) || (strcmp(argv[i], "-display") == 0)) { - if (i == argc) break; - pos = (char *)strchr(argv[++i], ':'); - if (pos != NULL) { Display_Name = argv[i]; } - continue; - } + for (i = 1; i < argc; i++) { + if (strcmp(argv[i], "-NF") == 0) { + doFork = 0; + break; } + } + if (doFork) fork_Unix(); - if ((Xdisplay = XOpenDisplay(Display_Name)) != (Display *)NULL) { - /* success to connect X-server */ +#ifdef SDL +#ifdef XWINDOW + /* if we have SDL *and* XWINDOW we only do SDL if requested */ + if (displayName && (0 == strcmp(displayName, "SDL"))) { +#else + /* otherwise SDL is it */ + { +#endif + filetorun = LDESDL; + goto run; + } +#endif /* SDL */ + +#ifdef XWINDOW + /* If an X server exists as specified in the -display option + * or environment variable DISPLAY, ldex is started. + */ + { + Display *Xdisplay = XOpenDisplay(displayName); + + if (Xdisplay) { + /* success connecting to X server. Close it now, it will be reopened by ldex */ XCloseDisplay(Xdisplay); - strcpy(filetorun, LDEX); - - /* JRB - call fork_Unix here, while we're REALLY small, unless -NF is - specified, of course... */ - for (i = 1; i < argc; i++) - if (!strcmp(argv[i], "-NF")) break; - if (i == argc) /* -NF not in arguments */ - fork_Unix(); - - argv[0] = filetorun; - execvp(filetorun, argv); - perror(filetorun); + filetorun = LDEX; + goto run; + } else { + fprintf(stderr, "Unable to open X11 display %s\n", + displayName ? displayName : "from DISPLAY"); exit(1); - } else { /* failed to connect X-server */ -#define NAME_LEN 100 - char host_name[NAME_LEN]; - gethostname(host_name, NAME_LEN); - if (Display_Name == NULL) { - if ((Display_Name = getenv("DISPLAY")) != NULL) { - if (strncmp(Display_Name, host_name, strlen(host_name)) == 0) { - fprintf(stderr, "ldeboot: can't find X-Server\n"); - exit(-1); - } /* end if */ - } - /* end if */ - } else { - fprintf(stderr, "ldeboot: can't find X-Server\n"); - exit(-1); - } /* end if */ - } /* end if */ + } } #endif /* XWINDOW */ #ifdef USESUNSCREEN if ((FrameBufferFd = open("/dev/fb", O_RDWR)) < 0) { - fprintf(stderr, "ldeboot: can't open FrameBuffer\n"); - exit(-1); + fprintf(stderr, "lde: can't open FrameBuffer\n"); + exit(1); } if (ioctl(FrameBufferFd, FBIOGTYPE, &my_screen) < 0) { - perror("initdisplay0:"); - exit(-1); + perror(argv[0]); + exit(1); } - if (my_screen.fb_type == FBTYPE_SUN4COLOR) { /* cg3 or cg6 */ - if (ioctl(FrameBufferFd, FBIOGATTR, &FBattr) >= 0) { - if (FBattr.real_type == FBTYPE_SUN3COLOR || /* cg3 */ - FBattr.real_type == FBTYPE_SUNFAST_COLOR) /* cg6 */ - { - strcpy(filetorun, LDECOLOR); + switch (my_screen.fb_type) { + case FBTYPE_SUN4COLOR: /* cg3 or cg6 */ + if (ioctl(FrameBufferFd, FBIOGATTR, &FBattr) >= 0) { + if (FBattr.real_type == FBTYPE_SUN3COLOR || /* cg3 */ + FBattr.real_type == FBTYPE_SUNFAST_COLOR) /* cg6 */ + { + filetorun = LDECOLOR; + } } - } else { /* if( ioctl... */ - perror("lde: This Display Model does not supported\n"); - exit(-1); - } - } else if (my_screen.fb_type == FBTYPE_SUN2BW) { /* bw2, cg4 or cg9 */ - strcpy(filetorun, LDEMONO); - } else if (my_screen.fb_type == FBTYPE_SUN3COLOR) { - if (ioctl(FrameBufferFd, FBIOGATTR, &FBattr) >= 0) { - if (FBattr.real_type == FBTYPE_MEMCOLOR) /* cg8 */ - { - strcpy(filetorun, LDETRUECOLOR); + break; + case FBTYPE_SUN2BW: /* bw2, cg4 or cg9 */ + filetorun = LDEMONO; + break; + case FBTYPE_SUN3COLOR: /* cg8 */ + if (ioctl(FrameBufferFd, FBIOGATTR, &FBattr) >= 0) { + if (FBattr.real_type == FBTYPE_MEMCOLOR) { filetorun = LDETRUECOLOR; } } - } else { /* if( ioctl... */ - perror("lde: This Display Model does not supported\n"); - exit(-1); - } - - } else if (my_screen.fb_type == FBTYPE_SUN2COLOR) { /* cg2 */ - strcpy(filetorun, LDEMONO); - } else { - perror("lde: This Display Model does not supported\n"); - exit(-1); - } /* endif( my_screen... */ - + break; + case FBTYPE_SUN2COLOR: /* cg2 */ + filetorun = LDEMONO; + break; + default: break; + } + if (filetorun == (char *)NULL) { + perror("lde: This Display Model is not supported\n"); + exit(1); + } close(FrameBufferFd); - #endif /* USESUNSCREEN */ - /* JRB - call fork_Unix here, while we're REALLY small, unless -NF is - specified, of course... */ - for (i = 1; i < argc; i++) - if (!strcmp(argv[i], "-NF")) break; - if (i == argc) /* -NF not in arguments */ - fork_Unix(); - - /* start ldemono or ldecolor */ - - if (filetorun[0] == '\0') { + run: + if (filetorun == NULL) { fprintf(stderr, "Unable to determine what display program to run.\n"); exit(1); } - argv[0] = filetorun; /* or whatever... */ - - /* then execve the LDE executable */ - execvp(filetorun, argv); - perror(filetorun); - + /* construct invocation path of display program parallel to this one, + * so that it will have higher probability of finding a corresponding + * display program if there are multiple versions findable via PATH + */ + dirsepp = strrchr(argv[0], '/'); + if (dirsepp == NULL) { + argv[0] = filetorun; + } else { + /* copy up to and including the final "/" in the path */ + dirsepp = stpncpy(filetorunpath, argv[0], dirsepp + 1 - argv[0]); + /* dirsepp now points to the trailing null in the copy */ + strncpy(dirsepp, filetorun, PATH_MAX - (dirsepp - filetorunpath)); + argv[0] = filetorunpath; + } + execvp(argv[0], argv); + perror(argv[0]); exit(1); + } diff --git a/src/main.c b/src/main.c index 36d2a44..4d23107 100644 --- a/src/main.c +++ b/src/main.c @@ -238,7 +238,9 @@ int flushing = FALSE; /* see dbprint.h if set, all debug/trace printing will cal #include "devif.h" extern DspInterface currentdsp; #endif /* DOS || XWINDOW */ - +#ifdef SDL +extern int init_SDL(char*, int, int, int); +#endif extern const time_t MDate; extern int nokbdflag; extern int nomouseflag; @@ -274,7 +276,18 @@ const char *helpstring = -bw The Medley screen borderwidth\n\ -g[eometry] ] The Medley screen geometry\n\ -sc[reen] x] The Medley screen geometry\n"; -#else /* not DOS, not XWINDOW */ +#elif SDL +const char *helpstring = + "\n\ + either setenv LDESRCESYSOUT or do:\n\ + medley [] []\n\ + -info Print general info about the system\n\ + -help Print this message\n\ + -pixelscale The amount of pixels to show for one Medley screen pixel.\n\ + -sc[reen] x] The Medley screen geometry\n\ + -t The window title\n\ + -title <title> The window title\n"; +#else /* not DOS, not XWINDOW, not SDL */ const char *helpstring = "\n\ either setenv LDESRCESYSOUT or do:\n\ @@ -313,6 +326,10 @@ int main(int argc, char *argv[]) extern int TIMER_INTERVAL; extern fd_set LispReadFds; long tmpint; + int width = 1024, height = 768; + int pixelscale = 1; + char *windowtitle = "Medley"; + #ifdef MAIKO_ENABLE_FOREIGN_FUNCTION_INTERFACE if (dld_find_executable(argv[0]) == 0) { perror("Name of executable not found."); @@ -440,7 +457,40 @@ int main(int argc, char *argv[]) } #endif /* DOS */ +#ifdef SDL + else if ((strcmp(argv[i], "-sc") == 0) || (strcmp(argv[i], "-SC") == 0)) { + if (argc > ++i) { + int read = sscanf(argv[i], "%dx%d", &width, &height); + if(read != 2) { + fprintf(stderr, "Could not parse -sc argument %s\n", argv[i]); + exit(1); + } + } else { + fprintf(stderr, "Missing argument after -sc\n"); + exit(1); + } + } else if ((strcmp(argv[i], "-pixelscale") == 0) || (strcmp(argv[i], "-PIXELSCALE") == 0)) { + if (argc > ++i) { + int read = sscanf(argv[i], "%d", &pixelscale); + if(read != 1) { + fprintf(stderr, "Could not parse -pixelscale argument %s\n", argv[i]); + exit(1); + } + } else { + fprintf(stderr, "Missing argument after -pixelscale\n"); + exit(1); + } + } else if ((strcmp(argv[i], "-t") == 0) || (strcmp(argv[i], "-T") == 0) + || (strcmp(argv[i], "-title") == 0) || (strcmp(argv[i], "-TITLE") == 0)) { + if (argc > ++i) { + windowtitle = argv[i]; + } else { + fprintf(stderr, "Missing argument after -title\n"); + exit(1); + } + } +#endif /* SDL */ /* Can only do this under SUNOs, for now */ else if (!strcmp(argv[i], "-E")) { /**** ethernet info ****/ #ifdef MAIKO_ENABLE_ETHERNET @@ -598,7 +648,9 @@ int main(int argc, char *argv[]) #if defined(DOS) || defined(XWINDOW) make_dsp_instance(currentdsp, 0, 0, 0, 1); /* All defaults the first time */ #endif /* DOS || XWINDOW */ - +#if defined(SDL) + init_SDL(windowtitle, width, height, pixelscale); +#endif /* SDL */ /* Load sysout to VM space and returns real sysout_size(not 0) */ sysout_size = sysout_loader(sysout_name, sysout_size); diff --git a/src/sdl.c b/src/sdl.c new file mode 100644 index 0000000..367fd4e --- /dev/null +++ b/src/sdl.c @@ -0,0 +1,737 @@ +#include <SDL2/SDL.h> +#include <SDL2/SDL_keycode.h> +#include <assert.h> +#include <limits.h> +#include "sdldefs.h" +#include "byteswapdefs.h" +#include "lispemul.h" +#include "lsptypes.h" +#include "keyboard.h" +#include "lspglob.h" // for IOPage +#include "display.h" // for CURSORHEIGHT, DisplayRegion68k + +/* if SDLRENDERING is defined, render to a texture rather than + * using the window surface + */ + +#define SDLRENDERING 1 + +static SDL_Window *sdl_window = NULL; +#if defined(SDLRENDERING) +static SDL_Renderer *sdl_renderer = NULL; +static SDL_RendererInfo sdl_rendererinfo = {0}; +static SDL_Texture *sdl_texture = NULL; +#else +static SDL_Surface *sdl_windowsurface = NULL; +static SDL_Surface *sdl_buffersurface = NULL; +static int buffer_size = 0; +static void *buffer = NULL; +#endif +static Uint32 sdl_white; +static Uint32 sdl_black; +static Uint32 sdl_foreground; +static Uint32 sdl_background; +static int sdl_bytesperpixel; +static SDL_PixelFormat *sdl_pixelformat; + +extern void kb_trans(u_short keycode, u_short upflg); +extern int error(const char *s); + +extern int KBDEventFlg; +/* clang-format off */ +int keymap[] = { + 0, SDLK_5, + 1, SDLK_4, + 2, SDLK_6, + 3, SDLK_e, + 4, SDLK_7, + 5, SDLK_d, + 6, SDLK_u, + 7, SDLK_v, + 8, SDLK_RIGHTPAREN, + 8, SDLK_0, + 9, SDLK_k, + 10, SDLK_MINUS, + 11, SDLK_p, + 12, SDLK_SLASH, + 13, SDLK_KP_PERIOD, + 14, SDLK_SCROLLLOCK, + 15, SDLK_BACKSPACE, + 16, SDLK_3, + 17, SDLK_2, + 18, SDLK_w, + 19, SDLK_q, + 20, SDLK_s, + 21, SDLK_a, + 22, SDLK_LEFTPAREN, + 22, SDLK_9, + 23, SDLK_i, + 24, SDLK_x, + 25, SDLK_o, + 26, SDLK_l, + 27, SDLK_COMMA, + 28, SDLK_QUOTE, + 29, SDLK_RIGHTBRACKET, + 31, SDLK_LALT, /* Meta, Sun-4 usual key */ + 32, SDLK_1, + 33, SDLK_ESCAPE, + 34, SDLK_TAB, + 35, SDLK_f, + 36, SDLK_LCTRL, + 37, SDLK_c, + 38, SDLK_j, + 39, SDLK_b, + 40, SDLK_z, + 41, SDLK_LSHIFT, + 42, SDLK_PERIOD, + 43, SDLK_SEMICOLON, + 43, SDLK_COLON, + 44, SDLK_RETURN, + 45, SDLK_BACKQUOTE, + 47, SDLK_RCTRL, + 48, SDLK_r, + 49, SDLK_t, + 50, SDLK_g, + 51, SDLK_y, + 52, SDLK_h, + 53, SDLK_8, + 54, SDLK_n, + 55, SDLK_m, + 56, SDLK_CAPSLOCK, + 57, SDLK_SPACE, + 58, SDLK_LEFTBRACKET, + 59, SDLK_EQUALS, + 60, SDLK_RSHIFT, + 61, SDLK_F11, + 61, SDLK_PAUSE, + 62, SDLK_HOME, + 63, SDLK_PAGEUP, + 64, SDLK_KP_EQUALS, + 65, SDLK_KP_DIVIDE, + 66, SDLK_F7, + 67, SDLK_F4, + 68, SDLK_F5, + 69, SDLK_KP_2, + 70, SDLK_KP_3, + // 71, XK_Linefeed, + // 73, XK_Numlock, + 76, SDLK_KP_ENTER, + 80, SDLK_F9, + 81, SDLK_KP_7, + 82, SDLK_KP_8, + 83, SDLK_KP_9, + 84, SDLK_KP_4, + 85, SDLK_KP_5, + 86, SDLK_LALT, /* (sun left-diamond key) */ + 87, SDLK_KP_6, + 89, SDLK_INSERT, + 90, SDLK_END, + 91, SDLK_F12, + 92, SDLK_PRINTSCREEN, // is this XK_Print?? + 93, SDLK_MODE, // is this XK_Mode_switch + 94, SDLK_KP_1, + 95, SDLK_KP_MULTIPLY, + 96, SDLK_KP_MINUS, + 97, SDLK_HELP, + 98, SDLK_KP_0, + 99, SDLK_F2, + 100, SDLK_F3, + 101, SDLK_F6, + 102, SDLK_KP_PLUS, + 104, SDLK_F8, + 105, SDLK_BACKSLASH, + 106, SDLK_F10, + 107, SDLK_F11, + 108, SDLK_F12, + -1, -1 +}; +/* clang-format on */ +static const DLword bitmask[16] = {1 << 15, 1 << 14, 1 << 13, 1 << 12, 1 << 11, 1 << 10, + 1 << 9, 1 << 8, 1 << 7, 1 << 6, 1 << 5, 1 << 4, + 1 << 3, 1 << 2, 1 << 1, 1 << 0}; +// all of the following are overwritten, the values here are irrelevant defaults! +// actual size of the lisp display in pixels. +int sdl_displaywidth = 0; +int sdl_displayheight = 0; +// current size of the window, in pixels +int sdl_windowwidth = 0; +int sdl_windowheight = 0; +// each pixel is shown as this many pixels +int sdl_pixelscale = 0; +extern DLword *EmKbdAd068K, *EmKbdAd168K, *EmKbdAd268K, *EmKbdAd368K, *EmKbdAd468K, *EmKbdAd568K, + *EmRealUtilin68K; +extern DLword *EmCursorBitMap68K; +extern DLword *CTopKeyevent; +extern int URaid_req; +extern LispPTR *KEYBUFFERING68k; + +void DoRing() { + DLword w, r; + KBEVENT *kbevent; + +do_ring: + /* DEL is not generally present on a Mac X keyboard, Ctrl-shift-ESC would be 18496 */ + if (((*EmKbdAd268K) & 2113) == 0) { /*Ctrl-shift-NEXT*/ + error("****** EMERGENCY Interrupt ******"); + *EmKbdAd268K = KB_ALLUP; /*reset*/ + ((RING *)CTopKeyevent)->read = 0; /* reset queue */ + ((RING *)CTopKeyevent)->write = MINKEYEVENT; + /*return(0);*/ + } else if (((*EmKbdAd268K) & 2114) == 0) { /* Ctrl-Shift-DEL */ + *EmKbdAd268K = KB_ALLUP; /*reset*/ + URaid_req = T; + ((RING *)CTopKeyevent)->read = 0; /* reset queue */ + ((RING *)CTopKeyevent)->write = MINKEYEVENT; + /*return(0);*/ + } + +#ifdef OS4_TYPE4BUG + else if (((*EmKbdAd268K) & 2120) == 0) { /* Ctrl-Shift-Return */ + *EmKbdAd268K = KB_ALLUP; /*reset*/ + URaid_req = T; + ((RING *)CTopKeyevent)->read = 0; /* reset queue */ + ((RING *)CTopKeyevent)->write = MINKEYEVENT; + } +#endif + + r = RING_READ(CTopKeyevent); + w = RING_WRITE(CTopKeyevent); + + if (r == w) /* event queue FULL */ + goto KBnext; + + kbevent = (KBEVENT *)(CTopKeyevent + w); + /* RCLK(kbevent->time); */ + kbevent->W0 = *EmKbdAd068K; + kbevent->W1 = *EmKbdAd168K; + kbevent->W2 = *EmKbdAd268K; + kbevent->W3 = *EmKbdAd368K; + kbevent->W4 = *EmKbdAd468K; + kbevent->W5 = *EmKbdAd568K; + kbevent->WU = *EmRealUtilin68K; + + if (r == 0) /* Queue was empty */ + ((RING *)CTopKeyevent)->read = w; + if (w >= MAXKEYEVENT) + ((RING *)CTopKeyevent)->write = MINKEYEVENT; + else + ((RING *)CTopKeyevent)->write = w + KEYEVENTSIZE; + +KBnext: + if (*KEYBUFFERING68k == NIL) *KEYBUFFERING68k = ATOM_T; +} + +static int min(int a, int b) { + if (a < b) return a; + return b; +} + +static int display_update_needed = 0; + +static int min_x = INT_MAX; +static int min_y = INT_MAX; +static int max_x = 0; +static int max_y = 0; +void sdl_notify_damage(int x, int y, int w, int h) { + if (x < min_x) min_x = x; + if (y < min_y) min_y = y; + if (x + w > max_x) max_x = min(x + w, sdl_displaywidth - 1); + if (y + h > max_y) max_y = min(y + h, sdl_displayheight - 1); + display_update_needed = 1; +} + +/* a simple linked list to remember generated cursors + * because cursors don't have any identifying information + * except for the actual bitmap in Lisp, just cache that. + * 16 DLwords, to give a 16x16 bitmap cursor. + */ +struct CachedCursor { + struct CachedCursor *next; + DLword EmCursorBitMap[CURSORHEIGHT]; + SDL_Cursor *cursor; +} *sdl_cursorlist = NULL; + +/* + * given a 16-bit value and a repeat count modify an array + * of bytes to contain the same bit pattern with each bit + * repeated "reps" times consecutively in the output + */ +static void replicate_bits(int bits, int reps, Uint8 *out) { + int dbyte = 0; + int dbit = 7; + for (int ibit = 15; ibit >= 0; --ibit) { + for (int r = 0; r < reps; r++) { + if (bits & (1 << ibit)) + out[dbyte] |= 1 << dbit; + if (--dbit < 0) { + dbyte++; + dbit = 7; + } + } + } +} + +static int cursor_equal_p(const DLword *a, const DLword *b) { + for (int i = 0; i < CURSORHEIGHT; i++) + if (a[i] != b[i]) return FALSE; + return TRUE; +} + +/* + * Try to find cursor CURSOR on the sdl_cursorlist, if it isn't there, add it. + * Return an SDL_Cursor that can be used directly. + */ +static SDL_Cursor *sdl_getOrAllocateCursor(DLword cursor[16], int hot_x, int hot_y) { + hot_x = 0; + hot_y = 0; + /* try to find the cursor by checking the full bitmap */ + struct CachedCursor *pclp = NULL; + struct CachedCursor *clp = sdl_cursorlist; + SDL_Cursor *c; + while (clp != NULL) { + if (cursor_equal_p(clp->EmCursorBitMap, cursor) == TRUE) { + /* if it's in the first two elements of the list, leave the order alone. + * There is a high probability of flipping back and forth between two + */ + if (clp == sdl_cursorlist || pclp == sdl_cursorlist) { + return clp->cursor; + } + /* otherwise unlink the found item and reinsert at the front */ + pclp->next = clp->next; + clp->next = sdl_cursorlist; + sdl_cursorlist = clp; + return clp->cursor; + } + pclp = clp; + clp = clp->next; + } + /* It isn't there, so build a new one */ + clp = (struct CachedCursor *)malloc(sizeof(struct CachedCursor)); + memcpy(clp->EmCursorBitMap, cursor, sizeof(clp->EmCursorBitMap)); + /* no scaling is an easy case, scale > 1 is harder */ + if (sdl_pixelscale == 1) { + Uint8 sdl_cursor_data[32]; + for (int i = 0; i < 32; i++) sdl_cursor_data[i] = GETBYTE(((Uint8 *)cursor) + i); + c = SDL_CreateCursor(sdl_cursor_data, sdl_cursor_data, 16, 16, hot_x, hot_y); + } else { + Uint8 *sdl_cursor_data = calloc(sdl_pixelscale * sdl_pixelscale, 32); + /* fill in the cursor data expanded */ + for (int i = 0; i < 32; i += 2) { + int v = GETBYTE(((Uint8 *)cursor) + i) << 8 | GETBYTE(((Uint8 *)cursor) + i + 1); + int db = i * sdl_pixelscale * sdl_pixelscale; + /* spread the bits out for the first copy of the row */ + replicate_bits(v, sdl_pixelscale, &sdl_cursor_data[db]); + /* and then copy the replicated bits for the copies of the row */ + for (int j = 1; j < sdl_pixelscale; j++) { + memcpy(&sdl_cursor_data[db + (j * 2 * sdl_pixelscale)], &sdl_cursor_data[db], 2 * sdl_pixelscale); + } + } + c = SDL_CreateCursor(sdl_cursor_data, sdl_cursor_data, 16 * sdl_pixelscale, 16 * sdl_pixelscale, hot_x, hot_y); + } + if (c == NULL) printf("ERROR creating cursor: %s\n", SDL_GetError()); + clp->cursor = c; + clp->next = sdl_cursorlist; + sdl_cursorlist = clp; + return clp->cursor; +} + +/* + * Read a cursor bitmap from lisp. Try to find a cached cursor, then use that. + * Use HOT_X and HOT_Y as the cursor hotspot. + * XXX: needs to deal with sdl_pixelscale > 1, and where is the hotspot? + */ +void sdl_setCursor(int hot_x, int hot_y) { + SDL_Cursor *c = sdl_getOrAllocateCursor(EmCursorBitMap68K, hot_x, hot_y); + SDL_SetCursor(c); +} +#if defined(SDLRENDERING) +void sdl_bitblt_to_texture(int _x, int _y, int _w, int _h) { + DLword *src = DisplayRegion68k; + void *dst; + int dstpitchbytes; + int dstpitchpixels; + const int bitsperword = 8 * sizeof(DLword); + int sourcepitchwords = sdl_displaywidth / bitsperword; + int xstart = _x / bitsperword; + int xlimit = (_x + _w + bitsperword - 1) / bitsperword; + int ystart = _y * sourcepitchwords; + int ylimit = (_y + _h) * sourcepitchwords; + SDL_Rect dstrect; + // Avoid dealing with partial words in the update by stretching the source rectangle + // left and right to cover complete units and lock the corresponding + // region in the texture + dstrect.x = xstart * bitsperword; + dstrect.w = (xlimit * bitsperword) - dstrect.x; + dstrect.y = _y; + dstrect.h = _h; + SDL_LockTexture(sdl_texture, &dstrect, &dst, &dstpitchbytes); + dstpitchpixels = dstpitchbytes / sdl_bytesperpixel; + int dy = 0; + // for each line in the source image + for (int sy = ystart; sy < ylimit; sy += sourcepitchwords, dy += dstpitchpixels) { + // for each word in the line + int dx = 0; + for (int sx = xstart; sx < xlimit; sx++, dx += bitsperword) { + int srcw = GETBASEWORD(src, sy + sx); + // for each bit in the word + for (int b = 0; b < bitsperword; b++) { + ((Uint32 *)dst)[dy + dx + b] = (srcw & bitmask[b]) ? sdl_foreground : sdl_background; + } + } + } + SDL_UnlockTexture(sdl_texture); +} +void sdl_bitblt_to_texture_exact(int _x, int _y, int _w, int _h) { + DLword *src = DisplayRegion68k; + void *dst; + int dstpitchbytes; + int dstpitchpixels; + const int bitsperword = 8 * sizeof(DLword); + int sourcepitchwords = sdl_displaywidth / bitsperword; + int xstart = _x / bitsperword; // "word" index of first accessed word in line + int xstartb = _x % bitsperword; // bit within word + int xlimit = (_x + _w + bitsperword - 1) / bitsperword; // word index + int ystart = _y * sourcepitchwords; + int ylimit = (_y + _h) * sourcepitchwords; + SDL_Rect dstrect = {.x = _x, .y = _y, .w = _w, .h = _h}; + SDL_LockTexture(sdl_texture, &dstrect, &dst, &dstpitchbytes); + dstpitchpixels = dstpitchbytes / sdl_bytesperpixel; + int dy = 0; + // for each line in the source image + for (int sy = ystart; sy < ylimit; sy += sourcepitchwords, dy += dstpitchpixels) { + int sx = xstart; + int b = xstartb; + int srcw = GETBASEWORD(src, sy + sx); + // for each pixel within the dstination region line + for (int dx = 0; dx < _w; dx++) { + ((Uint32 *)dst)[dy + dx] = (srcw & bitmask[b]) ? sdl_foreground : sdl_background; + if (++b == bitsperword) { + b = 0; + sx++; + srcw = GETBASEWORD(src, sy + sx); + } + } + } + SDL_UnlockTexture(sdl_texture); +} +#else +void sdl_bitblt_to_buffer(int _x, int _y, int _w, int _h) { + Uint32 *src = (Uint32 *)DisplayRegion68k; + int width = sdl_displaywidth; + int height = sdl_displayheight; + int bpw = 8 * sizeof(Uint32); + int pitch = sdl_displaywidth / bpw; + int xlimit = (_x + _w + bpw - 1) / bpw; + int ylimit = _y + _h; + for (int y = _y; y < ylimit; y++) { + int they = y * sdl_displaywidth; + for (int x = _x / bpw; x < xlimit; x++) { + int srcw = src[y * pitch + x]; + int thex = x * bpw; + for (int b = 0; b < bpw; b++) { + uint32_t px = 0; + if (srcw & (1 << (bpw - 1 - b))) { + px = sdl_foreground; + } else { + px = sdl_background; + } + int pxindex = they + thex + b; + assert(pxindex >= 0 && pxindex < buffer_size); + ((Uint32 *)buffer)[pxindex] = px; + } + } + } +} +void sdl_bitblt_to_window_surface(int _x, int _y, int _w, int _h) { + DLword *src = DisplayRegion68k; + Uint32 *dst = (Uint32 *)sdl_windowsurface->pixels; + int dstpitchbytes = sdl_windowsurface->pitch; + int dstpitchpixels = dstpitchbytes / sdl_bytesperpixel; + const int bitsperword = 8 * sizeof(DLword); + int sourcepitchwords = sdl_displaywidth / bitsperword; + int xstart = _x / bitsperword; + int xlimit = (_x + _w + bitsperword - 1) / bitsperword; + int ystart = _y * sourcepitchwords; + int ylimit = (_y + _h) * sourcepitchwords; + int dy = _y * dstpitchpixels; + // for each line in the source image + for (int sy = ystart; sy < ylimit; sy += sourcepitchwords, dy += dstpitchpixels) { + // for each word in the line + int dx = (_x / bitsperword) * bitsperword; + for (int sx = xstart; sx < xlimit; sx++, dx += bitsperword) { + int srcw = GETBASEWORD(src, sy + sx); + // for each bit in the word + for (int b = 0; b < bitsperword; b++) { + ((Uint32 *)dst)[dy + dx + b] = (srcw & bitmask[b]) ? sdl_foreground : sdl_background; + } + } + } +} +#endif +static int map_key(SDL_Keycode k) { + for (int i = 0; keymap[i] != -1; i += 2) { + if (keymap[i + 1] == k) return keymap[i]; + } + return -1; +} +#define KEYCODE_OFFSET 0 +static void handle_keydown(SDL_Keycode k, unsigned short mod) { + int lk = map_key(k); + if (lk == -1) { + printf("No mapping for key %s\n", SDL_GetKeyName(k)); + } else { + // printf("dn %s -> lisp keycode %d (0x%x)\n", SDL_GetKeyName(k), lk, mod); + kb_trans(lk - KEYCODE_OFFSET, FALSE); + DoRing(); + if ((KBDEventFlg += 1) > 0) Irq_Stk_End = Irq_Stk_Check = 0; + } +} +static void handle_keyup(SDL_Keycode k, unsigned short mod) { + int lk = map_key(k); + if (lk == -1) { + printf("No mapping for key %s\n", SDL_GetKeyName(k)); + } else { + // printf("up %s -> lisp keycode %d (0x%x)\n", SDL_GetKeyName(k), lk, mod); + kb_trans(lk - KEYCODE_OFFSET, TRUE); + DoRing(); + if ((KBDEventFlg += 1) > 0) Irq_Stk_End = Irq_Stk_Check = 0; + } +} +extern DLword *EmCursorX68K, *EmCursorY68K; +extern DLword *EmMouseX68K, *EmMouseY68K; +extern LispPTR *CLastUserActionCell68k; + +/* bits within the EmRealUtilin word */ +#define KEYSET_LEFT 8 +#define KEYSET_LEFTMIDDLE 9 +#define KEYSET_MIDDLE 10 +#define KEYSET_RIGHTMIDDLE 11 +#define KEYSET_RIGHT 12 +/* Mouse buttons */ +#define MOUSE_LEFT 13 +#define MOUSE_RIGHT 14 +#define MOUSE_MIDDLE 15 +static void sdl_update_viewport(int width, int height) { + /* XXX: needs work */ + int w = width / 32 * 32; + if (w > sdl_displaywidth * sdl_pixelscale) w = sdl_displaywidth * sdl_pixelscale; + int h = height / 32 * 32; + if (h > sdl_displayheight * sdl_pixelscale) h = sdl_displayheight * sdl_pixelscale; + SDL_Rect r; + r.x = 0; + r.y = 0; + r.w = w; + r.h = h; +#if defined(SDLRENDERING) + SDL_RenderSetViewport(sdl_renderer, &r); +#endif + printf("new viewport: %d / %d\n", w, h); +} +static int last_keystate[512] = {0}; +void sdl_set_invert(int flag) { + if (flag) { + sdl_foreground = sdl_white; + sdl_background = sdl_black; + } else { + sdl_foreground = sdl_black; + sdl_background = sdl_white; + } + sdl_notify_damage(0, 0, sdl_displaywidth, sdl_displayheight); +} +void sdl_setMousePosition(int x, int y) { + SDL_WarpMouseInWindow(sdl_window, x * sdl_pixelscale, y * sdl_pixelscale); +} +#if defined(SDLRENDERING) +void sdl_update_display() { + sdl_bitblt_to_texture(min_x, min_y, max_x - min_x, max_y - min_y); + SDL_RenderCopy(sdl_renderer, sdl_texture, NULL, NULL); + SDL_RenderPresent(sdl_renderer); +} +#else +void sdl_update_display() { + SDL_Rect r, s; + + r.x = min_x; + r.y = min_y; + r.w = max_x - min_x; + r.h = max_y - min_y; + if (sdl_pixelscale == 1) { + sdl_bitblt_to_window_surface(r.x, r.y, r.w, r.h); + SDL_UpdateWindowSurfaceRects(sdl_window, &r, 1); + } else { + s.x = r.x * sdl_pixelscale; + s.y = r.y * sdl_pixelscale; + s.w = r.w * sdl_pixelscale; + s.h = r.h * sdl_pixelscale; + sdl_bitblt_to_buffer(r.x, r.y, r.w, r.h); + SDL_LowerBlitScaled(sdl_buffersurface, &r, sdl_windowsurface, &s); + SDL_UpdateWindowSurfaceRects(sdl_window, &s, 1); + } +} +#endif +int process_events_time = 0; +void process_SDLevents() { + SDL_Event event; + while (SDL_PollEvent(&event)) { + switch (event.type) { + case SDL_QUIT: + printf("quitting\n"); + exit(0); + break; + case SDL_WINDOWEVENT: + switch (event.window.event) { + case SDL_WINDOWEVENT_RESIZED: + /* XXX: what about integer multiple of 32 requirements here? */ + sdl_windowwidth = event.window.data1; + sdl_windowheight = event.window.data2; + sdl_update_viewport(sdl_windowwidth, sdl_windowheight); + break; + } + break; + case SDL_KEYDOWN: +#if 0 + printf("dn ts: %x, type: %x, state: %x, repeat: %x, scancode: %x, sym: %x <%s>, mod: %x\n", + event.key.timestamp, event.key.type, event.key.state, event.key.repeat, + event.key.keysym.scancode, event.key.keysym.sym, + SDL_GetKeyName(event.key.keysym.sym), event.key.keysym.mod); +#endif + if (event.key.repeat) { + /* Lisp needs to see the UP transition before the DOWN transition */ + handle_keyup(event.key.keysym.sym, event.key.keysym.mod); + } + handle_keydown(event.key.keysym.sym, event.key.keysym.mod); + break; + case SDL_KEYUP: +#if 0 + printf("up ts: %x, type: %x, state: %x, repeat: %x, scancode: %x, sym: %x <%s>, mod: %x\n", + event.key.timestamp, event.key.type, event.key.state, event.key.repeat, + event.key.keysym.scancode, event.key.keysym.sym, + SDL_GetKeyName(event.key.keysym.sym), event.key.keysym.mod); +#endif + handle_keyup(event.key.keysym.sym, event.key.keysym.mod); + break; + case SDL_MOUSEMOTION: { + int x, y; + SDL_GetMouseState(&x, &y); + x /= sdl_pixelscale; + y /= sdl_pixelscale; + *CLastUserActionCell68k = MiscStats->secondstmp; + *EmCursorX68K = (*((DLword *)EmMouseX68K)) = (short)(x & 0xFFFF); + *EmCursorY68K = (*((DLword *)EmMouseY68K)) = (short)(y & 0xFFFF); + DoRing(); + if ((KBDEventFlg += 1) > 0) Irq_Stk_End = Irq_Stk_Check = 0; + break; + } + case SDL_MOUSEBUTTONDOWN: { + switch (event.button.button) { + case SDL_BUTTON_LEFT: PUTBASEBIT68K(EmRealUtilin68K, MOUSE_LEFT, FALSE); break; + case SDL_BUTTON_MIDDLE: PUTBASEBIT68K(EmRealUtilin68K, MOUSE_MIDDLE, FALSE); break; + case SDL_BUTTON_RIGHT: PUTBASEBIT68K(EmRealUtilin68K, MOUSE_RIGHT, FALSE); break; + } + DoRing(); + if ((KBDEventFlg += 1) > 0) Irq_Stk_End = Irq_Stk_Check = 0; + break; + } + case SDL_MOUSEBUTTONUP: { + switch (event.button.button) { + case SDL_BUTTON_LEFT: PUTBASEBIT68K(EmRealUtilin68K, MOUSE_LEFT, TRUE); break; + case SDL_BUTTON_MIDDLE: PUTBASEBIT68K(EmRealUtilin68K, MOUSE_MIDDLE, TRUE); break; + case SDL_BUTTON_RIGHT: PUTBASEBIT68K(EmRealUtilin68K, MOUSE_RIGHT, TRUE); break; + } + DoRing(); + if ((KBDEventFlg += 1) > 0) Irq_Stk_End = Irq_Stk_Check = 0; + break; + } + case SDL_MOUSEWHEEL: + /* + printf("mousewheel mouse %d x %d y %d direction %s\n", event.wheel.which, event.wheel.x, + event.wheel.y, + event.wheel.direction == SDL_MOUSEWHEEL_NORMAL ? "normal" : "flipped"); + + these are the 4 key bits for mouse wheel/trackpad scrolling - which unlike X11 are + *not* presented as mouse button down/up events for each scroll action + + case 4: PUTBASEBIT68K(EmRealUtilin68K, KEYSET_LEFT, FALSE); break; + case 5: PUTBASEBIT68K(EmRealUtilin68K, KEYSET_LEFTMIDDLE, FALSE); break; + case 6: PUTBASEBIT68K(EmRealUtilin68K, KEYSET_RIGHT, FALSE); break; + case 7: PUTBASEBIT68K(EmRealUtilin68K, KEYSET_RIGHTMIDDLE, FALSE); break; + + */ + break; + /* case SDL_KEYMAPCHANGED: */ + /* printf("SDL_KEYMAPCHANGED\n"); break; */ + /* case SDL_TEXTINPUT: */ + /* printf("SDL_TEXTINPUT\n"); break; */ + default: /* printf("other event type: %d\n", event.type); */ break; + } + } + if (display_update_needed) { + sdl_update_display(); + display_update_needed = 0; + min_x = min_y = INT_MAX; + max_x = max_y = 0; + } +} + +int init_SDL(char *windowtitle, int w, int h, int s) { + sdl_pixelscale = s; + // width must be multiple of 32 + w = (w + 31) / 32 * 32; + sdl_displaywidth = w; + sdl_displayheight = h; + sdl_windowwidth = w * s; + sdl_windowheight = h * s; + int width = sdl_displaywidth; + int height = sdl_displayheight; + printf("requested width: %d, height: %d\n", width, height); + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + printf("SDL could not be initialized. SDL_Error: %s\n", SDL_GetError()); + return 1; + } + printf("initialised\n"); + sdl_window = SDL_CreateWindow(windowtitle, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, + sdl_windowwidth, sdl_windowheight, 0); + printf("Window created\n"); + if (sdl_window == NULL) { + printf("Window could not be created. SDL_Error: %s\n", SDL_GetError()); + return 2; + } +#if defined(SDLRENDERING) + printf("Creating renderer...\n"); + sdl_renderer = SDL_CreateRenderer(sdl_window, -1, SDL_RENDERER_ACCELERATED); + if (NULL == sdl_renderer) { + printf("SDL Error: %s\n", SDL_GetError()); + return 3; + } + SDL_GetRendererInfo(sdl_renderer, &sdl_rendererinfo); + SDL_SetRenderDrawColor(sdl_renderer, 127, 127, 127, 255); + SDL_RenderClear(sdl_renderer); + SDL_RenderPresent(sdl_renderer); + SDL_RenderSetScale(sdl_renderer, 1.0, 1.0); + printf("Creating texture...\n"); + sdl_pixelformat = SDL_AllocFormat(sdl_rendererinfo.texture_formats[0]); + sdl_texture = SDL_CreateTexture(sdl_renderer, sdl_pixelformat->format, + SDL_TEXTUREACCESS_STREAMING, width, height); + sdl_black = SDL_MapRGB(sdl_pixelformat, 0, 0, 0); + sdl_white = SDL_MapRGB(sdl_pixelformat, 255, 255, 255); + sdl_foreground = sdl_black; + sdl_background = sdl_white; + sdl_bytesperpixel = sdl_pixelformat->BytesPerPixel; +#else + printf("Creating window surface and buffer surface\n"); + sdl_windowsurface = SDL_GetWindowSurface(sdl_window); + sdl_pixelformat = sdl_windowsurface->format; + sdl_black = SDL_MapRGB(sdl_pixelformat, 0, 0, 0); + sdl_white = SDL_MapRGB(sdl_pixelformat, 255, 255, 255); + sdl_foreground = sdl_black; + sdl_background = sdl_white; + sdl_bytesperpixel = sdl_pixelformat->BytesPerPixel; + buffer_size = width * height * sdl_bytesperpixel; + buffer = malloc(buffer_size); + sdl_buffersurface = SDL_CreateRGBSurfaceWithFormatFrom( + buffer, sdl_displaywidth, sdl_displayheight, sdl_bytesperpixel * 8, + sdl_displaywidth * sdl_bytesperpixel, sdl_pixelformat->format); +#endif + printf("SDL initialised\n"); + return 0; +} diff --git a/src/uutils.c b/src/uutils.c index 5a6607b..e3a58b2 100644 --- a/src/uutils.c +++ b/src/uutils.c @@ -219,6 +219,8 @@ LispPTR unix_getparm(LispPTR *args) { } else if (strcmp(envname, "DISPLAY") == 0) { #if defined(XWINDOW) envvalue = "X"; +#elif defined(SDL) + envvalue = "SDL"; #elif defined(DISPLAYBUFFER) envvalue = "BUFFERED"; #else diff --git a/src/xc.c b/src/xc.c index 1e9c800..5140042 100644 --- a/src/xc.c +++ b/src/xc.c @@ -95,7 +95,9 @@ #include "ubf3defs.h" #include "unwinddefs.h" #include "vars3defs.h" +#ifdef XWINDOW #include "xwinmandefs.h" +#endif #include "z2defs.h" #ifdef DOS @@ -103,10 +105,14 @@ extern KbdInterface currentkbd; extern DspInterface currentdsp; extern MouseInterface currentmouse; -#else +#elif defined(XWINDOW) extern DspInterface currentdsp; #endif /* DOS */ +#ifdef SDL +extern void process_SDLevents(); +#endif + typedef struct conspage ConsPage; typedef ByteCode *InstPtr; @@ -1131,10 +1137,12 @@ check_interrupt: * If the system is configured with SIGIO handling we have a hint * that allows us to cheaply skip if there's nothing to do */ -#ifndef INIT +#ifdef XWINDOW process_Xevents(currentdsp); #endif - +#ifdef SDL + process_SDLevents(); +#endif if (IO_Signalled) { IO_Signalled = FALSE; process_io_events();