11#include " profiles.h"
22#define STB_DS_IMPLEMENTATION
33#include " stb_ds.h"
4- #include " crc32 .h"
4+ #include " sha256 .h"
55#include " chip8.h"
66#include " toast.h"
77#include < SDL2/SDL.h>
88#include < stdio.h>
99#include < string.h>
1010#include < stddef.h>
1111
12- /* ROM profile hashmap: CRC32 -> profile */
13- static struct { uint32_t key; struct profile value; } *profile_map = NULL ;
12+ /* ROM profile hashmap: SHA256 -> profile */
13+ static struct { sha256_hash_t key; struct profile value; } *profile_map = NULL ;
1414
1515/* Track which path we loaded profiles.ini from */
1616static char loaded_profiles_path[512 ] = " " ;
@@ -36,7 +36,7 @@ static int create_profiles_file(const char *path) {
3636 FILE *file = fopen (path, " w" );
3737 if (!file) return 0 ;
3838 fprintf (file, " # ROM Profiles Database\n " );
39- fprintf (file, " # Format: [0xCRC32 ] followed by quirk settings\n\n " );
39+ fprintf (file, " # Format: [0xSHA256 ] followed by quirk settings\n\n " );
4040 fclose (file);
4141 return 1 ;
4242}
@@ -47,7 +47,8 @@ static void parse_profiles_ini(void) {
4747 if (!file) return ;
4848
4949 char line[512 ];
50- uint32_t current_crc = 0 ;
50+ sha256_hash_t current_sha256 = {0 };
51+ int has_current = 0 ;
5152 struct profile current_profile;
5253
5354 while (fgets (line, sizeof (line), file)) {
@@ -58,23 +59,46 @@ static void parse_profiles_ini(void) {
5859 /* Skip empty lines and comments */
5960 if (line[0 ] == ' \0 ' || line[0 ] == ' #' ) continue ;
6061
61- /* Section header [0xHEXVALUE] */
62+ /* Section header [0xHEXVALUE] - 64 hex chars for SHA256 */
6263 if (line[0 ] == ' [' ) {
63- if (current_crc != 0 ) hmput (profile_map, current_crc , current_profile);
64+ if (has_current ) hmput (profile_map, current_sha256 , current_profile);
6465
65- if (sscanf (line, " [0x%x]" , ¤t_crc) != 1 ) {
66+ char hex_str[65 ];
67+ if (sscanf (line, " [%64[0-9a-fA-F]]" , hex_str) != 1 ) {
6668 printf (" Error: Invalid profile section header: %s\n " , line);
67- current_crc = 0 ;
69+ has_current = 0 ;
6870 continue ;
6971 }
72+
73+ /* Parse 64 hex characters into 32 bytes */
74+ if (strlen (hex_str) != 64 ) {
75+ printf (" Error: SHA256 must be 64 hex characters: %s\n " , hex_str);
76+ has_current = 0 ;
77+ continue ;
78+ }
79+
80+ for (int i = 0 ; i < 32 ; i++) {
81+ unsigned int byte;
82+ if (sscanf (hex_str + i*2 , " %2x" , &byte) != 1 ) {
83+ printf (" Error: Invalid hex in SHA256: %s\n " , hex_str);
84+ has_current = 0 ;
85+ goto next_line;
86+ }
87+ current_sha256.bytes [i] = (uint8_t )byte;
88+ }
89+
7090 memset (¤t_profile, 0 , sizeof (current_profile));
71- current_profile.crc32 = current_crc ;
91+ current_profile.sha256 = current_sha256 ;
7292 current_profile.quirks = quirks_get_defaults ();
93+ has_current = 1 ;
94+ continue ;
95+
96+ next_line:
7397 continue ;
7498 }
7599
76100 /* Key=value pairs */
77- if (current_crc == 0 ) continue ;
101+ if (!has_current ) continue ;
78102
79103 char key[256 ];
80104 int value;
@@ -96,7 +120,7 @@ static void parse_profiles_ini(void) {
96120 }
97121
98122 /* Commit last entry */
99- if (current_crc != 0 ) hmput (profile_map, current_crc , current_profile);
123+ if (has_current ) hmput (profile_map, current_sha256 , current_profile);
100124 fclose (file);
101125}
102126
@@ -177,8 +201,8 @@ void profiles_init(const char *custom_path) {
177201 }
178202}
179203
180- const struct profile * profile_lookup (uint32_t crc32 ) {
181- ptrdiff_t idx = hmgeti (profile_map, crc32 );
204+ const struct profile * profile_lookup (const sha256_hash_t *sha256 ) {
205+ ptrdiff_t idx = hmgeti (profile_map, *sha256 );
182206 return (idx >= 0 ) ? &profile_map[idx].value : NULL ;
183207}
184208
@@ -196,11 +220,13 @@ static void profiles_write_to_file(void) {
196220 }
197221
198222 fprintf (file, " # ROM Profiles Database\n " );
199- fprintf (file, " # Format: [0xCRC32 ] followed by quirk settings\n\n " );
223+ fprintf (file, " # Format: [0xSHA256 ] followed by quirk settings\n\n " );
200224
201225 for (int i = 0 ; i < hmlen (profile_map); i++) {
202226 struct profile *p = &profile_map[i].value ;
203- fprintf (file, " [0x%X]\n " , p->crc32 );
227+ char hash_hex[65 ];
228+ sha256_to_hex (&p->sha256 , hash_hex, sizeof (hash_hex));
229+ fprintf (file, " [%s]\n " , hash_hex);
204230 if (p->rom_name [0 ] != ' \0 ' ) fprintf (file, " name=%s\n " , p->rom_name );
205231 for (size_t q = 0 ; q < NUM_QUIRK_FIELDS; q++) {
206232 bool val = *(bool *)((char *)&p->quirks + quirk_fields[q].offset );
@@ -222,18 +248,20 @@ void profiles_save_current(void) {
222248 return ;
223249 }
224250
225- uint32_t crc = crc32_compute (chip8.rom , chip8.rom_size );
251+ sha256_hash_t sha256 = sha256_compute (chip8.rom , chip8.rom_size );
226252
227253 struct profile p;
228254 memset (&p, 0 , sizeof (p));
229- p.crc32 = crc ;
255+ p.sha256 = sha256 ;
230256 set_path (p.rom_name , sizeof (p.rom_name ), chip8.rom_filename );
231257 p.quirks = chip8.quirks ;
232258
233- hmput (profile_map, crc , p);
259+ hmput (profile_map, sha256 , p);
234260 profiles_write_to_file ();
235261
236- printf (" Saved ROM profile for: %s (CRC32: 0x%X)\n " , chip8.rom_filename , crc);
262+ char hash_hex[65 ];
263+ sha256_to_hex (&sha256, hash_hex, sizeof (hash_hex));
264+ printf (" Saved ROM profile for: %s (SHA256: %s)\n " , chip8.rom_filename , hash_hex);
237265 char msg[256 ];
238266 snprintf (msg, sizeof (msg), " Profile saved: %s" , chip8.rom_filename );
239267 toast_show (TOAST_SUCCESS, msg);
0 commit comments