Add support for SDL on MACOS (#226)

This commit is contained in:
Lionel Touati 2022-05-21 13:51:34 +02:00 committed by GitHub
parent f70312008a
commit ca4bd81817
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 732 additions and 10 deletions

7
.gitignore vendored
View file

@ -97,3 +97,10 @@ Temporary Items
# SVN #
######################
.svn/
*.bin
debug/
.idea/
.vscode/
*.sav
bin/
release/

View file

@ -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}
)

View file

@ -14,8 +14,14 @@
#include <windows.h>
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
#endif
#ifdef __APPLE__
#ifndef GL3_PROTOTYPES
#define GL3_PROTOTYPES 1
#endif
#include <GL/gl.h>
#include <OpenGL/gl.h>
#endif
#define MAX_FRAME_DATA_SIZE (640 * 480 * 4)

View file

@ -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

32
os/sdl/gl_common.h Normal file
View file

@ -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

44
os/sdl/gl_config.c Normal file
View file

@ -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);
}

160
os/sdl/gl_config.h Normal file
View file

@ -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 <stddef.h>
#include <SDL.h>
#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

34
os/sdl/gl_context.h Normal file
View file

@ -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 <stddef.h>
#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

32
os/sdl/gl_display.h Normal file
View file

@ -0,0 +1,32 @@
#ifndef CEN64_OS_SDL_GL_DISPLAY
#define CEN64_OS_SDL_GL_DISPLAY
#include "gl_common.h"
#include <stddef.h>
#include <SDL.h>
#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

40
os/sdl/gl_screen.h Normal file
View file

@ -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 <stddef.h>
#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

165
os/sdl/gl_window.c Normal file
View file

@ -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 <unistd.h>
#include <SDL.h>
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(&current_time);
ns = compute_time_difference(&current_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;
}

93
os/sdl/gl_window.h Normal file
View file

@ -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 <unistd.h>
#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

84
os/sdl/keycodes.h Normal file
View file

@ -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 <SDL.h>
// 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