Merge remote-tracking branch 'origin/master' into wasm

This commit is contained in:
Maximilian Mader 2019-06-22 18:50:48 +02:00
commit e2ce844d2b
Signed by: Max
GPG Key ID: F71D56A3151C4FB3
18 changed files with 103 additions and 71 deletions

View File

@ -1,6 +1,10 @@
#include <assert.h>
#include <inttypes.h>
#include <stdio.h>
#include <stdio.h>
#ifdef _WIN32
#include <io.h>
#include <fcntl.h>
#endif
void pair(size_t count, uint8_t byte)
{
@ -35,7 +39,12 @@ int main(int argc, char *argv[])
size_t count = 1;
uint8_t byte = getchar();
int new;
size_t position = 0;
size_t position = 0;
#ifdef _WIN32
_setmode(0,_O_BINARY);
_setmode(1,_O_BINARY);
#endif
while ((new = getchar()) != EOF) {
if (byte == new) {

View File

@ -397,8 +397,8 @@
<outlet property="delegate" destination="-2" id="EAG-Zh-oRi"/>
</connections>
</imageView>
<popUpButton focusRingType="none" verticalHuggingPriority="750" id="loB-0k-Qff">
<rect key="frame" x="4" y="387" width="128" height="18"/>
<popUpButton focusRingType="none" verticalHuggingPriority="750" misplaced="YES" id="loB-0k-Qff">
<rect key="frame" x="4" y="388" width="128" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundRect" title="Effective Palettes" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="oUH-Sa-Ec1" id="Eij-Cp-URa">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -430,8 +430,8 @@
<action selector="reloadVRAMData:" target="-2" id="BmB-JE-W8g"/>
</connections>
</popUpButton>
<popUpButton focusRingType="none" verticalHuggingPriority="750" id="YIJ-Qc-SIZ">
<rect key="frame" x="135" y="387" width="96" height="18"/>
<popUpButton focusRingType="none" verticalHuggingPriority="750" misplaced="YES" id="YIJ-Qc-SIZ">
<rect key="frame" x="135" y="388" width="96" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundRect" title="Effective Tilemap" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="XRF-Vj-3gs" id="3W1-Db-wDn">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>
@ -448,8 +448,8 @@
<action selector="reloadVRAMData:" target="-2" id="xwp-Ju-p00"/>
</connections>
</popUpButton>
<popUpButton focusRingType="none" verticalHuggingPriority="750" id="k4c-Vg-MBu">
<rect key="frame" x="235" y="387" width="96" height="18"/>
<popUpButton focusRingType="none" verticalHuggingPriority="750" misplaced="YES" id="k4c-Vg-MBu">
<rect key="frame" x="235" y="388" width="96" height="17"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMinY="YES"/>
<popUpButtonCell key="cell" type="roundRect" title="Effective Tileset" bezelStyle="roundedRect" alignment="left" controlSize="mini" lineBreakMode="truncatingTail" state="on" borderStyle="border" focusRingType="none" imageScaling="proportionallyDown" inset="2" selectedItem="CRe-dX-rzY" id="h53-sb-Odg">
<behavior key="behavior" pushIn="YES" lightByBackground="YES" lightByGray="YES"/>

View File

@ -148,11 +148,11 @@
- (void) flip
{
if (underclockKeyDown && clockMultiplier > 0.5) {
clockMultiplier -= 0.1;
clockMultiplier -= 1.0/16;
GB_set_clock_multiplier(_gb, clockMultiplier);
}
if (!underclockKeyDown && clockMultiplier < 1.0) {
clockMultiplier += 0.1;
clockMultiplier += 1.0/16;
GB_set_clock_multiplier(_gb, clockMultiplier);
}
current_buffer = (current_buffer + 1) % self.numberOfBuffers;

View File

@ -70,7 +70,7 @@
<key>LSMinimumSystemVersion</key>
<string>10.9</string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015-2018 Lior Halphon</string>
<string>Copyright © 2015-2019 Lior Halphon</string>
<key>NSMainNibFile</key>
<string>MainMenu</string>
<key>NSPrincipalClass</key>

View File

@ -30,7 +30,7 @@
<h1>SameBoy</h1>
<h2>MIT License</h2>
<h3>Copyright © 2015-2018 Lior Halphon</h3>
<h3>Copyright © 2015-2019 Lior Halphon</h3>
<p>Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -819,7 +819,7 @@ static bool registers(GB_gameboy_t *gb, char *arguments, char *modifiers, const
GB_log(gb, "AF = $%04x (%c%c%c%c)\n", gb->registers[GB_REGISTER_AF], /* AF can't really be an address */
(gb->f & GB_CARRY_FLAG)? 'C' : '-',
(gb->f & GB_HALF_CARRY_FLAG)? 'H' : '-',
(gb->f & GB_SUBSTRACT_FLAG)? 'S' : '-',
(gb->f & GB_SUBSTRACT_FLAG)? 'N' : '-',
(gb->f & GB_ZERO_FLAG)? 'Z' : '-');
GB_log(gb, "BC = %s\n", value_to_string(gb, gb->registers[GB_REGISTER_BC], false));
GB_log(gb, "DE = %s\n", value_to_string(gb, gb->registers[GB_REGISTER_DE], false));
@ -1766,16 +1766,16 @@ static const debugger_command_t commands[] = {
{"cartridge", 2, mbc, "Displays information about the MBC and cartridge"},
{"mbc", 3, }, /* Alias */
{"apu", 3, apu, "Displays information about the current state of the audio chip"},
{"wave", 3, wave, "Prints a visual representation of the wave RAM" HELP_NEWLINE
{"wave", 3, wave, "Prints a visual representation of the wave RAM." HELP_NEWLINE
"Modifiers can be used for a (f)ull print (the default)," HELP_NEWLINE
"a more (c)ompact one, or a one-(l)iner"},
"a more (c)ompact one, or a one-(l)iner", "", "(f|c|l)"},
{"lcd", 3, lcd, "Displays information about the current state of the LCD controller"},
{"palettes", 3, palettes, "Displays the current CGB palettes"},
{"breakpoint", 1, breakpoint, "Add a new breakpoint at the specified address/expression" HELP_NEWLINE
"Can also modify the condition of existing breakpoints." HELP_NEWLINE
"If the j modifier is used, the breakpoint will occur just before" HELP_NEWLINE
"jumping to the target.",
"<expression>[ if <condition expression>]", "(j)"},
"<expression>[ if <condition expression>]", "j"},
{"delete", 2, delete, "Delete a breakpoint by its address, or all breakpoints", "[<expression>]"},
{"watch", 1, watch, "Add a new watchpoint at the specified address/expression." HELP_NEWLINE
"Can also modify the condition and type of existing watchpoints." HELP_NEWLINE

View File

@ -751,7 +751,7 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
/* Todo: find out actual access time of SCX */
gb->position_in_line = - (gb->io_registers[GB_IO_SCX] & 7) - 8;
gb->current_lcd_line++; // Todo: unverified timing
if (gb->current_lcd_line == LINES) {
if (gb->current_lcd_line == LINES && GB_is_sgb(gb)) {
display_vblank(gb);
}
gb->fetcher_x = ((gb->io_registers[GB_IO_SCX]) / 8) & 0x1f;
@ -915,12 +915,16 @@ void GB_display_run(GB_gameboy_t *gb, uint8_t cycles)
GB_STAT_update(gb);
if (gb->frame_skip_state == GB_FRAMESKIP_LCD_TURNED_ON) {
display_vblank(gb);
if (!GB_is_sgb(gb) || gb->current_lcd_line < LINES) {
display_vblank(gb);
}
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;
}
else {
gb->frame_skip_state = GB_FRAMESKIP_SECOND_FRAME_RENDERED;
display_vblank(gb);
if (!GB_is_sgb(gb) || gb->current_lcd_line < LINES) {
display_vblank(gb);
}
}
}

View File

@ -896,3 +896,8 @@ void GB_set_update_input_hint_callback(GB_gameboy_t *gb, GB_update_input_hint_ca
{
gb->update_input_hint_callback = callback;
}
double GB_get_usual_frame_rate(GB_gameboy_t *gb)
{
return GB_get_clock_rate(gb) / (double)LCDC_PERIOD;
}

View File

@ -695,7 +695,7 @@ void GB_set_clock_multiplier(GB_gameboy_t *gb, double multiplier);
unsigned GB_get_screen_width(GB_gameboy_t *gb);
unsigned GB_get_screen_height(GB_gameboy_t *gb);
double GB_get_usual_frame_rate(GB_gameboy_t *gb);
unsigned GB_get_player_count(GB_gameboy_t *gb);
#endif /* GB_h */

View File

@ -294,6 +294,8 @@ static bool buffer_read_section(const uint8_t **buffer, size_t *buffer_length, v
return false;
}
if (saved_size > *buffer_length) return false;
if (saved_size <= size) {
if (buffer_read(dest, saved_size, buffer, buffer_length) != saved_size) {
return false;

View File

@ -466,7 +466,7 @@ static void render_jingle(GB_gameboy_t *gb, size_t count);
void GB_sgb_render(GB_gameboy_t *gb)
{
if (gb->apu_output.sample_rate) {
render_jingle(gb, gb->apu_output.sample_rate / (GB_get_clock_rate(gb) / LCDC_PERIOD));
render_jingle(gb, gb->apu_output.sample_rate / GB_get_usual_frame_rate(gb));
}
if (gb->sgb->intro_animation < INTRO_ANIMATION_LENGTH) gb->sgb->intro_animation++;

View File

@ -59,7 +59,7 @@ void GB_timing_sync(GB_gameboy_t *gb)
return;
}
/* Prevent syncing if not enough time has passed.*/
if (gb->cycles_since_last_sync < LCDC_PERIOD / 4) return;
if (gb->cycles_since_last_sync < LCDC_PERIOD / 3) return;
uint64_t target_nanoseconds = gb->cycles_since_last_sync * 1000000000LL / 2 / GB_get_clock_rate(gb); /* / 2 because we use 8MHz units */
int64_t nanoseconds = get_nanoseconds();

View File

@ -1,6 +1,6 @@
MIT License
Copyright (c) 2015-2018 Lior Halphon
Copyright (c) 2015-2019 Lior Halphon
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal

View File

@ -13,8 +13,11 @@ ifneq ($(findstring MSYS,$(PLATFORM)),)
PLATFORM := windows32
endif
LOGO_COMPRESS := build/logo-compress
ifeq ($(PLATFORM),windows32)
_ := $(shell chcp 65001)
LOGO_COMPRESS := build/logo-compress.exe
endif
ifeq ($(PLATFORM),Darwin)
@ -29,7 +32,7 @@ ifeq ($(MAKECMDGOALS),)
MAKECMDGOALS := $(DEFAULT)
endif
VERSION := 0.11.1
VERSION := 0.12.1
export VERSION
CONF ?= debug
@ -326,10 +329,10 @@ $(OBJ)/%.1bpp: %.png
-@$(MKDIR) -p $(dir $@)
rgbgfx -d 1 -h -o $@ $<
$(OBJ)/BootROMs/SameBoyLogo.rle: $(OBJ)/BootROMs/SameBoyLogo.1bpp build/logo-compress
build/logo-compress < $< > $@
$(OBJ)/BootROMs/SameBoyLogo.rle: $(OBJ)/BootROMs/SameBoyLogo.1bpp $(LOGO_COMPRESS)
$(realpath $(LOGO_COMPRESS)) < $< > $@
build/logo-compress: BootROMs/logo-compress.c
$(LOGO_COMPRESS): BootROMs/logo-compress.c
$(CC) $< -o $@
$(BIN)/BootROMs/agb_boot.bin: BootROMs/cgb_boot.asm

View File

@ -47,7 +47,7 @@
<key>CFPlugInUnloadFunction</key>
<string></string>
<key>NSHumanReadableCopyright</key>
<string>Copyright © 2015-2018 Lior Halphon</string>
<string>Copyright © 2015-2019 Lior Halphon</string>
<key>QLNeedsToBeRunInMainThread</key>
<false/>
<key>QLPreviewHeight</key>

View File

@ -883,6 +883,7 @@ void run_gui(bool is_running)
}
}
break;
case SDL_JOYBUTTONDOWN:
event.type = SDL_KEYDOWN;
joypad_button_t button = get_joypad_button(event.jbutton.button);

View File

@ -33,7 +33,6 @@ static double clock_mutliplier = 1.0;
static char *filename = NULL;
static typeof(free) *free_function = NULL;
static char *battery_save_path_ptr;
static bool skip_audio;
SDL_AudioDeviceID device_id;
@ -318,11 +317,11 @@ static void handle_events(GB_gameboy_t *gb)
static void vblank(GB_gameboy_t *gb)
{
if (underclock_down && clock_mutliplier > 0.5) {
clock_mutliplier -= 0.1;
clock_mutliplier -= 1.0/16;
GB_set_clock_multiplier(gb, clock_mutliplier);
}
else if (!underclock_down && clock_mutliplier < 1.0) {
clock_mutliplier += 0.1;
clock_mutliplier += 1.0/16;
GB_set_clock_multiplier(gb, clock_mutliplier);
}
if (configuration.blend_frames) {
@ -337,8 +336,6 @@ static void vblank(GB_gameboy_t *gb)
}
do_rewind = rewind_down;
handle_events(gb);
skip_audio = (SDL_GetQueuedAudioSize(device_id) / sizeof(GB_sample_t)) > have_aspec.freq / 20;
}
@ -360,7 +357,9 @@ static void debugger_interrupt(int ignore)
static void gb_audio_callback(GB_gameboy_t *gb, GB_sample_t *sample)
{
if (skip_audio) return;
if ((SDL_GetQueuedAudioSize(device_id) / sizeof(GB_sample_t)) > have_aspec.freq / 12) {
return;
}
SDL_QueueAudio(device_id, sample, sizeof(*sample));
}

View File

@ -14,8 +14,6 @@
#define AUDIO_FREQUENCY 48000
#endif
#define FRAME_RATE (0x400000 / 70224.0)
#ifdef _WIN32
#include <direct.h>
#include <windows.h>
@ -727,7 +725,7 @@ void retro_get_system_info(struct retro_system_info *info)
void retro_get_system_av_info(struct retro_system_av_info *info)
{
struct retro_game_geometry geom;
struct retro_system_timing timing = { FRAME_RATE, AUDIO_FREQUENCY };
struct retro_system_timing timing = { GB_get_usual_frame_rate(&gameboy[0]), AUDIO_FREQUENCY };
if (emulated_devices == 2)
{
@ -947,11 +945,11 @@ bool retro_load_game_special(unsigned type, const struct retro_game_info *info,
environ_cb(RETRO_ENVIRONMENT_SET_VARIABLES, (void *)vars_dual);
check_variables();
frame_buf = (uint32_t*)malloc(emulated_devices * VIDEO_PIXELS * sizeof(uint32_t));
frame_buf_copy = (uint32_t*)malloc(emulated_devices * VIDEO_PIXELS * sizeof(uint32_t));
frame_buf = (uint32_t*)malloc(emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
frame_buf_copy = (uint32_t*)malloc(emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
memset(frame_buf, 0, emulated_devices * VIDEO_PIXELS * sizeof(uint32_t));
memset(frame_buf_copy, 0, emulated_devices * VIDEO_PIXELS * sizeof(uint32_t));
memset(frame_buf, 0, emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
memset(frame_buf_copy, 0, emulated_devices * SGB_VIDEO_PIXELS * sizeof(uint32_t));
enum retro_pixel_format fmt = RETRO_PIXEL_FORMAT_XRGB8888;
if (!environ_cb(RETRO_ENVIRONMENT_SET_PIXEL_FORMAT, &fmt))
@ -987,54 +985,65 @@ bool retro_load_game_special(unsigned type, const struct retro_game_info *info,
size_t retro_serialize_size(void)
{
if (emulated_devices == 2)
return GB_get_save_state_size(&gameboy[0]) + GB_get_save_state_size(&gameboy[1]);
else
return GB_get_save_state_size(&gameboy[0]);
static size_t maximum_save_size = 0;
if (maximum_save_size) {
return maximum_save_size * 2;
}
GB_gameboy_t temp;
GB_init(&temp, GB_MODEL_DMG_B);
maximum_save_size = GB_get_save_state_size(&temp);
GB_free(&temp);
GB_init(&temp, GB_MODEL_CGB_E);
maximum_save_size = MAX(maximum_save_size, GB_get_save_state_size(&temp));
GB_free(&temp);
GB_init(&temp, GB_MODEL_SGB2);
maximum_save_size = MAX(maximum_save_size, GB_get_save_state_size(&temp));
GB_free(&temp);
return maximum_save_size * 2;
}
bool retro_serialize(void *data, size_t size)
{
if (!initialized)
if (!initialized || !data)
return false;
void* save_data[2];
size_t state_size[2];
size_t offset = 0;
for (int i = 0; i < emulated_devices; i++)
{
state_size[i] = GB_get_save_state_size(&gameboy[i]);
save_data[i] = (uint8_t*)malloc(state_size[i]);
GB_save_state_to_buffer(&gameboy[i], (uint8_t*) save_data[i]);
memcpy(data + offset, save_data[i], state_size[i]);
offset += state_size[i];
free(save_data[i]);
for (int i = 0; i < emulated_devices; i++) {
size_t state_size = GB_get_save_state_size(&gameboy[i]);
if (state_size > size) {
return false;
}
GB_save_state_to_buffer(&gameboy[i], ((uint8_t *) data) + offset);
offset += state_size;
size -= state_size;
}
if (data)
return true;
else
return false;
return true;
}
bool retro_unserialize(const void *data, size_t size)
{
void* save_data[2];
size_t state_size[2];
int ret;
for (int i = 0; i < emulated_devices; i++)
{
state_size[i] = GB_get_save_state_size(&gameboy[i]);
save_data[i] = (uint8_t*)malloc(state_size[i]);
memcpy (save_data[i], data + (state_size[i] * i), state_size[i]);
ret = GB_load_state_from_buffer(&gameboy[i], save_data[i], state_size[i]);
free(save_data[i]);
if (ret != 0)
size_t state_size = GB_get_save_state_size(&gameboy[i]);
if (state_size > size) {
return false;
}
if (GB_load_state_from_buffer(&gameboy[i], data, state_size)) {
return false;
}
size -= state_size;
data = ((uint8_t *)data) + state_size;
}
return true;