mirror of https://github.com/LIJI32/SameBoy.git
Allow the SDL port to use custom palettes imported from Cocoa
This commit is contained in:
parent
9a966a5581
commit
cbf1a5481f
6
Makefile
6
Makefile
|
@ -206,7 +206,7 @@ endif
|
|||
|
||||
cocoa: $(BIN)/SameBoy.app
|
||||
quicklook: $(BIN)/SameBoy.qlgenerator
|
||||
sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/mgb_boot.bin $(BIN)/SDL/cgb0_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders
|
||||
sdl: $(SDL_TARGET) $(BIN)/SDL/dmg_boot.bin $(BIN)/SDL/mgb_boot.bin $(BIN)/SDL/cgb0_boot.bin $(BIN)/SDL/cgb_boot.bin $(BIN)/SDL/agb_boot.bin $(BIN)/SDL/sgb_boot.bin $(BIN)/SDL/sgb2_boot.bin $(BIN)/SDL/LICENSE $(BIN)/SDL/registers.sym $(BIN)/SDL/background.bmp $(BIN)/SDL/Shaders $(BIN)/SDL/Palettes
|
||||
bootroms: $(BIN)/BootROMs/agb_boot.bin $(BIN)/BootROMs/cgb_boot.bin $(BIN)/BootROMs/cgb0_boot.bin $(BIN)/BootROMs/dmg_boot.bin $(BIN)/BootROMs/mgb_boot.bin $(BIN)/BootROMs/sgb_boot.bin $(BIN)/BootROMs/sgb2_boot.bin
|
||||
tester: $(TESTER_TARGET) $(BIN)/tester/dmg_boot.bin $(BIN)/tester/cgb_boot.bin $(BIN)/tester/agb_boot.bin $(BIN)/tester/sgb_boot.bin $(BIN)/tester/sgb2_boot.bin
|
||||
all: cocoa sdl tester libretro
|
||||
|
@ -424,6 +424,10 @@ $(BIN)/SDL/background.bmp: SDL/background.bmp
|
|||
$(BIN)/SDL/Shaders: Shaders
|
||||
-@$(MKDIR) -p $@
|
||||
cp -rf Shaders/*.fsh $@
|
||||
|
||||
$(BIN)/SDL/Palettes: Misc/Palettes
|
||||
-@$(MKDIR) -p $@
|
||||
cp -rf Misc/Palettes/*.sbp $@
|
||||
|
||||
# Boot ROMs
|
||||
|
||||
|
|
Binary file not shown.
|
@ -0,0 +1 @@
|
|||
LPBS&6UiS˜‰®ה¦»מ©־ץ}ש^¬ױL<D7B1>לH+
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -98,6 +98,7 @@ typedef struct {
|
|||
/* v0.15.2 */
|
||||
bool allow_background_controllers;
|
||||
bool gui_pallete_enabled; // Change the GUI palette only once the user changed the DMG palette
|
||||
char dmg_palette_name[25];
|
||||
};
|
||||
} configuration_t;
|
||||
|
||||
|
|
131
SDL/gui.c
131
SDL/gui.c
|
@ -5,6 +5,7 @@
|
|||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <dirent.h>
|
||||
#include "utils.h"
|
||||
#include "gui.h"
|
||||
#include "font.h"
|
||||
|
@ -21,6 +22,9 @@ enum pending_command pending_command;
|
|||
unsigned command_parameter;
|
||||
char *dropped_state_file = NULL;
|
||||
|
||||
static char **custom_palettes;
|
||||
static unsigned n_custom_palettes;
|
||||
|
||||
|
||||
#ifdef __APPLE__
|
||||
#define MODIFIER_NAME " " CMD_STRING
|
||||
|
@ -561,6 +565,9 @@ const char *current_color_temperature(unsigned index)
|
|||
|
||||
const char *current_palette(unsigned index)
|
||||
{
|
||||
if (configuration.dmg_palette == 4) {
|
||||
return configuration.dmg_palette_name;
|
||||
}
|
||||
return (const char *[]){"Greyscale", "Lime (Game Boy)", "Olive (Pocket)", "Teal (Light)"}
|
||||
[configuration.dmg_palette];
|
||||
}
|
||||
|
@ -653,25 +660,45 @@ static void increase_color_temperature(unsigned index)
|
|||
}
|
||||
}
|
||||
|
||||
const GB_palette_t *current_dmg_palette(void)
|
||||
{
|
||||
typedef struct __attribute__ ((packed)) {
|
||||
uint32_t magic;
|
||||
uint8_t flags;
|
||||
struct GB_color_s colors[5];
|
||||
int32_t brightness_bias;
|
||||
uint32_t hue_bias;
|
||||
uint32_t hue_bias_strength;
|
||||
} theme_t;
|
||||
|
||||
static theme_t theme;
|
||||
|
||||
if (configuration.dmg_palette == 4) {
|
||||
char *path = resource_path("Palettes");
|
||||
sprintf(path + strlen(path), "/%s.sbp", configuration.dmg_palette_name);
|
||||
FILE *file = fopen(path, "rb");
|
||||
if (!file) return &GB_PALETTE_GREY;
|
||||
memset(&theme, 0, sizeof(theme));
|
||||
fread(&theme, sizeof(theme), 1, file);
|
||||
fclose(file);
|
||||
#ifdef GB_BIG_ENDIAN
|
||||
theme.magic = __builtin_bswap32(theme.magic);
|
||||
#endif
|
||||
if (theme.magic != 'SBPL') return &GB_PALETTE_GREY;
|
||||
return (GB_palette_t *)&theme.colors;
|
||||
}
|
||||
|
||||
switch (configuration.dmg_palette) {
|
||||
case 1: return &GB_PALETTE_DMG;
|
||||
case 2: return &GB_PALETTE_MGB;
|
||||
case 3: return &GB_PALETTE_GBL;
|
||||
default: return &GB_PALETTE_GREY;
|
||||
}
|
||||
}
|
||||
|
||||
static void update_gui_palette(void)
|
||||
{
|
||||
const GB_palette_t *palette;
|
||||
switch (configuration.dmg_palette) {
|
||||
case 1:
|
||||
palette = &GB_PALETTE_DMG;
|
||||
break;
|
||||
|
||||
case 2:
|
||||
palette = &GB_PALETTE_MGB;
|
||||
break;
|
||||
|
||||
case 3:
|
||||
palette = &GB_PALETTE_GBL;
|
||||
break;
|
||||
|
||||
default:
|
||||
palette = &GB_PALETTE_GREY;
|
||||
}
|
||||
const GB_palette_t *palette = current_dmg_palette();
|
||||
|
||||
SDL_Color colors[4];
|
||||
for (unsigned i = 4; i--; ) {
|
||||
|
@ -695,7 +722,26 @@ static void update_gui_palette(void)
|
|||
static void cycle_palette(unsigned index)
|
||||
{
|
||||
if (configuration.dmg_palette == 3) {
|
||||
configuration.dmg_palette = 0;
|
||||
if (n_custom_palettes == 0) {
|
||||
configuration.dmg_palette = 0;
|
||||
}
|
||||
else {
|
||||
configuration.dmg_palette = 4;
|
||||
strcpy(configuration.dmg_palette_name, custom_palettes[0]);
|
||||
}
|
||||
}
|
||||
else if (configuration.dmg_palette == 4) {
|
||||
for (unsigned i = 0; i < n_custom_palettes; i++) {
|
||||
if (strcmp(custom_palettes[i], configuration.dmg_palette_name) == 0) {
|
||||
if (i == n_custom_palettes - 1) {
|
||||
configuration.dmg_palette = 0;
|
||||
}
|
||||
else {
|
||||
strcpy(configuration.dmg_palette_name, custom_palettes[i + 1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
configuration.dmg_palette++;
|
||||
|
@ -707,7 +753,26 @@ static void cycle_palette(unsigned index)
|
|||
static void cycle_palette_backwards(unsigned index)
|
||||
{
|
||||
if (configuration.dmg_palette == 0) {
|
||||
configuration.dmg_palette = 3;
|
||||
if (n_custom_palettes == 0) {
|
||||
configuration.dmg_palette = 3;
|
||||
}
|
||||
else {
|
||||
configuration.dmg_palette = 4;
|
||||
strcpy(configuration.dmg_palette_name, custom_palettes[n_custom_palettes - 1]);
|
||||
}
|
||||
}
|
||||
else if (configuration.dmg_palette == 4) {
|
||||
for (unsigned i = 0; i < n_custom_palettes; i++) {
|
||||
if (strcmp(custom_palettes[i], configuration.dmg_palette_name) == 0) {
|
||||
if (i == 0) {
|
||||
configuration.dmg_palette = 3;
|
||||
}
|
||||
else {
|
||||
strcpy(configuration.dmg_palette_name, custom_palettes[i - 1]);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
configuration.dmg_palette--;
|
||||
|
@ -1896,3 +1961,31 @@ void run_gui(bool is_running)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__ ((constructor)) list_custom_palettes(void)
|
||||
{
|
||||
char *path = resource_path("Palettes");
|
||||
if (!path) return;
|
||||
if (strlen(path) > 1024 - 30) {
|
||||
// path too long to safely concat filenames
|
||||
return;
|
||||
}
|
||||
DIR *dir = opendir(path);
|
||||
if (!dir) return;
|
||||
|
||||
struct dirent *ent;
|
||||
|
||||
while ((ent = readdir(dir))) {
|
||||
unsigned length = strlen(ent->d_name);
|
||||
if (length < 5 || length > 28) {
|
||||
continue;
|
||||
}
|
||||
if (strcmp(ent->d_name + length - 4, ".sbp")) continue;
|
||||
ent->d_name[length - 4] = 0;
|
||||
custom_palettes = realloc(custom_palettes,
|
||||
sizeof(custom_palettes[0]) * (n_custom_palettes + 1));
|
||||
custom_palettes[n_custom_palettes++] = strdup(ent->d_name);
|
||||
}
|
||||
|
||||
closedir(dir);
|
||||
}
|
||||
|
|
|
@ -64,5 +64,6 @@ extern const char *osd_text;
|
|||
extern unsigned osd_countdown;
|
||||
extern unsigned osd_text_lines;
|
||||
void convert_mouse_coordinates(signed *x, signed *y);
|
||||
const GB_palette_t *current_dmg_palette(void);
|
||||
|
||||
#endif
|
||||
|
|
20
SDL/main.c
20
SDL/main.c
|
@ -161,22 +161,7 @@ static const char *end_capturing_logs(bool show_popup, bool should_exit, uint32_
|
|||
|
||||
static void update_palette(void)
|
||||
{
|
||||
switch (configuration.dmg_palette) {
|
||||
case 1:
|
||||
GB_set_palette(&gb, &GB_PALETTE_DMG);
|
||||
break;
|
||||
|
||||
case 2:
|
||||
GB_set_palette(&gb, &GB_PALETTE_MGB);
|
||||
break;
|
||||
|
||||
case 3:
|
||||
GB_set_palette(&gb, &GB_PALETTE_GBL);
|
||||
break;
|
||||
|
||||
default:
|
||||
GB_set_palette(&gb, &GB_PALETTE_GREY);
|
||||
}
|
||||
GB_set_palette(&gb, current_dmg_palette());
|
||||
}
|
||||
|
||||
static void screen_size_changed(void)
|
||||
|
@ -866,7 +851,7 @@ int main(int argc, char **argv)
|
|||
configuration.highpass_mode %= GB_HIGHPASS_MAX;
|
||||
configuration.model %= MODEL_MAX;
|
||||
configuration.sgb_revision %= SGB_MAX;
|
||||
configuration.dmg_palette %= 4;
|
||||
configuration.dmg_palette %= 5;
|
||||
if (configuration.dmg_palette) {
|
||||
configuration.gui_pallete_enabled = true;
|
||||
}
|
||||
|
@ -876,6 +861,7 @@ int main(int argc, char **argv)
|
|||
configuration.bootrom_path[sizeof(configuration.bootrom_path) - 1] = 0;
|
||||
configuration.cgb_revision %= GB_MODEL_CGB_E - GB_MODEL_CGB_0 + 1;
|
||||
configuration.audio_driver[15] = 0;
|
||||
configuration.dmg_palette_name[24] = 0;
|
||||
}
|
||||
|
||||
if (configuration.model >= MODEL_MAX) {
|
||||
|
|
|
@ -0,0 +1,51 @@
|
|||
#include <windows.h>
|
||||
#include <stdio.h>
|
||||
#include <winnls.h>
|
||||
#include <io.h>
|
||||
#include "dirent.h"
|
||||
|
||||
DIR *opendir(const char *filename)
|
||||
{
|
||||
wchar_t w_filename[MAX_PATH + 3] = {0,};
|
||||
unsigned length = MultiByteToWideChar(CP_UTF8, 0, filename, -1, w_filename, MAX_PATH);
|
||||
if (length) {
|
||||
w_filename[length - 1] = L'/';
|
||||
w_filename[length] = L'*';
|
||||
w_filename[length + 1] = 0;
|
||||
}
|
||||
DIR *ret = malloc(sizeof(*ret));
|
||||
ret->handle = FindFirstFileW(w_filename, &ret->entry);
|
||||
if (ret->handle == INVALID_HANDLE_VALUE) {
|
||||
free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int closedir(DIR *dir)
|
||||
{
|
||||
if (dir->handle != INVALID_HANDLE_VALUE) {
|
||||
FindClose(dir->handle);
|
||||
}
|
||||
free(dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct dirent *readdir(DIR *dir)
|
||||
{
|
||||
if (dir->handle == INVALID_HANDLE_VALUE) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
WideCharToMultiByte(CP_UTF8, 0, dir->entry.cFileName, -1,
|
||||
dir->out_entry.d_name, sizeof(dir->out_entry.d_name),
|
||||
NULL, NULL);
|
||||
|
||||
if (!FindNextFileW(dir->handle, &dir->entry)) {
|
||||
FindClose(dir->handle);
|
||||
dir->handle = INVALID_HANDLE_VALUE;
|
||||
}
|
||||
|
||||
return &dir->out_entry;
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
#include <windows.h>
|
||||
|
||||
struct dirent {
|
||||
char d_name[MAX_PATH + 1];
|
||||
};
|
||||
|
||||
typedef struct {
|
||||
HANDLE handle;
|
||||
WIN32_FIND_DATAW entry;
|
||||
struct dirent out_entry;
|
||||
} DIR;
|
||||
|
||||
DIR *opendir(const char *filename);
|
||||
int closedir(DIR *dir);
|
||||
struct dirent *readdir(DIR *dir);
|
Loading…
Reference in New Issue