forked from diasurgical/devilutionX
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
add initial language support using a simple MO parser
- Loading branch information
1 parent
86afa95
commit 8bf129f
Showing
8 changed files
with
171 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,5 +1,6 @@ | ||
|
||
#include "control.h" | ||
#include "language.h" | ||
#include "DiabloUI/diabloui.h" | ||
#include "DiabloUI/selok.h" | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#include "options.h" | ||
#include "utils/paths.h" | ||
#include <map> | ||
|
||
|
||
using namespace devilution; | ||
#define MO_MAGIC 0x950412de | ||
|
||
|
||
namespace { | ||
|
||
struct cstring_cmp { | ||
bool operator()(const char *s1, const char *s2) const { | ||
return strcmp(s1, s2) < 0; | ||
} | ||
}; | ||
|
||
std::map<const char*, const char*, cstring_cmp> map; | ||
|
||
|
||
struct mo_head { | ||
uint32_t magic; | ||
struct { | ||
uint16_t major; | ||
uint16_t minor; | ||
} revision; | ||
|
||
uint32_t nb_mappings; | ||
uint32_t src_offset; | ||
uint32_t dst_offset; | ||
}; | ||
|
||
|
||
struct mo_entry { | ||
uint32_t length; | ||
uint32_t offset; | ||
}; | ||
|
||
|
||
void* read_entry(FILE *fp, mo_entry* e) { | ||
void *data; | ||
|
||
if(fseek(fp, e->offset, SEEK_SET)) { | ||
return NULL; | ||
} | ||
|
||
if(!(data = calloc(e->length, sizeof(char)))) { | ||
return NULL; | ||
} | ||
|
||
if(fread(data, sizeof(char), e->length, fp) != e->length) { | ||
free(data); | ||
return NULL; | ||
} | ||
|
||
return data; | ||
} | ||
} | ||
|
||
|
||
const char* LanguageTranslate(const char* key) { | ||
auto it = map.find(key); | ||
if(it == map.end()) { | ||
return key; | ||
} | ||
|
||
return it->second; | ||
} | ||
|
||
|
||
void LanguageInitialize() { | ||
std::string path = GetLangPath() + "./" + sgOptions.Language.szCode + ".mo"; | ||
mo_head head; | ||
FILE *fp; | ||
|
||
if(!(fp = fopen(path.c_str(), "rb"))) { | ||
perror(path.c_str()); | ||
return; | ||
} | ||
// Read header and do sanity checks | ||
if(fread(&head, sizeof(mo_head), 1, fp) != 1) { | ||
return; | ||
} | ||
|
||
if(head.magic != MO_MAGIC) { | ||
return; // not a MO file | ||
} | ||
|
||
if(head.revision.major > 1 || head.revision.minor > 1) { | ||
return; // unsupported revision | ||
} | ||
|
||
// Read entries of source strings | ||
mo_entry src[head.nb_mappings]; | ||
if(fseek(fp, head.src_offset, SEEK_SET)) { | ||
return; | ||
} | ||
if(fread(src, sizeof(mo_entry), head.nb_mappings, fp) != head.nb_mappings) { | ||
return; | ||
} | ||
|
||
// Read entries of target strings | ||
mo_entry dst[head.nb_mappings]; | ||
if(fseek(fp, head.dst_offset, SEEK_SET)) { | ||
return; | ||
} | ||
|
||
if(fread(dst, sizeof(mo_entry), head.nb_mappings, fp) != head.nb_mappings) { | ||
return; | ||
} | ||
|
||
// Read strings described by entries | ||
for(uint32_t i=0; i<head.nb_mappings; i++) { | ||
void *key, *val; | ||
if((key = read_entry(fp, src+i))) { | ||
if((val = read_entry(fp, dst+i))) { | ||
map[static_cast<const char*>(key)] = static_cast<const char*>(val); | ||
} else { | ||
free(key); | ||
} | ||
} | ||
} | ||
} | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
#pragma once | ||
|
||
#define _(x) LanguageTranslate(x) | ||
|
||
void LanguageInitialize(); | ||
const char* LanguageTranslate(const char* key); | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters