Continuing work to remove esp32-specific code from emulators
This commit is contained in:
parent
887d6e7a80
commit
fe2d42ed1a
55
components/odroid/config.h
Normal file
55
components/odroid/config.h
Normal 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"
|
||||
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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,
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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;
|
||||
@ -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);
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
|
||||
@ -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(¤tApp, 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 ¤tApp;
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -4,7 +4,6 @@
|
||||
*/
|
||||
|
||||
#include "defs.h"
|
||||
#include <esp_attr.h>
|
||||
|
||||
static DRAM_ATTR const byte cycles_table[256] =
|
||||
{
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -9,8 +9,6 @@
|
||||
#include "lcd.h"
|
||||
#include "rtc.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
|
||||
|
||||
void emu_init()
|
||||
{
|
||||
|
||||
@ -7,7 +7,6 @@
|
||||
#include "lcd.h"
|
||||
#include "mem.h"
|
||||
|
||||
#include "esp_attr.h"
|
||||
|
||||
struct hw hw;
|
||||
|
||||
|
||||
@ -1,7 +1,6 @@
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <esp_attr.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "regs.h"
|
||||
|
||||
@ -1,5 +1,4 @@
|
||||
#include "stdlib.h"
|
||||
#include "esp_attr.h"
|
||||
|
||||
#include "defs.h"
|
||||
#include "hw.h"
|
||||
|
||||
@ -3,7 +3,6 @@
|
||||
|
||||
|
||||
#include "defs.h"
|
||||
#include <esp_attr.h>
|
||||
|
||||
/*DRAM_ATTR*/ static const byte noise7[] =
|
||||
{
|
||||
|
||||
@ -7,8 +7,6 @@
|
||||
#include "regs.h"
|
||||
#include "noise.h"
|
||||
|
||||
#include <esp_attr.h>
|
||||
|
||||
static const byte dmgwave[16] =
|
||||
{
|
||||
0xac, 0xdd, 0xda, 0x48,
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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) {
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -120,7 +120,7 @@ pce_run(void)
|
||||
}
|
||||
|
||||
osd_gfx_blit();
|
||||
osd_wait_next_vsync();
|
||||
osd_vsync();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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
|
||||
|
||||
@ -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;
|
||||
|
||||
@ -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);
|
||||
}
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
*/
|
||||
|
||||
#include <nofrendo.h>
|
||||
#include <esp_attr.h>
|
||||
#include <string.h>
|
||||
#include "nes6502.h"
|
||||
#include "dis6502.h"
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#include <nes6502.h>
|
||||
#include "nes_apu.h"
|
||||
|
||||
#include <esp_attr.h>
|
||||
#include <string.h>
|
||||
|
||||
#define APU_OVERSAMPLE
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
*/
|
||||
|
||||
#include <nofrendo.h>
|
||||
#include <esp_attr.h>
|
||||
#include "nes_input.h"
|
||||
|
||||
static nesinput_t nes_inputs[INP_TYPE_MAX];
|
||||
|
||||
@ -29,8 +29,6 @@
|
||||
#include <osd.h>
|
||||
#include <nes.h>
|
||||
|
||||
#include <esp_attr.h>
|
||||
|
||||
static mem_t mem;
|
||||
|
||||
|
||||
|
||||
@ -24,7 +24,6 @@
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <esp_attr.h>
|
||||
#include <nofrendo.h>
|
||||
#include <nes6502.h>
|
||||
#include <bitmap.h>
|
||||
|
||||
@ -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);
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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 */
|
||||
|
||||
@ -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())
|
||||
|
||||
@ -36,6 +36,7 @@
|
||||
"IS_LITTLE_ENDIAN",
|
||||
"INLINE=",
|
||||
"uint=unsigned int",
|
||||
"CONFIG_FREERTOS_HZ=100"
|
||||
],
|
||||
"C_Cpp.default.includePath": [
|
||||
"${workspaceFolder}/components/**",
|
||||
|
||||
@ -122,7 +122,6 @@
|
||||
*****************************************************************************/
|
||||
#include "shared.h"
|
||||
#include "z80.h"
|
||||
#include <esp_attr.h>
|
||||
|
||||
/* Show debugging messages */
|
||||
#define VERBOSE 0
|
||||
|
||||
@ -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++)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user