Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[develop] Add datel cheat support from filesystem #204

Draft
wants to merge 30 commits into
base: develop
Choose a base branch
from

Conversation

XLuma
Copy link

@XLuma XLuma commented Jan 14, 2025

Description

This pull request adds a parser for cheat code support in the frontend. If a file named the same as the selected rom with the extension .cht is found, it will attempt to parse the file for cheat codes and place them in menu->boot_params->cheat_list per the cheat backend API.

Cheat files should be formatted this way:

# Super mario 64 infinite lives
8033B21D 0064

# 120 stars
80207723 0001
8020770B 00C7
50001101 0000
8020770C 00FF

The parser ignores lines that start with a '#', are under 12 characters or over 15 characters. Every other line should be valid cheat code inputs with the code on the left, and the value on the right separated by a space.

Motivation and Context

Adds some initial cheat support in the frontend to allow users to modify their games more easily, and take advantage of the backend API.

How Has This Been Tested?

Tested on real hardware with a Summercart64 and Super Mario 64.

Screenshots

Types of changes

  • Improvement (non-breaking change that adds a new feature)
  • Bug fix (fixes an issue)
  • Breaking change (breaking change)
  • Documentation Improvement
  • Config and build (change in the configuration and build system, has no impact on code or features)

Checklist:

  • My code follows the code style of this project.
  • My change requires a change to the documentation.
  • I have updated the documentation accordingly.
  • I have added tests to cover my changes.
  • All new and existing tests passed.

Signed-off-by: XLuma

Summary by CodeRabbit

  • New Features

    • Added support for loading and managing cheat codes for N64 ROMs
    • Introduced ability to enable/disable cheats for specific ROMs
    • Added file type recognition for .cht cheat files
  • Documentation

    • Updated documentation with details about cheat code support, including Datel cart compatibility and supported code types
  • Bug Fixes

    • Implemented comprehensive error handling for cheat file loading
    • Added file parsing support for cheat codes

Copy link

coderabbitai bot commented Jan 14, 2025

Walkthrough

This pull request introduces comprehensive cheat code support for the N64 emulator menu system. The changes include adding a new source file cheat_load.c to handle cheat file loading, updating documentation to explain cheat code functionality, and modifying several menu-related files to integrate cheat loading and management. The implementation allows users to enable and load cheat codes for specific ROMs, with robust error handling and file parsing mechanisms.

Changes

File Change Summary
Makefile Added menu/cheat_load.c to source files
docs/13_datel_cheats.md Updated documentation with detailed cheat code information, supported code types, and file parsing rules
src/menu/cart_load.c Added #include "cheat_load.h"
src/menu/cheat_load.c New file with cheat loading functionality, error handling, and utility functions
src/menu/cheat_load.h New header defining cheat loading error types and function declarations
src/menu/rom_info.c Added rom_setting_set_cheats() function to manage cheat settings
src/menu/rom_info.h Added function declaration for cheat settings
src/menu/views/file_info.c Added support for .cht file type recognition
src/menu/views/load_rom.c Implemented cheat option management in ROM loading menu

Sequence Diagram

sequenceDiagram
    participant User
    participant ROMLoadMenu
    participant CheatLoader
    participant ROMInfo

    User->>ROMLoadMenu: Select ROM
    ROMLoadMenu->>ROMInfo: Check cheat settings
    User->>ROMLoadMenu: Enable/Disable Cheats
    ROMLoadMenu->>CheatLoader: Load Cheats
    CheatLoader-->>ROMLoadMenu: Cheats Loaded/Error
    ROMLoadMenu->>ROMInfo: Save Cheat Setting
Loading

Possibly related PRs

Suggested Labels

enhancement, documentation

Poem

🐰 Cheats Unleashed, a Rabbit's Delight!

In menu's realm, a new code takes flight
ROM secrets revealed, with magical might
Bytes dancing free, no limits in sight
Rabbit's code magic, shining so bright!

🎮✨


Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media?

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Generate unit testing code for this file.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai generate unit testing code for this file.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and generate unit testing code.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments.

CodeRabbit Commands (Invoked using PR comments)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR. (Beta)
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@XLuma
Copy link
Author

XLuma commented Jan 14, 2025

I would also like to implement the following before a merge in the main branch:

  • Per-game Cheats on/off setting
  • In accordance with above setting, a new screen to enable all cheats, specific cheats, or disable all

