Skip to content

Instantly share code, notes, and snippets.

@ccawley2011
Last active April 21, 2022 21:06
Show Gist options
  • Save ccawley2011/f63e882aa1cac6e799e3f886236b9140 to your computer and use it in GitHub Desktop.
Save ccawley2011/f63e882aa1cac6e799e3f886236b9140 to your computer and use it in GitHub Desktop.
Unfinished SDL locale code
/*
Simple DirectMedia Layer
Copyright (C) 1997-2022 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
*/
#if 0
#include "../../SDL_internal.h"
#include "../SDL_syslocale.h"
#else
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#define SDL_arraysize(array) (sizeof(array)/sizeof(array[0]))
#define SDL_zeroa(x) SDL_memset((x), 0, sizeof((x)))
#define SDL_min(x, y) (((x) < (y)) ? (x) : (y))
#define SDL_memset memset
#define SDL_strcmp strcmp
#define SDL_strlcpy strncpy
#define SDL_snprintf snprintf
#endif
#include "kernel.h"
#include "swis.h"
/**
* Territories:
* - 1: UK (uk) (English)
* - 4: Italy (it) (Italian)
* - 5: Spain (es) (Spanish)
* - 6: France (fr) (French)
* - 7: Germany (de) (German)
* - 8: Portugal (pt) (Portuguese)
* - 10: Greece (gr)
* - 11: Sweden (se) (Swedish)
* - 12: Finland (fi) (Finnish)
* - 14: Denmark (dk) (Danish)
* - 15: Norway (no) (Norwegian)
* - 16: Iceland (is) (Icelandic)
* - 17: Canada1 (ca) (French)
* - 18: Canada2 (ca)
* - 19: Canada (ca)
* - 20: Turkey (tr) (Turkish)
* - 22: Ireland (ie) (English)
* - 23: Hong Kong (hk)
* - 24: Russia (ru)
* - 25: Russia2 (ru)
* - 26: Israel (il)
* - 27: Mexico (mx)
* - 29: Australia (au) (English)
* - 30: Austria (at)
* - 31: Belgium (be)
* - 32: Japan (jp) (Japan)
* - 34: Netherlands (nl) (Dutch)
* - 35: Switzerland (ch)
* - 36: Wales (uk)
* - 48: USA (us) (English)
* - 49: Wales2 (uk)
* - 50: China (cn)
* - 51: Brazil (br)
* - 52: SAfrica (za) (English)
* - 53: Korea (kr) (Korean)
* - 54: Taiwan (tw) (Traditional Chinese)
* - 70: DvorakUK (uk)
* - 71: DvorakUSA (us)
*/
/* Source: https://gitlab.riscosopen.org/RiscOS/Sources/Internat/Inter/-/blob/Inter-1_70/s/InterBody#L1310 */
static const char ISO3166_1Strings[] = " uk itesfrdept " /* Countries 0-9 (the UK uses 'uk' not its allocated 'gb') */
"grsefi dknoiscacaca" /* Countries 10-19 */
"tr iehkruruilmx au" /* Countries 20-29 */
"atbejp nlchuk " /* Countries 30-39 */
" usuk" /* Countries 40-49 */
"cnbrzakrtw " /* Countries 50-59 */
" " /* Countries 60-69 */
"ukus " /* Countries 70-79 */
" " /* Countries 80-89 */
" "; /* Countries 90-99 */
static const char ISO639_1Strings[] = " en itesfrdept " /* Countries 0-9 */
"grsefi dknoiscacaca" /* Countries 10-19 */
"tr iehkruruilmx au" /* Countries 20-29 */
"atbejp nlchuk " /* Countries 30-39 */
" usuk" /* Countries 40-49 */
"cnbrzakrtw " /* Countries 50-59 */
" " /* Countries 60-69 */
"ukus " /* Countries 70-79 */
" " /* Countries 80-89 */
" "; /* Countries 90-99 */
static void territory_to_iso3166_1(int territory, char *buf, size_t buflen) {
_kernel_swi_regs regs;
const char *code;
SDL_memset(buf, 0, buflen);
regs.r[1] = 0x43; /* Service_International */
regs.r[2] = 9; /* Convert country number to ISO3166-1 two letter abbreviation */
regs.r[3] = territory;
regs.r[4] = (int)buf;
regs.r[5] = buflen;
if (_kernel_swi(OS_ServiceCall, &regs, &regs) == NULL) {
if (regs.r[1] == 0) {
buf[regs.r[5]] = 0;
return;
}
}
/* On older OS versions, fall back on the internal table */
code = &ISO3166_1Strings[territory * 2];
if (code[0] != ' ' || code[1] != ' ') {
SDL_strlcpy(buf, code, SDL_min(2, buflen));
}
}
static void territory_to_iso639_1(int territory, char *buf, size_t buflen) {
const char *code;
SDL_memset(buf, 0, buflen);
/**
* There's no service call for this, so it's necessary to use the internal
* table on all OS versions.
*/
code = &ISO639_1Strings[territory * 2];
if (code[0] != ' ' || code[1] != ' ') {
SDL_strlcpy(buf, code, SDL_min(2, buflen));
}
}
static int get_territory_number(void) {
_kernel_swi_regs regs;
if (_kernel_swi(Territory_Number, &regs, &regs) == NULL) {
return regs.r[0];
}
return 0;
}
void
SDL_SYS_GetPreferredLocales(char *buf, size_t buflen)
{
char iso3166_1[3];
char iso639_1[3];
int territory;
territory = get_territory_number();
territory_to_iso3166_1(territory, iso3166_1, sizeof(iso3166_1));
territory_to_iso639_1(territory, iso639_1, sizeof(iso639_1));
if (iso3166_1[0] == 0 && iso639_1[1] == 0) {
/* Caller already zero'd out buffer. */
/* SDL_Unsupported(); */
return;
}
if (SDL_strcmp(iso3166_1, "uk") == 0) {
SDL_strlcpy(iso3166_1, "gb", sizeof(iso3166_1));
}
SDL_snprintf(buf, buflen, "%s_%s", iso639_1, iso3166_1);
}
int main(int argc, char *argv[]) {
char locbuf[128];
SDL_zeroa(locbuf);
SDL_SYS_GetPreferredLocales(locbuf, sizeof(locbuf));
printf("locbuf = %s\n", locbuf);
return 0;
}
/* vi: set ts=4 sw=4 expandtab: */
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment