This commit is contained in:
Lior Halphon 2017-05-24 21:44:43 +03:00
parent 52e99adc32
commit 4d5dc6a30e
15 changed files with 154 additions and 133 deletions

View File

@ -15,14 +15,6 @@ _a > _b ? _a : _b; })
__typeof__ (b) _b = (b); \ __typeof__ (b) _b = (b); \
_a < _b ? _a : _b; }) _a < _b ? _a : _b; })
#ifdef _WIN32
/* "Old" (Pre-2015) Windows headers/libc don't have round. */
static inline double round(double f)
{
return f >= 0? (int)(f + 0.5) : (int)(f - 0.5);
}
#endif
#define APU_FREQUENCY 0x80000 #define APU_FREQUENCY 0x80000
static int16_t generate_square(uint64_t phase, uint32_t wave_length, int16_t amplitude, uint8_t duty) static int16_t generate_square(uint64_t phase, uint32_t wave_length, int16_t amplitude, uint8_t duty)

View File

@ -1,5 +1,4 @@
#include <stdbool.h> #include <stdbool.h>
#include <unistd.h>
#include <stdlib.h> #include <stdlib.h>
#include <assert.h> #include <assert.h>
#include <string.h> #include <string.h>

View File

@ -2,12 +2,13 @@
#include <stdbool.h> #include <stdbool.h>
#include <stdlib.h> #include <stdlib.h>
#include <stddef.h> #include <stddef.h>
#include <unistd.h>
#include <string.h> #include <string.h>
#include <errno.h> #include <errno.h>
#include <stdarg.h> #include <stdarg.h>
#include <sys/time.h> #ifndef _WIN32
#include <unistd.h>
#include <sys/select.h> #include <sys/select.h>
#endif
#include "gb.h" #include "gb.h"
void GB_attributed_logv(GB_gameboy_t *gb, GB_log_attributes attributes, const char *fmt, va_list args) void GB_attributed_logv(GB_gameboy_t *gb, GB_log_attributes attributes, const char *fmt, va_list args)

View File

