Skip to content
Open
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
33 changes: 28 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ GAME_DOL_LOADER := game_dol_loader
TARGET := $(notdir $(CURDIR))
BUILD := build
RELEASE := $(BUILD)/release
EXTRA_CFLAGS ?=
SOURCES := source source/update source/pngu source/loader
DATA := data
TEXTURES := textures
Expand All @@ -38,11 +39,11 @@ INCLUDES :=
# Find the length of the `patch_dol` function in $(GAME_DOL_LOADER).c and expose it as a macro, which is needed because we memcpy() it.
PATCH_DOL_LEN = 0x$(shell $(DEVKITPPC)/bin/powerpc-eabi-objdump $(GAME_DOL_LOADER).o -t | grep ' patch_dol' | awk '{print $$5}')

CFLAGS = -DPATCH_DOL_LEN=$(PATCH_DOL_LEN) -fno-builtin -g -O2 -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)
CFLAGS = -DPATCH_DOL_LEN=$(PATCH_DOL_LEN) $(EXTRA_CFLAGS) -fno-builtin -g -O2 -Wall $(MACHDEP) $(INCLUDE)
CXXFLAGS = $(CFLAGS)

# compiler flags for the special $(GAME_DOL_LOADER).c file
GAME_DOL_LOADER_CFLAGS = -O2 -fno-builtin -Wall -g $(MACHDEP) $(INCLUDE)
GAME_DOL_LOADER_CFLAGS = $(EXTRA_CFLAGS) -O2 -fno-builtin -Wall -g $(MACHDEP) $(INCLUDE)

LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map

Expand Down Expand Up @@ -116,15 +117,37 @@ export LIBPATHS := $(foreach dir,$(LIBDIRS),-L$(dir)/lib) \
-L$(LIBOGC_LIB)

export OUTPUT := $(CURDIR)/$(TARGET)
.PHONY: $(BUILD) clean
.PHONY: $(BUILD) build debug beta beta-package clean release run

#---------------------------------------------------------------------------------
$(BUILD):
make --no-print-directory -C runtime-ext
make --no-print-directory -C runtime-ext EXTRA_CFLAGS="$(EXTRA_CFLAGS)"
@[ -d $@ ] || mkdir -p $@
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile

#---------------------------------------------------------------------------------
debug: EXTRA_CFLAGS := -DRRC_DEBUG=1
debug: export EXTRA_CFLAGS := -DRRC_DEBUG=1
debug: $(BUILD) debug-package

debug-package:
# Move files to a debug staging directory instead of the release directory
mkdir -p $(BUILD)/debug/RetroRewindChannel
mkdir -p $(BUILD)/debug/apps/RetroRewind
cp runtime-ext/runtime-ext-* $(BUILD)/debug/RetroRewindChannel
cp $(OUTPUT).dol $(BUILD)/debug/apps/RetroRewind/boot.dol

beta: EXTRA_CFLAGS := -DRRC_BETA=1
beta: export EXTRA_CFLAGS := -DRRC_BETA=1
beta: $(BUILD) beta-package

beta-package:
# Move files to a beta staging directory instead of the release directory
mkdir -p $(BUILD)/beta/RetroRewindChannelBeta
mkdir -p $(BUILD)/beta/apps/RetroRewindBeta
cp runtime-ext/runtime-ext-* $(BUILD)/beta/RetroRewindChannelBeta
cp $(OUTPUT).dol $(BUILD)/beta/apps/RetroRewindBeta/boot.dol

clean:
@echo clean ...
make --no-print-directory -C runtime-ext clean
Expand Down
13 changes: 12 additions & 1 deletion runtime-ext/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,11 @@ OFILES := $(addprefix build/,$(CFILES:.c=.o))
# Prevent deletion of .o files, helps with incr rebuilds
.SECONDARY: $(OFILES)

.PHONY: all debug beta clean

INCLUDE := -I../shared -Ivendor -Ivendor/bslug_include
CFLAGS := -nostdlib -mno-eabi -O2 -Wall $(MACHDEP) $(INCLUDE)
EXTRA_CFLAGS ?=
CFLAGS := $(EXTRA_CFLAGS) -nostdlib -mno-eabi -O2 -Wall $(MACHDEP) $(INCLUDE)

LINKERSCRIPTS := $(wildcard linker-*.ld)
# get region characters
Expand All @@ -33,6 +36,14 @@ LDFLAGS := $(OFILES) $(MACHDEP) -Wl,--section-start=.init=81744260,--section-sta

all: $(DOLS)

debug: EXTRA_CFLAGS := -DDEBUG=1
debug: export EXTRA_CFLAGS := -DDEBUG=1
debug: all

