mirror of
https://github.com/n64dev/cen64.git
synced 2024-06-15 10:37:48 -04:00
Add support for SDL on MACOS (#226)
This commit is contained in:
parent
f70312008a
commit
ca4bd81817
7
.gitignore
vendored
7
.gitignore
vendored
|
@ -97,3 +97,10 @@ Temporary Items
|
|||
# SVN #
|
||||
######################
|
||||
.svn/
|
||||
*.bin
|
||||
debug/
|
||||
.idea/
|
||||
.vscode/
|
||||
*.sav
|
||||
bin/
|
||||
release/
|
|
@ -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,7 +404,17 @@ 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/sdl)
|
||||
include_directories(${SDL2_INCLUDE_DIRS})
|
||||
|
||||
list(APPEND OS_SOURCES
|
||||
${OS_COMMON_SOURCES}
|
||||
${OS_POSIX_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})
|
||||
|
@ -405,14 +424,19 @@ else ()
|
|||
${OS_POSIX_SOURCES}
|
||||
${OS_X11_SOURCES}
|
||||
)
|
||||
|
||||
endif (DEFINED WIN32)
|
||||
|
||||
#
|
||||
# Glob all the files together.
|
||||
#
|
||||
if (DEFINED UNIX)
|
||||
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}
|
||||
)
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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
32
os/sdl/gl_common.h
Normal 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
44
os/sdl/gl_config.c
Normal 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
160
os/sdl/gl_config.h
Normal 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
34
os/sdl/gl_context.h
Normal 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
32
os/sdl/gl_display.h
Normal 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
40
os/sdl/gl_screen.h
Normal 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
165
os/sdl/gl_window.c
Normal 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(¤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;
|
||||
}
|
93
os/sdl/gl_window.h
Normal file
93
os/sdl/gl_window.h
Normal 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
84
os/sdl/keycodes.h
Normal 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
|
||||
|
Loading…
Reference in a new issue