mirror of
https://github.com/Zelda64Recomp/Zelda64Recomp
synced 2026-08-28 01:16:39 -04:00
Update to use RecompFrontend.
This commit is contained in:
+113
-43
@@ -27,15 +27,22 @@
|
||||
#undef Always
|
||||
#endif
|
||||
|
||||
#include "recomp_ui.h"
|
||||
#include "recomp_input.h"
|
||||
#include "recompui/recompui.h"
|
||||
#include "recompui/program_config.h"
|
||||
#include "recompui/renderer.h"
|
||||
#include "recompui/config.h"
|
||||
#include "util/file.h"
|
||||
#include "recompinput/input_events.h"
|
||||
#include "recompinput/recompinput.h"
|
||||
#include "recompinput/profiles.h"
|
||||
#include "zelda_config.h"
|
||||
#include "zelda_sound.h"
|
||||
#include "zelda_render.h"
|
||||
#include "zelda_support.h"
|
||||
#include "zelda_game.h"
|
||||
#include "zelda_launcher.h"
|
||||
#include "recomp_data.h"
|
||||
#include "ovl_patches.hpp"
|
||||
#include "theme.h"
|
||||
#include "librecomp/game.hpp"
|
||||
#include "librecomp/mods.hpp"
|
||||
#include "librecomp/helpers.hpp"
|
||||
@@ -56,7 +63,7 @@
|
||||
|
||||
#include "../../lib/rt64/src/contrib/stb/stb_image.h"
|
||||
|
||||
const std::string version_string = "1.2.2";
|
||||
const std::string version_string = "1.2.3";
|
||||
|
||||
template<typename... Ts>
|
||||
void exit_error(const char* str, Ts ...args) {
|
||||
@@ -84,9 +91,23 @@ ultramodern::gfx_callbacks_t::gfx_data_t create_gfx() {
|
||||
return {};
|
||||
}
|
||||
|
||||
#if defined(__gnu_linux__)
|
||||
ultramodern::input::connected_device_info_t get_connected_device_info(int controller_num) {
|
||||
if (recompinput::players::is_single_player_mode() || recompinput::players::get_player_is_assigned(controller_num)) {
|
||||
return ultramodern::input::connected_device_info_t{
|
||||
.connected_device = ultramodern::input::Device::Controller,
|
||||
.connected_pak = ultramodern::input::Pak::RumblePak,
|
||||
};
|
||||
}
|
||||
|
||||
return ultramodern::input::connected_device_info_t{
|
||||
.connected_device = ultramodern::input::Device::None,
|
||||
.connected_pak = ultramodern::input::Pak::None,
|
||||
};
|
||||
}
|
||||
|
||||
#include "icon_bytes.h"
|
||||
|
||||
#if defined(__gnu_linux__)
|
||||
bool SetImageAsIcon(const char* filename, SDL_Window* window)
|
||||
{
|
||||
// Read data
|
||||
@@ -145,14 +166,6 @@ ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::
|
||||
#endif
|
||||
|
||||
window = SDL_CreateWindow("Zelda 64: Recompiled", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 1600, 960, flags);
|
||||
#if defined(__linux__)
|
||||
SetImageAsIcon("icons/512.png",window);
|
||||
if (ultramodern::renderer::get_graphics_config().wm_option == ultramodern::renderer::WindowMode::Fullscreen) { // TODO: Remove once RT64 gets native fullscreen support on Linux
|
||||
SDL_SetWindowFullscreen(window,SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
} else {
|
||||
SDL_SetWindowFullscreen(window,0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (window == nullptr) {
|
||||
exit_error("Failed to create window: %s\n", SDL_GetError());
|
||||
@@ -162,6 +175,10 @@ ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::
|
||||
SDL_VERSION(&wmInfo.version);
|
||||
SDL_GetWindowWMInfo(window, &wmInfo);
|
||||
|
||||
#if defined(__linux__)
|
||||
SetImageAsIcon("icons/512.png", window);
|
||||
#endif
|
||||
|
||||
#if defined(_WIN32)
|
||||
return ultramodern::renderer::WindowHandle{ wmInfo.info.win.window, GetCurrentThreadId() };
|
||||
#elif defined(__linux__) || defined(__ANDROID__)
|
||||
@@ -175,7 +192,7 @@ ultramodern::renderer::WindowHandle create_window(ultramodern::gfx_callbacks_t::
|
||||
}
|
||||
|
||||
void update_gfx(void*) {
|
||||
recomp::handle_events();
|
||||
recompinput::handle_events();
|
||||
}
|
||||
|
||||
static SDL_AudioCVT audio_convert;
|
||||
@@ -217,7 +234,7 @@ void queue_samples(int16_t* audio_data, size_t sample_count) {
|
||||
|
||||
// Convert the audio from 16-bit values to floats and swap the audio channels into the
|
||||
// swap buffer to correct for the address xor caused by endianness handling.
|
||||
float cur_main_volume = zelda64::get_main_volume() / 100.0f; // Get the current main volume, normalized to 0.0-1.0.
|
||||
float cur_main_volume = recompui::config::sound::get_main_volume() / 100.0f; // Get the current main volume, normalized to 0.0-1.0.
|
||||
for (size_t i = 0; i < sample_count; i += input_channels) {
|
||||
swap_buffer[i + 0 + duplicated_input_frames * input_channels] = audio_data[i + 1] * (0.5f / 32768.0f) * cur_main_volume;
|
||||
swap_buffer[i + 1 + duplicated_input_frames * input_channels] = audio_data[i + 0] * (0.5f / 32768.0f) * cur_main_volume;
|
||||
@@ -352,9 +369,11 @@ std::vector<recomp::GameEntry> supported_games = {
|
||||
{
|
||||
.rom_hash = 0xEF18B4A9E2386169ULL,
|
||||
.internal_name = "ZELDA MAJORA'S MASK",
|
||||
.display_name = "Majora's Mask",
|
||||
.game_id = u8"mm.n64.us.1.0",
|
||||
.mod_game_id = "mm",
|
||||
.save_type = recomp::SaveType::Flashram,
|
||||
.thumbnail_bytes = std::span<const char>(icon_bytes),
|
||||
.is_enabled = false,
|
||||
.decompression_routine = zelda64::decompress_mm,
|
||||
.has_compressed_code = true,
|
||||
@@ -538,7 +557,7 @@ void release_preload(PreloadContext& context) {
|
||||
context = {};
|
||||
}
|
||||
|
||||
#else
|
||||
#elif defined(__linux__) || defined(APPLE)
|
||||
|
||||
struct PreloadContext {
|
||||
|
||||
@@ -546,24 +565,51 @@ struct PreloadContext {
|
||||
|
||||
// TODO implement on other platforms
|
||||
bool preload_executable(PreloadContext& context) {
|
||||
// Preloading isn't implemented on Linux and MacOS, but it's also unnecessary there, as the OS already preloads the executable.
|
||||
// Therefore, we can just consider the executable to be preloaded.
|
||||
return false;
|
||||
}
|
||||
|
||||
void release_preload(PreloadContext& context) {
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
struct PreloadContext {};
|
||||
|
||||
bool preload_executable(PreloadContext &context) {
|
||||
return false;
|
||||
}
|
||||
|
||||
void release_preload(PreloadContext &context) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void enable_texture_pack(recomp::mods::ModContext& context, const recomp::mods::ModHandle& mod) {
|
||||
zelda64::renderer::enable_texture_pack(context, mod);
|
||||
recompui::renderer::enable_texture_pack(context, mod);
|
||||
}
|
||||
|
||||
void disable_texture_pack(recomp::mods::ModContext&, const recomp::mods::ModHandle& mod) {
|
||||
zelda64::renderer::disable_texture_pack(mod);
|
||||
recompui::renderer::disable_texture_pack(mod);
|
||||
}
|
||||
|
||||
void reorder_texture_pack(recomp::mods::ModContext&) {
|
||||
zelda64::renderer::trigger_texture_pack_update();
|
||||
recompui::renderer::trigger_texture_pack_update();
|
||||
}
|
||||
|
||||
void on_launcher_init(recompui::LauncherMenu *menu) {
|
||||
auto game_options_menu = menu->init_game_options_menu(
|
||||
supported_games[0].game_id,
|
||||
supported_games[0].mod_game_id,
|
||||
supported_games[0].display_name,
|
||||
supported_games[0].thumbnail_bytes,
|
||||
recompui::GameOptionsMenuLayout::Right
|
||||
);
|
||||
game_options_menu->add_default_options();
|
||||
|
||||
recompui::Element *menu_container = menu->get_menu_container();
|
||||
zelda64::launcher_animation_setup(menu);
|
||||
}
|
||||
|
||||
#define REGISTER_FUNC(name) recomp::overlays::register_base_export(#name, name)
|
||||
@@ -610,9 +656,6 @@ int main(int argc, char** argv) {
|
||||
// Set up console output to accept UTF-8 on windows
|
||||
SetConsoleOutputCP(CP_UTF8);
|
||||
|
||||
// Initialize native file dialogs.
|
||||
NFD_Init();
|
||||
|
||||
// Change to a font that supports Japanese characters
|
||||
CONSOLE_FONT_INFOEX cfi;
|
||||
cfi.cbSize = sizeof cfi;
|
||||
@@ -638,6 +681,13 @@ int main(int argc, char** argv) {
|
||||
std::filesystem::current_path("/var/data", ec);
|
||||
#endif
|
||||
|
||||
// Initialize native file dialogs.
|
||||
NFD_Init();
|
||||
|
||||
// Initialize program settings.
|
||||
recompui::programconfig::set_program_name(zelda64::program_name);
|
||||
recompui::programconfig::set_program_id(zelda64::program_id);
|
||||
|
||||
// Initialize SDL audio and set the output frequency.
|
||||
SDL_InitSubSystem(SDL_INIT_AUDIO);
|
||||
reset_audio(48000);
|
||||
@@ -648,7 +698,11 @@ int main(int argc, char** argv) {
|
||||
fprintf(stderr, "Failed to load controller mappings: %s\n", SDL_GetError());
|
||||
}
|
||||
|
||||
recomp::register_config_path(zelda64::get_app_folder_path());
|
||||
// Register fonts.
|
||||
recompui::register_primary_font("ChiaroNormal.otf", "Chiaro");
|
||||
recompui::register_extra_font("ChiaroBold.otf");
|
||||
|
||||
recomp::register_config_path(recompui::file::get_app_folder_path());
|
||||
|
||||
// Register supported games and patches
|
||||
for (const auto& game : supported_games) {
|
||||
@@ -672,18 +726,28 @@ int main(int argc, char** argv) {
|
||||
REGISTER_FUNC(recomp_get_analog_inverted_axes);
|
||||
recompui::register_ui_exports();
|
||||
recomputil::register_data_api_exports();
|
||||
recomptheme::set_custom_theme();
|
||||
|
||||
zelda64::register_overlays();
|
||||
zelda64::register_patches();
|
||||
recomputil::init_extended_actor_data();
|
||||
zelda64::load_config();
|
||||
|
||||
recompinput::players::set_single_player_mode(true);
|
||||
|
||||
zelda64::init_config();
|
||||
|
||||
recompui::register_launcher_init_callback(on_launcher_init);
|
||||
recompui::register_launcher_update_callback(zelda64::launcher_animation_update);
|
||||
|
||||
recomp::rsp::callbacks_t rsp_callbacks{
|
||||
.get_rsp_microcode = get_rsp_microcode,
|
||||
};
|
||||
|
||||
ultramodern::renderer::callbacks_t renderer_callbacks{
|
||||
.create_render_context = zelda64::renderer::create_render_context,
|
||||
.create_render_context = [](uint8_t *rdram, ultramodern::renderer::WindowHandle window_handle, bool developer_mode) {
|
||||
auto presentation_mode = ultramodern::renderer::PresentationMode::PresentEarly;
|
||||
return recompui::renderer::create_render_context(rdram, window_handle, presentation_mode, developer_mode);
|
||||
},
|
||||
};
|
||||
|
||||
ultramodern::gfx_callbacks_t gfx_callbacks{
|
||||
@@ -699,15 +763,15 @@ int main(int argc, char** argv) {
|
||||
};
|
||||
|
||||
ultramodern::input::callbacks_t input_callbacks{
|
||||
.poll_input = recomp::poll_inputs,
|
||||
.get_input = recomp::get_n64_input,
|
||||
.set_rumble = recomp::set_rumble,
|
||||
.get_connected_device_info = recomp::get_connected_device_info,
|
||||
.poll_input = recompinput::poll_inputs,
|
||||
.get_input = recompinput::profiles::get_n64_input,
|
||||
.set_rumble = recompinput::set_rumble,
|
||||
.get_connected_device_info = get_connected_device_info,
|
||||
};
|
||||
|
||||
ultramodern::events::callbacks_t thread_callbacks{
|
||||
.vi_callback = recomp::update_rumble,
|
||||
.gfx_init_callback = recompui::update_supported_options,
|
||||
.vi_callback = recompinput::update_rumble,
|
||||
.gfx_init_callback = nullptr,
|
||||
};
|
||||
|
||||
ultramodern::error_handling::callbacks_t error_handling_callbacks{
|
||||
@@ -731,18 +795,24 @@ int main(int argc, char** argv) {
|
||||
// Register the .rtz texture pack file format with the previous content type as its only allowed content type.
|
||||
recomp::mods::register_mod_container_type("rtz", std::vector{ texture_pack_content_type_id }, false);
|
||||
|
||||
recomp::start(
|
||||
project_version,
|
||||
{},
|
||||
rsp_callbacks,
|
||||
renderer_callbacks,
|
||||
audio_callbacks,
|
||||
input_callbacks,
|
||||
gfx_callbacks,
|
||||
thread_callbacks,
|
||||
error_handling_callbacks,
|
||||
threads_callbacks
|
||||
);
|
||||
// Configure and start.
|
||||
recomp::Configuration cfg;
|
||||
cfg.project_version = project_version;
|
||||
cfg.window_handle = {};
|
||||
cfg.rsp_callbacks = rsp_callbacks;
|
||||
cfg.renderer_callbacks = renderer_callbacks;
|
||||
cfg.audio_callbacks = audio_callbacks;
|
||||
cfg.input_callbacks = input_callbacks;
|
||||
cfg.gfx_callbacks = gfx_callbacks;
|
||||
cfg.events_callbacks = thread_callbacks;
|
||||
cfg.error_handling_callbacks = error_handling_callbacks;
|
||||
cfg.threads_callbacks = threads_callbacks;
|
||||
cfg.message_queue_control.requeue_pi = true;
|
||||
cfg.message_queue_control.requeue_ai = true;
|
||||
cfg.message_queue_control.requeue_sp = true;
|
||||
cfg.message_queue_control.requeue_dp = true;
|
||||
cfg.message_queue_control.requeue_timer = true;
|
||||
recomp::start(cfg);
|
||||
|
||||
NFD_Quit();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user