diff --git a/.gitignore b/.gitignore index 8accecb..f228ad8 100644 --- a/.gitignore +++ b/.gitignore @@ -97,3 +97,10 @@ Temporary Items # SVN # ###################### .svn/ +*.bin +debug/ +.idea/ +.vscode/ +*.sav +bin/ +release/ \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 2ee4ad2..88bb895 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -12,7 +12,10 @@ project(cen64 C) set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules" ${CMAKE_MODULE_PATH}) if(APPLE) - find_package(OpenGLXQuartz REQUIRED) +find_package(SDL2 REQUIRED) +find_package(GLEW REQUIRED) +find_package(OpenGL REQUIRED) + # Needed for signal.h on OS X. add_definitions(-D_DARWIN_C_SOURCE) else(APPLE) @@ -322,6 +325,12 @@ set(OS_X11_SOURCES ${PROJECT_SOURCE_DIR}/os/x11/gl_window.c ) +set(OS_SDL_SOURCES + ${PROJECT_SOURCE_DIR}/os/sdl/gl_config.c + ${PROJECT_SOURCE_DIR}/os/sdl/gl_window.c +) + + set(PI_SOURCES ${PROJECT_SOURCE_DIR}/pi/controller.c ${PROJECT_SOURCE_DIR}/pi/is_viewer.c @@ -395,24 +404,39 @@ if (DEFINED WIN32) ${OS_COMMON_SOURCES} ${OS_WINAPI_SOURCES} ) -else () +elseif(DEFINED APPLE) include_directories(${PROJECT_SOURCE_DIR}/os/posix) - include_directories(${PROJECT_SOURCE_DIR}/os/x11) - include_directories(${X11_xf86vmode_INCLUDE_PATH}) + include_directories(${PROJECT_SOURCE_DIR}/os/sdl) + include_directories(${SDL2_INCLUDE_DIRS}) list(APPEND OS_SOURCES ${OS_COMMON_SOURCES} ${OS_POSIX_SOURCES} - ${OS_X11_SOURCES} + ${OS_SDL_SOURCES} ) + else() + include_directories(${PROJECT_SOURCE_DIR}/os/posix) + include_directories(${PROJECT_SOURCE_DIR}/os/x11) + include_directories(${X11_xf86vmode_INCLUDE_PATH}) + + list(APPEND OS_SOURCES + ${OS_COMMON_SOURCES} + ${OS_POSIX_SOURCES} + ${OS_X11_SOURCES} + ) + endif (DEFINED WIN32) # # Glob all the files together. # if (DEFINED UNIX) - find_package(X11 REQUIRED) - + if(NOT DEFINED APPLE) + find_package(X11 REQUIRED) + set(VIDEO_LIB ${X11_X11_LIB}) + else() + set(VIDEO_LIB ${SDL2_LIBRARIES}) + endif() if (${CMAKE_C_COMPILER_ID} MATCHES GNU OR ${CMAKE_C_COMPILER_ID} MATCHES Clang OR ${CMAKE_C_COMPILER_ID} MATCHES Intel) set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -D_POSIX_C_SOURCE=200112L -D_BSD_SOURCE -D_DEFAULT_SOURCE") endif (${CMAKE_C_COMPILER_ID} MATCHES GNU OR ${CMAKE_C_COMPILER_ID} MATCHES Clang OR ${CMAKE_C_COMPILER_ID} MATCHES Intel) @@ -458,7 +482,7 @@ target_link_libraries(cen64 ${OPENAL_LIBRARY} ${OPENGL_gl_LIBRARY} ${ICONV_LIBRARIES} - ${X11_X11_LIB} + ${VIDEO_LIB} ${CMAKE_THREAD_LIBS_INIT} ) diff --git a/os/gl_window.h b/os/gl_window.h index b04e06c..7c48e51 100644 --- a/os/gl_window.h +++ b/os/gl_window.h @@ -14,8 +14,14 @@ #include #define GL_UNSIGNED_SHORT_5_5_5_1 0x8034 #endif +#ifdef __APPLE__ +#ifndef GL3_PROTOTYPES +#define GL3_PROTOTYPES 1 +#endif -#include +#include + +#endif #define MAX_FRAME_DATA_SIZE (640 * 480 * 4) diff --git a/os/keycodes.h b/os/keycodes.h index 2d96204..a73bfbb 100644 --- a/os/keycodes.h +++ b/os/keycodes.h @@ -12,7 +12,8 @@ #ifdef _WIN32 #include "os/windows/keycodes.h" - +#elif defined(__APPLE__) +#include "os/sdl/keycodes.h" #else #include "os/x11/keycodes.h" #endif diff --git a/os/sdl/gl_common.h b/os/sdl/gl_common.h new file mode 100644 index 0000000..7d10b56 --- /dev/null +++ b/os/sdl/gl_common.h @@ -0,0 +1,32 @@ +// +// +// CEN64: Cycle-Accurate Nintendo 64 Emulator. +// Copyright (C) 2015, Tyler J. Stachecki. +// +// This file is subject to the terms and conditions defined in +// 'LICENSE', which is part of this source code package. +// + +#ifndef CEN64_OS_SDL_GL_COMMON +#define CEN64_OS_SDL_GL_COMMON +#include "common.h" + + +enum cen64_gl_context_type { + CEN64_GL_CONTEXT_TYPE_RGBA, + CEN64_GL_CONTEXT_TYPE_COLOR_INDEX +}; + +enum cen64_gl_drawable_type { + CEN64_GL_DRAWABLE_TYPE_WINDOW, + CEN64_GL_DRAWABLE_TYPE_BITMAP +}; + +enum cen64_gl_layer_type { + CEN64_GL_LAYER_TYPE_DEFAULT = 0, + CEN64_GL_LAYER_TYPE_OVERLAY = 1, + CEN64_GL_LAYER_TYPE_UNDERLAY = 2 +}; + +#endif + diff --git a/os/sdl/gl_config.c b/os/sdl/gl_config.c new file mode 100644 index 0000000..e1904bd --- /dev/null +++ b/os/sdl/gl_config.c @@ -0,0 +1,44 @@ +#include "common.h" +#include "gl_common.h" +#include "gl_config.h" +#include "gl_hints.h" + +#define SET_ATTRIBUTE_IF_VALID(ATTR, VALUE_TO_TEST) \ + if ((VALUE_TO_TEST) != -1) \ + { \ + SDL_GL_SetAttribute((ATTR), (VALUE_TO_TEST)); \ + } + +#define SET_ATTRIBUTE_STATIC_IF_VALID(ATTR, VALUE_TO_TEST) \ + if ((VALUE_TO_TEST) != -1) \ + { \ + SDL_GL_SetAttribute((ATTR), 1); \ + } + +cen64_gl_config *cen64_gl_config_create(cen64_gl_display display, + cen64_gl_screen screen, const cen64_gl_hints *hints, int *matching) +{ + int idx = 0; + + SET_ATTRIBUTE_STATIC_IF_VALID(SDL_GL_DOUBLEBUFFER, hints->double_buffered); + SET_ATTRIBUTE_STATIC_IF_VALID(SDL_GL_STEREO, hints->stereoscopic); + if (hints->rgb_color_depth != -1) + { + int component_depth = hints->rgb_color_depth > 0 + ? hints->rgb_color_depth / 3 + : 0; + SDL_GL_SetAttribute(SDL_GL_RED_SIZE, component_depth); + SDL_GL_SetAttribute(SDL_GL_GREEN_SIZE, component_depth); + SDL_GL_SetAttribute(SDL_GL_BLUE_SIZE, component_depth); + } + SET_ATTRIBUTE_IF_VALID(SDL_GL_ALPHA_SIZE, hints->alpha_color_depth); + + SET_ATTRIBUTE_IF_VALID(SDL_GL_DEPTH_SIZE, hints->depth_buffer_size); + + SET_ATTRIBUTE_IF_VALID(SDL_GL_STENCIL_SIZE, hints->stencil_buffer_size); + + SET_ATTRIBUTE_IF_VALID(SDL_GL_ACCUM_RED_SIZE, hints->accum_buffer_red_bits); + SET_ATTRIBUTE_IF_VALID(SDL_GL_ACCUM_GREEN_SIZE, hints->accum_buffer_green_bits); + SET_ATTRIBUTE_IF_VALID(SDL_GL_ACCUM_BLUE_SIZE, hints->accum_buffer_blue_bits); + SET_ATTRIBUTE_IF_VALID(SDL_GL_ACCUM_ALPHA_SIZE, hints->accum_buffer_alpha_bits); +} \ No newline at end of file diff --git a/os/sdl/gl_config.h b/os/sdl/gl_config.h new file mode 100644 index 0000000..d4c76af --- /dev/null +++ b/os/sdl/gl_config.h @@ -0,0 +1,160 @@ +// +// os/x11/gl_config.h: X11/OpenGL framebuffer configuration. +// +// CEN64: Cycle-Accurate Nintendo 64 Emulator. +// Copyright (C) 2015, Tyler J. Stachecki. +// +// This file is subject to the terms and conditions defined in +// 'LICENSE', which is part of this source code package. +// + +#ifndef CEN64_OS_SDL_GL_CONFIG +#define CEN64_OS_SDL_GL_CONFIG +#include "gl_common.h" +#include "gl_display.h" +#include "gl_hints.h" +#include "gl_screen.h" +#include +#include + +#define CEN64_GL_CONFIG_BAD (NULL) +typedef struct { +}cen64_gl_config; + +// +// Creates a matching cen64_gl_config from a cen64_gl_hints struct. +// +// On error, CEN64_GL_CONFIG_BAD is returned. On success, something +// other than CEN64_GL_CONFIG_BAD is returned, and matching is set +// to indicate the number of matches present in the returned array. +// +cen64_gl_config *cen64_gl_config_create(cen64_gl_display display, + cen64_gl_screen screen, const cen64_gl_hints *hints, int *matching); + +// Releases resources allocated by cen64_gl_config_create. +static inline void cen64_gl_config_destroy(cen64_gl_config *config) +{ +} + +// +// Fetches an attribute from the cen64_gl_config object. +// +// Used by the cen64_gl_config_get_* accessors. +// +int cen64_gl_config_fetch_attribute(cen64_gl_display display, + cen64_gl_config *config, int what); + +// Wrappers for querying for features/types. +static inline enum cen64_gl_context_type cen64_gl_config_get_context_type( + cen64_gl_display display, cen64_gl_config *config) +{ + return CEN64_GL_CONTEXT_TYPE_RGBA; +} + +static inline enum cen64_gl_drawable_type cen64_gl_config_get_drawable_type( + cen64_gl_display display, cen64_gl_config *config) +{ + return CEN64_GL_DRAWABLE_TYPE_WINDOW; +} + +static inline enum cen64_gl_layer_type cen64_gl_config_get_layer_type( + cen64_gl_display display, cen64_gl_config *config) +{ + return CEN64_GL_LAYER_TYPE_DEFAULT; +} + +static inline int cen64_gl_config_is_double_buffered( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_DOUBLEBUFFER) == 1; +} + +static inline int cen64_gl_config_is_renderable( + cen64_gl_display display, cen64_gl_config *config) +{ + return true; +} + +static inline int cen64_gl_config_is_stereoscopic( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_STEREO) == 1; +} + +// Wrappers for querying for color depths. +static inline int cen64_gl_config_get_color_depth( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_BUFFER_SIZE); +} + +static inline int cen64_gl_config_get_red_color_depth( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_RED_SIZE); +} + +static inline int cen64_gl_config_get_green_color_depth( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_GREEN_SIZE); +} + +static inline int cen64_gl_config_get_blue_color_depth( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_BLUE_SIZE); +} + +static inline int cen64_gl_config_get_alpha_color_depth( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_ALPHA_SIZE); +} + +// Wrappers for querying for buffer sizes, counts. +static inline int cen64_gl_config_get_depth_buffer_count( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_DEPTH_SIZE); +} + +static inline int cen64_gl_config_get_num_auxiliary_buffers( + cen64_gl_display display, cen64_gl_config *config) +{ + return 0; + //cen64_gl_config_fetch_attribute(display, config, SDL_GL_AUX_BUFFERS); +} + +static inline int cen64_gl_config_get_stencil_buffer_size( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_STENCIL_SIZE); +} + +// Wrappers for querying for accumulation buffer bits. +static inline int cen64_gl_config_get_red_accum_buffer_bits( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_ACCUM_RED_SIZE); +} + +static inline int cen64_gl_config_get_blue_accum_buffer_bits( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_ACCUM_BLUE_SIZE); +} + +static inline int cen64_gl_config_get_green_accum_buffer_bits( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_ACCUM_GREEN_SIZE); +} + +static inline int cen64_gl_config_get_alpha_accum_buffer_bits( + cen64_gl_display display, cen64_gl_config *config) +{ + return cen64_gl_config_fetch_attribute(display, config, SDL_GL_ACCUM_ALPHA_SIZE); +} + +#endif diff --git a/os/sdl/gl_context.h b/os/sdl/gl_context.h new file mode 100644 index 0000000..f7c8051 --- /dev/null +++ b/os/sdl/gl_context.h @@ -0,0 +1,34 @@ +// +// +// CEN64: Cycle-Accurate Nintendo 64 Emulator. +// Copyright (C) 2015, Tyler J. Stachecki. +// +// This file is subject to the terms and conditions defined in +// 'LICENSE', which is part of this source code package. +// + +#ifndef CEN64_OS_SDL_GL_CONTEXT +#define CEN64_OS_SDL_GL_CONTEXT +#include "gl_common.h" +#include "gl_display.h" +#include "gl_screen.h" +#include "gl_window.h" +#include + +#define CEN64_GL_CONTEXT_BAD (NULL) +typedef SDL_GLContext cen64_gl_context; + +// Creates a cen64_gl_context and binds it to the cen64_gl_window. +static inline cen64_gl_context cen64_gl_context_create(cen64_gl_window window) +{ + return SDL_GL_CreateContext(window->window); +} + +// Unbinds the cen64_gl_context from the window and releases the context. +static inline void cen64_gl_context_destroy( + cen64_gl_context context, cen64_gl_window window) +{ + SDL_GL_DeleteContext(window->window); +} + +#endif diff --git a/os/sdl/gl_display.h b/os/sdl/gl_display.h new file mode 100644 index 0000000..d84f450 --- /dev/null +++ b/os/sdl/gl_display.h @@ -0,0 +1,32 @@ +#ifndef CEN64_OS_SDL_GL_DISPLAY +#define CEN64_OS_SDL_GL_DISPLAY +#include "gl_common.h" +#include +#include + + +#define CEN64_GL_DISPLAY_BAD (NULL) +typedef int cen64_gl_display; + +// +// Creates a cen64_gl_display (where 'source' selects the display to use). +// +// If source is NULL, it is treated as a don't care. +// +static inline cen64_gl_display cen64_gl_display_create(const char *source) { + SDL_Init(SDL_INIT_VIDEO); + return 1; +} + +// Releases resources allocated by cen64_gl_display_create. +static inline void cen64_gl_display_destroy(cen64_gl_display display) { + SDL_Quit(); +} + +// Returns the number of screens present on a given cen64_gl_display. +static inline int cen64_gl_display_get_num_screens(cen64_gl_display display) { + return 1; +} + +#endif + diff --git a/os/sdl/gl_screen.h b/os/sdl/gl_screen.h new file mode 100644 index 0000000..6c36221 --- /dev/null +++ b/os/sdl/gl_screen.h @@ -0,0 +1,40 @@ +// +// os/sdl/gl_screen.h: SDL screen definitions. +// +// CEN64: Cycle-Accurate Nintendo 64 Emulator. +// Copyright (C) 2015, Tyler J. Stachecki. +// +// This file is subject to the terms and conditions defined in +// 'LICENSE', which is part of this source code package. +// + +#ifndef CEN64_OS_SDL_GL_SCREEN +#define CEN64_OS_SDL_GL_SCREEN +#include "gl_common.h" +#include + +#define CEN64_GL_SCREEN_BAD (-1) +typedef int cen64_gl_screen; + +// +// Creates a cen64_gl_screen object on a given cen64_gl_display. +// +// 'which' specifies which screen on a display to use (from 0 to +// num_screens - 1). If 'which' is less than zero, it is treated as +// a don't care. +// +// On error, CEN64_GL_SCREEN_BAD is returned. +// +static inline cen64_gl_screen cen64_gl_screen_create( + cen64_gl_display display, int which) { + // Not used with SDL + return 0; +} + +// +// Releases resources allocated by cen64_screen_create. +// +static inline void cen64_gl_screen_destroy(cen64_gl_screen screen) {} + +#endif + diff --git a/os/sdl/gl_window.c b/os/sdl/gl_window.c new file mode 100644 index 0000000..d7e273e --- /dev/null +++ b/os/sdl/gl_window.c @@ -0,0 +1,165 @@ +// +// os/x11/gl_window.c: X11/OpenGL window definitions. +// +// CEN64: Cycle-Accurate Nintendo 64 Emulator. +// Copyright (C) 2015, Tyler J. Stachecki. +// +// This file is subject to the terms and conditions defined in +// 'LICENSE', which is part of this source code package. +// + +#include "common.h" +#include "device/device.h" +#include "gl_common.h" +#include "gl_display.h" +#include "gl_screen.h" +#include "gl_window.h" +#include "input.h" +#include "timer.h" +#include "vi/controller.h" +#include "vi/render.h" +#include +#include + +static int cen64_gl_window_create_objects(cen64_gl_window window); +static bool cen64_gl_window_pump_events(struct vi_controller *vi, + cen64_time *last_update_time, unsigned *frame_count); + +// Creates an (initially hidden) cen64_gl_window. +cen64_gl_window cen64_gl_window_create( + cen64_gl_display display, cen64_gl_screen screen, + const cen64_gl_config *config, const char *title) +{ + cen64_gl_window window; + + if ((window = malloc(sizeof(*window))) == NULL) + return CEN64_GL_WINDOW_BAD; + + // Create synchronization primitives for the window. + if (cen64_gl_window_create_objects(window)) + { + free(window); + return CEN64_GL_WINDOW_BAD; + } + window->window = SDL_CreateWindow( + "cen64", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + 640, + 474, + SDL_WINDOW_HIDDEN | SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_ALLOW_HIGHDPI); + window->exit_requested = false; + window->display = display; + window->screen = screen; + return window; +} + +// Handles events that come from SDL. +bool cen64_gl_window_pump_events(struct vi_controller *vi, + cen64_time *last_update_time, unsigned *frame_count) +{ + bool released, exit_requested = false; + SDL_Event e; + + cen64_mutex_lock(&vi->window->event_mutex); + + while (SDL_PollEvent(&e)) + { + if (e.type == SDL_QUIT) + { + vi->window->exit_requested = exit_requested = true; + break; + } + if (e.type == SDL_WINDOWEVENT) + { + if (e.window.event == SDL_WINDOWEVENT_RESIZED) + { + gl_window_resize_cb(e.window.data1, e.window.data2); + } + } + if (e.type == SDL_KEYDOWN) + { + keyboard_press_callback(vi->bus, e.key.keysym.sym); + } + if (e.type == SDL_KEYUP) + { + keyboard_release_callback(vi->bus, e.key.keysym.sym); + } + if (e.type == SDL_USEREVENT) + { + cen64_gl_window window = vi->window; + + cen64_mutex_lock(&window->render_mutex); + + gl_window_render_frame(vi, window->frame_buffer, + window->frame_hres, window->frame_vres, + window->frame_hskip, window->frame_type); + + cen64_mutex_unlock(&window->render_mutex); + + // Update the window title every 60 VIs + // to display the current VI/s rate. + if (++(*frame_count) == 60) + { + char title[128]; + cen64_time current_time; + float ns; + + // Compute time spent rendering last 60 frames, reset timer/counter. + get_time(¤t_time); + ns = compute_time_difference(¤t_time, last_update_time); + *last_update_time = current_time; + *frame_count = 0; + + sprintf(title, + "CEN64 [" CEN64_COMPILER " - " CEN64_ARCH_DIR "/" CEN64_ARCH_SUPPORT "]" + " - %.1f VI/s", + (60 / (ns / NS_PER_SEC))); + + cen64_gl_window_set_title(window, title); + } + } + } + cen64_mutex_unlock(&vi->window->event_mutex); + + return exit_requested; +} + +// Allocate mutexes, pipes, etc. for the UI/window. +int cen64_gl_window_create_objects(cen64_gl_window window) +{ + if (cen64_mutex_create(&window->event_mutex)) + { + return 1; + } + + if (cen64_mutex_create(&window->render_mutex)) + { + cen64_mutex_destroy(&window->event_mutex); + return 1; + } + + if (pipe(window->pipefds) < 0) + { + cen64_mutex_destroy(&window->render_mutex); + cen64_mutex_destroy(&window->event_mutex); + return 1; + } + + return 0; +} + +// Thread that controls the user interface, etc. +int cen64_gl_window_thread(struct cen64_device *device) +{ + cen64_time last_update_time; + unsigned frame_count; + + get_time(&last_update_time); + frame_count = 0; + + while (!cen64_gl_window_pump_events(&device->vi, + &last_update_time, &frame_count)); + + return 0; +} diff --git a/os/sdl/gl_window.h b/os/sdl/gl_window.h new file mode 100644 index 0000000..b03800f --- /dev/null +++ b/os/sdl/gl_window.h @@ -0,0 +1,93 @@ +// +// os/x11/gl_window.h: X11/OpenGL window definitions. +// +// CEN64: Cycle-Accurate Nintendo 64 Emulator. +// Copyright (C) 2015, Tyler J. Stachecki. +// +// This file is subject to the terms and conditions defined in +// 'LICENSE', which is part of this source code package. +// + +#ifndef CEN64_OS_SDL_GL_WINDOW +#define CEN64_OS_SDL_GL_WINDOW +#include "common.h" +#include "gl_config.h" +#include "gl_common.h" +#include "gl_display.h" +#include "gl_screen.h" +#include "thread.h" +#include + +#define FRAMEBUF_SZ (640 * 474 * 4) +#define CEN64_GL_WINDOW_BAD (NULL) +struct cen64_gl_window +{ + cen64_gl_display display; + cen64_gl_screen screen; + + SDL_Window *window; + + int pipefds[2]; + + cen64_mutex render_mutex; + uint8_t frame_buffer[FRAMEBUF_SZ]; + unsigned frame_hres, frame_vres; + unsigned frame_hskip, frame_type; + + cen64_mutex event_mutex; + bool exit_requested; +}; + +typedef struct cen64_gl_window *cen64_gl_window; + +// Forward declaration. +struct cen64_device; + +// Creates an (initially hidden) cen64_gl_window. +cen64_cold cen64_gl_window cen64_gl_window_create( + cen64_gl_display display, cen64_gl_screen screen, + const cen64_gl_config *config, const char *title); + +// Releases resources allocated by cen64_gl_window_create. +static inline void cen64_gl_window_destroy(cen64_gl_window window) +{ + SDL_DestroyWindow(window->window); + close(window->pipefds[0]); + close(window->pipefds[1]); + + cen64_mutex_destroy(&window->render_mutex); + cen64_mutex_destroy(&window->event_mutex); + free(window); +} + +// Pushes a notification to the UI queue to indicate a frame is ready. +static inline void cen64_gl_window_push_frame(cen64_gl_window window) +{ + SDL_Event sdlevent; + sdlevent.type = SDL_USEREVENT; + SDL_PushEvent(&sdlevent); +} + +// Sets the title of the cen64_gl_window. +static inline void cen64_gl_window_set_title( + cen64_gl_window window, const char *title) +{ + SDL_SetWindowTitle(window->window, title); +} + +// Swaps the front and back buffers of the cen64_gl_window. +static inline void cen64_gl_window_swap_buffers(cen64_gl_window window) +{ + SDL_GL_SwapWindow(window->window); +} + +// Thread that controls the user interface, etc. +int cen64_gl_window_thread(struct cen64_device *device); + +// Unhides the cen64_gl_window. +static inline void cen64_gl_window_unhide(cen64_gl_window window) +{ + SDL_ShowWindow(window->window); +} + +#endif diff --git a/os/sdl/keycodes.h b/os/sdl/keycodes.h new file mode 100644 index 0000000..4779c18 --- /dev/null +++ b/os/sdl/keycodes.h @@ -0,0 +1,84 @@ +// +// os/x11/keycodes.h: X11 keycode definitions. +// +// CEN64: Cycle-Accurate Nintendo 64 Emulator. +// Copyright (C) 2015, Tyler J. Stachecki. +// +// This file is subject to the terms and conditions defined in +// 'LICENSE', which is part of this source code package. +// + +#ifndef CEN64_OS_SDL_KEYCODES +#define CEN64_OS_SDL_KEYCODES +#include + +// Letter keys. +#define CEN64_KEY_A SDLK_a +#define CEN64_KEY_B SDLK_b +#define CEN64_KEY_C SDLK_c +#define CEN64_KEY_D SDLK_d +#define CEN64_KEY_E SDLK_e +#define CEN64_KEY_F SDLK_f +#define CEN64_KEY_G SDLK_g +#define CEN64_KEY_H SDLK_h +#define CEN64_KEY_I SDLK_i +#define CEN64_KEY_J SDLK_j +#define CEN64_KEY_K SDLK_k +#define CEN64_KEY_L SDLK_l +#define CEN64_KEY_M SDLK_m +#define CEN64_KEY_N SDLK_n +#define CEN64_KEY_O SDLK_o +#define CEN64_KEY_P SDLK_p +#define CEN64_KEY_Q SDLK_q +#define CEN64_KEY_R SDLK_r +#define CEN64_KEY_S SDLK_s +#define CEN64_KEY_T SDLK_t +#define CEN64_KEY_U SDLK_u +#define CEN64_KEY_V SDLK_v +#define CEN64_KEY_W SDLK_w +#define CEN64_KEY_X SDLK_x +#define CEN64_KEY_Y SDLK_y +#define CEN64_KEY_Z SDLK_z + +// Number keys. +#define CEN64_KEY_0 SDLK_0 +#define CEN64_KEY_1 SDLK_1 +#define CEN64_KEY_2 SDLK_2 +#define CEN64_KEY_3 SDLK_3 +#define CEN64_KEY_4 SDLK_4 +#define CEN64_KEY_5 SDLK_5 +#define CEN64_KEY_6 SDLK_6 +#define CEN64_KEY_7 SDLK_7 +#define CEN64_KEY_8 SDLK_8 +#define CEN64_KEY_9 SDLK_9 + +// Directional keys. +#define CEN64_KEY_LEFT SDLK_LEFT +#define CEN64_KEY_UP SDLK_UP +#define CEN64_KEY_RIGHT SDLK_RIGHT +#define CEN64_KEY_DOWN SDLK_DOWN + +// Other keys. +#define CEN64_KEY_BSLASH SDLK_backslash +#define CEN64_KEY_COMMA SDLK_comma +#define CEN64_KEY_EQUALS SDLK_equal +#define CEN64_KEY_FSLASH SDLK_fslash +#define CEN64_KEY_MINUS SDLK_minus +#define CEN64_KEY_LALT SDLK_Alt_L +#define CEN64_KEY_LBRACKET SDLK_bracketleft +#define CEN64_KEY_LCTRL SDLK_Control_L +#define CEN64_KEY_LSHIFT SDLK_LSHIFT +#define CEN64_KEY_LSUPER SDLK_Super_L +#define CEN64_KEY_PERIOD SDLK_period +#define CEN64_KEY_RALT SDLK_Alt_R +#define CEN64_KEY_RBRACKET SDLK_bracketright +#define CEN64_KEY_RCTRL SDLK_Control_R +#define CEN64_KEY_RETURN SDLK_RETURN +#define CEN64_KEY_RSHIFT SDLK_RSHIFT +#define CEN64_KEY_RSUPER SDLK_Super_R +#define CEN64_KEY_SEMICOLON SDLK_semicolon +#define CEN64_KEY_SLASH SDLK_slash +#define CEN64_KEY_SPACE SDLK_space + +#endif +