beta: EXTRA_CFLAGS := -DRRC_BETA=1
beta: export EXTRA_CFLAGS := -DRRC_BETA=1
beta: all

runtime-ext-%.dol: $(ELFS)
@echo runtime-ext-$*.elf
@elf2dol runtime-ext-$*.elf $@
Expand Down
17 changes: 6 additions & 11 deletions runtime-ext/source/dvd.c
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "trampoline.h"
#include <string.h>
#include <ctype.h>
#include <dir.h>

/**
* Contains all <file> and <folder> replacements. Initialized in the launcher DOL based on the XML.
Expand Down Expand Up @@ -232,7 +233,7 @@ static bool rte_dvd_resolve_my_stuff_path_to_entry_num(const char *path, s32 *en
char my_stuff_path[64];
if (rrc_bitflags & (RRC_BITFLAGS_MY_STUFF_RR | RRC_BITFLAGS_MY_STUFF_RR_MUSIC))
{
snprintf(my_stuff_path, sizeof(my_stuff_path), "/RetroRewind6/MyStuff/%s", filename);
snprintf(my_stuff_path, sizeof(my_stuff_path), "/" RRC_RETRO_REWIND_BASE_DIR "/MyStuff/%s", filename);
}
else
{
Expand All @@ -242,7 +243,7 @@ static bool rte_dvd_resolve_my_stuff_path_to_entry_num(const char *path, s32 *en
bool cached_file_exists = false;
for (int i = 0; i < my_stuff_replacement->folder_contents_count; i++)
{
if (strcmp(my_stuff_replacement->folder_contents[i], filename) == 0)
if (strcicmp(my_stuff_replacement->folder_contents[i], filename) == 0)
{
cached_file_exists = true;
break;
Expand Down Expand Up @@ -292,7 +293,7 @@ static bool rte_dvd_resolve_path_to_entry_num(const char *filename, s32 *entry_n
{
case RRC_RIIVO_FILE_REPLACEMENT:
{
RTE_DBG("Checking file replacement: '%s' == '%s'\n", replacement->disc, "strm");
RTE_DBG("Checking file replacement: '%s' == '%s'\n", replacement->disc, filename);

// Trim leading slashes from either path.
const char *disc_path = replacement->disc;
Expand All @@ -306,7 +307,7 @@ static bool rte_dvd_resolve_path_to_entry_num(const char *filename, s32 *entry_n
ffilename++;
}

if (strcmp(disc_path, ffilename) == 0)
if (strcicmp(disc_path, ffilename) == 0)
{
// We already checked that the external file exists when we registered the replacement.
RTE_DBG("Found a file replacement! %d (%s)\n", i, disc_path);
Expand Down Expand Up @@ -391,13 +392,7 @@ static bool rte_dvd_resolve_path_to_entry_num(const char *filename, s32 *entry_n
bool cached_file_exists = false;
for (int i = 0; i < replacement->folder_contents_count; i++)
{
// We need to enforce case insensitivity here because FAT is case-insensitive,
// and the folder_contents are populated based on FAT reads.

to_lowercase((char *)replacement->folder_contents[i]);
to_lowercase(new_path_filename);

if (strcmp(replacement->folder_contents[i], new_path_filename) == 0)
if (strcicmp(replacement->folder_contents[i], new_path_filename) == 0)
{
RTE_DBG("Found a cached match for the filename in the folder contents!\n");
cached_file_exists = true;
Expand Down
23 changes: 22 additions & 1 deletion runtime-ext/source/util.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@

#include <types.h>
#include <ctype.h>
#include <stdlib.h>
#include <string.h>

u32 align_down(u32 num, u32 align_as)
{
Expand All @@ -32,8 +34,27 @@ u32 align_up(u32 num, u32 align_as)

void to_lowercase(char *str)
{
for (int i = 0; str[i]; i++) {
for (int i = 0; str[i]; i++)
{
// Cast to unsigned char to avoid undefined behaviour with non-ASCII chars
str[i] = tolower((unsigned char)str[i]);
}
}

int strcicmp(const char *a, const char *b)
{
const unsigned char *p1 = (const unsigned char *)a;
const unsigned char *p2 = (const unsigned char *)b;
int result;

if (p1 == p2)
return 0;

while ((result = tolower(*p1) - tolower(*p2++)) == 0)
{
if (*p1++ == '\0')
break;
}

return result;
}
12 changes: 6 additions & 6 deletions runtime-ext/source/util.h
Original file line number Diff line number Diff line change
Expand Up @@ -25,12 +25,10 @@
void OS_Report(const char *, ...);
void OS_Fatal(u32 *, u32 *, const char *);

#ifndef DEBUG
#define RTE_DBG(...)
#endif

#ifdef DEBUG
#define RTE_DBG OS_Report
#if (defined(RRC_DEBUG) && RRC_DEBUG >= 1) || (defined(RRC_BETA) && RRC_BETA >= 1)
# define RTE_DBG OS_Report
#else
# define RTE_DBG(...)
#endif

#define RTE_FATAL(...) \
Expand All @@ -51,4 +49,6 @@ u32 align_up(u32 num, u32 align_as);

void to_lowercase(char *str);

int strcicmp(const char *a, const char *b);

#endif
31 changes: 31 additions & 0 deletions shared/dir.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
dir.h - File base directory handling based on macros

Copyright (C) 2025 Retro Rewind Team

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.

This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#ifndef RRC_DIR_H
#define RRC_DIR_H

#if defined(RRC_BETA) && RRC_BETA >= 1
# define RRC_RETRO_REWIND_BASE_DIR "RRBeta"
# define RRC_RETRO_REWIND_CHANNEL_DIR "RetroRewindChannelBeta"
#else
# define RRC_RETRO_REWIND_BASE_DIR "RetroRewind6"
# define RRC_RETRO_REWIND_CHANNEL_DIR "RetroRewindChannel"
#endif

#endif
3 changes: 2 additions & 1 deletion shared/riivo.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,10 @@
#ifndef RRC_RIIVO_H
#define RRC_RIIVO_H

#include <dir.h>
#include "types.h"

#define RRC_RIIVO_XML_PATH "RetroRewind6/xml/RetroRewind6.xml"
#define RRC_RIIVO_XML_PATH "/" RRC_RETRO_REWIND_BASE_DIR "/xml/" RRC_RETRO_REWIND_BASE_DIR ".xml"

enum rrc_riivo_disc_replacement_type
{
Expand Down
9 changes: 8 additions & 1 deletion source/console.c
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,14 @@ void rrc_con_display_version()
}

char vertext[32];
snprintf(vertext, 32, "Version: %i.%i.%i", cached_version.major, cached_version.minor, cached_version.patch);

#if defined(RRC_BETA) && RRC_BETA >= 1
snprintf(vertext, 32, "Version: %i.%i.%i (RRBETA BUILD)", cached_version.major, cached_version.minor, cached_version.patch);
#else
snprintf(vertext, 32, "Version: %i.%i.%i", cached_version.major, cached_version.minor, cached_version.patch);
#endif


rrc_con_cursor_seek_to(rrc_con_get_rows() - 2, rrc_con_get_cols() - strlen(vertext));
printf("%s", vertext);
}
Expand Down
3 changes: 2 additions & 1 deletion source/crash.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/

#include <dir.h>
#include "crash.h"
#include "console.h"
#include "prompt.h"
Expand Down Expand Up @@ -59,7 +60,7 @@ void rrc_crash_handle(void *xfb, struct rrc_settingsfile *settings)
"instructions found on https://rwfc.net/downloads,",
"and do not manually delete any files.",
"",
"A crash file was written to sd:/RetroRewind6/Crash.pul.",
"A crash file was written to sd:/" RRC_RETRO_REWIND_BASE_DIR "/Crash.pul.",
"If you continue to experience issues, please report it",
"along with this file to our Discord server:",
"https://discord.gg/retrorewind",
Expand Down
2 changes: 2 additions & 0 deletions source/crash.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@

#include "settingsfile.h"

// Do not use the channel base dir constant here, as the game is unaware of this.
// It will always write into the "main" folder. Since it's an ephemeral file, it doesn't really matter.
#define RRC_CRASH_FILE_PATH "/RetroRewindChannel/.crash"

/*
Expand Down
2 changes: 2 additions & 0 deletions source/ephfile.h
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
#ifndef RRC_EPHFILE_H
#define RRC_EPHFILE_H

// Do not use the channel base dir constant here, as the game is unaware of this.
// It will always write into the "main" folder. Since it's an ephemeral file, it doesn't really matter.
#define RRC_LAUNCHED_FROM_RR_FILE_PATH "/RetroRewindChannel/.lfrr"

bool rrc_launched_from_rr();
Expand Down
5 changes: 3 additions & 2 deletions source/loader/binary_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
#define BINARY_LOADER_H

#include <dol.h>
#include <dir.h>
#include "../result.h"

#define RRC_LOADER_PUL_PATH "RetroRewind6/Binaries/Loader.pul"
#define RRC_LOADER_PUL_PATH "/" RRC_RETRO_REWIND_BASE_DIR "/Binaries/Loader.pul"

// We need to load the correct runtime-ext.
// This is provided as a base; however, the region and file extension needs
// to be appended at runtime.
#define RRC_RUNTIME_EXT_BASE_PATH "RetroRewindChannel/runtime-ext"
#define RRC_RUNTIME_EXT_BASE_PATH "/" RRC_RETRO_REWIND_CHANNEL_DIR "/runtime-ext"

// At the moment this file handles Loader.pul and runtime-ext.

Expand Down
15 changes: 9 additions & 6 deletions source/loader/riivo_patch_loader.c
Original file line number Diff line number Diff line change
Expand Up @@ -309,12 +309,12 @@ struct rrc_result rrc_riivo_patch_loader_parse(struct rrc_settingsfile *settings
// All current My Stuff music options *do* have this attribute, so it's fine for them to use this (for now, anyway...).
// When all is said and done, we MUST be left with only one folder replacement marked as My Stuff, if My Stuff is enabled.
// If there are multiple, they will conflict.
bool is_rr_mystuff = strcmp(elem_id, "RRLoad") == 0;
bool is_ctgpr_mystuff = strcmp(elem_id, "RRCTGPLoad") == 0;
bool is_rr_mystuff = strcmp(elem_id, RRC_RR_MY_STUFF_PATCH_ID) == 0;
bool is_ctgpr_mystuff = strcmp(elem_id, RRC_CTGP_MY_STUFF_PATCH_ID) == 0;

// Skip music if the My Stuff exclusive option for it is disabled.
bool is_rr_music = strcmp(elem_id, "RRLoadMusic") == 0;
bool is_ctgp_music = strcmp(elem_id, "RRCTGPLoadMusic") == 0;
bool is_rr_music = strcmp(elem_id, RRC_RR_MUSIC_MY_STUFF_PATCH_ID) == 0;
bool is_ctgp_music = strcmp(elem_id, RRC_CTGP_MUSIC_MY_STUFF_PATCH_ID) == 0;

mxml_index_t *file_repl_index = mxmlIndexNew(cur, "file", NULL);
for (mxml_node_t *file = mxmlIndexEnum(file_repl_index); file != NULL; file = mxmlIndexEnum(file_repl_index))
Expand Down Expand Up @@ -450,15 +450,18 @@ struct rrc_result rrc_riivo_patch_loader_parse(struct rrc_settingsfile *settings
// where we barely only have access to a single function.
if (valuefile_mxml != NULL)
{
if (strcmp(valuefile_mxml, "/" RRC_LOADER_PUL_PATH) == 0)
if (strcmp(valuefile_mxml, RRC_LOADER_PUL_PATH) == 0)
{
// Loader.pul specifically is handled manually elsewhere, so make an exception for this.
u32 loader_addr = strtoul(addr_mxml, NULL, 16);
out->loader_pul_dest = (void *)loader_addr;
continue;
}

return rrc_result_create_error_corrupted_rr_xml("Unhandled valuefile memory patch encountered");
char error[128];
snprintf(error, 128, "Unsupported valuefile '%s' in memory patch", valuefile_mxml);

return rrc_result_create_error_corrupted_rr_xml(error);
}

PARSE_REQUIRED_ATTR(memory, value_mxml, "value");
Expand Down
22 changes: 22 additions & 0 deletions source/loader/riivo_patch_loader.h
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,28 @@
#include "../settingsfile.h"
#include "../result.h"

/*
bool is_rr_mystuff = strcmp(elem_id, "RRLoad") == 0;
bool is_ctgpr_mystuff = strcmp(elem_id, "RRCTGPLoad") == 0;

// Skip music if the My Stuff exclusive option for it is disabled.
bool is_rr_music = strcmp(elem_id, "RRLoadMusic") == 0;
bool is_ctgp_music = strcmp(elem_id, "RRCTGPLoadMusic") == 0;

*/

#if defined(RRC_BETA) && RRC_BETA >= 1
# define RRC_RR_MY_STUFF_PATCH_ID "RRBetaLoad"
# define RRC_CTGP_MY_STUFF_PATCH_ID "RRBetaCTGPLoad"
# define RRC_RR_MUSIC_MY_STUFF_PATCH_ID "RRBetaLoadMusic"
# define RRC_CTGP_MUSIC_MY_STUFF_PATCH_ID "RRBetaCTGPLoadMusic"
#else
# define RRC_RR_MY_STUFF_PATCH_ID "RRLoad"
# define RRC_CTGP_MY_STUFF_PATCH_ID "RRCTGPLoad"
# define RRC_RR_MUSIC_MY_STUFF_PATCH_ID "RRLoadMusic"
# define RRC_CTGP_MUSIC_MY_STUFF_PATCH_ID "RRCTGPLoadMusic"
#endif

#define MAX_FILE_PATCHES 1000
#define MAX_MEMORY_PATCHES 128
#define MAX_ENABLED_SETTINGS (64)
Expand Down
Loading
Loading