Skip to content

Commit

Permalink
Merge pull request #5209 from maron2000/fix_chcp
Browse files Browse the repository at this point in the history
Fix codepage and language file switching issues
  • Loading branch information
joncampbell123 authored Sep 14, 2024
2 parents 85ba4e1 + 9f73000 commit 645d77a
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 33 deletions.
2 changes: 1 addition & 1 deletion include/control.h
Original file line number Diff line number Diff line change
Expand Up @@ -106,7 +106,7 @@ class Config{
bool opt_showrt = false;
bool opt_nomenu = false;
bool opt_prerun = false;
bool opt_langcp = false;
bool opt_langcp = false; // True if command line option -langcp is specified, always use codepage specified by the language file
bool opt_debug = false;
bool opt_nogui = false;
bool opt_nolog = false;
Expand Down
6 changes: 4 additions & 2 deletions include/shell.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ extern DOS_Shell * first_shell;

const std::map<int, std::string> langcp_map {
{437, "en_US"},
{850, "de_DE"},
{857, "tr_TR"},
//{850, "de_DE"},
{852, "hu_HU"},
{857, "tr_TR"},
{858, "es_ES"},
{859, "fr_FR"},
{860, "pt_BR"},
{866, "ru_RU"},
{932, "ja_JP"},
{936, "zh_CN"},
{949, "ko_KR"},
Expand Down
4 changes: 1 addition & 3 deletions src/dos/dos_keyboard_layout.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1424,11 +1424,9 @@ Bitu DOS_ChangeKeyboardLayout(const char* layoutname, int32_t codepage) {
}

Bitu DOS_ChangeCodepage(int32_t codepage, const char* codepagefile) {
keyboard_layout* temp_layout = new keyboard_layout();
// try to read the layout for the specified codepage
Bitu kerrcode = temp_layout->read_codepage_file(codepagefile, codepage);
Bitu kerrcode = loaded_layout->read_codepage_file(codepagefile, codepage);
if(kerrcode) {
delete temp_layout;
return kerrcode;
}
// Everything went fine
Expand Down
54 changes: 29 additions & 25 deletions src/misc/messages.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@
using namespace std;

int msgcodepage = 0, lastmsgcp = 0;
bool morelen = false, inmsg = false, loadlang = false, uselangcp = false;
bool morelen = false, inmsg = false, loadlang = false;
bool uselangcp = false; // True if Language file is loaded via CONFIG -set langcp option. Use codepage specified in the language file
bool isSupportedCP(int newCP), CodePageHostToGuestUTF8(char *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/), CodePageGuestToHostUTF8(char *d/*CROSS_LEN*/,const char *s/*CROSS_LEN*/), systemmessagebox(char const * aTitle, char const * aMessage, char const * aDialogType, char const * aIconType, int aDefaultButton), OpenGL_using(void);
void InitFontHandle(void), ShutFontHandle(void), refreshExtChar(void), SetIME(void), runRescan(const char *str), menu_update_dynamic(void), menu_update_autocycle(void), update_bindbutton_text(void), set_eventbutton_text(const char *eventname, const char *buttonname), JFONT_Init(), DOSBox_SetSysMenu(), UpdateSDLDrawTexture(), makestdcp950table(), makeseacp951table();
std::string langname = "", langnote = "", GetDOSBoxXPath(bool withexe=false);
Expand Down Expand Up @@ -203,20 +204,19 @@ void AddMessages() {
MSG_Add("AUTO_CYCLE_OFF","Auto cycles [off]");
}

void MSG_Init(void);
void SetKEYBCP() {
if (IS_PC98_ARCH || IS_JEGA_ARCH || IS_DOSV || dos_kernel_disabled || !strcmp(RunningProgram, "LOADLIN")) return;
Bitu return_code;
const char* layout_name = DOS_GetLoadedLayout();
return_code = DOS_LoadKeyboardLayout("us", 437, "auto");
if(strlen(layout_name) == 2) {
return_code = DOS_ChangeKeyboardLayout(layout_name, 0);
}

if(msgcodepage == 932 || msgcodepage == 936 || msgcodepage == 949 || msgcodepage == 950 || msgcodepage == 951) {
MSG_Init();
InitFontHandle();
JFONT_Init();
dos.loaded_codepage = msgcodepage;
}
else {
return_code = DOS_ChangeCodepage(858, "auto"); /* FIX_ME: Somehow requires to load codepage twice */
return_code = DOS_ChangeCodepage(msgcodepage, "auto");
if(return_code == KEYB_NOERROR) {
dos.loaded_codepage = msgcodepage;
Expand Down Expand Up @@ -259,13 +259,17 @@ FILE *testLoadLangFile(const char *fname) {
return mfile;
}

char loaded_fname[LINE_IN_MAXLEN + 1024];
void LoadMessageFile(const char * fname) {
if (!fname) return;
if(*fname=='\0') return;//empty string=no languagefile
if (!strcmp(fname, loaded_fname)){
//LOG_MSG("Message file %s already loaded.",fname);
return;
}
strcpy(loaded_fname, fname);
LOG(LOG_MISC,LOG_DEBUG)("Loading message file %s",loaded_fname);

LOG(LOG_MISC,LOG_DEBUG)("Loading message file %s",fname);

lastmsgcp = 0;
FILE * mfile=testLoadLangFile(fname);
/* This should never happen and since other modules depend on this use a normal printf */
if (!mfile) {
Expand All @@ -276,7 +280,6 @@ void LoadMessageFile(const char * fname) {
control->opt_lang = "";
return;
}
msgcodepage = 0;
langname = langnote = "";
char linein[LINE_IN_MAXLEN+1024];
char name[LINE_IN_MAXLEN+1024], menu_name[LINE_IN_MAXLEN], mapper_name[LINE_IN_MAXLEN];
Expand All @@ -285,6 +288,7 @@ void LoadMessageFile(const char * fname) {
name[0]=0;string[0]=0;
morelen=inmsg=true;
bool res=true;
bool loadlangcp = false;
int cp=dos.loaded_codepage;
if (!dos.loaded_codepage) res=InitCodePage();
while(fgets(linein, LINE_IN_MAXLEN+1024, mfile)) {
Expand All @@ -300,7 +304,6 @@ void LoadMessageFile(const char * fname) {
parser++;
}
*writer=0;

/* New string name */
if (linein[0]==':') {
string[0]=0;
Expand All @@ -313,22 +316,24 @@ void LoadMessageFile(const char * fname) {
int c = atoi(r+1);
if(!isSupportedCP(c)) {
LOG_MSG("Language file: Invalid codepage :DOSBOX-X:CODEPAGE:%d", c);
loadlangcp = false;
}
else if((!res || control->opt_langcp || uselangcp) && c > 0){
if (((IS_PC98_ARCH||IS_JEGA_ARCH) && c!=437 && c!=932 && !systemmessagebox("DOSBox-X language file", "You have specified a language file which uses a code page incompatible with the Japanese PC-98 or JEGA/AX system.\n\nAre you sure to use the language file for this machine type?", "yesno","question", 2)) || (((IS_JDOSV && c!=932) || (IS_PDOSV && c!=936) || (IS_KDOSV && c!=949) || (IS_TDOSV && c!=950 && c!=951)) && c!=437 && !systemmessagebox("DOSBox-X language file", "You have specified a language file which uses a code page incompatible with the current DOS/V system.\n\nAre you sure to use the language file for this system type?", "yesno","question", 2))) {
else if (((IS_PC98_ARCH||IS_JEGA_ARCH) && c!=437 && c!=932 && !systemmessagebox("DOSBox-X language file", "You have specified a language file which uses a code page incompatible with the Japanese PC-98 or JEGA/AX system.\n\nAre you sure to use the language file for this machine type?", "yesno","question", 2)) || (((IS_JDOSV && c!=932) || (IS_PDOSV && c!=936) || (IS_KDOSV && c!=949) || (IS_TDOSV && c!=950 && c!=951)) && c!=437 && !systemmessagebox("DOSBox-X language file", "You have specified a language file which uses a code page incompatible with the current DOS/V system.\n\nAre you sure to use the language file for this system type?", "yesno","question", 2))) {
fclose(mfile);
dos.loaded_codepage = cp;
return;
}
}
else {
std::string msg = "The specified language file uses code page " + std::to_string(c) + ". Do you want to change to this code page accordingly?";
if (loadlang && !control->opt_langcp && !uselangcp && c != 437 && GetDefaultCP() == 437 && systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno", "question", 1)) control->opt_langcp = true;
else control->opt_langcp = true;
msgcodepage = c;
dos.loaded_codepage = c;
if (c == 950 && !chinasea) makestdcp950table();
if (c == 951 && chinasea) makeseacp951table();
if(c != dos.loaded_codepage && (control->opt_langcp || uselangcp || !loadlang || (loadlang && systemmessagebox("DOSBox-X language file", msg.c_str(), "yesno", "question", 1)))){
loadlangcp = true;
msgcodepage = c;
dos.loaded_codepage = c;
if (c == 950 && !chinasea) makestdcp950table();
if (c == 951 && chinasea) makeseacp951table();
lastmsgcp = c;
}
}
lastmsgcp = c;
} else if (!strcmp(p, "LANGUAGE"))
langname = r+1;
else if (!strcmp(p, "REMARK"))
Expand Down Expand Up @@ -382,15 +387,14 @@ void LoadMessageFile(const char * fname) {
menu_update_autocycle();
update_bindbutton_text();
dos.loaded_codepage=cp;
if ((control->opt_langcp || uselangcp) && msgcodepage>0 && isSupportedCP(msgcodepage) && msgcodepage != dos.loaded_codepage) {
if (loadlangcp && msgcodepage>0 && isSupportedCP(msgcodepage) && msgcodepage != dos.loaded_codepage) {
ShutFontHandle();
if(msgcodepage == 932 || msgcodepage == 936 || msgcodepage == 949 || msgcodepage == 950 || msgcodepage == 951) {
dos.loaded_codepage = msgcodepage;
InitFontHandle();
JFONT_Init();
dos.loaded_codepage = cp;
}
if (uselangcp && !IS_DOSV && !IS_JEGA_ARCH) {
if (!IS_DOSV && !IS_JEGA_ARCH) {
#if defined(USE_TTF)
if (ttf.inUse) toSetCodePage(NULL, msgcodepage, -2); else
#endif
Expand All @@ -407,7 +411,7 @@ void LoadMessageFile(const char * fname) {
}
refreshExtChar();
LOG_MSG("LoadMessageFile: Loaded language file: %s",fname);
loadlang=true;
loadlang = true;
}

const char * MSG_Get(char const * msg) {
Expand Down
8 changes: 6 additions & 2 deletions src/shell/shell_cmds.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4553,7 +4553,7 @@ int toSetCodePage(DOS_Shell *shell, int newCP, int opt) {
SetupDBCSTable();
runRescan("-A -Q");
#if defined(USE_TTF)
if ((opt==-1||opt==-2)&&TTF_using()&&(newCP==932||newCP==936||newCP==949||newCP==950||newCP==951)) {
if ((opt==-1||opt==-2)&&TTF_using()) {
Section_prop * ttf_section = static_cast<Section_prop *>(control->GetSection("ttf"));
const char *font = ttf_section->Get_string("font");
if (!font || !*font) {
Expand Down Expand Up @@ -4619,12 +4619,16 @@ void DOS_Shell::CMD_CHCP(char * args) {
keyb_error = DOS_ChangeCodepage(newCP, "auto");
if(keyb_error == KEYB_NOERROR) {
SwitchLanguage(cp, newCP, true);
/**
if(layout_name != NULL) {
keyb_error = DOS_ChangeKeyboardLayout(layout_name, cp);
}
*/
}
else
else {
WriteOut(MSG_Get("SHELL_CMD_CHCP_INVALID"), StripArg(args));
return;
}
}
WriteOut(MSG_Get("SHELL_CMD_CHCP_ACTIVE"), dos.loaded_codepage);
}
Expand Down

0 comments on commit 645d77a

Please sign in to comment.