diff options
Diffstat (limited to 'tools')
-rw-r--r-- | tools/aif2pcm/main.c | 112 | ||||
-rw-r--r-- | tools/mapjson/mapjson.cpp | 40 |
2 files changed, 103 insertions, 49 deletions
diff --git a/tools/aif2pcm/main.c b/tools/aif2pcm/main.c index 51dbf1bb9..cd5ac4a50 100644 --- a/tools/aif2pcm/main.c +++ b/tools/aif2pcm/main.c @@ -34,8 +34,8 @@ double ieee754_read_extended (uint8_t*); #define FATAL_ERROR(format, ...) \ do \ { \ - fprintf(stderr, format, __VA_ARGS__); \ - exit(1); \ + fprintf(stderr, format, __VA_ARGS__); \ + exit(1); \ } while (0) #else @@ -43,8 +43,8 @@ do \ #define FATAL_ERROR(format, ...) \ do \ { \ - fprintf(stderr, format, ##__VA_ARGS__); \ - exit(1); \ + fprintf(stderr, format, ##__VA_ARGS__); \ + exit(1); \ } while (0) #endif // _MSC_VER @@ -64,6 +64,12 @@ struct Bytes { uint8_t *data; }; +struct Marker { + unsigned short id; + unsigned long position; + // don't care about the name +}; + struct Bytes *read_bytearray(const char *filename) { struct Bytes *bytes = malloc(sizeof(struct Bytes)); @@ -167,6 +173,8 @@ void read_aif(struct Bytes *aif, AifData *aif_data) FATAL_ERROR("FORM Type is '%s', but it must be AIFF!", chunk_type); } + struct Marker *markers = NULL; + unsigned short num_markers = 0, loop_start = 0, loop_end = 0; unsigned long num_sample_frames = 0; // Read all the Chunks to populate the AifData struct. @@ -219,10 +227,17 @@ void read_aif(struct Bytes *aif, AifData *aif_data) } else if (strcmp(chunk_name, "MARK") == 0) { - unsigned short num_markers = (aif->data[pos++] << 8); + num_markers = (aif->data[pos++] << 8); num_markers |= (uint8_t)aif->data[pos++]; - // Read each marker and look for the "START" marker. + if (markers) + { + FATAL_ERROR("More than one MARK Chunk in file!\n"); + } + + markers = calloc(num_markers, sizeof(struct Marker)); + + // Read each marker. for (int i = 0; i < num_markers; i++) { unsigned short marker_id = (aif->data[pos++] << 8); @@ -233,28 +248,16 @@ void read_aif(struct Bytes *aif, AifData *aif_data) marker_position |= (aif->data[pos++] << 8); marker_position |= (uint8_t)aif->data[pos++]; - // Marker id is a pascal-style string. + // Marker name is a Pascal-style string. uint8_t marker_name_size = aif->data[pos++]; - char *marker_name = (char *)malloc((marker_name_size + 1) * sizeof(char)); + // We don't actually need the marker name for anything anymore. + /*char *marker_name = (char *)malloc((marker_name_size + 1) * sizeof(char)); memcpy(marker_name, &aif->data[pos], marker_name_size); - marker_name[marker_name_size] = '\0'; - pos += marker_name_size; - - if (strcmp(marker_name, "START") == 0) - { - aif_data->loop_offset = marker_position; - aif_data->has_loop = true; - } - else if (strcmp(marker_name, "END") == 0) - { - if (!aif_data->has_loop) { - aif_data->loop_offset = marker_position; - aif_data->has_loop = true; - } - aif_data->num_samples = marker_position; - } + marker_name[marker_name_size] = '\0';*/ + pos += marker_name_size + !(marker_name_size & 1); - free(marker_name); + markers[i].id = marker_id; + markers[i].position = marker_position; } } else if (strcmp(chunk_name, "INST") == 0) @@ -264,11 +267,31 @@ void read_aif(struct Bytes *aif, AifData *aif_data) aif_data->midi_note = midi_note; // Skip over data we don't need. - pos += 19; + pos += 7; + + unsigned short loop_type = (aif->data[pos++] << 8); + loop_type |= (uint8_t)aif->data[pos++]; + + if (loop_type) + { + loop_start = (aif->data[pos++] << 8); + loop_start |= (uint8_t)aif->data[pos++]; + + loop_end = (aif->data[pos++] << 8); + loop_end |= (uint8_t)aif->data[pos++]; + } + else + { + // Skip NoLooping sustain loop. + pos += 4; + } + + // Skip release loop, we don't need it. + pos += 6; } else if (strcmp(chunk_name, "SSND") == 0) { - // SKip offset and blockSize + // Skip offset and blockSize pos += 8; unsigned long num_samples = chunk_size - 8; @@ -285,6 +308,41 @@ void read_aif(struct Bytes *aif, AifData *aif_data) pos += chunk_size; } } + + if (markers) + { + // Resolve loop points. + struct Marker *cur_marker = markers; + + // Grab loop start point. + for (int i = 0; i < num_markers; i++, cur_marker++) + { + if (cur_marker->id == loop_start) + { + aif_data->loop_offset = cur_marker->position; + aif_data->has_loop = true; + break; + } + } + + cur_marker = markers; + + // Grab loop end point. + for (int i = 0; i < num_markers; i++, cur_marker++) + { + if (cur_marker->id == loop_end) + { + if (cur_marker->position < aif_data->loop_offset) { + aif_data->loop_offset = cur_marker->position; + aif_data->has_loop = true; + } + aif_data->num_samples = cur_marker->position; + break; + } + } + + free(markers); + } } // This is a table of deltas between sample values in compressed PCM data. diff --git a/tools/mapjson/mapjson.cpp b/tools/mapjson/mapjson.cpp index f4e7380b9..ad3aa3769 100644 --- a/tools/mapjson/mapjson.cpp +++ b/tools/mapjson/mapjson.cpp @@ -104,24 +104,22 @@ string generate_map_header_text(Json map_data, Json layouts_data) { << "\t.byte " << map_data["weather"].string_value() << "\n" << "\t.byte " << map_data["map_type"].string_value() << "\n"; - if (version == "firered") - text << "\t.byte " << map_data["unknown_18"].int_value() << "\n" - << "\t.byte " << map_data["unknown_19"].int_value() << "\n"; - else + if (version != "firered") text << "\t.2byte 0\n"; if (version == "ruby") { text << "\t.byte " << map_data["show_map_name"].bool_value() << "\n"; } - else if (version == "emerald") { + else if (version == "emerald" || version == "firered") { text << "\tmap_header_flags " - << "allow_bike=" << map_data["allow_bike"].bool_value() << ", " - << "allow_escape_rope=" << map_data["allow_escape_rope"].bool_value() << ", " - << "allow_run=" << map_data["allow_running"].bool_value() << ", " + << "allow_cycling=" << map_data["allow_cycling"].bool_value() << ", " + << "allow_escaping=" << map_data["allow_escaping"].bool_value() << ", " + << "allow_running=" << map_data["allow_running"].bool_value() << ", " << "show_map_name=" << map_data["show_map_name"].bool_value() << "\n"; } - else if (version == "firered") { - text << "\t.byte " << map_data["elevator_flag"].int_value() << "\n"; + + if (version == "firered") { + text << "\t.byte " << map_data["floor_number"].int_value() << "\n"; } text << "\t.byte " << map_data["battle_scene"].string_value() << "\n\n"; @@ -276,6 +274,7 @@ string generate_firered_map_events_text(Json map_data) { auto obj_event = map_data["object_events"].array_items()[i]; text << "\tobject_event " << i + 1 << ", " << obj_event["graphics_id"].string_value() << ", " + << (obj_event["in_connection"].bool_value() ? 255 : 0) << ", " << obj_event["x"].int_value() << ", " << obj_event["y"].int_value() << ", " << obj_event["elevation"].int_value() << ", " @@ -338,7 +337,15 @@ string generate_firered_map_events_text(Json map_data) { bgs_label = map_data["name"].string_value() + "_MapBGEvents"; text << bgs_label << "::\n"; for (auto &bg_event : map_data["bg_events"].array_items()) { - if (bg_event["type"] == "hidden_item") { + if (bg_event["type"] == "sign") { + text << "\tbg_event " + << bg_event["x"].int_value() << ", " + << bg_event["y"].int_value() << ", " + << bg_event["elevation"].int_value() << ", " + << bg_event["player_facing_dir"].string_value() << ", 0," + << bg_event["script"].string_value() << "\n"; + } + else if (bg_event["type"] == "hidden_item") { text << "\tbg_hidden_item_event " << bg_event["x"].int_value() << ", " << bg_event["y"].int_value() << ", " @@ -348,17 +355,6 @@ string generate_firered_map_events_text(Json map_data) { << bg_event["quantity"].int_value() << ", " << bg_event["underfoot"].bool_value() << "\n"; } - else { - string type_string = bg_event["type"].string_value(); - type_string.erase(0, 14); - int type = std::stoi(type_string); - text << "\tbg_event " - << bg_event["x"].int_value() << ", " - << bg_event["y"].int_value() << ", " - << bg_event["elevation"].int_value() << ", " - << type << ", 0, " - << bg_event["script"].string_value() << "\n"; - } } text << "\n"; } else { |