@@ -48,7 +48,7 @@ class sys_console_c: public sys_IConsole, public conPrintHook_c, public thread_c
4848 void RunMessages (HWND hwnd = nullptr );
4949 void ThreadProc ();
5050
51- void Print (const char * text);
51+ void Print (std::u32string_view text);
5252 void CopyToClipboard ();
5353
5454 void ConPrintHook (const char * text);
@@ -118,16 +118,16 @@ void sys_console_c::ThreadProc()
118118 if (RegisterClass (&conClass) == 0 ) exit (0 );
119119
120120 // Create the system console window
121- hwMain = CreateWindowEx (
121+ hwMain = CreateWindowExW (
122122 0 , CFG_SCON_TITLE " Class" , CFG_SCON_TITLE, SCON_STYLE,
123123 wrec.left , wrec.top , wrec.right - wrec.left , wrec.bottom - wrec.top ,
124124 NULL , NULL , sys->hinst , NULL
125125 );
126126 SetWindowLongPtr (hwMain, GWLP_USERDATA, (LONG_PTR)this );
127127
128128 // Populate window
129- hwOut = CreateWindowEx (
130- WS_EX_CLIENTEDGE, " EDIT" , " " , WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_READONLY,
129+ hwOut = CreateWindowExW (
130+ WS_EX_CLIENTEDGE, L " EDIT" , L "" , WS_VISIBLE | WS_CHILD | WS_BORDER | WS_VSCROLL | ES_MULTILINE | ES_READONLY,
131131 10 , 10 , SCON_WIDTH - 20 , SCON_HEIGHT - 20 ,
132132 hwMain, NULL , sys->hinst , NULL
133133 );
@@ -138,7 +138,7 @@ void sys_console_c::ThreadProc()
138138 FW_LIGHT, FALSE , FALSE , FALSE ,
139139 DEFAULT_CHARSET,
140140 OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
141- FIXED_PITCH|FF_MODERN, " Lucida Console"
141+ FIXED_PITCH|FF_MODERN, L " Lucida Console"
142142 );
143143 SetWindowFont (hwOut, font, FALSE );
144144 Edit_LimitText (hwOut, 0xFFFF );
@@ -173,7 +173,7 @@ void sys_console_c::ThreadProc()
173173 isRunning = false ;
174174
175175 // Flush windowless messages (Like WM_QUIT)
176- sys-> RunMessages ();
176+ RunMessages ();
177177}
178178
179179sys_console_c::~sys_console_c ()
@@ -227,9 +227,11 @@ void sys_console_c::SetVisible(bool show)
227227 SetForegroundWindow (hwMain);
228228
229229 // Select all text and replace with full text
230- Edit_SetText (hwOut, " " );
230+ Edit_SetText (hwOut, L "" );
231231 char * buffer = sys->con ->BuildBuffer ();
232- Print (buffer);
232+ std::u32string u32_text = IndexUTF8ToUTF32 (buffer).text ;
233+
234+ Print (u32_text);
233235 delete buffer;
234236
235237 RunMessages (hwMain);
@@ -256,54 +258,72 @@ bool sys_console_c::IsVisible()
256258
257259void sys_console_c::SetTitle (const char * title)
258260{
259- SetWindowText (hwMain, (title && *title)? title : CFG_SCON_TITLE);
261+ WCHAR* text = WidenUTF8String (title);
262+ SetWindowText (hwMain, (text && *text)? text : CFG_SCON_TITLE);
260263}
261264
262- void sys_console_c::Print (const char * text )
265+ void sys_console_c::Print (std::u32string_view string_view_text )
263266{
264267 if ( !shown ) {
265268 return ;
266269 }
267270
268271 int escLen;
272+ const char32_t * text = string_view_text.data ();
269273
270274 // Find the required buffer length
271275 int len = 0 ;
272276 for (int b = 0 ; text[b]; b++) {
273- if (text[b] == ' \n ' ) {
277+ if (text[b] == U ' \n ' ) {
274278 // Newline takes 2 characters
275279 len+= 2 ;
276280 } else if (escLen = IsColorEscape (&text[b])) {
277281 // Skip colour escapes
278282 b+= escLen - 1 ;
279283 } else {
280- len++;
284+ if (text[b] > UINT16_MAX) {
285+ // Higher codepoints will be separated into surrogate pairs
286+ len += 2 ;
287+ }
288+ else {
289+ len++;
290+ }
281291 }
282292 }
283293
284294 // Parse into the buffer
285- char * winText = AllocStringLen ( len) ;
286- char * p = winText;
295+ char16_t * winText = new char16_t [ len + 1 ] ;
296+ char16_t * p = winText;
287297 for (int b = 0 ; text[b]; b++) {
288- if (text[b] == ' \n ' ) {
298+ if (text[b] == L ' \n ' ) {
289299 // Append newline
290- *(p++) = ' \r ' ;
291- *(p++) = ' \n ' ;
300+ *(p++) = L ' \r ' ;
301+ *(p++) = L ' \n ' ;
292302 } else if (escLen = IsColorEscape (&text[b])) {
293303 // Skip colour escapes
294304 b+= escLen - 1 ;
295305 } else {
296306 // Add character
297- *(p++) = text[b];
307+ if (text[b] > UINT16_MAX) { // Outside the BMP
308+ char16_t high_surrogate = ((text[b] - 0x10000 ) / 0x400 ) + 0xD800 ;
309+ char16_t low_surrogate = ((text[b] - 0x10000 ) % 0x400 ) + 0xDC00 ;
310+ *(p++) = high_surrogate;
311+ *(p++) = low_surrogate;
312+ }
313+ else {
314+ *(p++) = (char16_t )text[b];
315+ }
316+
298317 }
299318 }
319+ winText[len] = 0 ;
300320
301321 // Append to the output
302322 Edit_SetSel (hwOut, Edit_GetTextLength (hwOut), -1 );
303323 Edit_ReplaceSel (hwOut, winText);
304324 Edit_Scroll (hwOut, 0xFFFF , 0 );
305325 RunMessages (hwMain);
306- delete winText;
326+ delete[] winText;
307327}
308328
309329void sys_console_c::CopyToClipboard ()
@@ -312,8 +332,8 @@ void sys_console_c::CopyToClipboard()
312332 if (len) {
313333 HGLOBAL hg = GlobalAlloc (GMEM_MOVEABLE, len + 1 );
314334 if ( !hg ) return ;
315- char * cp = (char *)GlobalLock (hg);
316- GetWindowText (hwOut, cp, len + 1 );
335+ WCHAR * cp = (WCHAR *)GlobalLock (hg);
336+ GetWindowTextW (hwOut, cp, len + 1 );
317337 GlobalUnlock (hg);
318338 OpenClipboard (hwMain);
319339 EmptyClipboard ();
@@ -324,10 +344,10 @@ void sys_console_c::CopyToClipboard()
324344
325345void sys_console_c::ConPrintHook (const char * text)
326346{
327- Print (text);
347+ Print (IndexUTF8ToUTF32 (text). text );
328348}
329349
330350void sys_console_c::ConPrintClear ()
331351{
332- Edit_SetText (hwOut, " " );
352+ Edit_SetText (hwOut, L "" );
333353}
0 commit comments