mirror of
https://github.com/open-goal/jak-project.git
synced 2024-10-20 21:27:52 -04:00
196 lines
5 KiB
C++
196 lines
5 KiB
C++
|
/*!
|
||
|
* @file isocommon.cpp
|
||
|
* Common ISO utilities.
|
||
|
*/
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include "common/common_types.h"
|
||
|
#include <cstring>
|
||
|
#include "isocommon.h"
|
||
|
|
||
|
/*!
|
||
|
* Convert file name to "ISO Name"
|
||
|
* ISO names are upper case and 12 bytes long.
|
||
|
* xxxxxxxxyyy0
|
||
|
*
|
||
|
* x - uppercase letter of file name, or space
|
||
|
* y - uppercase letter of file extension, or space
|
||
|
* 0 - null terminator (\0, not the character zero)
|
||
|
*/
|
||
|
void MakeISOName(char* dst, const char* src) {
|
||
|
int i = 0;
|
||
|
const char* src_ptr = src;
|
||
|
char* dst_ptr = dst;
|
||
|
|
||
|
// copy name and upper case
|
||
|
while ((i < 8) && (*src_ptr) && (*src_ptr != '.')) {
|
||
|
char c = *src_ptr;
|
||
|
src_ptr++;
|
||
|
if (('`' < c) && (c < '{')) { // lower case
|
||
|
c -= 0x20;
|
||
|
}
|
||
|
*dst_ptr = c;
|
||
|
dst_ptr++;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
// pad out name with spaces
|
||
|
while (i < 8) {
|
||
|
*dst_ptr = ' ';
|
||
|
dst_ptr++;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
// increment past period
|
||
|
if (*src_ptr == '.')
|
||
|
src_ptr++;
|
||
|
|
||
|
// same for extension
|
||
|
while (i < 11 && (*src_ptr)) {
|
||
|
char c = *src_ptr;
|
||
|
src_ptr++;
|
||
|
if (('`' < c) && (c < '{')) { // lower case
|
||
|
c -= 0x20;
|
||
|
}
|
||
|
*dst_ptr = c;
|
||
|
dst_ptr++;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
while (i < 11) {
|
||
|
*dst_ptr = ' ';
|
||
|
dst_ptr++;
|
||
|
i++;
|
||
|
}
|
||
|
*dst_ptr = 0;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* Unmakes an ISO name back to the original name.
|
||
|
* Keeps it upper case.
|
||
|
* Not used.
|
||
|
*/
|
||
|
void UnmakeISOName(char* dst, const char* src) {
|
||
|
int i = 0;
|
||
|
const char* src_ptr = src;
|
||
|
char* dst_ptr = dst;
|
||
|
|
||
|
// copy non-space characters
|
||
|
while ((i < 8) && (*src != ' ')) {
|
||
|
*dst_ptr = *src_ptr;
|
||
|
src_ptr++;
|
||
|
dst_ptr++;
|
||
|
i++;
|
||
|
}
|
||
|
|
||
|
// skip src to the extension
|
||
|
src_ptr += 8 - i;
|
||
|
|
||
|
if (*src_ptr != ' ') {
|
||
|
// if there's an extension, add the period
|
||
|
*dst_ptr = '.';
|
||
|
i = 0;
|
||
|
// copy extension
|
||
|
dst_ptr++;
|
||
|
while (i < 3 && *src_ptr != ' ') {
|
||
|
*dst_ptr = *src_ptr;
|
||
|
src_ptr++;
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
*dst_ptr = 0;
|
||
|
}
|
||
|
|
||
|
/*!
|
||
|
* Convert an animation name to ISO name.
|
||
|
* The animation name is a bunch of dash separated words.
|
||
|
* The resulting ISO name has the same first two chars as the animation name, and one char from each
|
||
|
* remaining word. Once there are no more words but remaining chars in the ISO name, the ith extra
|
||
|
* char is the i+1 th char of the last word. A word ending in a number (or just a number) is turned
|
||
|
* into the number. The word "resolution" becomes z. The word "accept" becomes y. The word "reject"
|
||
|
* becomes n. Other words become the first char of the word. The result is uppercased and the file
|
||
|
* extension is STR Examples (animation name and disc file name, not ISO name):
|
||
|
* green-sagecage-outro-beat-boss-enough-cells -> GRSOBBEC.STR
|
||
|
* swamp-tetherrock-swamprockexplode-4 -> SWTS4.STR
|
||
|
* minershort-resolution-1-orbs -> MIZ1ORBS.STR
|
||
|
* @param dst
|
||
|
* @param src
|
||
|
*/
|
||
|
void ISONameFromAnimationName(char* dst, const char* src) {
|
||
|
// The Animation Name is a bunch of words separated by dashes
|
||
|
|
||
|
// copy first two chars of the first word exactly
|
||
|
dst[0] = src[0];
|
||
|
dst[1] = src[1];
|
||
|
s32 i = 2; // 2 chars added to dst.
|
||
|
|
||
|
// skip ahead to the first dash (or \0 if there's no dashes)
|
||
|
const char* src_ptr = src;
|
||
|
while (*src_ptr && *src_ptr != '-') {
|
||
|
src_ptr++;
|
||
|
}
|
||
|
|
||
|
// the points to the next dash (or \0 if there's none).
|
||
|
const char* next_ptr = src_ptr;
|
||
|
if (*src_ptr) {
|
||
|
// loop over words (next_ptr points to dash before word, i counts chars in dest)
|
||
|
while (src_ptr = next_ptr + 1, i < 8) {
|
||
|
// scan next_ptr forward to next dash
|
||
|
next_ptr = src_ptr;
|
||
|
while (*next_ptr && *next_ptr != '-') {
|
||
|
next_ptr++;
|
||
|
}
|
||
|
|
||
|
// there's no next word, so break (the current word will be handled there)
|
||
|
if (!*next_ptr)
|
||
|
break;
|
||
|
|
||
|
// add a char for the current word:
|
||
|
char char_to_add;
|
||
|
if (next_ptr[-1] < '0' || next_ptr[-1] > '9') {
|
||
|
// word doesn't end in a number.
|
||
|
|
||
|
// some special case words map to special letters (likely to avoid animation name conflicts)
|
||
|
if (next_ptr - src_ptr == 10 && !memcmp(src_ptr, "resolution", 10)) {
|
||
|
char_to_add = 'z';
|
||
|
} else if (next_ptr - src_ptr == 6 && !memcmp(src_ptr, "accept", 6)) {
|
||
|
char_to_add = 'y';
|
||
|
} else if (next_ptr - src_ptr == 6 && !memcmp(src_ptr, "reject", 6)) {
|
||
|
char_to_add = 'n';
|
||
|
} else {
|
||
|
// not a special case, just take the first letter.
|
||
|
char_to_add = *src_ptr;
|
||
|
}
|
||
|
} else {
|
||
|
// the current word ends in a number, just use this number (I think usually the whole word
|
||
|
// is just a number)
|
||
|
char_to_add = next_ptr[-1];
|
||
|
}
|
||
|
|
||
|
dst[i++] = char_to_add;
|
||
|
}
|
||
|
|
||
|
// here we ran out of room in dest, or words in source.
|
||
|
// if there's still room in dest and chars in source, just add them
|
||
|
while (*src_ptr && (i < 8)) {
|
||
|
dst[i] = *src_ptr;
|
||
|
src_ptr++;
|
||
|
i++;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// pad with spaces (for ISO Name)
|
||
|
while (i < 8) {
|
||
|
dst[i++] = ' ';
|
||
|
}
|
||
|
|
||
|
// upper case
|
||
|
for (i = 0; i < 8; i++) {
|
||
|
if (dst[i] > '`' && dst[i] < '{') {
|
||
|
dst[i] -= 0x20;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// append file extension
|
||
|
strcpy(dst + 8, "STR");
|
||
|
}
|