Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Data/mupen64plus.ini
Original file line number Diff line number Diff line change
Expand Up @@ -14149,6 +14149,18 @@ CRC=D68CEFC0 0B81D955
RefMD5=5AAC6E652C5CF1E37A466AC0073E88CA
CountPerOp=1

[2B2D6B295106C54216B7FC7A2F14346E]
GoodName=SmashRemix2.0.1
CRC=34EE4749 1833C64C
RefMD5=5AAC6E652C5CF1E37A466AC0073E88CA
CountPerOp=1

[0CFDA9AB8E7DEE5B088385D2576369E6]
GoodName=SmashRemix2.0.1 (PAL60)
CRC=96D0976A 2FB7654F
RefMD5=5AAC6E652C5CF1E37A466AC0073E88CA
CountPerOp=1

[B8D4B92E66A312708626B3216DE07A3A]
GoodName=Snobow Kids (J) [!]
CRC=84FC04FF B1253CE9
Expand Down
12 changes: 12 additions & 0 deletions src/converter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -351,6 +351,18 @@ bool convert_one(const std::string& krec_path, const std::string& output_path,

emu.apply_deterministic_settings();

// Apply GameShark cheats if requested
if (config.remove_music) {
m64p_cheat_code no_music[] = {
{0x81462BE2, 0x0000},
};
if (emu.apply_cheat("NoMusic", no_music, 1)) {
converter_log(LOG_INFO, "Applied 'Remove Background Music' cheat.");
} else {
converter_log(LOG_WARNING, "Warning: failed to apply music removal cheat.");
}
}

// Setup FFmpeg encoder config (video only, to temp file)
// Encoder is opened lazily on first frame to match actual render dimensions
FFmpegEncoder encoder;
Expand Down
3 changes: 3 additions & 0 deletions src/converter.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#pragma once
#include <string>
#include <vector>
#include <functional>
#include <atomic>

Expand Down Expand Up @@ -40,7 +41,9 @@ struct AppConfig {
int aniso = 0; // 0=off, 2, 4, 8, 16
std::string encoder = "libx264"; // FFmpeg codec name
bool batch = false;
std::vector<std::string> batch_files; // selected files for batch mode
bool verbose = false;
bool remove_music = false;
};

// Get the directory containing the executable
Expand Down
16 changes: 16 additions & 0 deletions src/emulator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ bool Emulator::load_core(const std::string& path) {
RESOLVE(config_open_section, ptr_ConfigOpenSection, "ConfigOpenSection");
RESOLVE(config_set_parameter, ptr_ConfigSetParameter, "ConfigSetParameter");

// Optional cheat API
core_add_cheat = (ptr_CoreAddCheat)GET_PROC(core_handle, "CoreAddCheat");

// Optional RMG-K extension
set_pif_callback_fn = (ptr_set_pif_sync_callback)GET_PROC(core_handle, "set_pif_sync_callback");
if (!set_pif_callback_fn) {
Expand Down Expand Up @@ -333,6 +336,19 @@ void Emulator::apply_deterministic_settings() {
// via GLideN64.ini in configure_gliden64(), called during init().
}

bool Emulator::apply_cheat(const char* name, m64p_cheat_code* codes, int num_codes) {
if (!core_add_cheat) {
fprintf(stderr, "Warning: CoreAddCheat not available in this core build\n");
return false;
}
m64p_error ret = core_add_cheat(name, codes, num_codes);
if (ret != M64ERR_SUCCESS) {
fprintf(stderr, "Error: CoreAddCheat('%s') failed (error %d)\n", name, ret);
return false;
}
return true;
}

void Emulator::configure_controllers_for_replay(int num_players) {
m64p_handle section;

Expand Down
12 changes: 12 additions & 0 deletions src/emulator.h
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,12 @@ struct pif {

typedef void (*pif_sync_callback_t)(struct pif*);

// Cheat code structure
typedef struct {
uint32_t address;
int value;
} m64p_cheat_code;

} // extern "C"

// Mupen64plus core function pointer types
Expand Down Expand Up @@ -128,6 +134,10 @@ typedef m64p_error (*ptr_ConfigSetDefaultString)(m64p_handle, const char*, const
typedef m64p_error (*ptr_PluginStartup)(m64p_dynlib_handle, void*, ptr_DebugCallback);
typedef m64p_error (*ptr_PluginShutdown)(void);

// Cheat API
typedef m64p_error (*ptr_CoreAddCheat)(const char*, m64p_cheat_code*, int);
typedef m64p_error (*ptr_CoreCheatEnabled)(const char*, int);

// RMG-K extension
typedef void (*ptr_set_pif_sync_callback)(pif_sync_callback_t);

Expand Down Expand Up @@ -158,6 +168,7 @@ class Emulator {
bool open_rom(const std::string& rom_path);
bool attach_plugins();
void apply_deterministic_settings();
bool apply_cheat(const char* name, m64p_cheat_code* codes, int num_codes);
void configure_controllers_for_replay(int num_players);
void set_pif_callback(pif_sync_callback_t callback);
void set_frame_callback(m64p_frame_callback callback);
Expand Down Expand Up @@ -186,6 +197,7 @@ class Emulator {
ptr_ConfigOpenSection config_open_section = nullptr;
ptr_ConfigSetParameter config_set_parameter = nullptr;
ptr_set_pif_sync_callback set_pif_callback_fn = nullptr;
ptr_CoreAddCheat core_add_cheat = nullptr;
ptr_ReadScreen2 read_screen2 = nullptr;

bool verbose = false;
Expand Down
8 changes: 4 additions & 4 deletions src/frame_capture.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ static FFmpegConfig s_ff_config;
static bool s_encoder_opened = false;
static int s_captured_frames = 0;
static int s_total_frames = 0;
static bool s_speed_limiter_disabled = false;
static bool s_speed_set = false;
static ProgressCallback s_progress_callback;
static std::atomic<bool>* s_cancel_flag = nullptr;

Expand Down Expand Up @@ -194,7 +194,7 @@ void frame_capture_init(Emulator* emu, FFmpegEncoder* encoder, const FFmpegConfi
s_encoder_opened = false;
s_captured_frames = 0;
s_total_frames = total_frames;
s_speed_limiter_disabled = false;
s_speed_set = false;
// Keep buffers allocated across batch runs to avoid reallocation
s_progress_callback = nullptr;
s_cancel_flag = nullptr;
Expand Down Expand Up @@ -235,10 +235,10 @@ void frame_capture_callback(unsigned int frame_index) {
}

// Disable speed limiter on first frame for maximum conversion speed
if (!s_speed_limiter_disabled && s_emu) {
if (!s_speed_set && s_emu) {
int limiter = 0; // 0 = off
s_emu->core_do_command(M64CMD_CORE_STATE_SET, M64CORE_SPEED_LIMITER, &limiter);
s_speed_limiter_disabled = true;
s_speed_set = true;
}

// Reset PIF sync flag for next frame
Expand Down
Loading
Loading