pokediamond/arm9/src/unk_02021934.c

307 lines
7.6 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "global.h"
#include "heap.h"
#include "string16.h"
#include "string_util.h"
#define ASSERT_STR16(_str) ({ GF_ASSERT(_str != NULL); GF_ASSERT(_str->magic == STR16_MAGIC); })
struct String *String_New(u32 length, enum HeapID heapID) {
struct String *ret = Heap_Alloc(heapID, length * 2 + 10);
if (ret != NULL) {
ret->magic = STR16_MAGIC;
ret->maxsize = (u16)length;
ret->size = 0;
ret->data[0] = EOS;
}
return ret;
}
void String_Delete(struct String *str) {
ASSERT_STR16(str);
str->magic = STR16_MAGIC | 1;
Heap_Free(str);
}
void String_SetEmpty(struct String *str) {
ASSERT_STR16(str);
str->size = 0;
str->data[0] = EOS;
}
void StringCopy(struct String *dest, struct String *src) {
ASSERT_STR16(dest);
ASSERT_STR16(src);
if (dest->maxsize > src->size) {
memcpy(dest->data, src->data, (u32)((src->size + 1) * 2));
dest->size = src->size;
return;
}
GF_ASSERT(0);
}
struct String *StringDup(struct String *src, enum HeapID heapID) {
ASSERT_STR16(src);
struct String *dest = String_New((u32)(src->size + 1), heapID);
if (dest != NULL) {
StringCopy(dest, src);
}
return dest;
}
void String16_FormatInteger(struct String *str, int num, u32 ndigits, enum PrintingMode printingMode, BOOL whichCharset) {
static const u16 sCharset_EN[10] = {
0x121, 0x122, 0x123, 0x124, 0x125, 0x126, 0x127, 0x128, 0x129, 0x12A
};
static const u16 sCharset_JP[10] = {
0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB
};
static const u32 sPowersOfTen[10] = {
1,
10,
100,
1000,
10000,
100000,
1000000,
10000000,
100000000,
1000000000
};
ASSERT_STR16(str);
const u16 *charbase;
BOOL isNegative = (num < 0);
if (str->maxsize > ndigits + isNegative) {
charbase = (whichCharset == 0) ? sCharset_JP : sCharset_EN;
String_SetEmpty(str);
if (isNegative) {
num *= -1;
u16 hyphen = (u16)((whichCharset == 0) ? 0x00F1 : 0x01BE);
str->data[str->size++] = hyphen;
}
u32 dividend = sPowersOfTen[ndigits - 1];
while (dividend != 0) {
u16 digit = (u16)(num / dividend);
num -= dividend * digit;
if (printingMode == PRINTING_MODE_LEADING_ZEROS) {
u16 value = (u16)((digit < 10) ? charbase[digit] : 0x00E2);
str->data[str->size++] = value;
} else if (digit != 0 || dividend == 1) {
printingMode = PRINTING_MODE_LEADING_ZEROS;
u16 value = (u16)((digit < 10) ? charbase[digit] : 0x00E2);
str->data[str->size++] = value;
} else if (printingMode == PRINTING_MODE_RIGHT_ALIGN) {
u16 value = (u16)((whichCharset == 0) ? 0x0001 : 0x01E2);
str->data[str->size++] = value;
}
dividend /= 10;
}
str->data[str->size] = EOS;
return;
}
GF_ASSERT(FALSE);
}
s64 String_atoi(struct String *str, BOOL *flag) {
s64 ret = 0;
s64 pow10 = 1;
if (str->size > 18) {
return 0;
}
int ndigits = str->size - 1;
while (ndigits >= 0) {
//
s64 digit = str->data[ndigits] - 0x00A2;
if (digit >= 10ull) {
// 0
digit = str->data[ndigits] - 0x0121;
if (digit >= 10ull) {
*flag = FALSE;
return ret;
}
}
digit *= pow10;
ret += digit;
pow10 *= 10;
ndigits--;
}
*flag = TRUE;
return ret;
}
BOOL String_Compare(struct String *str1, struct String *str2) {
ASSERT_STR16(str1);
ASSERT_STR16(str2);
for (int i = 0; str1->data[i] == str2->data[i]; i++) {
if (str1->data[i] == EOS) {
return FALSE;
}
}
return TRUE;
}
u16 StringGetLength(struct String *str) {
ASSERT_STR16(str);
return str->size;
}
int StringCountLines(volatile struct String *str) {
ASSERT_STR16(str);
int i, nline;
for (i = 0, nline = 1; i < str->size; i++) {
if (str->data[i] == CHAR_LF) {
nline++;
}
}
return nline;
}
void StringGetLineN(struct String *dest, volatile struct String *src, u32 n) {
ASSERT_STR16(src);
ASSERT_STR16(dest);
int i = 0;
if (n != 0) {
for (i = 0; i < src->size; i++) {
if (src->data[i] == CHAR_LF && --n == 0) {
i++;
break;
}
}
}
String_SetEmpty(dest);
for (; i < src->size; i++) {
u16 c = src->data[i];
if (c == CHAR_LF) {
break;
}
StrAddChar(dest, c);
}
}
void CopyU16ArrayToString(struct String *str, u16 *buf) {
ASSERT_STR16(str);
for (str->size = 0; *buf != EOS;) {
if (str->size >= str->maxsize - 1) {
GF_ASSERT(0);
break;
}
str->data[str->size++] = *buf++;
}
str->data[str->size] = EOS;
}
void CopyU16ArrayToStringN(struct String *str, u16 *buf, u32 length) {
ASSERT_STR16(str);
if (length <= str->maxsize) {
memcpy(str->data, buf, length * 2);
int i;
for (i = 0; i < length; i++) {
if (str->data[i] == EOS) {
break;
}
}
str->size = (u16)i;
if (i == length) {
str->data[length - 1] = EOS;
}
return;
}
GF_ASSERT(0);
}
void CopyStringToU16Array(struct String *str, u16 *buf, u32 length) {
ASSERT_STR16(str);
if (str->size + 1 <= length) {
memcpy(buf, str->data, (u32)((str->size + 1) * 2));
return;
}
GF_ASSERT(0);
}
u16 *String_c_str(struct String *str) {
ASSERT_STR16(str);
return str->data;
}
void StringCat(struct String *dest, struct String *src) {
ASSERT_STR16(dest);
ASSERT_STR16(src);
if (dest->size + src->size + 1 <= dest->maxsize) {
memcpy(dest->data + dest->size, src->data, (u32)(2 * (src->size + 1)));
dest->size += src->size;
return;
}
GF_ASSERT(0);
}
void StrAddChar(struct String *str, u16 val) {
ASSERT_STR16(str);
if (str->size + 1 < str->maxsize) {
str->data[str->size++] = val;
str->data[str->size] = EOS;
return;
}
GF_ASSERT(0);
}
void StrUpperFirstChar(struct String *str) {
ASSERT_STR16(str);
if (str->size != 0) {
// a z
if (str->data[0] >= 0x0145 && str->data[0] <= 0x015E) {
// (a - A)
str->data[0] -= 26;
}
}
}
BOOL String_IsTrainerName(struct String *string) {
return string->size != 0 && string->data[0] == 0xF100;
}
void StringCat_HandleTrainerName(struct String *dest, struct String *src) {
if (String_IsTrainerName(src)) {
u16 *dest_p = &dest->data[dest->size];
u16 *src_p = &src->data[1];
s32 bit = 0;
u32 outsize = 0;
u16 cur_char = 0;
while (1) {
cur_char = (u16)((*src_p >> bit) & 0x1FF);
bit += 9;
if (bit >= 15) {
src_p++;
bit -= 15;
if (bit != 0) {
cur_char |= (*src_p << (9 - bit)) & 0x1FF;
}
}
if (cur_char == 0x1FF) {
break;
}
*dest_p++ = cur_char;
outsize++;
}
*dest_p = EOS;
dest->size += outsize;
} else {
StringCat(dest, src);
}
}