Continuing work to remove esp32-specific code from emulators

This commit is contained in:
Alex Duchesne 2020-11-17 14:51:04 -05:00
parent 887d6e7a80
commit fe2d42ed1a
40 changed files with 309 additions and 316 deletions

View File

@ -0,0 +1,55 @@
// Audio
#define ODROID_I2S_NUM (I2S_NUM_0)
#define ODROID_AUDIO_VOLUME_MIN 0
#define ODROID_AUDIO_VOLUME_MAX 9
#define ODROID_AUDIO_VOLUME_DEFAULT (ODROID_AUDIO_VOLUME_MAX/3)
// Video
#define ODROID_SCREEN_WIDTH 320
#define ODROID_SCREEN_HEIGHT 240
// Battery ADC
#define BATT_VOLTAGE_FULL (4.2f)
#define BATT_VOLTAGE_EMPTY (3.5f)
#define BATT_DIVIDER_R1 (10000)
#define BATT_DIVIDER_R2 (10000)
// GPIO Allocations
#define ODROID_PIN_LED GPIO_NUM_2
#define ODROID_PIN_DAC1 GPIO_NUM_25
#define ODROID_PIN_DAC2 GPIO_NUM_26
#define ODROID_PIN_I2S_DAC_BCK GPIO_NUM_4
#define ODROID_PIN_I2S_DAC_WS GPIO_NUM_12
#define ODROID_PIN_I2S_DAC_DATA GPIO_NUM_15
#define ODROID_PIN_GAMEPAD_X ADC1_CHANNEL_6
#define ODROID_PIN_GAMEPAD_Y ADC1_CHANNEL_7
#define ODROID_PIN_GAMEPAD_SELECT GPIO_NUM_27
#define ODROID_PIN_GAMEPAD_START GPIO_NUM_39
#define ODROID_PIN_GAMEPAD_A GPIO_NUM_32
#define ODROID_PIN_GAMEPAD_B GPIO_NUM_33
#define ODROID_PIN_GAMEPAD_MENU GPIO_NUM_13
#define ODROID_PIN_GAMEPAD_VOLUME GPIO_NUM_0
#define ODROID_PIN_SPI_MISO GPIO_NUM_19
#define ODROID_PIN_SPI_MOSI GPIO_NUM_23
#define ODROID_PIN_SPI_CLK GPIO_NUM_18
#define ODROID_PIN_LCD_MISO ODROID_PIN_SPI_MISO
#define ODROID_PIN_LCD_MOSI ODROID_PIN_SPI_MOSI
#define ODROID_PIN_LCD_CLK ODROID_PIN_SPI_CLK
#define ODROID_PIN_LCD_CS GPIO_NUM_5
#define ODROID_PIN_LCD_DC GPIO_NUM_21
#define ODROID_PIN_LCD_BCKL GPIO_NUM_14
#define ODROID_PIN_SD_MISO ODROID_PIN_SPI_MISO
#define ODROID_PIN_SD_MOSI ODROID_PIN_SPI_MOSI
#define ODROID_PIN_SD_CLK ODROID_PIN_SPI_CLK
#define ODROID_PIN_SD_CS GPIO_NUM_22
#define ODROID_PIN_NES_LATCH GPIO_NUM_15
#define ODROID_PIN_NES_CLOCK GPIO_NUM_12
#define ODROID_PIN_NES_DATA GPIO_NUM_4
// SD Card Paths
#define ODROID_BASE_PATH "/sd"
#define ODROID_BASE_PATH_ROMS ODROID_BASE_PATH "/roms"
#define ODROID_BASE_PATH_SAVES ODROID_BASE_PATH "/odroid/data"
#define ODROID_BASE_PATH_TEMP ODROID_BASE_PATH "/odroid/data" // temp
#define ODROID_BASE_PATH_ROMART ODROID_BASE_PATH "/romart"
#define ODROID_BASE_PATH_CRC_CACHE ODROID_BASE_PATH "/odroid/cache/crc"

View File

@ -7,8 +7,6 @@
#include "odroid_system.h"
#include "odroid_audio.h"
#define I2S_NUM (I2S_NUM_0)
static int audioSink = ODROID_AUDIO_SINK_SPEAKER;
static int audioSampleRate = 0;
static int audioFilter = 0;
@ -65,8 +63,8 @@ void odroid_audio_init(int sample_rate)
.use_apll = 0 //1
};
i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM, NULL);
i2s_driver_install(ODROID_I2S_NUM, &i2s_config, 0, NULL);
i2s_set_pin(ODROID_I2S_NUM, NULL);
}
else if (audioSink == ODROID_AUDIO_SINK_DAC)
{
@ -89,8 +87,8 @@ void odroid_audio_init(int sample_rate)
.data_in_num = -1 //Not used
};
i2s_driver_install(I2S_NUM, &i2s_config, 0, NULL);
i2s_set_pin(I2S_NUM, &pin_config);
i2s_driver_install(ODROID_I2S_NUM, &i2s_config, 0, NULL);
i2s_set_pin(ODROID_I2S_NUM, &pin_config);
// Disable internal amp
gpio_set_direction(ODROID_PIN_DAC1, GPIO_MODE_OUTPUT);
@ -104,15 +102,15 @@ void odroid_audio_init(int sample_rate)
odroid_audio_volume_set(volumeLevel);
printf("%s: I2S init done. clock=%f\n", __func__, i2s_get_clk(I2S_NUM));
printf("%s: I2S init done. clock=%f\n", __func__, i2s_get_clk(ODROID_I2S_NUM));
}
void odroid_audio_terminate()
{
if (audioInitialized)
{
i2s_zero_dma_buffer(I2S_NUM);
i2s_driver_uninstall(I2S_NUM);
i2s_zero_dma_buffer(ODROID_I2S_NUM);
i2s_driver_uninstall(ODROID_I2S_NUM);
audioInitialized = false;
}
@ -218,7 +216,7 @@ IRAM_ATTR void odroid_audio_submit(short* stereoAudioBuffer, int frameCount)
filter_samples(stereoAudioBuffer, bufferSize);
}
i2s_write(I2S_NUM, (const short *)stereoAudioBuffer, bufferSize, &written, 1000);
i2s_write(ODROID_I2S_NUM, (const short *)stereoAudioBuffer, bufferSize, &written, 1000);
if (written == 0) // Anything > 0 is fine
{
RG_PANIC("i2s_write failed.");
@ -258,6 +256,6 @@ void odroid_audio_mute(bool mute)
if (mute && audioInitialized)
{
i2s_zero_dma_buffer(I2S_NUM);
i2s_zero_dma_buffer(ODROID_I2S_NUM);
}
}