@ -1,7 +1,4 @@
#include "gb.h" #include "gb.h"
#ifdef _WIN32
typedef intptr_t ssize_t;
#endif
static size_t GB_map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr) static size_t GB_map_find_symbol_index(GB_symbol_map_t *map, uint16_t addr)
{ {

View File

@ -60,7 +60,7 @@ SDL_LDFLAGS := -F/Library/Frameworks -framework SDL2
endif endif
CFLAGS += -Wno-deprecated-declarations CFLAGS += -Wno-deprecated-declarations
ifeq ($(PLATFORM),windows32) ifeq ($(PLATFORM),windows32)
CFLAGS += -Wno-deprecated-declarations -Dstrdup=_strdup # Seems like Microsoft deprecated every single LIBC function CFLAGS += -Wno-deprecated-declarations # Seems like Microsoft deprecated every single LIBC function
LDFLAGS += -Wl,/NODEFAULTLIB:libcmt.lib LDFLAGS += -Wl,/NODEFAULTLIB:libcmt.lib
endif endif

View File

@ -1,27 +1,26 @@
#include <stdio.h>
#include <stdbool.h> #include <stdbool.h>
#include <unistd.h>
#include <time.h>
#include <assert.h>
#include <signal.h> #include <signal.h>
#include <SDL2/SDL.h> #include <SDL2/SDL.h>
#include "gb.h"
#include "utils.h"
#ifndef _WIN32 #ifndef _WIN32
#define AUDIO_FREQUENCY 96000 #define AUDIO_FREQUENCY 96000
#else #else
/* Windows (well, at least my VM) can't handle 96KHz sound well :( */ /* Windows (well, at least my VM) can't handle 96KHz sound well :( */
#define AUDIO_FREQUENCY 44100 #define AUDIO_FREQUENCY 44100
#include <direct.h>
#include <windows.h>
#define snprintf _snprintf
#endif #endif
#include "gb.h"
GB_gameboy_t gb;
static bool dmg = false;
static bool paused = false;
static uint32_t pixels[160*144];
static char *filename = NULL; static char *filename = NULL;
static bool should_free_filename = false; static bool should_free_filename = false;
static char *battery_save_path_ptr; static char *battery_save_path_ptr;
static void replace_extension(const char *src, size_t length, char *dest, const char *ext);
static SDL_Window *window = NULL; static SDL_Window *window = NULL;
static SDL_Renderer *renderer = NULL; static SDL_Renderer *renderer = NULL;
@ -29,11 +28,6 @@ static SDL_Texture *texture = NULL;
static SDL_PixelFormat *pixel_format = NULL; static SDL_PixelFormat *pixel_format = NULL;
static SDL_AudioSpec want_aspec, have_aspec; static SDL_AudioSpec want_aspec, have_aspec;
static bool paused = false;
static uint32_t pixels[160*144];
GB_gameboy_t gb;
static enum { static enum {
GB_SDL_NO_COMMAND, GB_SDL_NO_COMMAND,
GB_SDL_SAVE_STATE_COMMAND, GB_SDL_SAVE_STATE_COMMAND,
@ -59,8 +53,8 @@ static void update_viewport(void)
double y_factor = win_height / 144.0; double y_factor = win_height / 144.0;
if (scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) { if (scaling_mode == GB_SDL_SCALING_INTEGER_FACTOR) {
x_factor = floor(x_factor); x_factor = (int)(x_factor);
y_factor = floor(y_factor); y_factor = (int)(y_factor);
} }
if (scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) { if (scaling_mode != GB_SDL_SCALING_ENTIRE_WINDOW) {
@ -244,56 +238,6 @@ static void vblank(GB_gameboy_t *gb)
handle_events(gb); handle_events(gb);
} }
#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif
static const char *executable_folder(void)
{
static char path[1024] = {0,};
if (path[0]) {
return path;
}
/* Ugly unportable code! :( */
#ifdef __APPLE__
unsigned int length = sizeof(path) - 1;
_NSGetExecutablePath(&path[0], &length);
#else
#ifdef __linux__
ssize_t length = readlink("/proc/self/exe", &path[0], sizeof(path) - 1);
assert (length != -1);
#else
#ifdef _WIN32
HMODULE hModule = GetModuleHandle(NULL);
GetModuleFileName(hModule, path, sizeof(path) - 1);
#else
/* No OS-specific way, assume running from CWD */
getcwd(&path[0], sizeof(path) - 1);
return path;
#endif
#endif
#endif
size_t pos = strlen(path);
while (pos) {
pos--;
#ifdef _WIN32
if (path[pos] == '\\') {
#else
if (path[pos] == '/') {
#endif
path[pos] = 0;
break;
}
}
return path;
}
static char *executable_relative_path(const char *filename)
{
static char path[1024];
snprintf(path, sizeof(path), "%s/%s", executable_folder(), filename);
return path;
}
static uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b) static uint32_t rgb_encode(GB_gameboy_t *gb, uint8_t r, uint8_t g, uint8_t b)
{ {
@ -320,25 +264,41 @@ static void audio_callback(void *gb, Uint8 *stream, int len)
} }
} }
static void replace_extension(const char *src, size_t length, char *dest, const char *ext) static bool handle_pending_command(void)
{ {
memcpy(dest, src, length); switch (pending_command) {
dest[length] = 0; case GB_SDL_LOAD_STATE_COMMAND:
case GB_SDL_SAVE_STATE_COMMAND: {
char save_path[strlen(filename) + 4];
char save_extension[] = ".s0";
save_extension[2] += command_parameter;
replace_extension(filename, strlen(filename), save_path, save_extension);
/* Remove extension */ if (pending_command == GB_SDL_LOAD_STATE_COMMAND) {
for (size_t i = length; i--;) { GB_load_state(&gb, save_path);
if (dest[i] == '/') break;
if (dest[i] == '.') {
dest[i] = 0;
break;
} }
else {
GB_save_state(&gb, save_path);
}
return false;
} }
/* Add new extension */ case GB_SDL_RESET_COMMAND:
strcat(dest, ext); GB_reset(&gb);
} return false;
static bool dmg = false; case GB_SDL_NO_COMMAND:
return false;
case GB_SDL_NEW_FILE_COMMAND:
return true;
case GB_SDL_TOGGLE_MODEL_COMMAND:
dmg = !dmg;
return true;
}
return false;
}
static void run(void) static void run(void)
{ {
@ -402,36 +362,9 @@ restart:
else { else {
GB_run(&gb); GB_run(&gb);
} }
switch (pending_command) {
case GB_SDL_LOAD_STATE_COMMAND:
case GB_SDL_SAVE_STATE_COMMAND: {
char save_path[strlen(filename) + 4];
char save_extension[] = ".s0";
save_extension[2] += command_parameter;
replace_extension(filename, strlen(filename), save_path, save_extension);
if (pending_command == GB_SDL_LOAD_STATE_COMMAND) { /* These commands can't run in the handle_event function, because they're not safe in a vblank context. */
GB_load_state(&gb, save_path); if (handle_pending_command()) {
}
else {
GB_save_state(&gb, save_path);
}
break;
}
case GB_SDL_RESET_COMMAND:
GB_reset(&gb);
break;
case GB_SDL_NO_COMMAND:
break;
case GB_SDL_NEW_FILE_COMMAND:
pending_command = GB_SDL_NO_COMMAND;
goto restart;
case GB_SDL_TOGGLE_MODEL_COMMAND:
dmg = !dmg;
pending_command = GB_SDL_NO_COMMAND; pending_command = GB_SDL_NO_COMMAND;
goto restart; goto restart;
} }

76
SDL/utils.c Normal file
View File

@ -0,0 +1,76 @@
#include <stdio.h>
#include <string.h>
#ifdef __APPLE__
#include <mach-o/dyld.h>
#endif
#ifdef _WIN32
#include <direct.h>
#include <windows.h>
#endif
#include "utils.h"
const char *executable_folder(void)
{
static char path[1024] = {0,};
if (path[0]) {
return path;
}
/* Ugly unportable code! :( */
#ifdef __APPLE__
unsigned int length = sizeof(path) - 1;
_NSGetExecutablePath(&path[0], &length);
#else
#ifdef __linux__
ssize_t length = readlink("/proc/self/exe", &path[0], sizeof(path) - 1);
assert (length != -1);
#else
#ifdef _WIN32
HMODULE hModule = GetModuleHandle(NULL);
GetModuleFileName(hModule, path, sizeof(path) - 1);
#else
/* No OS-specific way, assume running from CWD */
getcwd(&path[0], sizeof(path) - 1);
return path;
#endif
#endif
#endif
size_t pos = strlen(path);
while (pos) {
pos--;
#ifdef _WIN32
if (path[pos] == '\\') {
#else
if (path[pos] == '/') {
#endif
path[pos] = 0;
break;
}
}
return path;
}
char *executable_relative_path(const char *filename)
{
static char path[1024];
snprintf(path, sizeof(path), "%s/%s", executable_folder(), filename);
return path;
}
void replace_extension(const char *src, size_t length, char *dest, const char *ext)
{
memcpy(dest, src, length);
dest[length] = 0;
/* Remove extension */
for (size_t i = length; i--;) {
if (dest[i] == '/') break;
if (dest[i] == '.') {
dest[i] = 0;
break;
}
}
/* Add new extension */
strcat(dest, ext);
}

8
SDL/utils.h Normal file
View File

@ -0,0 +1,8 @@
#ifndef utils_h
#define utils_h
const char *executable_folder(void);
char *executable_relative_path(const char *filename);
void replace_extension(const char *src, size_t length, char *dest, const char *ext);
#endif /* utils_h */

7
Windows/math.h Executable file
View File

@ -0,0 +1,7 @@
#pragma once
#include_next <math.h>
/* "Old" (Pre-2015) Windows headers/libc don't have round. */
static inline double round(double f)
{
return f >= 0? (int)(f + 0.5) : (int)(f - 0.5);
}

3
Windows/stdint.h Executable file
View File

@ -0,0 +1,3 @@
#pragma once
#include_next <stdint.h>
typedef intptr_t ssize_t;

View File

@ -67,3 +67,5 @@ static inline size_t getline(char **lineptr, size_t *n, FILE *stream) {
return p - bufptr - 1; return p - bufptr - 1;
} }
#define snprintf _snprintf

3
Windows/string.h Executable file
View File

@ -0,0 +1,3 @@
#pragma once
#include_next <string.h>
#define strdup _strdup

View File

View File

View File