diff --git a/README.md b/README.md index baede79..811490e 100644 --- a/README.md +++ b/README.md @@ -142,9 +142,10 @@ how to interpret them. They're comprised of the following key/value pairs: decimal digits of a number. The byte sequence `0x12 0x34` would translate to the decimal value `1234`. When converting BCD values, treat the nibbles 0xA to 0xF as 0 numerically, or a space for display purposes. - - `"ch"`: A sequence of 7-bit ASCII characters. If the JSON file has a - `_char_map` key, use bytes from the NV file as indexes into that string - instead of interpreting them as 7-bit ASCII. + - `"ch"`: A sequence of 7-bit ASCII characters that may be shortened by a + null byte (0x00) terminator based on the `"null"` attribute for the entry. + If the JSON file has a `_char_map` key, all bytes (including 0x00) are + indexes into that string. - `"raw"`: A series of raw bytes, useful for extracting data yet to be decoded or that requires custom processing. - `"wpc_rtc"`: A special type for a real-time clock value @@ -162,6 +163,12 @@ how to interpret them. They're comprised of the following key/value pairs: - **offsets**: Alternative to using start/end or start/length when bytes aren't contiguous. List of offsets to use. Either `start` or `offsets` are required. +- **null**: Used for `"ch"` encodings to specify null (0x00) byte handling. + For `truncate` and `terminate`, ignore all bytes after the null. + - `"ignore"`: Ignore (skip over) null bytes. + - `"truncate"`: A null can shorten the string, but won't be present for + strings that fill the allotted space. + - `"terminate"`: Null bytes are always present and terminate the string. - **min** and **max**: Used for adjustments to specify the valid range of values. - **default**: Used for adjustments to specify the factory default value. @@ -256,3 +263,4 @@ treat a single descriptor as a list of groupings-sized ranges. - v0.1: Initial Version - v0.2: Deprecate `packed` attribute in favor of `nibble`. - v0.3: Deprecate usage of hex strings for `start`, `end` and `offsets`. + Add the `null` attribute for entries with `ch` encoding. diff --git a/st_161h.nv.json b/st_161h.nv.json new file mode 100644 index 0000000..571b346 --- /dev/null +++ b/st_161h.nv.json @@ -0,0 +1,202 @@ +{ + "_notes": [ + "Compiled by Tom Collins, based on st_162h by HorsePin" + ], + "_copyright": "Copyright (C)2024 by Tom Collins ", + "_license": "GNU Lesser General Public License v3.0", + "_endian": "little", + "_ramsize": 131118, + "_roms": [ + "st_161h" + ], + "_fileformat": 0.3, + "_version": 0.1, + "last_game": [ + { + "encoding": "int", + "length": 4, + "start": 68108 + }, + { + "encoding": "int", + "length": 4, + "start": 68112 + }, + { + "encoding": "int", + "length": 4, + "start": 68116 + }, + { + "encoding": "int", + "length": 4, + "start": 68120 + } + ], + "high_scores": [ + { + "label": "Grand Champion", + "short_label": "GC", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 11904 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 11928 + } + }, + { + "label": "High Score #1", + "short_label": "#1", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 11936 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 11960 + } + }, + { + "label": "High Score #2", + "short_label": "#2", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 11968 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 11992 + } + }, + { + "label": "High Score #3", + "short_label": "#3", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12000 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12024 + } + }, + { + "label": "High Score #4", + "short_label": "#4", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12032 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12056 + } + } + ], + "mode_champions": [ + { + "label": "Combo Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12064 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12088, + "suffix": " Combos" + } + }, + { + "label": "Warp Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12096 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12120, + "suffix": " Warps" + } + }, + { + "label": "Medals Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12128 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12152, + "suffix": " Medals" + } + } + ], + "checksum16": [ + { + "start": 11904, + "length": 30, + "label": "Grand Champion" + }, + { + "start": 11936, + "length": 30, + "label": "High Score #1" + }, + { + "start": 11968, + "length": 30, + "label": "High Score #2" + }, + { + "start": 12000, + "length": 30, + "label": "High Score #3" + }, + { + "start": 12032, + "length": 30, + "label": "High Score #4" + }, + { + "start": 12064, + "length": 30, + "label": "Combo Champion" + }, + { + "start": 12096, + "length": 30, + "label": "Warp Champion" + }, + { + "start": 12128, + "length": 30, + "label": "Medals Champion" + } + ] +} diff --git a/st_162.nv.json b/st_162.nv.json new file mode 100644 index 0000000..6c338a9 --- /dev/null +++ b/st_162.nv.json @@ -0,0 +1,202 @@ +{ + "_notes": [ + "Compiled by Tom Collins, based on st_162h by HorsePin" + ], + "_copyright": "Copyright (C)2024 by Tom Collins ", + "_license": "GNU Lesser General Public License v3.0", + "_endian": "little", + "_ramsize": 131118, + "_roms": [ + "st_162" + ], + "_fileformat": 0.3, + "_version": 0.1, + "last_game": [ + { + "encoding": "int", + "length": 4, + "start": 68068 + }, + { + "encoding": "int", + "length": 4, + "start": 68072 + }, + { + "encoding": "int", + "length": 4, + "start": 68076 + }, + { + "encoding": "int", + "length": 4, + "start": 68080 + } + ], + "high_scores": [ + { + "label": "Grand Champion", + "short_label": "GC", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 11968 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 11992 + } + }, + { + "label": "High Score #1", + "short_label": "#1", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12000 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12024 + } + }, + { + "label": "High Score #2", + "short_label": "#2", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12032 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12056 + } + }, + { + "label": "High Score #3", + "short_label": "#3", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12064 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12088 + } + }, + { + "label": "High Score #4", + "short_label": "#4", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12096 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12120 + } + } + ], + "mode_champions": [ + { + "label": "Combo Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12128 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12152, + "suffix": " Combos" + } + }, + { + "label": "Warp Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12160 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12184, + "suffix": " Warps" + } + }, + { + "label": "Medals Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12192 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12216, + "suffix": " Medals" + } + } + ], + "checksum16": [ + { + "start": 11968, + "length": 30, + "label": "Grand Champion" + }, + { + "start": 12000, + "length": 30, + "label": "High Score #1" + }, + { + "start": 12032, + "length": 30, + "label": "High Score #2" + }, + { + "start": 12064, + "length": 30, + "label": "High Score #3" + }, + { + "start": 12096, + "length": 30, + "label": "High Score #4" + }, + { + "start": 12128, + "length": 30, + "label": "Combo Champion" + }, + { + "start": 12160, + "length": 30, + "label": "Warp Champion" + }, + { + "start": 12192, + "length": 30, + "label": "Medals Champion" + } + ] +} diff --git a/st_162h.nv.json b/st_162h.nv.json index 6883e0d..a67c162 100644 --- a/st_162h.nv.json +++ b/st_162h.nv.json @@ -1,15 +1,15 @@ { "_notes": [ - "Compiled by NV Mapping Helper (Replace with your name)" + "Compiled by Tom Collins, based on st_162h by HorsePin" ], - "_copyright": "Copyright (C) 2022 by YourName your email>", + "_copyright": "Copyright (C)2024 by Tom Collins ", "_license": "GNU Lesser General Public License v3.0", "_endian": "little", "_ramsize": 131118, "_roms": [ "st_162h" ], - "_fileformat": 0.1, + "_fileformat": 0.3, "_version": 0.1, "last_game": [ { @@ -39,70 +39,164 @@ "short_label": "GC", "initials": { "encoding": "ch", - "length": 3, + "null": "terminate", + "length": 11, "start": 11984 }, "score": { "encoding": "int", "length": 4, - "start": 8600 + "start": 12008 } }, { - "label": "#1", + "label": "High Score #1", "short_label": "#1", "initials": { "encoding": "ch", - "length": 3, + "null": "terminate", + "length": 11, "start": 12016 }, "score": { "encoding": "int", "length": 4, - "start": 8608 + "start": 12040 } }, { - "label": "#2", + "label": "High Score #2", "short_label": "#2", "initials": { "encoding": "ch", - "length": 3, + "null": "terminate", + "length": 11, "start": 12048 }, "score": { "encoding": "int", "length": 4, - "start": 8616 + "start": 12072 } }, { - "label": "#3", + "label": "High Score #3", "short_label": "#3", "initials": { "encoding": "ch", - "length": 3, + "null": "terminate", + "length": 11, "start": 12080 }, "score": { "encoding": "int", "length": 4, - "start": 8624 + "start": 12104 } }, { - "label": "#4", + "label": "High Score #4", "short_label": "#4", "initials": { "encoding": "ch", - "length": 2, + "null": "terminate", + "length": 11, "start": 12112 }, "score": { "encoding": "int", "length": 4, - "start": 8632 + "start": 12136 } } + ], + "mode_champions": [ + { + "label": "Combo Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12144 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12168, + "suffix": " Combos" + } + }, + { + "label": "Warp Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12176 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12200, + "suffix": " Warps" + } + }, + { + "label": "Medals Champion", + "initials": { + "encoding": "ch", + "null": "terminate", + "length": 11, + "start": 12208 + }, + "score": { + "encoding": "int", + "length": 4, + "start": 12232, + "suffix": " Medals" + } + } + ], + "checksum16": [ + { + "start": 11984, + "length": 30, + "label": "Grand Champion" + }, + { + "start": 12016, + "length": 30, + "label": "High Score #1" + }, + { + "start": 12048, + "length": 30, + "label": "High Score #2" + }, + { + "start": 12080, + "length": 30, + "label": "High Score #3" + }, + { + "start": 12112, + "length": 30, + "label": "High Score #4" + }, + { + "start": 12144, + "length": 30, + "label": "Combo Champion" + }, + { + "start": 12176, + "length": 30, + "label": "Warp Champion" + }, + { + "start": 12208, + "length": 30, + "label": "Medals Champion" + } ] } diff --git a/tools/normalize-map.py b/tools/normalize-map.py index fc1b873..ee85728 100755 --- a/tools/normalize-map.py +++ b/tools/normalize-map.py @@ -13,6 +13,7 @@ ------------------- * v0.3: - convert start/end values stored as hex strings to decimal values + - introduce new `null` attribute for `ch` encoding * v0.2: - remove "packed"=true and replace "packed"=false with "nibble"="low" @@ -37,10 +38,13 @@ def map_convert(pairs): result = {} for k, v in pairs: if k == '_fileformat': - file_format = v + minimum_file_format(v) elif k == 'nibble': # "nibble" is only valid in v0.2 and later minimum_file_format(0.2) + elif k == 'null': + # "null" is only valid in v0.3 and later + minimum_file_format(0.3) if k == 'packed': # as of v0.2, "packed" attribute deprecated in favor of "nibble"