SCP/VIDEO: Added support for libSDL2 video capabilities. Changed existing video layer to carry pixels as 32bpp vs 8bpp for more natural behaviors in libSDL2.
This commit is contained in:
parent
351d748b4a
commit
6b45d9b2ad
15 changed files with 926 additions and 93 deletions
10
VAX/vax_vc.c
10
VAX/vax_vc.c
|
@ -711,7 +711,7 @@ return 0; /* no intr req */
|
|||
t_stat vc_svc (UNIT *uptr)
|
||||
{
|
||||
t_bool updated = FALSE; /* flag for refresh */
|
||||
uint8 line[1024];
|
||||
uint32 line[1024];
|
||||
uint32 ln, col, off;
|
||||
uint8 *cur;
|
||||
|
||||
|
@ -741,7 +741,8 @@ for (ln = 0; ln < VC_YSIZE; ln++) {
|
|||
if ((vc_map[ln] & VCMAP_VLD) == 0) { /* line invalid? */
|
||||
off = vc_map[ln] * 32; /* get video buf offet */
|
||||
for (col = 0; col < 1024; col++)
|
||||
line[col] = (vc_buf[off + (col >> 5)] >> col) & 1; /* 1bpp to 8bpp */
|
||||
line[col] = vid_mono_palette[(vc_buf[off + (col >> 5)] >> (col & 0x1F)) & 1];
|
||||
/* 1bpp to 32bpp */
|
||||
if (CUR_V) { /* cursor visible? */
|
||||
if ((ln >= CUR_Y) && (ln < (CUR_Y + 16))) { /* cursor on this line? */
|
||||
cur = &vc_cur[((ln - CUR_Y) << 4)]; /* get image base */
|
||||
|
@ -749,10 +750,9 @@ for (ln = 0; ln < VC_YSIZE; ln++) {
|
|||
if ((CUR_X + col) >= 1024) /* Part of cursor off screen? */
|
||||
continue; /* Skip */
|
||||
if (CUR_F) /* mask function */
|
||||
line[CUR_X + col] = line[CUR_X + col] | cur[col];
|
||||
line[CUR_X + col] = vid_mono_palette[(line[CUR_X + col] == vid_mono_palette[1]) | (cur[col] & 1)];
|
||||
else
|
||||
line[CUR_X + col] = line[CUR_X + col] & ~cur[col];
|
||||
line [CUR_X + col] = line[CUR_X + col] & 1;
|
||||
line[CUR_X + col] = vid_mono_palette[(line[CUR_X + col] == vid_mono_palette[1]) & (~cur[col] & 1)];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@ For Example, the directory structure should look like:
|
|||
.../simh/simhv38-2-rc1/BIN/Nt/Win32-Release/vax.exe
|
||||
.../simh/windows-build/pthreads/pthread.h
|
||||
.../simh/windows-build/winpcap/WpdPack/Include/pcap.h
|
||||
.../simh/windows-build/libSDL/SDL-1.2.15/include/SDL.h
|
||||
.../simh/windows-build/libSDL/SDL2-2.0.0/include/SDL.h
|
||||
|
||||
The contents of the windows-build directory can be downloaded from:
|
||||
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL-1.2.15/include""
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.0/include""
|
||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_610;USE_SHARED;USE_SIM_VIDEO;HAVE_LIBSDL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID"
|
||||
KeepComments="false"
|
||||
MinimalRebuild="true"
|
||||
|
@ -69,10 +69,10 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib SDL-StaticD.lib dxguid.lib"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib SDL-StaticD.lib dxguid.lib Imm32.lib Version.lib"
|
||||
OutputFile="$(OutDir)\MicroVAX1.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/";"../../windows-build/libSDL/SDL-1.2.15/lib/";"../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)\Lib\x86""
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/";"../../windows-build/libSDL/SDL2-2.0.0/lib/";"../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)\Lib\x86""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\MicroVAX1.pdb"
|
||||
SubSystem="1"
|
||||
|
@ -135,7 +135,7 @@
|
|||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL-1.2.15/include""
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.0/include""
|
||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_610;USE_SHARED;USE_SIM_VIDEO;HAVE_LIBSDL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID"
|
||||
KeepComments="false"
|
||||
StringPooling="true"
|
||||
|
@ -160,10 +160,10 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib SDL-Static.lib dxguid.lib"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib SDL2-Static.lib dxguid.lib Imm32.lib Version.lib"
|
||||
OutputFile="$(OutDir)\MicroVAX1.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/";"../../windows-build/libSDL/SDL-1.2.15/lib/";"../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)\Lib\x86""
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/";"../../windows-build/libSDL/SDL2-2.0.0/lib/";"../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)\Lib\x86""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
|
|
|
@ -44,7 +44,7 @@
|
|||
<Tool
|
||||
Name="VCCLCompilerTool"
|
||||
Optimization="0"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL-1.2.15/include""
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.0/include""
|
||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_630;USE_SHARED;USE_SIM_VIDEO;HAVE_LIBSDL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID"
|
||||
KeepComments="false"
|
||||
MinimalRebuild="true"
|
||||
|
@ -69,10 +69,10 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib SDL-StaticD.lib dxguid.lib"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib SDL2-StaticD.lib dxguid.lib Imm32.lib Version.lib"
|
||||
OutputFile="$(OutDir)\MicroVAX2.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/";"../../windows-build/libSDL/SDL-1.2.15/lib/";"../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)\Lib\x86""
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/";"../../windows-build/libSDL/SDL2-2.0.0/lib/";"../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)\Lib\x86""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\MicroVAX2.pdb"
|
||||
SubSystem="1"
|
||||
|
@ -135,7 +135,7 @@
|
|||
FavorSizeOrSpeed="1"
|
||||
OmitFramePointers="true"
|
||||
WholeProgramOptimization="true"
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL-1.2.15/include""
|
||||
AdditionalIncludeDirectories="./;../;../VAX/;../pdp11/;"../../windows-build/winpcap/Wpdpack/Include";"../../windows-build/pthreads";"../../windows-build/libSDL/SDL2-2.0.0/include""
|
||||
PreprocessorDefinitions="USE_INT64;USE_ADDR64;VM_VAX;VAX_630;USE_SHARED;USE_SIM_VIDEO;HAVE_LIBSDL;_CRT_NONSTDC_NO_WARNINGS;_CRT_SECURE_NO_WARNINGS;PTW32_STATIC_LIB;USE_READER_THREAD;SIM_ASYNCH_IO;SIM_NEED_GIT_COMMIT_ID"
|
||||
KeepComments="false"
|
||||
StringPooling="true"
|
||||
|
@ -160,10 +160,10 @@
|
|||
<Tool
|
||||
Name="VCLinkerTool"
|
||||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib SDL-Static.lib dxguid.lib"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib SDL2-Static.lib dxguid.lib Imm32.lib Version.lib"
|
||||
OutputFile="$(OutDir)\MicroVAX2.exe"
|
||||
LinkIncremental="1"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/";"../../windows-build/libSDL/SDL-1.2.15/lib/";"../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)\Lib\x86""
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/";"../../windows-build/libSDL/SDL2-2.0.0/lib/";"../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)\Lib\x86""
|
||||
GenerateDebugInformation="true"
|
||||
SubSystem="1"
|
||||
OptimizeReferences="2"
|
||||
|
|
|
@ -63,7 +63,7 @@ if exist ../../windows-build-windows-build move ../../windows-build-windows-buil
|
|||
if not exist ../../windows-build/winpcap/Wpdpack/Include/pcap.h goto _notice1
|
||||
if not exist ../../windows-build/pthreads/pthread.h goto _notice1
|
||||
if "%_X_LIBSDL%" == "" goto _done_build
|
||||
if not exist ../../windows-build/libSDL/SDL-1.2.15/include/SDL.h goto _notice2
|
||||
if not exist ../../windows-build/libSDL/SDL2-2.0.0/include/SDL.h goto _notice2
|
||||
if not exist "../../windows-build/libSDL/Microsoft DirectX SDK (June 2010)/Lib/x86/dxguid.lib" goto _notice2
|
||||
goto _done_build
|
||||
:_notice1
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib"
|
||||
OutputFile="$(OutDir)\VAX.exe"
|
||||
LinkIncremental="1"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\VAX.pdb"
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib"
|
||||
OutputFile="$(OutDir)\VAX730.exe"
|
||||
LinkIncremental="1"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;"../../pthreads/Pre-built.2/lib/""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\VAX730.pdb"
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib"
|
||||
OutputFile="$(OutDir)\VAX750.exe"
|
||||
LinkIncremental="1"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories="../../winpcap/Wpdpack/Lib/;"../../pthreads/Pre-built.2/lib/""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\VAX750.pdb"
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib"
|
||||
OutputFile="$(OutDir)\VAX780.exe"
|
||||
LinkIncremental="1"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\VAX780.pdb"
|
||||
|
|
|
@ -70,7 +70,7 @@
|
|||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib"
|
||||
OutputFile="$(OutDir)\VAX8600.exe"
|
||||
LinkIncremental="1"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\VAX8600.pdb"
|
||||
|
|
|
@ -71,7 +71,7 @@
|
|||
AdditionalOptions="/fixed:no"
|
||||
AdditionalDependencies="wsock32.lib winmm.lib"
|
||||
OutputFile="$(OutDir)\rtVAX1000.exe"
|
||||
LinkIncremental="1"
|
||||
LinkIncremental="2"
|
||||
AdditionalLibraryDirectories=""../../windows-build/winpcap/Wpdpack/Lib/""
|
||||
GenerateDebugInformation="true"
|
||||
ProgramDatabaseFile="$(OutDir)\rtVAX1000.pdb"
|
||||
|
|
26
makefile
26
makefile
|
@ -314,12 +314,24 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
|
|||
endif
|
||||
endif
|
||||
ifneq (,$(call find_include,SDL/SDL))
|
||||
ifneq (,$(call find_lib,SDL))
|
||||
OS_CCDEFS += -DHAVE_LIBSDL -I$(dir $(call find_include,SDL/SDL))
|
||||
OS_LDFLAGS += -lSDL
|
||||
$(info using libSDL: $(call find_lib,SDL) $(call find_include,SDL/SDL))
|
||||
ifeq (Darwin,$(OSTYPE))
|
||||
OS_LDFLAGS += -lSDLmain -lobjc -framework cocoa
|
||||
SDL_VERSION = $(shell grep SDL_MAJOR_VERSION $(call find_include,SDL/SDL_version) | awk '{ print $$3 }')
|
||||
ifeq (2,$(SDL_VERSION))
|
||||
ifneq (,$(call find_lib,SDL2))
|
||||
OS_CCDEFS += -DHAVE_LIBSDL -I$(dir $(call find_include,SDL/SDL))
|
||||
OS_LDFLAGS += -lSDL2
|
||||
$(info using libSDL2: $(call find_lib,SDL2) $(call find_include,SDL/SDL))
|
||||
ifeq (Darwin,$(OSTYPE))
|
||||
OS_LDFLAGS += -lobjc -framework cocoa
|
||||
endif
|
||||
endif
|
||||
else
|
||||
ifneq (,$(call find_lib,SDL))
|
||||
OS_CCDEFS += -DHAVE_LIBSDL -I$(dir $(call find_include,SDL/SDL))
|
||||
OS_LDFLAGS += -lSDL
|
||||
$(info using libSDL: $(call find_lib,SDL) $(call find_include,SDL/SDL))
|
||||
ifeq (Darwin,$(OSTYPE))
|
||||
OS_LDFLAGS += -lobjc -framework cocoa
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
endif
|
||||
|
@ -328,7 +340,7 @@ ifeq ($(WIN32),) #*nix Environments (&& cygwin)
|
|||
$(info *** Warning ***)
|
||||
$(info *** Warning *** The simulator$(BUILD_MULTIPLE) you are building could provide more)
|
||||
$(info *** Warning *** functionality if video support were available on your system.)
|
||||
$(info *** Warning *** Install the development components of libSDL and rebuild)
|
||||
$(info *** Warning *** Install the development components of libSDL2 and rebuild)
|
||||
$(info *** Warning *** your simulator to enable this extra functionality.)
|
||||
$(info *** Warning ***)
|
||||
endif
|
||||
|
|
3
scp.c
3
scp.c
|
@ -233,9 +233,6 @@
|
|||
#endif
|
||||
#include <sys/stat.h>
|
||||
|
||||
#if defined(HAVE_LIBSDL) && defined(USE_SIM_VIDEO) /* SDL (Simple DirectMedial Layer) */
|
||||
#include <SDL.h>
|
||||
#endif
|
||||
#if defined(HAVE_DLOPEN) /* Dynamic Readline support */
|
||||
#include <dlfcn.h>
|
||||
#endif
|
||||
|
|
869
sim_video.c
869
sim_video.c
|
@ -61,6 +61,19 @@ typedef struct {
|
|||
|
||||
int vid_thread (void* arg);
|
||||
|
||||
/*
|
||||
Currently there are two separate video implementations which exist
|
||||
due to the fact that libSDL and libSDL2 provide vastly different APIs.
|
||||
|
||||
libSDL2 is the distinctly better choice going forward, and, given the
|
||||
background thread event digestion, is the only one which will work on
|
||||
OSX.
|
||||
|
||||
We will abandon libSDL (Version 1) completely when the libSDL2 developer
|
||||
components are readily packaged for most Linux distributions.
|
||||
*/
|
||||
|
||||
#if SDL_MAJOR_VERSION == 1
|
||||
t_bool vid_key_state[SDLK_LAST];
|
||||
t_bool vid_mouse_captured;
|
||||
int32 vid_width;
|
||||
|
@ -68,7 +81,7 @@ int32 vid_height;
|
|||
SDL_Surface *vid_image; /* video buffer */
|
||||
SDL_Surface *vid_window; /* window handle */
|
||||
SDL_Thread *vid_thread_handle; /* event thread handle */
|
||||
SDL_Color vid_palette[256];
|
||||
uint32 vid_mono_palette[2];
|
||||
KEY_EVENT_QUEUE vid_key_events; /* keyboard events */
|
||||
MOUSE_EVENT_QUEUE vid_mouse_events; /* mouse events */
|
||||
DEVICE *vid_dev;
|
||||
|
@ -166,20 +179,15 @@ if (SDL_SemTryWait (vid_mouse_events.sem) == 0) {
|
|||
return SCPE_EOF;
|
||||
}
|
||||
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint8 *buf)
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf)
|
||||
{
|
||||
int32 i, j;
|
||||
uint8* pix;
|
||||
int32 i;
|
||||
uint32* pixels;
|
||||
|
||||
pix = (uint8 *)vid_image->pixels;
|
||||
pix = pix + (y * vid_width) + x;
|
||||
pixels = (uint32 *)vid_image->pixels;
|
||||
|
||||
for (i = y; i < (y + h); i++) {
|
||||
for (j = x; j < (x + w); j++) {
|
||||
*pix++ = *buf++;
|
||||
}
|
||||
pix = pix + vid_width;
|
||||
}
|
||||
for (i = y; i < (y + h); i++)
|
||||
memcpy (pixels + (i * vid_width) + x, buf, (size_t)w*sizeof(*pixels));
|
||||
}
|
||||
|
||||
void vid_refresh (void)
|
||||
|
@ -728,15 +736,14 @@ vid_window = SDL_SetVideoMode (vid_width, vid_height, 8, 0);
|
|||
|
||||
SDL_EnableKeyRepeat (SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_INTERVAL);
|
||||
|
||||
vid_image = SDL_CreateRGBSurface (SDL_SWSURFACE, vid_width, vid_height, 8, 0, 0, 0, 0);
|
||||
if (sim_end)
|
||||
vid_image = SDL_CreateRGBSurface (SDL_SWSURFACE, vid_width, vid_height, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
|
||||
else
|
||||
vid_image = SDL_CreateRGBSurface (SDL_SWSURFACE, vid_width, vid_height, 32, 0xff000000, 0x00ff0000, 0x0000ff00, 0x000000ff);
|
||||
|
||||
vid_mono_palette[0] = sim_end ? 0xFF000000 : 0x000000FF;
|
||||
vid_mono_palette[1] = 0xFFFFFFFF;
|
||||
|
||||
vid_palette[0].r = 0;
|
||||
vid_palette[0].g = 0;
|
||||
vid_palette[0].b = 0;
|
||||
vid_palette[1].r = 255;
|
||||
vid_palette[1].g = 255;
|
||||
vid_palette[1].b = 255;
|
||||
SDL_SetColors (vid_image, vid_palette, 0, 2);
|
||||
|
||||
SDL_WM_SetCaption (&sim_name[0], &sim_name[0]);
|
||||
|
||||
|
@ -777,13 +784,827 @@ SDL_Quit ();
|
|||
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE, vid_dev, "vid_thread() - Exiting\n");
|
||||
return 0;
|
||||
}
|
||||
#else /* libSDL2 implementation */
|
||||
t_bool vid_key_state[SDL_NUM_SCANCODES];
|
||||
t_bool vid_mouse_captured;
|
||||
int32 vid_width;
|
||||
int32 vid_height;
|
||||
SDL_Texture *vid_texture; /* video buffer in GPU */
|
||||
SDL_Window *vid_window; /* window handle */
|
||||
SDL_Renderer *vid_renderer;
|
||||
SDL_Thread *vid_thread_handle; /* event thread handle */
|
||||
uint32 vid_mono_palette[2]; /* Monochrome Color Map */
|
||||
SDL_Color vid_colors[256];
|
||||
KEY_EVENT_QUEUE vid_key_events; /* keyboard events */
|
||||
MOUSE_EVENT_QUEUE vid_mouse_events; /* mouse events */
|
||||
DEVICE *vid_dev;
|
||||
|
||||
t_stat vid_open (DEVICE *dptr, uint32 width, uint32 height)
|
||||
{
|
||||
if (!vid_active) {
|
||||
int wait_count = 0;
|
||||
|
||||
vid_active = TRUE;
|
||||
vid_width = width;
|
||||
vid_height = height;
|
||||
vid_mouse_captured = FALSE;
|
||||
|
||||
vid_key_events.head = 0;
|
||||
vid_key_events.tail = 0;
|
||||
vid_key_events.count = 0;
|
||||
vid_key_events.sem = SDL_CreateSemaphore (1);
|
||||
vid_mouse_events.head = 0;
|
||||
vid_mouse_events.tail = 0;
|
||||
vid_mouse_events.count = 0;
|
||||
vid_mouse_events.sem = SDL_CreateSemaphore (1);
|
||||
|
||||
vid_dev = dptr;
|
||||
|
||||
vid_thread_handle = SDL_CreateThread (vid_thread, "vid-thread", NULL);
|
||||
if (vid_thread_handle == NULL) {
|
||||
vid_close ();
|
||||
return SCPE_OPENERR;
|
||||
}
|
||||
while ((!vid_texture) && (++wait_count < 20))
|
||||
sim_os_ms_sleep (100);
|
||||
if (!vid_texture) {
|
||||
vid_close ();
|
||||
return SCPE_OPENERR;
|
||||
}
|
||||
|
||||
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE, vid_dev, "vid_open() - Success\n");
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat vid_close (void)
|
||||
{
|
||||
SDL_Event user_event;
|
||||
int status;
|
||||
|
||||
if (vid_active) {
|
||||
vid_active = FALSE;
|
||||
if (vid_thread_handle) {
|
||||
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE, vid_dev, "vid_close()\n");
|
||||
user_event.type = SDL_USEREVENT;
|
||||
user_event.user.code = EVENT_CLOSE;
|
||||
user_event.user.data1 = NULL;
|
||||
user_event.user.data2 = NULL;
|
||||
|
||||
SDL_PushEvent (&user_event);
|
||||
SDL_WaitThread (vid_thread_handle, &status);
|
||||
vid_thread_handle = NULL;
|
||||
vid_dev = NULL;
|
||||
}
|
||||
if (vid_mouse_events.sem) {
|
||||
SDL_DestroySemaphore(vid_mouse_events.sem);
|
||||
vid_mouse_events.sem = NULL;
|
||||
}
|
||||
if (vid_key_events.sem) {
|
||||
SDL_DestroySemaphore(vid_key_events.sem);
|
||||
vid_key_events.sem = NULL;
|
||||
}
|
||||
}
|
||||
return SCPE_OK;
|
||||
}
|
||||
|
||||
t_stat vid_poll_kb (SIM_KEY_EVENT *ev)
|
||||
{
|
||||
if (SDL_SemTryWait (vid_key_events.sem) == 0) { /* get lock */
|
||||
if (vid_key_events.count > 0) { /* events in queue? */
|
||||
*ev = vid_key_events.events[vid_key_events.head++];
|
||||
vid_key_events.count--;
|
||||
if (vid_key_events.head == MAX_EVENTS)
|
||||
vid_key_events.head = 0;
|
||||
SDL_SemPost (vid_key_events.sem);
|
||||
return SCPE_OK;
|
||||
}
|
||||
SDL_SemPost (vid_key_events.sem);
|
||||
}
|
||||
return SCPE_EOF;
|
||||
}
|
||||
|
||||
t_stat vid_poll_mouse (SIM_MOUSE_EVENT *ev)
|
||||
{
|
||||
if (SDL_SemTryWait (vid_mouse_events.sem) == 0) {
|
||||
if (vid_mouse_events.count > 0) {
|
||||
*ev = vid_mouse_events.events[vid_mouse_events.head++];
|
||||
vid_mouse_events.count--;
|
||||
if (vid_mouse_events.head == MAX_EVENTS)
|
||||
vid_mouse_events.head = 0;
|
||||
SDL_SemPost (vid_mouse_events.sem);
|
||||
return SCPE_OK;
|
||||
}
|
||||
SDL_SemPost (vid_mouse_events.sem);
|
||||
}
|
||||
return SCPE_EOF;
|
||||
}
|
||||
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf)
|
||||
{
|
||||
int32 i;
|
||||
uint32 *pixels;
|
||||
int pitch;
|
||||
|
||||
SDL_LockTexture(vid_texture, NULL, (void *)&pixels, &pitch);
|
||||
|
||||
for (i = y; i < (y + h); i++)
|
||||
memcpy (pixels + (i * vid_width) + x, buf, (size_t)w*sizeof(*pixels));
|
||||
SDL_UnlockTexture(vid_texture);
|
||||
}
|
||||
|
||||
void vid_refresh (void)
|
||||
{
|
||||
SDL_Event user_event;
|
||||
|
||||
user_event.type = SDL_USEREVENT;
|
||||
user_event.user.code = EVENT_REDRAW;
|
||||
user_event.user.data1 = NULL;
|
||||
user_event.user.data2 = NULL;
|
||||
|
||||
SDL_PushEvent (&user_event);
|
||||
}
|
||||
|
||||
int vid_map_key (int key)
|
||||
{
|
||||
switch (key) {
|
||||
|
||||
case SDLK_BACKSPACE:
|
||||
return SIM_KEY_BACKSPACE;
|
||||
|
||||
case SDLK_TAB:
|
||||
return SIM_KEY_TAB;
|
||||
|
||||
case SDLK_RETURN:
|
||||
return SIM_KEY_ENTER;
|
||||
|
||||
case SDLK_ESCAPE:
|
||||
return SIM_KEY_ESC;
|
||||
|
||||
case SDLK_SPACE:
|
||||
return SIM_KEY_SPACE;
|
||||
|
||||
case SDLK_QUOTE:
|
||||
return SIM_KEY_SINGLE_QUOTE;
|
||||
|
||||
case SDLK_COMMA:
|
||||
return SIM_KEY_COMMA;
|
||||
|
||||
case SDLK_MINUS:
|
||||
return SIM_KEY_MINUS;
|
||||
|
||||
case SDLK_PERIOD:
|
||||
return SIM_KEY_PERIOD;
|
||||
|
||||
case SDLK_SLASH:
|
||||
return SIM_KEY_SLASH;
|
||||
|
||||
case SDLK_0:
|
||||
return SIM_KEY_0;
|
||||
|
||||
case SDLK_1:
|
||||
return SIM_KEY_1;
|
||||
|
||||
case SDLK_2:
|
||||
return SIM_KEY_2;
|
||||
|
||||
case SDLK_3:
|
||||
return SIM_KEY_3;
|
||||
|
||||
case SDLK_4:
|
||||
return SIM_KEY_4;
|
||||
|
||||
case SDLK_5:
|
||||
return SIM_KEY_5;
|
||||
|
||||
case SDLK_6:
|
||||
return SIM_KEY_6;
|
||||
|
||||
case SDLK_7:
|
||||
return SIM_KEY_7;
|
||||
|
||||
case SDLK_8:
|
||||
return SIM_KEY_8;
|
||||
|
||||
case SDLK_9:
|
||||
return SIM_KEY_9;
|
||||
|
||||
case SDLK_SEMICOLON:
|
||||
return SIM_KEY_SEMICOLON;
|
||||
|
||||
case SDLK_EQUALS:
|
||||
return SIM_KEY_EQUALS;
|
||||
|
||||
case SDLK_LEFTBRACKET:
|
||||
return SIM_KEY_LEFT_BRACKET;
|
||||
|
||||
case SDLK_BACKSLASH:
|
||||
return SIM_KEY_BACKSLASH;
|
||||
|
||||
case SDLK_RIGHTBRACKET:
|
||||
return SIM_KEY_RIGHT_BRACKET;
|
||||
|
||||
case SDLK_BACKQUOTE:
|
||||
return SIM_KEY_BACKQUOTE;
|
||||
|
||||
case SDLK_a:
|
||||
return SIM_KEY_A;
|
||||
|
||||
case SDLK_b:
|
||||
return SIM_KEY_B;
|
||||
|
||||
case SDLK_c:
|
||||
return SIM_KEY_C;
|
||||
|
||||
case SDLK_d:
|
||||
return SIM_KEY_D;
|
||||
|
||||
case SDLK_e:
|
||||
return SIM_KEY_E;
|
||||
|
||||
case SDLK_f:
|
||||
return SIM_KEY_F;
|
||||
|
||||
case SDLK_g:
|
||||
return SIM_KEY_G;
|
||||
|
||||
case SDLK_h:
|
||||
return SIM_KEY_H;
|
||||
|
||||
case SDLK_i:
|
||||
return SIM_KEY_I;
|
||||
|
||||
case SDLK_j:
|
||||
return SIM_KEY_J;
|
||||
|
||||
case SDLK_k:
|
||||
return SIM_KEY_K;
|
||||
|
||||
case SDLK_l:
|
||||
return SIM_KEY_L;
|
||||
|
||||
case SDLK_m:
|
||||
return SIM_KEY_M;
|
||||
|
||||
case SDLK_n:
|
||||
return SIM_KEY_N;
|
||||
|
||||
case SDLK_o:
|
||||
return SIM_KEY_O;
|
||||
|
||||
case SDLK_p:
|
||||
return SIM_KEY_P;
|
||||
|
||||
case SDLK_q:
|
||||
return SIM_KEY_Q;
|
||||
|
||||
case SDLK_r:
|
||||
return SIM_KEY_R;
|
||||
|
||||
case SDLK_s:
|
||||
return SIM_KEY_S;
|
||||
|
||||
case SDLK_t:
|
||||
return SIM_KEY_T;
|
||||
|
||||
case SDLK_u:
|
||||
return SIM_KEY_U;
|
||||
|
||||
case SDLK_v:
|
||||
return SIM_KEY_V;
|
||||
|
||||
case SDLK_w:
|
||||
return SIM_KEY_W;
|
||||
|
||||
case SDLK_x:
|
||||
return SIM_KEY_X;
|
||||
|
||||
case SDLK_y:
|
||||
return SIM_KEY_Y;
|
||||
|
||||
case SDLK_z:
|
||||
return SIM_KEY_Z;
|
||||
|
||||
case SDLK_DELETE:
|
||||
return SIM_KEY_DELETE;
|
||||
|
||||
case SDLK_KP_0:
|
||||
return SIM_KEY_KP_INSERT;
|
||||
|
||||
case SDLK_KP_1:
|
||||
return SIM_KEY_KP_END;
|
||||
|
||||
case SDLK_KP_2:
|
||||
return SIM_KEY_KP_DOWN;
|
||||
|
||||
case SDLK_KP_3:
|
||||
return SIM_KEY_KP_PAGE_DOWN;
|
||||
|
||||
case SDLK_KP_4:
|
||||
return SIM_KEY_KP_LEFT;
|
||||
|
||||
case SDLK_KP_5:
|
||||
return SIM_KEY_KP_5;
|
||||
|
||||
case SDLK_KP_6:
|
||||
return SIM_KEY_KP_RIGHT;
|
||||
|
||||
case SDLK_KP_7:
|
||||
return SIM_KEY_KP_HOME;
|
||||
|
||||
case SDLK_KP_8:
|
||||
return SIM_KEY_KP_UP;
|
||||
|
||||
case SDLK_KP_9:
|
||||
return SIM_KEY_KP_PAGE_UP;
|
||||
|
||||
case SDLK_KP_PERIOD:
|
||||
return SIM_KEY_KP_DELETE;
|
||||
|
||||
case SDLK_KP_DIVIDE:
|
||||
return SIM_KEY_KP_DIVIDE;
|
||||
|
||||
case SDLK_KP_MULTIPLY:
|
||||
return SIM_KEY_KP_MULTIPLY;
|
||||
|
||||
case SDLK_KP_MINUS:
|
||||
return SIM_KEY_KP_SUBTRACT;
|
||||
|
||||
case SDLK_KP_PLUS:
|
||||
return SIM_KEY_KP_ADD;
|
||||
|
||||
case SDLK_KP_ENTER:
|
||||
return SIM_KEY_KP_ENTER;
|
||||
|
||||
case SDLK_UP:
|
||||
return SIM_KEY_UP;
|
||||
|
||||
case SDLK_DOWN:
|
||||
return SIM_KEY_DOWN;
|
||||
|
||||
case SDLK_RIGHT:
|
||||
return SIM_KEY_RIGHT;
|
||||
|
||||
case SDLK_LEFT:
|
||||
return SIM_KEY_LEFT;
|
||||
|
||||
case SDLK_INSERT:
|
||||
return SIM_KEY_INSERT;
|
||||
|
||||
case SDLK_HOME:
|
||||
return SIM_KEY_HOME;
|
||||
|
||||
case SDLK_END:
|
||||
return SIM_KEY_END;
|
||||
|
||||
case SDLK_PAGEUP:
|
||||
return SIM_KEY_PAGE_UP;
|
||||
|
||||
case SDLK_PAGEDOWN:
|
||||
return SIM_KEY_PAGE_DOWN;
|
||||
|
||||
case SDLK_F1:
|
||||
return SIM_KEY_F1;
|
||||
|
||||
case SDLK_F2:
|
||||
return SIM_KEY_F2;
|
||||
|
||||
case SDLK_F3:
|
||||
return SIM_KEY_F3;
|
||||
|
||||
case SDLK_F4:
|
||||
return SIM_KEY_F4;
|
||||
|
||||
case SDLK_F5:
|
||||
return SIM_KEY_F5;
|
||||
|
||||
case SDLK_F6:
|
||||
return SIM_KEY_F6;
|
||||
|
||||
case SDLK_F7:
|
||||
return SIM_KEY_F7;
|
||||
|
||||
case SDLK_F8:
|
||||
return SIM_KEY_F8;
|
||||
|
||||
case SDLK_F9:
|
||||
return SIM_KEY_F9;
|
||||
|
||||
case SDLK_F10:
|
||||
return SIM_KEY_F10;
|
||||
|
||||
case SDLK_F11:
|
||||
return SIM_KEY_F11;
|
||||
|
||||
case SDLK_F12:
|
||||
return SIM_KEY_F12;
|
||||
|
||||
case SDLK_NUMLOCKCLEAR:
|
||||
return SIM_KEY_NUM_LOCK;
|
||||
|
||||
case SDLK_CAPSLOCK:
|
||||
return SIM_KEY_CAPS_LOCK;
|
||||
|
||||
case SDLK_SCROLLLOCK:
|
||||
return SIM_KEY_SCRL_LOCK;
|
||||
|
||||
case SDLK_RSHIFT:
|
||||
return SIM_KEY_SHIFT_R;
|
||||
|
||||
case SDLK_LSHIFT:
|
||||
return SIM_KEY_SHIFT_L;
|
||||
|
||||
case SDLK_RCTRL:
|
||||
return SIM_KEY_CTRL_R;
|
||||
|
||||
case SDLK_LCTRL:
|
||||
return SIM_KEY_CTRL_L;
|
||||
|
||||
case SDLK_RALT:
|
||||
return SIM_KEY_ALT_R;
|
||||
|
||||
case SDLK_LALT:
|
||||
return SIM_KEY_ALT_L;
|
||||
|
||||
case SDLK_LGUI:
|
||||
return SIM_KEY_WIN_L;
|
||||
|
||||
case SDLK_RGUI:
|
||||
return SIM_KEY_WIN_R;
|
||||
|
||||
case SDLK_PRINTSCREEN:
|
||||
return SIM_KEY_PRINT;
|
||||
|
||||
case SDLK_PAUSE:
|
||||
return SIM_KEY_PAUSE;
|
||||
|
||||
case SDLK_MENU:
|
||||
return SIM_KEY_MENU;
|
||||
|
||||
default:
|
||||
return SIM_KEY_UNKNOWN;
|
||||
}
|
||||
}
|
||||
|
||||
void vid_key (SDL_KeyboardEvent *event)
|
||||
{
|
||||
SIM_KEY_EVENT ev;
|
||||
|
||||
if (vid_mouse_captured) {
|
||||
static const Uint8 *KeyStates = NULL;
|
||||
static int numkeys;
|
||||
|
||||
if (!KeyStates)
|
||||
KeyStates = SDL_GetKeyboardState(&numkeys);
|
||||
if ((event->state == SDL_PRESSED) && KeyStates[SDL_SCANCODE_RSHIFT] && (KeyStates[SDL_SCANCODE_LCTRL] || KeyStates[SDL_SCANCODE_RCTRL])) {
|
||||
sim_debug (SIM_VID_DBG_KEY, vid_dev, "vid_key() - Cursor Release\n");
|
||||
SDL_SetRelativeMouseMode(SDL_FALSE); /* release cursor, show cursor */
|
||||
vid_mouse_captured = FALSE;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!sim_is_running)
|
||||
return;
|
||||
if (SDL_SemWait (vid_key_events.sem) == 0) {
|
||||
sim_debug (SIM_VID_DBG_KEY, vid_dev, "Keyboard Event: State: %d, Keysym: %d\n", event->state, event->keysym);
|
||||
if (vid_key_events.count < MAX_EVENTS) {
|
||||
if (event->state == SDL_PRESSED) {
|
||||
if (!vid_key_state[event->keysym.sym]) { /* Key was not down before */
|
||||
vid_key_state[event->keysym.sym] = TRUE;
|
||||
ev.key = vid_map_key (event->keysym.sym);
|
||||
ev.state = SIM_KEYPRESS_DOWN;
|
||||
}
|
||||
else {
|
||||
ev.key = vid_map_key (event->keysym.sym);
|
||||
ev.state = SIM_KEYPRESS_REPEAT;
|
||||
}
|
||||
}
|
||||
else {
|
||||
vid_key_state[event->keysym.sym] = FALSE;
|
||||
ev.key = vid_map_key (event->keysym.sym);
|
||||
ev.state = SIM_KEYPRESS_UP;
|
||||
}
|
||||
vid_key_events.events[vid_key_events.tail++] = ev;
|
||||
vid_key_events.count++;
|
||||
if (vid_key_events.tail == MAX_EVENTS)
|
||||
vid_key_events.tail = 0;
|
||||
}
|
||||
SDL_SemPost (vid_key_events.sem);
|
||||
}
|
||||
}
|
||||
|
||||
void vid_mouse_move (SDL_MouseMotionEvent *event)
|
||||
{
|
||||
SDL_Event dummy_event;
|
||||
int32 cx;
|
||||
int32 cy;
|
||||
SIM_MOUSE_EVENT ev;
|
||||
|
||||
if (!vid_mouse_captured)
|
||||
return;
|
||||
|
||||
if ((event->x == 0) ||
|
||||
(event->y == 0) ||
|
||||
(event->x == (vid_width - 1)) ||
|
||||
(event->y == (vid_height - 1))) { /* reached edge of window? */
|
||||
cx = vid_width / 2;
|
||||
cy = vid_height / 2;
|
||||
SDL_WarpMouseInWindow (NULL, cx, cy); /* back to centre */
|
||||
SDL_PumpEvents ();
|
||||
while (SDL_PeepEvents (&dummy_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION)) {};
|
||||
}
|
||||
if (!sim_is_running)
|
||||
return;
|
||||
if (SDL_SemWait (vid_mouse_events.sem) == 0) {
|
||||
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Move Event: (%d,%d)\n", event->xrel, event->yrel);
|
||||
if (vid_mouse_events.count < MAX_EVENTS) {
|
||||
ev.x_rel = event->xrel;
|
||||
ev.y_rel = (-event->yrel);
|
||||
ev.b1_state = (event->state & SDL_BUTTON(SDL_BUTTON_LEFT)) ? TRUE : FALSE;
|
||||
ev.b2_state = (event->state & SDL_BUTTON(SDL_BUTTON_MIDDLE)) ? TRUE : FALSE;
|
||||
ev.b3_state = (event->state & SDL_BUTTON(SDL_BUTTON_RIGHT)) ? TRUE : FALSE;
|
||||
vid_mouse_events.b1_state = ev.b1_state;
|
||||
vid_mouse_events.b2_state = ev.b2_state;
|
||||
vid_mouse_events.b3_state = ev.b3_state;
|
||||
vid_mouse_events.events[vid_mouse_events.tail++] = ev;
|
||||
vid_mouse_events.count++;
|
||||
if (vid_mouse_events.tail == MAX_EVENTS)
|
||||
vid_mouse_events.tail = 0;
|
||||
}
|
||||
SDL_SemPost (vid_mouse_events.sem);
|
||||
}
|
||||
}
|
||||
|
||||
void vid_mouse_button (SDL_MouseButtonEvent *event)
|
||||
{
|
||||
SDL_Event dummy_event;
|
||||
int32 cx;
|
||||
int32 cy;
|
||||
SIM_MOUSE_EVENT ev;
|
||||
t_bool state;
|
||||
|
||||
if (!vid_mouse_captured) {
|
||||
if ((event->state == SDL_PRESSED) &&
|
||||
(event->button == SDL_BUTTON_LEFT)) { /* left click and cursor not captured? */
|
||||
sim_debug (SIM_VID_DBG_KEY, vid_dev, "vid_mouse_button() - Cursor Captured\n");
|
||||
SDL_SetRelativeMouseMode(SDL_TRUE); /* lock cursor to window, hide cursor */
|
||||
cx = vid_width / 2;
|
||||
cy = vid_height / 2;
|
||||
SDL_WarpMouseInWindow (NULL, cx, cy); /* back to centre */
|
||||
SDL_PumpEvents ();
|
||||
while (SDL_PeepEvents (&dummy_event, 1, SDL_GETEVENT, SDL_MOUSEMOTION, SDL_MOUSEMOTION)) {};
|
||||
vid_mouse_captured = TRUE;
|
||||
}
|
||||
return;
|
||||
}
|
||||
if (!sim_is_running)
|
||||
return;
|
||||
if (SDL_SemWait (vid_mouse_events.sem) == 0) {
|
||||
sim_debug (SIM_VID_DBG_MOUSE, vid_dev, "Mouse Button Event: State: %d, Button: %d, (%d,%d)\n", event->state, event->button, event->x, event->y);
|
||||
if (vid_mouse_events.count < MAX_EVENTS) {
|
||||
state = (event->state == SDL_PRESSED) ? TRUE : FALSE;
|
||||
ev.x_rel = 0;
|
||||
ev.y_rel = 0;
|
||||
switch (event->button) {
|
||||
case SDL_BUTTON_LEFT:
|
||||
vid_mouse_events.b1_state = state;
|
||||
break;
|
||||
case SDL_BUTTON_MIDDLE:
|
||||
vid_mouse_events.b2_state = state;
|
||||
break;
|
||||
case SDL_BUTTON_RIGHT:
|
||||
vid_mouse_events.b3_state = state;
|
||||
break;
|
||||
}
|
||||
ev.b1_state = vid_mouse_events.b1_state;
|
||||
ev.b2_state = vid_mouse_events.b2_state;
|
||||
ev.b3_state = vid_mouse_events.b3_state;
|
||||
vid_mouse_events.events[vid_mouse_events.tail++] = ev;
|
||||
vid_mouse_events.count++;
|
||||
if (vid_mouse_events.tail == MAX_EVENTS)
|
||||
vid_mouse_events.tail = 0;
|
||||
}
|
||||
SDL_SemPost (vid_mouse_events.sem);
|
||||
}
|
||||
}
|
||||
|
||||
void vid_update (void)
|
||||
{
|
||||
SDL_Rect vid_dst;
|
||||
|
||||
vid_dst.x = 0;
|
||||
vid_dst.y = 0;
|
||||
vid_dst.w = vid_width;
|
||||
vid_dst.h = vid_height;
|
||||
|
||||
sim_debug (SIM_VID_DBG_VIDEO, vid_dev, "Video Update Event: \n");
|
||||
SDL_RenderClear(vid_renderer);
|
||||
SDL_RenderCopy(vid_renderer, vid_texture, NULL, NULL);
|
||||
SDL_RenderPresent(vid_renderer);
|
||||
}
|
||||
|
||||
int vid_thread (void* arg)
|
||||
{
|
||||
SDL_Event event;
|
||||
static char *eventtypes[SDL_LASTEVENT];
|
||||
static t_bool initialized = FALSE;
|
||||
|
||||
if (!initialized) {
|
||||
initialized = TRUE;
|
||||
eventtypes[SDL_QUIT] = "QUIT"; /**< User-requested quit */
|
||||
|
||||
/* These application events have special meaning on iOS, see README-ios.txt for details */
|
||||
eventtypes[SDL_APP_TERMINATING] = "APP_TERMINATING"; /**< The application is being terminated by the OS
|
||||
Called on iOS in applicationWillTerminate()
|
||||
Called on Android in onDestroy()
|
||||
*/
|
||||
eventtypes[SDL_APP_LOWMEMORY] = "APP_LOWMEMORY"; /**< The application is low on memory, free memory if possible.
|
||||
Called on iOS in applicationDidReceiveMemoryWarning()
|
||||
Called on Android in onLowMemory()
|
||||
*/
|
||||
eventtypes[SDL_APP_WILLENTERBACKGROUND] = "APP_WILLENTERBACKGROUND"; /**< The application is about to enter the background
|
||||
Called on iOS in applicationWillResignActive()
|
||||
Called on Android in onPause()
|
||||
*/
|
||||
eventtypes[SDL_APP_DIDENTERBACKGROUND] = "APP_DIDENTERBACKGROUND"; /**< The application did enter the background and may not get CPU for some time
|
||||
Called on iOS in applicationDidEnterBackground()
|
||||
Called on Android in onPause()
|
||||
*/
|
||||
eventtypes[SDL_APP_WILLENTERFOREGROUND] = "APP_WILLENTERFOREGROUND"; /**< The application is about to enter the foreground
|
||||
Called on iOS in applicationWillEnterForeground()
|
||||
Called on Android in onResume()
|
||||
*/
|
||||
eventtypes[SDL_APP_DIDENTERFOREGROUND] = "APP_DIDENTERFOREGROUND"; /**< The application is now interactive
|
||||
Called on iOS in applicationDidBecomeActive()
|
||||
Called on Android in onResume()
|
||||
*/
|
||||
|
||||
/* Window events */
|
||||
eventtypes[SDL_WINDOWEVENT] = "WINDOWEVENT"; /**< Window state change */
|
||||
eventtypes[SDL_SYSWMEVENT] = "SYSWMEVENT"; /**< System specific event */
|
||||
|
||||
/* Keyboard events */
|
||||
eventtypes[SDL_KEYDOWN] = "KEYDOWN"; /**< Key pressed */
|
||||
eventtypes[SDL_KEYUP] = "KEYUP"; /**< Key released */
|
||||
eventtypes[SDL_TEXTEDITING] = "TEXTEDITING"; /**< Keyboard text editing (composition) */
|
||||
eventtypes[SDL_TEXTINPUT] = "TEXTINPUT"; /**< Keyboard text input */
|
||||
|
||||
/* Mouse events */
|
||||
eventtypes[SDL_MOUSEMOTION] = "MOUSEMOTION"; /**< Mouse moved */
|
||||
eventtypes[SDL_MOUSEBUTTONDOWN] = "MOUSEBUTTONDOWN"; /**< Mouse button pressed */
|
||||
eventtypes[SDL_MOUSEBUTTONUP] = "MOUSEBUTTONUP"; /**< Mouse button released */
|
||||
eventtypes[SDL_MOUSEWHEEL] = "MOUSEWHEEL"; /**< Mouse wheel motion */
|
||||
|
||||
/* Joystick events */
|
||||
eventtypes[SDL_JOYAXISMOTION] = "JOYAXISMOTION"; /**< Joystick axis motion */
|
||||
eventtypes[SDL_JOYBALLMOTION] = "JOYBALLMOTION"; /**< Joystick trackball motion */
|
||||
eventtypes[SDL_JOYHATMOTION] = "JOYHATMOTION"; /**< Joystick hat position change */
|
||||
eventtypes[SDL_JOYBUTTONDOWN] = "JOYBUTTONDOWN"; /**< Joystick button pressed */
|
||||
eventtypes[SDL_JOYBUTTONUP] = "JOYBUTTONUP"; /**< Joystick button released */
|
||||
eventtypes[SDL_JOYDEVICEADDED] = "JOYDEVICEADDED"; /**< A new joystick has been inserted into the system */
|
||||
eventtypes[SDL_JOYDEVICEREMOVED] = "JOYDEVICEREMOVED"; /**< An opened joystick has been removed */
|
||||
|
||||
/* Game controller events */
|
||||
eventtypes[SDL_CONTROLLERAXISMOTION] = "CONTROLLERAXISMOTION"; /**< Game controller axis motion */
|
||||
eventtypes[SDL_CONTROLLERBUTTONDOWN] = "CONTROLLERBUTTONDOWN"; /**< Game controller button pressed */
|
||||
eventtypes[SDL_CONTROLLERBUTTONUP] = "CONTROLLERBUTTONUP"; /**< Game controller button released */
|
||||
eventtypes[SDL_CONTROLLERDEVICEADDED] = "CONTROLLERDEVICEADDED"; /**< A new Game controller has been inserted into the system */
|
||||
eventtypes[SDL_CONTROLLERDEVICEREMOVED] = "CONTROLLERDEVICEREMOVED"; /**< An opened Game controller has been removed */
|
||||
eventtypes[SDL_CONTROLLERDEVICEREMAPPED] = "CONTROLLERDEVICEREMAPPED"; /**< The controller mapping was updated */
|
||||
|
||||
/* Touch events */
|
||||
eventtypes[SDL_FINGERDOWN] = "FINGERDOWN";
|
||||
eventtypes[SDL_FINGERUP] = "FINGERUP";
|
||||
eventtypes[SDL_FINGERMOTION] = "FINGERMOTION";
|
||||
|
||||
/* Gesture events */
|
||||
eventtypes[SDL_DOLLARGESTURE] = "DOLLARGESTURE";
|
||||
eventtypes[SDL_DOLLARRECORD] = "DOLLARRECORD";
|
||||
eventtypes[SDL_MULTIGESTURE] = "MULTIGESTURE";
|
||||
|
||||
/* Clipboard events */
|
||||
eventtypes[SDL_CLIPBOARDUPDATE] = "CLIPBOARDUPDATE"; /**< The clipboard changed */
|
||||
|
||||
/* Drag and drop events */
|
||||
eventtypes[SDL_DROPFILE] = "DROPFILE"; /**< The system requests a file open */
|
||||
|
||||
/** Events ::SDL_USEREVENT through ::SDL_LASTEVENT are for your use,
|
||||
* and should be allocated with SDL_RegisterEvents()
|
||||
*/
|
||||
eventtypes[SDL_USEREVENT] = "USEREVENT";
|
||||
|
||||
}
|
||||
|
||||
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE, vid_dev, "vid_thread() - Starting\n");
|
||||
|
||||
vid_mono_palette[0] = sim_end ? 0xFF000000 : 0x000000FF;
|
||||
vid_mono_palette[1] = 0xFFFFFFFF;
|
||||
|
||||
memset (&vid_key_state, 0, sizeof(vid_key_state));
|
||||
|
||||
SDL_Init (SDL_INIT_VIDEO);
|
||||
|
||||
SDL_CreateWindowAndRenderer (vid_width, vid_height, SDL_WINDOW_SHOWN, &vid_window, &vid_renderer);
|
||||
|
||||
if ((vid_window == NULL) || (vid_renderer == NULL)) {
|
||||
printf ("%s: Error Creating Video Window: %s\b", sim_dname(vid_dev), SDL_GetError());
|
||||
if (sim_log)
|
||||
fprintf (sim_log, "%s: Error Creating Video Window: %s\b", sim_dname(vid_dev), SDL_GetError());
|
||||
SDL_Quit ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
SDL_SetRenderDrawColor (vid_renderer, 0, 0, 0, 255);
|
||||
SDL_RenderClear (vid_renderer);
|
||||
SDL_RenderPresent (vid_renderer);
|
||||
|
||||
vid_texture = SDL_CreateTexture (vid_renderer,
|
||||
SDL_PIXELFORMAT_ARGB8888,
|
||||
SDL_TEXTUREACCESS_STREAMING,
|
||||
vid_width, vid_height);
|
||||
if (!vid_texture) {
|
||||
printf ("%s: Error configuring Video environment: %s\b", sim_dname(vid_dev), SDL_GetError());
|
||||
if (sim_log)
|
||||
fprintf (sim_log, "%s: Error configuring Video environment: %s\b", sim_dname(vid_dev), SDL_GetError());
|
||||
SDL_DestroyRenderer(vid_renderer);
|
||||
vid_renderer = NULL;
|
||||
SDL_DestroyWindow(vid_window);
|
||||
vid_window = NULL;
|
||||
SDL_Quit ();
|
||||
return 0;
|
||||
}
|
||||
|
||||
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE, vid_dev, "vid_thread() - Started\n");
|
||||
|
||||
while (vid_active) {
|
||||
if (SDL_WaitEvent (&event)) {
|
||||
switch (event.type) {
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
vid_key ((SDL_KeyboardEvent*)&event);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
vid_mouse_button ((SDL_MouseButtonEvent*)&event);
|
||||
break;
|
||||
|
||||
case SDL_MOUSEMOTION:
|
||||
vid_mouse_move ((SDL_MouseMotionEvent*)&event);
|
||||
break;
|
||||
|
||||
case SDL_USEREVENT:
|
||||
/* There are 2 user events generated */
|
||||
/* EVENT_REDRAW to update the display */
|
||||
/* EVENT_CLOSE to wake up this thread and let */
|
||||
/* it notice vid_active has changed */
|
||||
if (event.user.code == EVENT_REDRAW)
|
||||
vid_update ();
|
||||
break;
|
||||
|
||||
default:
|
||||
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE, vid_dev, "vid_thread() - Ignored Event: Type: %s(%d)\n", eventtypes[event.type], event.type);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
SDL_DestroyTexture(vid_texture);
|
||||
vid_texture = NULL;
|
||||
SDL_DestroyRenderer(vid_renderer);
|
||||
vid_renderer = NULL;
|
||||
SDL_DestroyWindow(vid_window);
|
||||
vid_window = NULL;
|
||||
SDL_Quit ();
|
||||
sim_debug (SIM_VID_DBG_VIDEO|SIM_VID_DBG_KEY|SIM_VID_DBG_MOUSE, vid_dev, "vid_thread() - Exiting\n");
|
||||
return 0;
|
||||
}
|
||||
#endif /* libSDL2 implementation */
|
||||
|
||||
const char *vid_version(void)
|
||||
{
|
||||
static char SDLVersion[80];
|
||||
const SDL_version *ver = SDL_Linked_Version();
|
||||
SDL_version compiled, running;
|
||||
|
||||
sprintf(SDLVersion, "SDL Version %d.%d.%d", ver->major, ver->minor, ver->patch);
|
||||
#if SDL_MAJOR_VERSION == 1
|
||||
const SDL_version *ver = SDL_Linked_Version();
|
||||
running.major = ver->major;
|
||||
running.minor = ver->minor;
|
||||
running.patch = ver->patch;
|
||||
#else
|
||||
SDL_GetVersion(&running);
|
||||
#endif
|
||||
SDL_VERSION(&compiled);
|
||||
|
||||
if ((compiled.major == running.major) &&
|
||||
(compiled.minor == running.minor) &&
|
||||
(compiled.patch == running.patch))
|
||||
sprintf(SDLVersion, "SDL Version %d.%d.%d",
|
||||
compiled.major, compiled.minor, compiled.patch);
|
||||
else
|
||||
sprintf(SDLVersion, "SDL Version (Compiled: %d.%d.%d, Runtime: %d.%d.%d)",
|
||||
compiled.major, compiled.minor, compiled.patch,
|
||||
running.major, running.minor, running.patch);
|
||||
return (const char *)SDLVersion;
|
||||
}
|
||||
|
||||
|
@ -802,6 +1623,8 @@ return SCPE_OK;
|
|||
|
||||
/* Non-implemented versions */
|
||||
|
||||
uint32 vid_mono_palette[2]; /* Monochrome Color Map */
|
||||
|
||||
t_stat vid_open (DEVICE *dptr, uint32 width, uint32 height)
|
||||
{
|
||||
return SCPE_NOFNC;
|
||||
|
@ -822,7 +1645,7 @@ t_stat vid_poll_mouse (SIM_MOUSE_EVENT *ev)
|
|||
return SCPE_EOF;
|
||||
}
|
||||
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint8 *buf)
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -172,13 +172,14 @@ t_stat vid_open (DEVICE *dptr, uint32 width, uint32 height);
|
|||
t_stat vid_close (void);
|
||||
t_stat vid_poll_kb (SIM_KEY_EVENT *ev);
|
||||
t_stat vid_poll_mouse (SIM_MOUSE_EVENT *ev);
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint8 *buf);
|
||||
void vid_draw (int32 x, int32 y, int32 w, int32 h, uint32 *buf);
|
||||
void vid_refresh (void);
|
||||
const char *vid_version (void);
|
||||
t_stat vid_set_release_key (FILE* st, UNIT* uptr, int32 val, void* desc);
|
||||
t_stat vid_show_release_key (FILE* st, UNIT* uptr, int32 val, void* desc);
|
||||
|
||||
extern t_bool vid_active;
|
||||
extern uint32 vid_mono_palette[2];
|
||||
|
||||
#define SIM_VID_DBG_MOUSE 0x01000000
|
||||
#define SIM_VID_DBG_KEY 0x02000000
|
||||
|
|
Loading…
Add table
Reference in a new issue