Skip to content

Commit 240eaaf

Browse files
committed
Fix config reload crash and add ROM organizer docs
1 parent a15a9f6 commit 240eaaf

File tree

7 files changed

+83
-7
lines changed

7 files changed

+83
-7
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ https://github.com/nextcode4u/FirmMux/tree/main/docs
2828
- `docs/RetroArch Emulators.md`
2929
- `docs/NDS Options.md`
3030
- `docs/Themes.md`
31+
- `docs/ROM Organizer (PowerShell).md`
3132

3233
Widescreen notes and options:
3334
https://wiki.ds-homebrew.com/ds-index/rtcom?tab=forwarders

SD/3ds/FirmMux.3dsx

2.32 KB
Binary file not shown.

build_number.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
198
1+
201

docs/ROM Organizer (PowerShell).md

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
# ROM Organizer (PowerShell)
2+
3+
For large ROM collections, use:
4+
https://github.com/nextcode4u/PowerShell-File-Organizer-Scripts
5+
6+
This external script pack helps organize files inside an existing ROM system folder after files are already placed there, for example:
7+
8+
- `sd:/roms/<system>/` (unorganized ROMs)
9+
10+
It is especially useful when a single system folder has thousands of files and you want quick A–Z buckets for browsing and cleanup.
11+
12+
## Scripts
13+
14+
- `Alphabetic organizer.ps1`
15+
- Sorts files in the current folder into `#` and `A``Z` subfolders.
16+
- `Flatten back to root.ps1`
17+
- Moves files from subfolders back to the current root and removes empty folders.
18+
19+
## Requirements
20+
21+
- Windows
22+
- PowerShell 5.1 or newer
23+
24+
If scripts are blocked, run:
25+
26+
```powershell
27+
Set-ExecutionPolicy -Scope CurrentUser -ExecutionPolicy RemoteSigned
28+
```
29+
30+
## Suggested workflow for big ROM sets
31+
32+
1. Download scripts from the repo above.
33+
2. Put the scripts into a large unsorted ROM folder.
34+
3. Run `Alphabetic organizer.ps1`.
35+
4. Work one letter bucket at a time to clean duplicates, bad dumps, and naming issues.
36+
5. Split cleaned files into system folders for FirmMux under `sd:/roms/<system>/`.
37+
6. Use `Flatten back to root.ps1` if you want to undo bucket folders.
38+
39+
## How this helps with very large ROM collections
40+
41+
- Reduces overload:
42+
- Instead of one huge folder, you get smaller `#`, `A``Z` batches that are easier to review.
43+
- Speeds manual QA:
44+
- You can verify names and remove duplicates in smaller chunks.
45+
- Improves final structure:
46+
- After cleanup, move files to clear system paths like `sd:/roms/nds/`, `sd:/roms/gb/`, `sd:/roms/snes/`.
47+
- Safe rollback:
48+
- If needed, flatten returns files back to one directory.
49+
50+
## Practical example
51+
52+
If you run `Alphabetic organizer.ps1` inside a folder, it organizes files in that same directory into:
53+
54+
- `#` for names starting with numbers/symbols
55+
- `A` through `Z` for names starting with letters
56+
57+
It does not auto-detect systems or move files by ROM type.
58+
59+
Use it to organize files already inside `sd:/roms/<system>/` into filename buckets (`#`, `A``Z`) for easier browsing and cleanup.

include/build_id.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#ifndef FIRMUX_BUILD_ID
2-
#define FIRMUX_BUILD_ID "Build:198"
2+
#define FIRMUX_BUILD_ID "Build:201"
33
#endif

source/config.c

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,14 @@ bool load_or_create_config(Config* cfg) {
123123
size_t size = 0;
124124
bool exists = file_exists(CONFIG_PATH);
125125
if (exists && read_file(CONFIG_PATH, &data, &size)) {
126-
bool ok = parse_config((const char*)data, cfg);
126+
char* text = (char*)malloc(size + 1);
127+
bool ok = false;
128+
if (text) {
129+
memcpy(text, data, size);
130+
text[size] = 0;
131+
ok = parse_config(text, cfg);
132+
free(text);
133+
}
127134
free(data);
128135
if (ok) return true;
129136
rename(CONFIG_PATH, CONFIG_BAK_PATH);

source/main.c

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2939,11 +2939,16 @@ static void reorder_base_targets(Config* cfg) {
29392939
static void apply_emulator_targets(Config* cfg) {
29402940
if (!cfg) return;
29412941
if (g_base_target_count == 0) capture_base_targets(cfg);
2942+
if (g_base_target_count < 0) g_base_target_count = 0;
2943+
if (g_base_target_count > MAX_TARGETS) g_base_target_count = MAX_TARGETS;
29422944
cfg->target_count = g_base_target_count;
29432945
for (int i = 0; i < g_base_target_count; i++) cfg->targets[i] = g_base_targets[i];
29442946
reorder_base_targets(cfg);
29452947

2946-
for (int i = 0; i < g_emu.count && cfg->target_count < MAX_TARGETS; i++) {
2948+
int emu_count = g_emu.count;
2949+
if (emu_count < 0) emu_count = 0;
2950+
if (emu_count > MAX_SYSTEMS) emu_count = MAX_SYSTEMS;
2951+
for (int i = 0; i < emu_count && cfg->target_count < MAX_TARGETS; i++) {
29472952
const EmuSystem* sys = &g_emu.systems[i];
29482953
if (!sys->enabled) continue;
29492954
Target* t = &cfg->targets[cfg->target_count];
@@ -3335,16 +3340,20 @@ static void handle_option_action(int idx, Config* cfg, State* state, int* curren
33353340
g_nds_cache.count = 0;
33363341
snprintf(status_message, status_size, "Cache cleared");
33373342
} else if (action == OPTION_ACTION_RELOAD_CONFIG) {
3338-
Config newcfg;
3339-
if (load_or_create_config(&newcfg)) {
3340-
*cfg = newcfg;
3343+
Config* newcfg = (Config*)malloc(sizeof(Config));
3344+
if (!newcfg) {
3345+
snprintf(status_message, status_size, "Reload failed");
3346+
} else if (load_or_create_config(newcfg)) {
3347+
*cfg = *newcfg;
33413348
g_base_target_count = 0;
33423349
rebuild_targets_from_backend(cfg, state, current_target, state_dirty, status_message, status_size, status_timer);
33433350
apply_theme_from_state_or_config(cfg, state);
33443351
if (state_dirty) *state_dirty = true;
33453352
snprintf(status_message, status_size, "Config reloaded");
3353+
free(newcfg);
33463354
} else {
33473355
snprintf(status_message, status_size, "Reload failed");
3356+
free(newcfg);
33483357
}
33493358
} else if (action == OPTION_ACTION_TOGGLE_DEBUG) {
33503359
bool on = !debug_log_enabled();

0 commit comments

Comments
 (0)