GBA-Exploader/arm9/source/unicode.c
ApacheThunder 65962d1a37 Add support for SuperCard/3in1 Plus
* Add new error message for detecting if run on DSi/3DS consoles as this
program isn't really compatible with those consoles for obvious reasons.
* Add initial support for SuperCard Lite (and possibly other SuperCard
varients). Note that saves are not currently functional though.
* Add back initial support for EZ Flash 3 in 1 Plus. Note that NorFlash
commands appear to not be working at the moment. RAM mode untested. New
code added for detecting 3 in 1 Plus when detecting max allowed file
size. This should allow writing 64MB gba roms to 3 in 1 Plus...once
NorFlash stuff is fixed that is. :P
* Tested as working properly with regular EZ Flash 3 in 1 carts.
* Note that version 0.58 already exists but we do not have source code
for it. (source was released only for 0.57. Rudolph could not find the
last version's source code unfortunately. This is why 3 in 1 Plus
support is incomplete. (it at least detects it now which original 0.57
could not do and will in theory allow writing 64MB GBA roms once
NorFlash stuff is fixed for that cart)
2024-05-18 14:07:26 -05:00

206 lines
3.7 KiB
C
Raw 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 <nds.h>
#include <string.h>
#include <ctype.h>
#include "unicode.h"
/*#include "unicode_u2l_bin.h"
#include "unicode_l2u_bin.h"
#include "unicode_ank_bin.h"*/
extern u16 unicode_u2l_bin[];
extern u16 unicode_l2u_bin[];
extern u16 unicode_ank_bin[];
static u16 _codePage = 0;
static const u16 * _L2UTable = NULL; // custom local to unicode
static u16 _L2UTableSize = 0;
static const u16 * _U2LTable = NULL;
static u16 _U2LTableSize = 0;
static const u8 * _ankTable = NULL;
void _FAT_unicode_init_default() // ANSI CODE PAGE
{
// _L2UTable = NULL;
// _U2LTable = NULL;
// _ankTable = NULL;
_FAT_unicode_init((const u16*)unicode_l2u_bin, (const u16*)unicode_u2l_bin, (const u8*)unicode_ank_bin);
}
void _FAT_unicode_init( const u16 * l2uTableData, const u16 * u2lTableData, const u8 * ankData )
{
if( NULL != l2uTableData ) {
_codePage = l2uTableData[0];
_L2UTableSize = l2uTableData[1];
_L2UTable = l2uTableData + 2;
}
if( NULL != u2lTableData ) {
_U2LTableSize = u2lTableData[1];
_U2LTable = u2lTableData + 2;
}
_ankTable = ankData;
}
static void _ank_char_to_unicode( const u8 * src, u16 * dest )
{
while( 0 != *src )
{
*dest = (UNICHAR)(*src);
dest++;
src++;
}
*dest = (UNICHAR)0;
}
static void _unicode_to_ank_char( const u16 * src, u8 * dest )
{
u16 local = 0;
while( 0x0000 != *src )
{
local = (*src++);
if( !(local >= 0x20 && local <= 0xff) )
local = '_';
*dest++ = local & 0xff;
}
*dest = 0x00;
}
void _FAT_unicode_local_to_unicode( const u8 * src, UNICHAR * dest )
{
if( NULL == _L2UTable || NULL == _ankTable )
{
_ank_char_to_unicode( src, dest );
return;
}
while( 0 != *src )
{
u16 lc = 0;
lc=(u16)*src;
src++;
if( 0 == _ankTable[lc] && 0 != *src )
{
lc=(lc << 8)+((u16)*src);
src++;
}
if( lc < _L2UTableSize )
{
*dest = _L2UTable[lc];
if( *dest == (UNICHAR)0)
*dest = (UNICHAR)'?';
}
else
{
*dest=(UNICHAR)'?';
}
dest++;
}
*dest = (UNICHAR)0;
}
void _FAT_unicode_unicode_to_local( const UNICHAR * src, u8 * dest )
{
//if( defCharUsed )
// *defCharUsed = false;
//std::string ret;
if( NULL == _U2LTable || NULL == _ankTable )
{
_unicode_to_ank_char( src, dest );
return;
}
const UNICHAR * p = src;
while( *p != 0x0000 /*&& p < unicode_string + length*/ )
{
u16 localChar = 0;
if( *p < _U2LTableSize ) { // p's value < table size;
localChar = _U2LTable[*p];
}
else {
localChar = '?';
// ʹ<><CAB9> '?' <20><>ΪĬ<CEAA><C4AC><EFBFBD>ַ<EFBFBD><D6B7>ô<EFBFBD><C3B4>ǣ<EFBFBD><C7A3>ļ<EFBFBD>ϵͳ<CFB5><CDB3><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD><EFBFBD><EFBFBD><EFB2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD> '?' <20>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>׷<EFBFBD><D7B7><EFBFBD>
}
if( '?' == localChar && (u16)'?' != *p ) {
//if( defCharUsed )
// *defCharUsed = true;
//dbg_printf( "caution: uni %04x->%04x, CP%d\n", *p, localChar, _codePage );
}
*dest++ = (u8)(localChar & 0xFF);
if( (localChar & 0xFF00) ) {
*dest++ = (u8)( (localChar & 0xFF00) >> 8 );
}
++p;
}
*dest = 0;
}
u32 _unistrnlen( const u16 * unistr, u32 maxlen )
{
const u16 * pstr = NULL;
u32 len = 0;
if( NULL == unistr )
return 0;
if( 0 == maxlen )
return 0;
pstr = unistr;
while( len < maxlen && *pstr != 0x0000 )
{
++len;
++pstr;
}
return len;
}
int _unistrncmp( const u16 * src, const u16 * dest, u32 maxlen ) {
if( NULL == src || NULL == dest ) {
// if( src == dest ) return NULL;
if( src == dest ) return -1;
return (NULL == src ) ? -1 : 1;
}
while( *src == *dest && maxlen && *src != 0x0000 && *dest != 0x0000 ) {
++src;
++dest;
--maxlen;
}
if( 0 == maxlen ) return 0;
return *src > *dest ? 1 : -1;
}
const u16 * _unistrchr( const u16 * str, u16 unichar )
{
if( NULL == str )
return NULL;
while( *str != unichar && *str != 0x0000 )
{
++str;
}
return str;
}
bool _uniisalnum( u8 ch )
{
if( NULL == _ankTable )
return isalnum( ch );
return (0 == _ankTable[ch]) || isalnum( ch );
}