View File

@ -1,6 +1,6 @@
#pragma once
#include "stdbool.h"
#include <stdbool.h>
typedef enum
{
@ -16,10 +16,6 @@ typedef enum
ODROID_AUDIO_FILTER_WEIGHTED,
} ODROID_AUDIO_FILTER;
#define ODROID_AUDIO_VOLUME_MIN 0
#define ODROID_AUDIO_VOLUME_MAX 9 // (sizeof(volumeLevels) / sizeof(float) - 1)
#define ODROID_AUDIO_VOLUME_DEFAULT (ODROID_AUDIO_VOLUME_MAX/3)
int odroid_audio_volume_get();
void odroid_audio_volume_set(int levwl);
void odroid_audio_init(int sample_rate);

View File

@ -3,9 +3,6 @@
#include <stdint.h>
#include "odroid_colors.h"
#define ODROID_SCREEN_WIDTH 320
#define ODROID_SCREEN_HEIGHT 240
typedef enum {
SCREEN_UPDATE_EMPTY,
SCREEN_UPDATE_FULL,

View File

@ -9,11 +9,6 @@
#include "odroid_system.h"
#include "odroid_input.h"
#define BATT_VOLTAGE_FULL (4.2f)
#define BATT_VOLTAGE_EMPTY (3.5f)
#define BATT_DIVIDER_R1 (10000)
#define BATT_DIVIDER_R2 (10000)
static volatile bool input_task_is_running = false;
static volatile uint last_gamepad_read = 0;
static volatile uint use_external_gamepad = 0;

View File

@ -70,7 +70,7 @@ static void network_setup(tcpip_adapter_if_t tcpip_if)
local_player = &players[player_id];
local_player->id = player_id;
local_player->version = NETPLAY_VERSION;
local_player->game_id = odroid_system_get_game_id();
local_player->game_id = odroid_system_get_app()->gameId;
local_player->ip_addr = local_if.ip.addr;
printf("netplay: Local player ID: %d\n", local_player->id);

View File

@ -14,9 +14,6 @@ static uint16_t *overlay_buffer = NULL;
static short dialog_open_depth = 0;
static short font_size = 8;
// To do: move this out
int8_t speedupEnabled = 0;
void odroid_overlay_init()
{
overlay_buffer = (uint16_t *)rg_alloc(ODROID_SCREEN_WIDTH * 32 * 2, MEM_SLOW);
@ -441,7 +438,7 @@ static bool filter_update_cb(odroid_dialog_choice_t *option, odroid_dialog_event
odroid_display_set_filter_mode(mode);
}
if (mode == ODROID_DISPLAY_FILTER_OFF) strcpy(option->value, "Off ");
if (mode == ODROID_DISPLAY_FILTER_OFF) strcpy(option->value, "Off ");
if (mode == ODROID_DISPLAY_FILTER_LINEAR_X) strcpy(option->value, "Horiz");
if (mode == ODROID_DISPLAY_FILTER_LINEAR_Y) strcpy(option->value, "Vert ");
if (mode == ODROID_DISPLAY_FILTER_BILINEAR) strcpy(option->value, "Both ");
@ -462,7 +459,7 @@ static bool scaling_update_cb(odroid_dialog_choice_t *option, odroid_dialog_even
odroid_display_set_scaling_mode(mode);
}
if (mode == ODROID_DISPLAY_SCALING_OFF) strcpy(option->value, "Off ");
if (mode == ODROID_DISPLAY_SCALING_OFF) strcpy(option->value, "Off ");
if (mode == ODROID_DISPLAY_SCALING_FIT) strcpy(option->value, "Fit ");
if (mode == ODROID_DISPLAY_SCALING_FILL) strcpy(option->value, "Full ");
@ -471,10 +468,11 @@ static bool scaling_update_cb(odroid_dialog_choice_t *option, odroid_dialog_even
bool speedup_update_cb(odroid_dialog_choice_t *option, odroid_dialog_event_t event)
{
if (event == ODROID_DIALOG_PREV && --speedupEnabled < 0) speedupEnabled = 2;
if (event == ODROID_DIALOG_NEXT && ++speedupEnabled > 2) speedupEnabled = 0;
rg_app_desc_t *app = odroid_system_get_app();
if (event == ODROID_DIALOG_PREV && --app->speedupEnabled < 0) app->speedupEnabled = 2;
if (event == ODROID_DIALOG_NEXT && ++app->speedupEnabled > 2) app->speedupEnabled = 0;
sprintf(option->value, "%dx", speedupEnabled + 1);
sprintf(option->value, "%dx", app->speedupEnabled + 1);
return event == ODROID_DIALOG_ENTER;
}
@ -506,7 +504,7 @@ static void draw_game_status_bar(runtime_stats_t stats)
int pad_text = (height - odroid_overlay_get_font_size()) / 2;
char bottom[40], header[40];
const char *romPath = odroid_system_get_rom_path();
const char *romPath = odroid_system_get_app()->romPath;
snprintf(header, 40, "FPS: %.0f (%.0f) / BUSY: %.0f%%",
round(stats.totalFPS), round(stats.skippedFPS), round(stats.busyPercent));
@ -548,6 +546,22 @@ int odroid_overlay_game_settings_menu(odroid_dialog_choice_t *extra_options)
return r;
}
int odroid_overlay_game_debug_menu(void)
{
odroid_dialog_choice_t options[12] = {
{10, "Screen Res", "A", 1, NULL},
{10, "Game Res", "B", 1, NULL},
{10, "Scaled Res", "C", 1, NULL},
{10, "Cheats", "C", 1, NULL},
{10, "Rewind", "C", 1, NULL},
{10, "Registers", "C", 1, NULL},
ODROID_DIALOG_CHOICE_LAST
};
while (odroid_input_key_is_pressed(ODROID_INPUT_ANY));
return odroid_overlay_dialog("Debugging", options, 0);
}
int odroid_overlay_game_menu()
{
odroid_dialog_choice_t choices[] = {
@ -560,7 +574,8 @@ int odroid_overlay_game_menu()
#else
// {40, "Netplay", "", 0, NULL},
#endif
{50, "Quit", "", 1, NULL},
{50, "Tools", "", 1, NULL},
{100, "Quit", "", 1, NULL},
ODROID_DIALOG_CHOICE_LAST
};
@ -579,7 +594,8 @@ int odroid_overlay_game_menu()
case 20: odroid_system_emu_save_state(0); odroid_system_switch_app(0); break;
case 30: odroid_system_emu_load_state(0); break; // esp_restart();
case 40: odroid_netplay_quick_start(); break;
case 50: odroid_system_switch_app(0); break;
case 50: odroid_overlay_game_debug_menu(); break;
case 100: odroid_system_switch_app(0); break;
}
odroid_audio_mute(false);

View File

@ -54,5 +54,3 @@ bool odroid_overlay_dialog_is_open(void);
int odroid_overlay_settings_menu(odroid_dialog_choice_t *extra_options);
int odroid_overlay_game_settings_menu(odroid_dialog_choice_t *extra_options);
int odroid_overlay_game_menu();
extern int8_t speedupEnabled;

View File

@ -1,6 +1,6 @@
#pragma once
#include <stddef.h>
#include <stdint.h>
// All <int> functions return 0 on success, negative value on error.
// All <char*> functions return pointer on success, NULL on failure. Freeing required.
@ -16,4 +16,4 @@ int odroid_sdcard_unzip_file(const char* path, void* buf, size_t buf_size);
int odroid_sdcard_write_file(const char* path, void* buf, size_t buf_size);
int odroid_sdcard_get_filesize(const char* path);
const char* odroid_sdcard_get_filename(const char* path);
const char* odroid_sdcard_get_extension(const char* path);
const char* odroid_sdcard_get_extension(const char* path);

View File

@ -189,14 +189,14 @@ void odroid_settings_int32_set(const char *key, int32_t value)
int32_t odroid_settings_app_int32_get(const char *key, int32_t default_value)
{
char app_key[16];
sprintf(app_key, "%.12s.%d", key, odroid_system_get_app_id());
sprintf(app_key, "%.12s.%d", key, odroid_system_get_app()->id);
return odroid_settings_int32_get(app_key, default_value);
}
void odroid_settings_app_int32_set(const char *key, int32_t value)
{
char app_key[16];
sprintf(app_key, "%.12s.%d", key, odroid_system_get_app_id());
sprintf(app_key, "%.12s.%d", key, odroid_system_get_app()->id);
odroid_settings_int32_set(app_key, value);
}

View File

@ -19,13 +19,7 @@
// panic. We don't use this region so we can point anywhere in it.
static panic_trace_t *panicTrace = (void *)0x50001000;
static uint applicationId = 0;
static uint gameId = 0;
static uint startAction = 0;
static char *romPath = NULL;
static state_handler_t loadState;
static state_handler_t saveState;
static rg_app_desc_t currentApp;
static SemaphoreHandle_t spiMutex;
static spi_lock_res_t spiMutexOwner;
static runtime_stats_t statistics;
@ -64,9 +58,11 @@ void odroid_system_init(int appId, int sampleRate)
printf("%s: %d KB free\n", __func__, esp_get_free_heap_size() / 1024);
memset(&currentApp, 0, sizeof(currentApp));
spiMutex = xSemaphoreCreateMutex();
spiMutexOwner = -1;
applicationId = appId;
currentApp.id = appId;
// sdcard init must be before odroid_display_init()
// and odroid_settings_init() if JSON is used
@ -140,62 +136,42 @@ void odroid_system_emu_init(state_handler_t load, state_handler_t save, netplay_
odroid_system_set_boot_app(0);
}
startAction = odroid_settings_StartAction_get();
if (startAction == ODROID_START_ACTION_NEWGAME)
currentApp.startAction = odroid_settings_StartAction_get();
if (currentApp.startAction == ODROID_START_ACTION_NEWGAME)
{
odroid_settings_StartAction_set(ODROID_START_ACTION_RESUME);
odroid_settings_commit();
}
romPath = odroid_settings_RomFilePath_get();
if (!romPath || strlen(romPath) < 4)
currentApp.romPath = odroid_settings_RomFilePath_get();
if (!currentApp.romPath || strlen(currentApp.romPath) < 4)
{
RG_PANIC("Invalid ROM Path!");
}
printf("%s: romPath='%s'\n", __func__, romPath);
printf("%s: romPath='%s'\n", __func__, currentApp.romPath);
// Read some of the ROM to derive a unique id
if (odroid_sdcard_read_file(romPath, buffer, sizeof(buffer)) < 0)
if (odroid_sdcard_read_file(currentApp.romPath, buffer, sizeof(buffer)) < 0)
{
RG_PANIC("ROM File not found!");
}
gameId = crc32_le(0, buffer, sizeof(buffer));
loadState = load;
saveState = save;
currentApp.gameId = crc32_le(0, buffer, sizeof(buffer));
currentApp.loadState = load;
currentApp.saveState = save;
printf("%s: Init done. GameId=%08X\n", __func__, gameId);
printf("%s: Init done. GameId=%08X\n", __func__, currentApp.gameId);
}
void odroid_system_set_app_id(int _appId)
rg_app_desc_t *odroid_system_get_app()
{
applicationId = _appId;
}
uint odroid_system_get_app_id()
{
return applicationId;
}
uint odroid_system_get_game_id()
{
return gameId;
}
uint odroid_system_get_start_action()
{
return startAction;
}
const char* odroid_system_get_rom_path()
{
return romPath;
return &currentApp;
}
char* odroid_system_get_path(emu_path_type_t type, const char *_romPath)
{
const char *fileName = _romPath ?: romPath;
const char *fileName = _romPath ?: currentApp.romPath;
char buffer[256];
if (strstr(fileName, ODROID_BASE_PATH_ROMS))
@ -256,7 +232,7 @@ char* odroid_system_get_path(emu_path_type_t type, const char *_romPath)
bool odroid_system_emu_load_state(int slot)
{
if (!romPath || !loadState)
if (!currentApp.romPath || !currentApp.loadState)
{
printf("%s: No game/emulator loaded...\n", __func__);
return false;
@ -267,8 +243,8 @@ bool odroid_system_emu_load_state(int slot)
odroid_display_show_hourglass();
odroid_system_spi_lock_acquire(SPI_LOCK_SDCARD);
char *pathName = odroid_system_get_path(ODROID_PATH_SAVE_STATE, romPath);
bool success = (*loadState)(pathName);
char *pathName = odroid_system_get_path(ODROID_PATH_SAVE_STATE, currentApp.romPath);
bool success = (*currentApp.loadState)(pathName);
odroid_system_spi_lock_release(SPI_LOCK_SDCARD);
@ -284,7 +260,7 @@ bool odroid_system_emu_load_state(int slot)
bool odroid_system_emu_save_state(int slot)
{
if (!romPath || !saveState)
if (!currentApp.romPath || !currentApp.saveState)
{
printf("%s: No game/emulator loaded...\n", __func__);
return false;
@ -296,13 +272,13 @@ bool odroid_system_emu_save_state(int slot)
odroid_display_show_hourglass();
odroid_system_spi_lock_acquire(SPI_LOCK_SDCARD);
char *saveName = odroid_system_get_path(ODROID_PATH_SAVE_STATE, romPath);
char *backName = odroid_system_get_path(ODROID_PATH_SAVE_BACK, romPath);
char *tempName = odroid_system_get_path(ODROID_PATH_TEMP_FILE, romPath);
char *saveName = odroid_system_get_path(ODROID_PATH_SAVE_STATE, currentApp.romPath);
char *backName = odroid_system_get_path(ODROID_PATH_SAVE_BACK, currentApp.romPath);
char *tempName = odroid_system_get_path(ODROID_PATH_TEMP_FILE, currentApp.romPath);
bool success = false;
if ((*saveState)(tempName))
if ((*currentApp.saveState)(tempName))
{
rename(saveName, backName);

View File

@ -11,6 +11,8 @@
#include <rom/crc.h>
#endif
#include "config.h"
#include "odroid_audio.h"
#include "odroid_display.h"
#include "odroid_input.h"
@ -20,56 +22,18 @@
#include "odroid_sdcard.h"
#include "odroid_settings.h"
// GPIO Allocations
#define ODROID_PIN_LED GPIO_NUM_2
#define ODROID_PIN_DAC1 GPIO_NUM_25
#define ODROID_PIN_DAC2 GPIO_NUM_26
#define ODROID_PIN_I2S_DAC_BCK GPIO_NUM_4
#define ODROID_PIN_I2S_DAC_WS GPIO_NUM_12
#define ODROID_PIN_I2S_DAC_DATA GPIO_NUM_15
#define ODROID_PIN_GAMEPAD_X ADC1_CHANNEL_6
#define ODROID_PIN_GAMEPAD_Y ADC1_CHANNEL_7
#define ODROID_PIN_GAMEPAD_SELECT GPIO_NUM_27
#define ODROID_PIN_GAMEPAD_START GPIO_NUM_39
#define ODROID_PIN_GAMEPAD_A GPIO_NUM_32
#define ODROID_PIN_GAMEPAD_B GPIO_NUM_33
#define ODROID_PIN_GAMEPAD_MENU GPIO_NUM_13
#define ODROID_PIN_GAMEPAD_VOLUME GPIO_NUM_0
#define ODROID_PIN_SPI_MISO GPIO_NUM_19
#define ODROID_PIN_SPI_MOSI GPIO_NUM_23
#define ODROID_PIN_SPI_CLK GPIO_NUM_18
#define ODROID_PIN_LCD_MISO ODROID_PIN_SPI_MISO
#define ODROID_PIN_LCD_MOSI ODROID_PIN_SPI_MOSI
#define ODROID_PIN_LCD_CLK ODROID_PIN_SPI_CLK
#define ODROID_PIN_LCD_CS GPIO_NUM_5
#define ODROID_PIN_LCD_DC GPIO_NUM_21
#define ODROID_PIN_LCD_BCKL GPIO_NUM_14
#define ODROID_PIN_SD_MISO ODROID_PIN_SPI_MISO
#define ODROID_PIN_SD_MOSI ODROID_PIN_SPI_MOSI
#define ODROID_PIN_SD_CLK ODROID_PIN_SPI_CLK
#define ODROID_PIN_SD_CS GPIO_NUM_22
#define ODROID_PIN_NES_LATCH GPIO_NUM_15
#define ODROID_PIN_NES_CLOCK GPIO_NUM_12
#define ODROID_PIN_NES_DATA GPIO_NUM_4
// SD Card Paths
#define ODROID_BASE_PATH "/sd"
#define ODROID_BASE_PATH_ROMS ODROID_BASE_PATH "/roms"
#define ODROID_BASE_PATH_SAVES ODROID_BASE_PATH "/odroid/data"
#define ODROID_BASE_PATH_TEMP ODROID_BASE_PATH "/odroid/data" // temp
#define ODROID_BASE_PATH_ROMART ODROID_BASE_PATH "/romart"
#define ODROID_BASE_PATH_CRC_CACHE ODROID_BASE_PATH "/odroid/cache/crc"
typedef bool (*state_handler_t)(char *pathName);
typedef struct
{
char *romPath;
char *startAction;
int8_t speedup;
state_handler_t load;
state_handler_t save;
} emu_state_t;
uint32_t id;
uint32_t gameId;
const char *romPath;
state_handler_t loadState;
state_handler_t saveState;
int32_t speedupEnabled;
int32_t startAction;
} rg_app_desc_t;
typedef enum
{
@ -138,16 +102,11 @@ typedef struct
#define PANIC_TRACE_MAGIC 0x12345678
void odroid_system_init(int app_id, int sampleRate);
char* odroid_system_get_path(emu_path_type_t type, const char *romPath);
void odroid_system_emu_init(state_handler_t load, state_handler_t save, netplay_callback_t netplay_cb);
bool odroid_system_emu_save_state(int slot);
bool odroid_system_emu_load_state(int slot);
void odroid_system_init(int app_id, int sampleRate);
uint odroid_system_get_app_id();
void odroid_system_set_app_id(int appId);
uint odroid_system_get_game_id();
uint odroid_system_get_start_action();
const char* odroid_system_get_rom_path();
char* odroid_system_get_path(emu_path_type_t type, const char *romPath);
void odroid_system_panic_dialog(const char *reason);
void odroid_system_panic(const char *reason, const char *file, const char *function) __attribute__((noreturn));
void odroid_system_halt() __attribute__((noreturn));
@ -157,6 +116,7 @@ void odroid_system_reload_app() __attribute__((noreturn));
void odroid_system_set_boot_app(int slot);
void odroid_system_set_led(int value);
void odroid_system_tick(uint skippedFrame, uint fullFrame, uint busyTime);
rg_app_desc_t* odroid_system_get_app();
runtime_stats_t odroid_system_get_stats();
void odroid_system_spi_lock_acquire(spi_lock_res_t);

View File

@ -4,7 +4,6 @@
*/
#include "defs.h"
#include <esp_attr.h>
static DRAM_ATTR const byte cycles_table[256] =
{

View File

@ -25,6 +25,7 @@ typedef word addr;
#include <stdlib.h>
#include <stdarg.h>
#include <malloc.h>
#include <esp_attr.h>
#include <math.h>
/* Implemented by the port */

View File

@ -9,8 +9,6 @@
#include "lcd.h"
#include "rtc.h"
#include "esp_attr.h"
void emu_init()
{

View File

@ -7,7 +7,6 @@
#include "lcd.h"
#include "mem.h"
#include "esp_attr.h"
struct hw hw;

View File

@ -1,7 +1,6 @@
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <esp_attr.h>
#include "defs.h"
#include "regs.h"

View File

@ -1,5 +1,4 @@
#include "stdlib.h"
#include "esp_attr.h"
#include "defs.h"
#include "hw.h"

View File

@ -3,7 +3,6 @@
#include "defs.h"
#include <esp_attr.h>
/*DRAM_ATTR*/ static const byte noise7[] =
{

View File

@ -7,8 +7,6 @@
#include "regs.h"
#include "noise.h"
#include <esp_attr.h>
static const byte dmgwave[16] =
{
0xac, 0xdd, 0xda, 0x48,

View File

@ -1,6 +1,3 @@
#include <freertos/FreeRTOS.h>
#include <esp_system.h>
#include <esp_task_wdt.h>
#include <odroid_system.h>
#include <string.h>
@ -220,11 +217,13 @@ void app_main(void)
pcm.buf = (n16*)&audioBuffer;
pcm.pos = 0;
rg_app_desc_t *app = odroid_system_get_app();
emu_init();
pal_set_dmg(odroid_settings_Palette_get());
if (odroid_system_get_start_action() == ODROID_START_ACTION_RESUME)
if (app->startAction == ODROID_START_ACTION_RESUME)
{
odroid_system_emu_load_state(0);
}
@ -284,7 +283,7 @@ void app_main(void)
if (skipFrames == 0)
{
if (get_elapsed_time_since(startTime) > frameTime) skipFrames = 1;
if (speedupEnabled) skipFrames += speedupEnabled * 2;
if (app->speedupEnabled) skipFrames += app->speedupEnabled * 2;
}
else if (skipFrames > 0)
{
@ -294,7 +293,7 @@ void app_main(void)
// Tick before submitting audio/syncing
odroid_system_tick(!drawFrame, fullFrame, get_elapsed_time_since(startTime));
if (!speedupEnabled)
if (!app->speedupEnabled)
{
odroid_audio_submit(pcm.buf, pcm.pos >> 1);
}

View File

@ -161,16 +161,16 @@ extern "C" void app_main(void)
update1.buffer = (void*)rg_alloc(update1.stride * update1.height, MEM_FAST);
update2.buffer = (void*)rg_alloc(update2.stride * update2.height, MEM_FAST);
const char *romFile = odroid_system_get_rom_path();
rg_app_desc_t *app = odroid_system_get_app();
// Init emulator
lynx = new CSystem(romFile, MIKIE_PIXEL_FORMAT_16BPP_565_BE, AUDIO_SAMPLE_RATE);
lynx = new CSystem(app->romPath, MIKIE_PIXEL_FORMAT_16BPP_565_BE, AUDIO_SAMPLE_RATE);
gPrimaryFrameBuffer = (UBYTE*)currentUpdate->buffer;
gAudioBuffer = (SWORD*)&audioBuffer;
gAudioEnabled = 1;
if (odroid_system_get_start_action() == ODROID_START_ACTION_RESUME)
if (app->startAction == ODROID_START_ACTION_RESUME)
{
odroid_system_emu_load_state(0);
}
@ -230,7 +230,7 @@ extern "C" void app_main(void)
{
// The Lynx uses a variable framerate so we use the count of generated audio samples as reference instead
if (get_elapsed_time_since(startTime) > ((gAudioBufferPointer/2) * sampleTime)) skipFrames += 1;
if (speedupEnabled) skipFrames += speedupEnabled * 2.5;
if (app->speedupEnabled) skipFrames += app->speedupEnabled * 2.5;
}
else if (skipFrames > 0)
{
@ -239,7 +239,7 @@ extern "C" void app_main(void)
odroid_system_tick(!drawFrame, fullFrame, get_elapsed_time_since(startTime));
if (!speedupEnabled)
if (!app->speedupEnabled)
{
odroid_audio_submit(gAudioBuffer, gAudioBufferPointer >> 1);
gAudioBufferPointer = 0;

View File

@ -8,6 +8,9 @@ static bool sprite_usespbg = 0;
static int display_counter = 0;
static int last_display_counter = 0;
// Active screen buffer
static uint8_t* screen_buffer;
// Sprite priority mask memory
static uint8_t *SPM, *SPM_ptr;
@ -108,7 +111,7 @@ FAST_INLINE void
draw_sprite(int offset, uint16_t *C, uint32_t *C2, uint8_t *PAL, int h, int inc,
uint8_t pr, bool hflip, bool update_mask)
{
uint8_t *P = osd_gfx_buffer + offset;
uint8_t *P = screen_buffer + offset;
uint8_t *M = SPM + offset;
for (int i = 0; i < h; i++, C = (uint16_t*)((uint8_t*)C + inc),
@ -239,7 +242,7 @@ draw_tiles(int Y1, int Y2)
h = Y2 - Y1;
y >>= 3;
PP = (osd_gfx_buffer + XBUF_WIDTH * Y1) - (ScrollX & 7);
PP = (screen_buffer + XBUF_WIDTH * Y1) - (ScrollX & 7);
XW = io.screen_w / 8 + 1;
for (int Line = Y1; Line < Y2; y++) {
@ -490,23 +493,20 @@ gfx_load_context(int slot_number)
FAST_INLINE void
render_lines(int min_line, int max_line)
{
if (osd_skipFrames == 0) // Check for frameskip
{
gfx_save_context(1);
gfx_load_context(0);
gfx_save_context(1);
gfx_load_context(0);
sprite_usespbg = 0;
sprite_usespbg = 0;
if (SpriteON)
draw_sprites(min_line, max_line, false); // max_line + 1
if (SpriteON)
draw_sprites(min_line, max_line, false); // max_line + 1
draw_tiles(min_line, max_line); // max_line + 1
draw_tiles(min_line, max_line); // max_line + 1
if (SpriteON)
draw_sprites(min_line, max_line, true); // max_line + 1
if (SpriteON)
draw_sprites(min_line, max_line, true); // max_line + 1
gfx_load_context(1);
}
gfx_load_context(1);
gfx_need_redraw = 0;
}
@ -519,18 +519,12 @@ gfx_init(void)
OBJ_CACHE = osd_alloc(0x10000);
SPM_ptr = osd_alloc(XBUF_WIDTH * XBUF_HEIGHT);
SPM = SPM_ptr + XBUF_WIDTH * 64 + 32;
SPM = SPM_ptr + XBUF_WIDTH * 16 + 32;
gfx_clear_cache();
osd_gfx_init();
// Build palette
for (int i = 0; i < 255; i++) {
osd_gfx_set_color(i, (i & 0x1C) << 1, (i & 0xe0) >> 2, (i & 0x03) << 4);
}
osd_gfx_set_color(255, 0x3f, 0x3f, 0x3f);
return 0;
}
@ -593,6 +587,8 @@ gfx_irq(int type)
void
gfx_run(void)
{
screen_buffer = osd_gfx_framebuffer();
/* DMA Transfer in "progress" */
if (io.vdc_satb_counter > 0) {
if (--io.vdc_satb_counter == 0) {
@ -628,7 +624,11 @@ gfx_run(void)
if (Scanline >= io.vdc_minline && Scanline <= io.vdc_maxline) {
if (gfx_need_redraw) {
render_lines(last_display_counter, display_counter);
if (screen_buffer) {
render_lines(last_display_counter, display_counter);
} else {
gfx_need_redraw = 0;
}
last_display_counter = display_counter;
}
display_counter++;
@ -647,7 +647,11 @@ gfx_run(void)
gfx_save_context(0);
render_lines(last_display_counter, display_counter);
if (screen_buffer) {
render_lines(last_display_counter, display_counter);
} else {
gfx_need_redraw = 0;
}
/* VRAM to SATB DMA */
if (io.vdc_satb == 1 || IO_VDC_REG[DCR].W & 0x0010) {

View File

@ -42,13 +42,6 @@ typedef struct {
short control;
} gfx_context_t;
enum {
OBJ_INVALID = 0,
OBJ_VALID_TILE = 1,
OBJ_VALID_SPRITE = 2,
};
// extern bool OBJ_CACHE_STATUS[512];
extern bool TILE_CACHE[2048];
extern bool SPR_CACHE[512];
@ -57,11 +50,11 @@ extern int ScrollYDiff;
#define V_FLIP 0x8000
#define H_FLIP 0x0800
// The extra 32's and 64's are linked to the way the sprite are blitted on screen, which can overlap to near memory
// The extra 32's are linked to the way the sprite are drawn on screen, which can overlap to near memory
// If only one pixel is drawn in the screen, the whole sprite is written, which can eventually overlap unexpected area
// This could be fixed at the cost of performance but we don't need the extra memory
#define XBUF_WIDTH (512 + 32 + 32) // Most games only need 360 but as of rg 1.20 we have memory to spare
#define XBUF_HEIGHT (242 + 64 + 64)
#define XBUF_WIDTH (480 + 32)
#define XBUF_HEIGHT (242 + 32)
int gfx_init(void);
void gfx_run(void);

View File

@ -120,7 +120,7 @@ pce_run(void)
}
osd_gfx_blit();
osd_wait_next_vsync();
osd_vsync();
}
}

View File

@ -1,36 +1,9 @@
#ifndef _INCLUDE_OSD_H
#define _INCLUDE_OSD_H
// osd.h - This header contains all functions that a port should implement
//
#pragma once
#include "pce.h"
/* This header include all functionalities needed to be implemented in order
* to make a port of Hu-Go! on various platforms
*/
/*
* Gfx section
*
* Certainly one of the most important one, this one deals with all what can
* be displayed.
*/
extern uint8_t *osd_gfx_buffer;
extern uint osd_blitFrames;
extern uint osd_fullFrames;
extern uint osd_skipFrames;
extern void osd_gfx_init(void);
extern void osd_gfx_shutdown(void);
extern void osd_gfx_blit(void);
extern void osd_gfx_set_mode(int width, int height);
extern void osd_gfx_set_color(int index, uint8_t r, uint8_t g, uint8_t b);
/*
* Input section
*
* This one function part implements the input functionality
*/
#define JOY_A 0x01
#define JOY_B 0x02
#define JOY_SELECT 0x04
@ -40,47 +13,73 @@ extern void osd_gfx_set_color(int index, uint8_t r, uint8_t g, uint8_t b);
#define JOY_DOWN 0x40
#define JOY_LEFT 0x80
/*!
/**
* Init graphics (allocate buffers, etc)
*/
extern void osd_gfx_init(void);
/**
* Shutdown graphics
*/
extern void osd_gfx_shutdown(void);
/**
* Blit framebuffer to screen
*/
extern void osd_gfx_blit(void);
/**
* Return active framebuffer to draw to
* or NULL if we can't draw (frameskip, etc)
*/
extern uint8_t *osd_gfx_framebuffer(void);
/**
* Change video resolution
*/
extern void osd_gfx_set_mode(int width, int height);
/**
* Init input devices
*/
extern int osd_input_init(void);
/**
* Shutdown input
*/
extern void osd_input_shutdown(void);
/**
* Read input devices (uses a bitmask of JOY_*)
* It also handles quit/menu/etc.
*/
extern void osd_input_read(void);
/*!
* Initialize the input services
*/
extern int osd_input_init(void);
/*!
* Shutdown input services
*/
extern void osd_shutdown_input(void);
/*!
* Netplay
/**
* Init Netplay
*/
extern int osd_netplay_init(void);
/**
* Shutdown Netplay
*/
extern void osd_netplay_shutdown(void);
/*
* Sound section
* The osd is responsible for calling snd_update() once per frame
/**
* Init sound
*/
extern void osd_snd_init();
extern void osd_snd_shutdown();
/*
* Miscellaneous section
/**
* Shutdown sound
*/
extern void osd_snd_shutdown();
/*
* Emulation speed throttling. It will sleep or skip frames in order to
* maintain full speed emulation.
* maintain full speed emulation. It needs to be netplay-aware as well.
*/
extern void osd_wait_next_vsync(void);
extern void osd_vsync(void);
/*
* Logging function, printf-style arguments
@ -91,6 +90,3 @@ extern void osd_log(const char *, ...);
* Malloc function
*/
extern void* osd_alloc(size_t size);
#endif

View File

@ -24,6 +24,7 @@
static uint16_t mypalette[256];
static uint8_t *framebuffers[2];
static uint8_t *screen_buffers[2];
static odroid_video_frame_t frames[2];
static odroid_video_frame_t *curFrame, *prevFrame;
static uint8_t current_fb = 0;
@ -31,34 +32,59 @@ static bool gfx_init_done = false;
static bool overscan = false;
static int current_height, current_width;
uint8_t* osd_gfx_buffer = NULL;
uint osd_skipFrames = 0;
uint osd_blitFrames = 0;
uint osd_fullFrames = 0;
static uint skipFrames = 0;
static uint blitFrames = 0;
static uint fullFrames = 0;
#define COLOR_RGB(r,g,b) ( (((r)<<12)&0xf800) + (((g)<<7)&0x07e0) + (((b)<<1)&0x001f) )
// We center the content vertically and horizontally to allow overflows all around
#define FB_INTERNAL_OFFSET (((XBUF_HEIGHT - current_height) / 2 + 16) * XBUF_WIDTH + (XBUF_WIDTH - current_width) / 2)
// #define USE_PARTIAL_FRAMES
static inline void set_current_fb(int i)
{
current_fb = i & 1;
osd_gfx_buffer = framebuffers[current_fb];
prevFrame = curFrame;
curFrame = &frames[current_fb];
}
static inline void set_color(int index, uint8_t r, uint8_t g, uint8_t b)
{
uint16_t col = 0xffff;
if (index != 255)
{
col = COLOR_RGB(r >> 2, g >> 2, b >> 2);
col = (col << 8) | (col >> 8);
}
mypalette[index] = col;
}
uint8_t *osd_gfx_framebuffer(void)
{
if (skipFrames == 0) {
return framebuffers[current_fb] + FB_INTERNAL_OFFSET;
}
return NULL;
}
void osd_gfx_init(void)
{
framebuffers[0] = rg_alloc(XBUF_WIDTH * XBUF_HEIGHT, MEM_SLOW);
framebuffers[1] = rg_alloc(XBUF_WIDTH * XBUF_HEIGHT, MEM_SLOW);
// We never de-allocate them, so we don't care about the malloc pointer
framebuffers[0] += XBUF_WIDTH * 64 + 32;
framebuffers[1] += XBUF_WIDTH * 64 + 32;
overscan = odroid_settings_DisplayOverscan_get();
// Build palette
for (int i = 0; i < 255; i++) {
set_color(i, (i & 0x1C) << 1, (i & 0xe0) >> 2, (i & 0x03) << 4);
}
set_color(255, 0x3f, 0x3f, 0x3f);
}
@ -71,6 +97,7 @@ void osd_gfx_set_mode(int width, int height)
int crop_h = MAX(0, width - ODROID_SCREEN_WIDTH);
int crop_v = MAX(0, height - ODROID_SCREEN_HEIGHT) + (overscan ? 6 : 0);
int crop_offset = (crop_v / 2) * XBUF_WIDTH + (crop_h / 2);
printf("%s: Cropping H: %d V: %d\n", __func__, crop_h, crop_v);
@ -83,8 +110,8 @@ void osd_gfx_set_mode(int width, int height)
frames[0].palette = mypalette;
frames[1] = frames[0];
frames[0].buffer = framebuffers[0] + (crop_v / 2) * XBUF_WIDTH + (crop_h / 2);
frames[1].buffer = framebuffers[1] + (crop_v / 2) * XBUF_WIDTH + (crop_h / 2);
frames[0].buffer = framebuffers[0] + FB_INTERNAL_OFFSET + crop_offset;
frames[1].buffer = framebuffers[1] + FB_INTERNAL_OFFSET + crop_offset;
set_current_fb(0);
@ -97,7 +124,7 @@ void osd_gfx_blit(void)
{
if (!gfx_init_done) return;
bool drawFrame = !osd_skipFrames;
bool drawFrame = !skipFrames;
if (drawFrame)
{
@ -106,23 +133,24 @@ void osd_gfx_blit(void)
prevFrame = NULL;
#endif
if (odroid_display_queue_update(curFrame, prevFrame) == SCREEN_UPDATE_FULL) {
osd_fullFrames++;
fullFrames++;
}
set_current_fb(!current_fb);
osd_blitFrames++;
blitFrames++;
}
// See if we need to skip a frame to keep up
if (osd_skipFrames == 0)
if (skipFrames == 0)
{
rg_app_desc_t *app = odroid_system_get_app();
#ifndef USE_PARTIAL_FRAMES
osd_skipFrames++;
skipFrames++;
#endif
if (speedupEnabled) osd_skipFrames += speedupEnabled * 2.5;
if (app->speedupEnabled) skipFrames += app->speedupEnabled * 2.5;
}
else if (osd_skipFrames > 0)
else if (skipFrames > 0)
{
osd_skipFrames--;
skipFrames--;
}
}
@ -133,18 +161,6 @@ void osd_gfx_shutdown(void)
}
void osd_gfx_set_color(int index, uint8_t r, uint8_t g, uint8_t b)
{
uint16_t col = 0xffff;
if (index != 255)
{
col = COLOR_RGB(r >> 2, g >> 2, b >> 2);
col = (col << 8) | (col >> 8);
}
mypalette[index] = col;
}
/**
* Keyboard
*/
@ -262,7 +278,7 @@ void osd_log(const char *format, ...)
}
void osd_wait_next_vsync(void)
void osd_vsync(void)
{
const double deltatime = (1000000.0 / 60.0);
static double lasttime, curtime, prevtime, sleep;
@ -282,12 +298,12 @@ void osd_wait_next_vsync(void)
}
else if (sleep < -8333.0)
{
osd_skipFrames++;
skipFrames++;
}
odroid_system_tick(!osd_blitFrames, osd_fullFrames, (uint)(curtime - prevtime));
osd_blitFrames = 0;
osd_fullFrames = 0;
odroid_system_tick(!blitFrames, fullFrames, (uint)(curtime - prevtime));
blitFrames = 0;
fullFrames = 0;
gettimeofday(&tp, NULL);
curtime = prevtime = tp.tv_sec * 1000000.0 + tp.tv_usec;

View File

@ -36,11 +36,11 @@ void app_main(void)
odroid_system_init(APP_ID, AUDIO_SAMPLE_RATE);
odroid_system_emu_init(&load_state, &save_state, NULL);
const char *romPath = odroid_system_get_rom_path();
rg_app_desc_t *app = odroid_system_get_app();
InitPCE(romPath);
InitPCE(app->romPath);
if (odroid_system_get_start_action() == ODROID_START_ACTION_RESUME)
if (app->startAction == ODROID_START_ACTION_RESUME)
{
odroid_system_emu_load_state(0);
}

View File

@ -24,7 +24,6 @@
*/
#include <nofrendo.h>
#include <esp_attr.h>
#include <string.h>
#include "nes6502.h"
#include "dis6502.h"

View File

@ -27,7 +27,6 @@
#include <nes6502.h>
#include "nes_apu.h"
#include <esp_attr.h>
#include <string.h>
#define APU_OVERSAMPLE

View File

@ -24,7 +24,6 @@
*/
#include <nofrendo.h>
#include <esp_attr.h>
#include "nes_input.h"
static nesinput_t nes_inputs[INP_TYPE_MAX];

View File

@ -29,8 +29,6 @@
#include <osd.h>
#include <nes.h>
#include <esp_attr.h>
static mem_t mem;

View File

@ -24,7 +24,6 @@
*/
#include <string.h>
#include <esp_attr.h>
#include <nofrendo.h>
#include <nes6502.h>
#include <bitmap.h>

View File

@ -23,7 +23,6 @@
** $Id: nes_rom.c,v 1.2 2001/04/27 14:37:11 neil Exp $
*/
#include <odroid_system.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
@ -142,7 +141,7 @@ rominfo_t *rom_load(const char *filename)
rom_ptr = rom;
strncpy(rominfo->filename, filename, sizeof(rominfo->filename) - 1);
rominfo->checksum = crc32_le(0, rom + 16, filesize - 16);
rominfo->checksum = osd_getromcrc();
// rominfo->checksum = crc32_le(0, rom, filesize);
MESSAGE_INFO("ROM: Loading '%s'\n", rominfo->filename);

View File

@ -94,6 +94,7 @@ typedef unsigned int uint32;
#include <stdbool.h>
#include <stdlib.h>
#include <stdint.h>
#include <esp_attr.h>
#include <nes.h>
/* End basic types */

View File

@ -50,6 +50,8 @@ extern char *osd_newextension(char *string, const char *ext);
extern void osd_getinput(void);
/* get rom data */
extern unsigned int osd_getromcrc(void);
extern unsigned int osd_getromsize(void);
extern size_t osd_getromdata(unsigned char **data);
/* Log output */

View File

@ -18,6 +18,7 @@
#define NVS_KEY_AUTOCROP "autocrop"
static char* romData;
static uint romCRC32;
static size_t romSize;
static uint16_t myPalette[64];
@ -213,9 +214,14 @@ size_t osd_getromdata(unsigned char **data)
return romSize;
}
uint osd_getromcrc()
{
return romCRC32;
}
void osd_loadstate()
{
if (odroid_system_get_start_action() == ODROID_START_ACTION_RESUME)
if (odroid_system_get_app()->startAction == ODROID_START_ACTION_RESUME)
{
odroid_system_emu_load_state(0);
}
@ -256,8 +262,9 @@ void osd_wait_for_vsync()
if (skipFrames == 0)
{
rg_app_desc_t *app = odroid_system_get_app();
if (elapsed > frameTime) skipFrames = 1;
if (speedupEnabled) skipFrames += speedupEnabled * 2;
if (app->speedupEnabled) skipFrames += app->speedupEnabled * 2;
}
else if (skipFrames > 0)
{
@ -284,7 +291,7 @@ void osd_wait_for_vsync()
*/
void osd_audioframe(int audioSamples)
{
if (speedupEnabled)
if (odroid_system_get_app()->speedupEnabled)
return;
apu_process(audioBuffer, audioSamples); //get audio data
@ -384,7 +391,7 @@ void app_main(void)
romData = rg_alloc(0x200000, MEM_ANY);
const char *romPath = odroid_system_get_rom_path();
const char *romPath = odroid_system_get_app()->romPath;
// Load ROM
if (strcasecmp(romPath + (strlen(romPath) - 4), ".zip") == 0)
@ -404,6 +411,8 @@ void app_main(void)
RG_PANIC("ROM file loading failed!");
}
romCRC32 = crc32_le(0, (const uint8_t*)(romData + 16), romSize - 16);
int region, ret;
switch(odroid_settings_Region_get())

View File

@ -36,6 +36,7 @@
"IS_LITTLE_ENDIAN",
"INLINE=",
"uint=unsigned int",
"CONFIG_FREERTOS_HZ=100"
],
"C_Cpp.default.includePath": [
"${workspaceFolder}/components/**",

View File

@ -122,7 +122,6 @@
*****************************************************************************/
#include "shared.h"
#include "z80.h"
#include <esp_attr.h>
/* Show debugging messages */
#define VERBOSE 0

View File

@ -1,8 +1,4 @@
#include <freertos/FreeRTOS.h>
#include <odroid_system.h>
#include <esp_system.h>
#include <esp_event.h>
#include <esp_err.h>
#include "../components/smsplus/shared.h"
@ -116,8 +112,9 @@ void app_main(void)
update2.buffer = rg_alloc(SMS_WIDTH * SMS_HEIGHT, MEM_FAST);
// Load ROM
const char *romPath = odroid_system_get_rom_path();
load_rom(romPath);
rg_app_desc_t *app = odroid_system_get_app();
load_rom(app->romPath);
system_reset_config();
@ -145,7 +142,7 @@ void app_main(void)
// if (consoleIsSMS) odroid_system_set_app_id(APP_ID + 1);
// if (consoleIsGG) odroid_system_set_app_id(APP_ID + 2);
if (odroid_system_get_start_action() == ODROID_START_ACTION_RESUME)
if (app->startAction == ODROID_START_ACTION_RESUME)
{
odroid_system_emu_load_state(0);
}
@ -295,7 +292,7 @@ void app_main(void)
if (skipFrames == 0)
{
if (get_elapsed_time_since(startTime) > frameTime) skipFrames = 1;
if (speedupEnabled) skipFrames += speedupEnabled * 2.5;
if (app->speedupEnabled) skipFrames += app->speedupEnabled * 2.5;
}
else if (skipFrames > 0)
{
@ -305,7 +302,7 @@ void app_main(void)
// Tick before submitting audio/syncing
odroid_system_tick(!drawFrame, fullFrame, get_elapsed_time_since(startTime));
if (!speedupEnabled)
if (!app->speedupEnabled)
{
// Process audio
for (short i = 0; i < snd.sample_count; i++)