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 #
|
||||||
######################
|
######################
|
||||||
.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})
|
set(CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake/Modules" ${CMAKE_MODULE_PATH})
|
||||||
|
|
||||||
if(APPLE)
|
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.
|
# Needed for signal.h on OS X.
|
||||||
add_definitions(-D_DARWIN_C_SOURCE)
|
add_definitions(-D_DARWIN_C_SOURCE)
|
||||||
else(APPLE)
|
else(APPLE)
|
||||||
|
@ -322,6 +325,12 @@ set(OS_X11_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/os/x11/gl_window.c
|
${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
|
set(PI_SOURCES
|
||||||
${PROJECT_SOURCE_DIR}/pi/controller.c
|
${PROJECT_SOURCE_DIR}/pi/controller.c
|
||||||
${PROJECT_SOURCE_DIR}/pi/is_viewer.c
|
${PROJECT_SOURCE_DIR}/pi/is_viewer.c
|
||||||
|
@ -395,24 +404,39 @@ if (DEFINED WIN32)
|
||||||
${OS_COMMON_SOURCES}
|
${OS_COMMON_SOURCES}
|
||||||
${OS_WINAPI_SOURCES}
|
${OS_WINAPI_SOURCES}
|
||||||
)
|
)
|
||||||
else ()
|
elseif(DEFINED APPLE)
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/os/posix)
|
include_directories(${PROJECT_SOURCE_DIR}/os/posix)
|
||||||
include_directories(${PROJECT_SOURCE_DIR}/os/x11)
|
include_directories(${PROJECT_SOURCE_DIR}/os/sdl)
|
||||||
include_directories(${X11_xf86vmode_INCLUDE_PATH})
|
include_directories(${SDL2_INCLUDE_DIRS})
|
||||||
|
|
||||||
list(APPEND OS_SOURCES
|
list(APPEND OS_SOURCES
|
||||||
${OS_COMMON_SOURCES}
|
${OS_COMMON_SOURCES}
|
||||||
${OS_POSIX_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)
|
endif (DEFINED WIN32)
|
||||||
|
|
||||||
#
|
#
|
||||||
# Glob all the files together.
|
# Glob all the files together.
|
||||||
#
|
#
|
||||||
if (DEFINED UNIX)
|
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)
|
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")
|
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)
|
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}
|
${OPENAL_LIBRARY}
|
||||||
${OPENGL_gl_LIBRARY}
|
${OPENGL_gl_LIBRARY}
|
||||||
${ICONV_LIBRARIES}
|
${ICONV_LIBRARIES}
|
||||||
${X11_X11_LIB}
|
${VIDEO_LIB}
|
||||||
${CMAKE_THREAD_LIBS_INIT}
|
${CMAKE_THREAD_LIBS_INIT}
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
|
@ -14,8 +14,14 @@
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
#define GL_UNSIGNED_SHORT_5_5_5_1 0x8034
|
||||||
#endif
|
#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)
|
#define MAX_FRAME_DATA_SIZE (640 * 480 * 4)
|
||||||
|
|
||||||
|
|
|
@ -12,7 +12,8 @@
|
||||||
|
|
||||||
#ifdef _WIN32
|
#ifdef _WIN32
|
||||||
#include "os/windows/keycodes.h"
|
#include "os/windows/keycodes.h"
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
#include "os/sdl/keycodes.h"
|
||||||
#else
|
#else
|
||||||
#include "os/x11/keycodes.h"
|
#include "os/x11/keycodes.h"
|
||||||
#endif
|
#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