src/menu/cart_load.c Outdated Show resolved Hide resolved
src/menu/menu.c Outdated Show resolved Hide resolved
cheat_load_err_t cheat_err = load_cheats(menu);
if (cheat_err != CHEAT_LOAD_OK) {
menu_show_error(menu, cheat_load_convert_error_message(cheat_err));
return;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If cheats are not loaded, are you sure you want to return? that will stop the ROM from loading?!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be possible to display the error, but proceed with boot after a timeout ?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can also just set cheat_list to NULL if there is an error, but I wanted to provide the user with feedback in case something happened

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We need to think about that senario in a bit more depth then.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An idea is to parse the cheats not at game launch, but rather when a user enables cheats for their game. This way, feedback can be provided way earlier in the timeline without hindering at the game boot process

@networkfusion
Copy link
Collaborator

@XLuma would you take issue if I make some further codestyle improvements (mainly space vs tabs) and just push them to the branch? it will require you to pull after...

@XLuma
Copy link
Author

XLuma commented Jan 14, 2025

@XLuma would you take issue if I make some further codestyle improvements (mainly space vs tabs) and just push them to the branch? it will require you to pull after...

Go ahead !

@networkfusion
Copy link
Collaborator

networkfusion commented Jan 14, 2025

@XLuma would you take issue if I make some further codestyle improvements (mainly space vs tabs) and just push them to the branch? it will require you to pull after...

Go ahead !

Done. The other main thing that I can see (for code style) is wrapping ifs etc with {} even one liners. This has become common practice.

I have not done it as it is too easy to get the flow incorrect.

@networkfusion networkfusion marked this pull request as draft January 14, 2025 23:27
@XLuma
Copy link
Author

XLuma commented Jan 16, 2025

Some games that use the Expansion pak will not work with cheats. Ideally, we prompt the user before enabling cheats for any game that "Recommends" or "Requires" the expansion pak

@networkfusion
Copy link
Collaborator

Some games that use the Expansion pak will not work with cheats. Ideally, we prompt the user before enabling cheats for any game that "Recommends" or "Requires" the expansion pak

Technically that is what "enable code"s are for, so that needs to be part of the suggestion.

@networkfusion
Copy link
Collaborator

@XLuma I have pushed codestyle fixes. Please check I have not broke it (especially find_str and get_next_str)

@@ -857,6 +857,8 @@ static rom_err_t save_override (path_t *path, const char *id, int value, int def

if (value == default_value) {
mini_err = mini_delete_value(rom_info_ini, "custom_boot", id);
} else if (strncmp(id, "cheat_codes", strlen("cheat_codes"))) {
mini_err = mini_set_bool(rom_info_ini, NULL, id, value);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

something funky going on here... need to check

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Current thinking is that this block

    if (value == default_value) {
        mini_err = mini_delete_value(rom_info_ini, "custom_boot", id);
    } else if (strncmp(id, "cheat_codes", strlen("cheat_codes"))) {
        mini_err = mini_set_bool(rom_info_ini, NULL, id, value);
    } else {
        mini_err = mini_set_int(rom_info_ini, "custom_boot", id, value);
    }

is in the wrong place and should be seperate from the ROM info file.

Though I have not looked into where it should actually be.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So i wrote this before I had this next idea:
Ideally, the .ini file stores an array or something like that) of cheat titles/indexes (whatever ends up working best), so that rather than having an on-off cheat, the menu will parse previously enabled cheats.
This approach would ensure errors would ahve been shown to the user at some point, and thus only working/enabled cheats are included

@@ -15,6 +15,7 @@ static const char *image_extensions[] = { "png", "jpg", "gif", NULL };
static const char *music_extensions[] = { "mp3", "wav", "ogg", "wma", "flac", NULL };
static const char *controller_pak_extensions[] = { "mpk", "pak", NULL };
static const char *emulator_extensions[] = { "nes", "smc", "gb", "gbc", "sms", "gg", "chf", NULL };
static const char *cheat_extensions[] = {"cht", NULL};
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are we happy with this extension name?!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This allows users to kinda drag-and-drop files from other sources(PJ64 for ex) with only some reformatting. Totally open to other extensions though

@networkfusion networkfusion changed the title [develop] Add initial cheat support in frontend [develop] Add datel cheat support from filesystem Jan 16, 2025
@networkfusion
Copy link
Collaborator

@CodeRabbit full review

Copy link

coderabbitai bot commented Jan 16, 2025

✅ Actions performed

Full review triggered.

Copy link

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (5)
src/menu/cheat_load.c (2)

89-115: Replace custom ft_split with a standard function

The custom string splitting function ft_split can be replaced with standard or library functions for better reliability and maintainability.

Consider using strtok or a well-tested library function to split strings.


31-57: Simplify and optimize the find_str function

The find_str function can be simplified to improve readability and performance.

Consider simplifying the function as follows:

-static int find_str (char const *s, char c) {
-    int i;
-    int nb_str;
-
-    i = 0;
-    nb_str = 0;
-    if (!s[0]) {
-        return (0);
-    }
-    while (s[i] && s[i] == c) {
-        i++;
-    }
-    while (s[i]) {
-        if (s[i] == c) {
-            nb_str++;
-            while (s[i] && s[i] == c) {
-                i++;
-            }
-            continue;
-        }
-        i++;
-    }
-    if (s[i - 1] != c) {
-        nb_str++;
-    }
-    return (nb_str);
+static int count_substrings(const char *s, char c) {
+    int count = 0;
+    int in_substring = 0;
+
+    while (*s) {
+        if (*s != c && !in_substring) {
+            in_substring = 1;
+            count++;
+        } else if (*s == c) {
+            in_substring = 0;
+        }
+        s++;
+    }
+    return count;
 }

Don't forget to update calls to use count_substrings instead of find_str.

docs/13_datel_cheats.md (3)

19-22: Add descriptions for the supported code types.

The code type descriptions are missing. Please provide clear explanations for each supported code type (80, D0, Fx).


16-18: Complete the expansion pak caveats section.

The caveats section about cheats and expansion paks is incomplete.


34-42: Add language specifiers to code blocks.

The code blocks should specify the language for proper syntax highlighting.

Apply these changes:

-```
+```txt
 # Super mario 64 infinite lives
 8033B21D 0064
...
-```
+```txt
 # Example cheat codes for the game "Majoras Mask USA"
 # Enable code
...

Also applies to: 45-54

🧰 Tools
🪛 Markdownlint (0.37.0)

34-34: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between ae9f10c and b8f3bcc.

📒 Files selected for processing (9)
  • Makefile (1 hunks)
  • docs/13_datel_cheats.md (1 hunks)
  • src/menu/cart_load.c (1 hunks)
  • src/menu/cheat_load.c (1 hunks)
  • src/menu/cheat_load.h (1 hunks)
  • src/menu/rom_info.c (2 hunks)
  • src/menu/rom_info.h (1 hunks)
  • src/menu/views/file_info.c (2 hunks)
  • src/menu/views/load_rom.c (3 hunks)
🧰 Additional context used
🪛 LanguageTool
docs/13_datel_cheats.md

[formatting] ~24-~24: If the ‘because’ clause is essential to the meaning, do not use a comma before the clause.
Context: ...on here) The codes XX are not supported, because... - e.g. they rely on the button. ###...

(COMMA_BEFORE_BECAUSE)

🪛 Markdownlint (0.37.0)
docs/13_datel_cheats.md

34-34: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)


46-46: null
Fenced code blocks should have a language specified

(MD040, fenced-code-language)

🪛 cppcheck (2.10-2)
src/menu/cheat_load.c

[error] 152-152: Memory leak

(memleak)


[error] 158-158: Memory leak

(memleak)

🔇 Additional comments (12)
src/menu/cheat_load.c (2)

111-111: Ensure strlcpy is portable or provide an alternative

The function strlcpy is not part of the C standard library and may not be available on all platforms.

Check if strlcpy is available in your development environment. If not, consider using strncpy or implementing strlcpy manually.

Would you like assistance in providing a portable implementation of strlcpy?


183-184: Validate the return values of strtoul

strtoul may fail or return zero for invalid inputs, which could cause unexpected behavior.

Ensure to check for errors after calling strtoul and handle invalid inputs appropriately.

 uint32_t cheatValue1 = strtoul(splitCheat[0], NULL, 16);
 uint32_t cheatValue2 = strtoul(splitCheat[1], NULL, 16);
+if (cheatValue1 == 0 && splitCheat[0][0] != '0') {
+    // Handle invalid cheat code
+    continue;
+}
+if (cheatValue2 == 0 && splitCheat[1][0] != '0') {
+    // Handle invalid cheat value
+    continue;
+}
src/menu/cheat_load.h (1)

26-26: Add a newline at the end of the file

POSIX standards recommend that files end with a newline character.

src/menu/views/file_info.c (1)

18-18: Confirm the cheat file extension 'cht'

Ensure that the extension 'cht' for cheat files aligns with project conventions and does not conflict with other file types.

src/menu/rom_info.h (1)

250-251: LGTM!

The function declaration follows the established naming convention and has appropriate parameters for managing cheat settings.

src/menu/views/load_rom.c (3)

170-185: LGTM! Error handling looks good.

The function properly handles memory management and displays errors without blocking the ROM loading process, addressing the concerns raised in previous reviews.


225-229: LGTM! Menu integration is clean.

The cheat options menu is properly integrated into the existing context menu system.


235-235: LGTM! Menu item placement is appropriate.

The "Set Cheats" option is logically placed among other ROM settings.

src/menu/rom_info.c (1)

967-970: LGTM! Clean implementation.

The function implementation is clean and follows the established pattern of other similar functions.

Makefile (1)

46-46: LGTM! Source file addition is properly structured.

The new source file menu/cheat_load.c is correctly added to the SRCS list and follows the alphabetical ordering convention within the menu section.

src/menu/cart_load.c (2)

9-9: LGTM! Header inclusion is properly placed.

The cheat_load.h header is correctly positioned after system headers and before local headers.


Line range hint 1-200: Verify integration of cheat loading functionality.

While the header is included, there appears to be no integration of the cheat loading functionality in the ROM loading process. Based on the PR objectives, we should verify if cheat loading needs to be integrated here, particularly in the cart_load_n64_rom_and_save function where ROM loading occurs.

Let's verify the integration requirements:

Comment on lines +121 to +195
path_t *path = path_clone(menu->load.rom_path);

// Parse cheats from file
path_ext_replace(path, "cht");
if((cheatsFile = fopen(path_get(path), "rb")) == NULL) {
path_free(path);
return CHEAT_LOAD_OK; // no file is not an error.
}

if (fstat(fileno(cheatsFile), &st)){
path_free(path);
return CHEAT_LOAD_ERR_SIZE_FAILED;
}

cheatsLength = st.st_size;
if (cheatsLength <= 0) {
path_free(path);
return CHEAT_LOAD_ERR_CHEAT_EMPTY;
}
if (cheatsLength > KiB(128)) {
path_free(path);
return CHEAT_LOAD_ERR_CHEAT_TOO_LARGE;
}

char *cheatsContent = NULL;
if((cheatsContent = malloc((cheatsLength + 1) * sizeof(char))) == NULL) {
path_free(path);
return CHEAT_LOAD_ERR_MALLOC_FAILED;
}
if(fread(cheatsContent, cheatsLength, 1, cheatsFile) != 1) {
path_free(path);
return CHEAT_LOAD_ERR_READ_FAILED;
}

cheatsContent[cheatsLength] = '\0';
if(fclose(cheatsFile) != 0){
path_free(path);
return CHEAT_LOAD_ERR_CLOSE_FAILED;
}
cheatsFile = NULL;

char **tab = ft_split(cheatsContent, '\n');
size_t lines = 1;
for (size_t i = 0; tab[i] != NULL; i++) {
lines++;
}

free(cheatsContent);

uint32_t *cheats = (uint32_t*)malloc(((lines * sizeof(uint32_t)) * 2) + 2);
memset(cheats, 0, ((lines * sizeof(uint32_t)) * 2) + 2);
size_t cheatIndex = 0;
for(size_t i = 0; tab[i] != NULL; i++) {
// ignore titles
if (tab[i][0] == '#' || tab[i][0] == '$') {
continue;
}
// ignore empty, too small or too big lines
if (strlen(tab[i]) < 12 || strlen(tab[i]) > 15) {
continue;
}
char **splitCheat = ft_split(tab[i], ' ');
uint32_t cheatValue1 = strtoul(splitCheat[0], NULL, 16);
uint32_t cheatValue2 = strtoul(splitCheat[1], NULL, 16);
cheats[cheatIndex] = cheatValue1;
cheats[cheatIndex + 1] = cheatValue2;
free_tab(splitCheat);
cheatIndex += 2;
}
free_tab(tab);

cheats[cheatIndex] = 0;
cheats[cheatIndex + 1] = 0;
menu->boot_params->cheat_list = cheats;

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Ensure all allocated resources are freed in error paths

In the function load_cheats, some error paths do not free allocated resources like path, cheatsContent, and cheats.

Review all return statements and make sure that allocated resources are properly freed to prevent memory leaks.

Would you like me to help refactor the function to ensure all resources are correctly managed?

🧰 Tools
🪛 cppcheck (2.10-2)

[error] 152-152: Memory leak

(memleak)


[error] 158-158: Memory leak

(memleak)

Comment on lines +156 to +159
if(fclose(cheatsFile) != 0){
path_free(path);
return CHEAT_LOAD_ERR_CLOSE_FAILED;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix memory leak when fclose fails

If fclose fails, cheatsContent is not freed before returning, leading to a memory leak.

Apply this diff to fix the issue:

 if(fclose(cheatsFile) != 0){
     path_free(path);
+    free(cheatsContent);
     return CHEAT_LOAD_ERR_CLOSE_FAILED;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(fclose(cheatsFile) != 0){
path_free(path);
return CHEAT_LOAD_ERR_CLOSE_FAILED;
}
if(fclose(cheatsFile) != 0){
path_free(path);
free(cheatsContent);
return CHEAT_LOAD_ERR_CLOSE_FAILED;
}
🧰 Tools
🪛 cppcheck (2.10-2)

[error] 158-158: Memory leak

(memleak)

Comment on lines +150 to +153
if(fread(cheatsContent, cheatsLength, 1, cheatsFile) != 1) {
path_free(path);
return CHEAT_LOAD_ERR_READ_FAILED;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix memory leak when fread fails

If fread fails, cheatsContent is not freed before returning, leading to a memory leak.

Apply this diff to fix the issue:

 if(fread(cheatsContent, cheatsLength, 1, cheatsFile) != 1) {
     path_free(path);
+    free(cheatsContent);
     return CHEAT_LOAD_ERR_READ_FAILED;
 }
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
if(fread(cheatsContent, cheatsLength, 1, cheatsFile) != 1) {
path_free(path);
return CHEAT_LOAD_ERR_READ_FAILED;
}
if(fread(cheatsContent, cheatsLength, 1, cheatsFile) != 1) {
path_free(path);
free(cheatsContent);
return CHEAT_LOAD_ERR_READ_FAILED;
}
🧰 Tools
🪛 cppcheck (2.10-2)

[error] 152-152: Memory leak

(memleak)

Comment on lines +170 to +171
uint32_t *cheats = (uint32_t*)malloc(((lines * sizeof(uint32_t)) * 2) + 2);
memset(cheats, 0, ((lines * sizeof(uint32_t)) * 2) + 2);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Adjust the allocation size for cheats array

The calculation for the size of the cheats array may lead to insufficient memory allocation.

Update the allocation size to accommodate all cheat entries and the terminating zeros:

-uint32_t  *cheats = (uint32_t*)malloc(((lines * sizeof(uint32_t)) * 2) + 2);
-memset(cheats, 0, ((lines * sizeof(uint32_t)) * 2) + 2);
+uint32_t *cheats = (uint32_t *)malloc(((lines + 1) * 2 * sizeof(uint32_t)));
+memset(cheats, 0, ((lines + 1) * 2 * sizeof(uint32_t)));
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
uint32_t *cheats = (uint32_t*)malloc(((lines * sizeof(uint32_t)) * 2) + 2);
memset(cheats, 0, ((lines * sizeof(uint32_t)) * 2) + 2);
uint32_t *cheats = (uint32_t *)malloc(((lines + 1) * 2 * sizeof(uint32_t)));
memset(cheats, 0, ((lines + 1) * 2 * sizeof(uint32_t)));

Comment on lines +164 to +166
for (size_t i = 0; tab[i] != NULL; i++) {
lines++;
}
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Correct the initialization of lines

Initializing lines to 1 may lead to an incorrect count of cheat entries.

Initialize lines to 0 to accurately count the number of lines:

-size_t lines = 1;
+size_t lines = 0;
 for (size_t i = 0; tab[i] != NULL; i++) {
     lines++;
 }

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +860 to +861
} else if (strncmp(id, "cheat_codes", strlen("cheat_codes"))) {
mini_err = mini_set_bool(rom_info_ini, NULL, id, value);
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix the string comparison logic.

The strncmp condition is incorrect. It returns 0 for equal strings, so the current logic is inverted.

Apply this diff to fix the logic:

-    } else if (strncmp(id, "cheat_codes", strlen("cheat_codes"))) {
+    } else if (strncmp(id, "cheat_codes", strlen("cheat_codes")) == 0) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
} else if (strncmp(id, "cheat_codes", strlen("cheat_codes"))) {
mini_err = mini_set_bool(rom_info_ini, NULL, id, value);
} else if (strncmp(id, "cheat_codes", strlen("cheat_codes")) == 0) {
mini_err = mini_set_bool(rom_info_ini, NULL, id, value);

@networkfusion
Copy link
Collaborator

@XLuma the coderabbit review is AI (imperfect) some suggestions might be helpful, but they are only suggestions, and not mandatory.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants