1 #include "core/dispatch.hpp"
2 #include "core/framebuffer.hpp"
3 #include "core/framerate.hpp"
4 #include "core/window.hpp"
6 #include "plat-sdl/paint.hpp"
10 #if SDL_BYTEORDER == SDL_BIG_ENDIAN
11 #define WRITE3(ptr, idx, c) do {\
12 (ptr)[(idx) + 0] = (c) >> 16; \
13 (ptr)[(idx) + 1] = (c) >> 8; \
14 (ptr)[(idx) + 2] = (c); \
17 #define WRITE3(ptr, idx, c) do {\
18 (ptr)[(idx) + 0] = (c); \
19 (ptr)[(idx) + 1] = (c) >> 8; \
20 (ptr)[(idx) + 2] = (c) >> 16; \
28 sdlw_display_parameters dp
;
29 bool fullscreen_console_active
;
31 bool screen_paintable
;
33 bool modal_dialog_shown
;
34 std::string modal_dialog_text
;
35 bool modal_dialog_confirm
;
36 bool have_received_frames
;
38 void paint_line(uint8_t* ptr
, uint32_t length
, uint32_t step
, uint32_t pbytes
, uint32_t color
)
42 for(uint32_t i
= 0; i
< length
; i
++) {
48 for(uint32_t i
= 0; i
< length
; i
++) {
49 *reinterpret_cast<uint16_t*>(ptr
) = color
;
54 for(uint32_t i
= 0; i
< length
; i
++) {
55 WRITE3(ptr
, 0, color
);
60 for(uint32_t i
= 0; i
< length
; i
++) {
61 *reinterpret_cast<uint32_t*>(ptr
) = color
;
68 std::vector
<uint32_t> decode_utf8(std::string s
)
70 std::vector
<uint32_t> ret
;
71 for(auto i
= s
.begin(); i
!= s
.end(); i
++) {
72 uint32_t j
= static_cast<uint8_t>(*i
);
78 uint32_t j2
= static_cast<uint8_t>(*(++i
));
79 ret
.push_back((j
- 192) * 64 + (j2
- 128));
81 uint32_t j2
= static_cast<uint8_t>(*(++i
));
82 uint32_t j3
= static_cast<uint8_t>(*(++i
));
83 ret
.push_back((j
- 224) * 4096 + (j2
- 128) * 64 + (j3
- 128));
85 uint32_t j2
= static_cast<uint8_t>(*(++i
));
86 uint32_t j3
= static_cast<uint8_t>(*(++i
));
87 uint32_t j4
= static_cast<uint8_t>(*(++i
));
88 ret
.push_back((j
- 240) * 262144 + (j2
- 128) * 4096 + (j3
- 128) * 64 + (j4
- 128));
94 inline void draw_blank_glyph_3(uint8_t* base
, uint32_t pitch
, uint32_t w
, uint32_t color
, uint32_t curstart
)
96 for(uint32_t j
= 0; j
< 16; j
++) {
97 uint8_t* ptr
= base
+ j
* pitch
;
98 uint32_t c
= (j
>= curstart
) ? color
: 0;
99 for(uint32_t i
= 0; i
< w
; i
++)
100 WRITE3(ptr
, 3 * i
, c
);
105 inline void draw_blank_glyph_T(uint8_t* base
, uint32_t pitch
, uint32_t w
, uint32_t color
, uint32_t curstart
)
107 for(uint32_t j
= 0; j
< 16; j
++) {
108 T
* ptr
= reinterpret_cast<T
*>(base
+ j
* pitch
);
109 T c
= (j
>= curstart
) ? color
: 0;
110 for(uint32_t i
= 0; i
< w
; i
++)
116 inline void draw_glyph_3(uint8_t* base
, uint32_t pitch
, uint32_t w
, const uint32_t* gdata
, uint32_t color
,
119 for(uint32_t j
= 0; j
< 16; j
++) {
120 uint8_t* ptr
= base
+ j
* pitch
;
121 uint32_t bgc
= (j
>= curstart
) ? color
: 0;
122 uint32_t fgc
= (j
>= curstart
) ? 0 : color
;
123 uint32_t dataword
= gdata
[j
>> (wide
? 1 : 2)];
124 unsigned rbit
= (~(j
<< (wide
? 4 : 3))) & 0x1F;
125 for(uint32_t i
= 0; i
< w
; i
++) {
126 bool b
= (((dataword
>> (rbit
- i
)) & 1));
127 WRITE3(ptr
, 3 * i
, b
? fgc
: bgc
);
132 template<typename T
, bool wide
>
133 inline void draw_glyph_T(uint8_t* base
, uint32_t pitch
, uint32_t w
, const uint32_t* gdata
, uint32_t color
,
136 for(uint32_t j
= 0; j
< 16; j
++) {
137 T
* ptr
= reinterpret_cast<T
*>(base
+ j
* pitch
);
138 T bgc
= (j
>= curstart
) ? color
: 0;
139 T fgc
= (j
>= curstart
) ? 0 : color
;
140 uint32_t dataword
= gdata
[j
>> (wide
? 1 : 2)];
141 unsigned rbit
= (~(j
<< (wide
? 4 : 3))) & 0x1F;
142 for(uint32_t i
= 0; i
< w
; i
++) {
143 bool b
= (((dataword
>> (rbit
- i
)) & 1));
144 ptr
[i
] = b
? fgc
: bgc
;
150 void draw_blank_glyph(uint8_t* base
, uint32_t pitch
, uint32_t pbytes
, uint32_t w
, uint32_t wleft
,
151 uint32_t color
, uint32_t hilite_mode
)
157 uint32_t curstart
= 16;
164 draw_blank_glyph_T
<uint8_t>(base
, pitch
, w
, color
, curstart
);
167 draw_blank_glyph_T
<uint16_t>(base
, pitch
, w
, color
, curstart
);
170 draw_blank_glyph_3(base
, pitch
, w
, color
, curstart
);
173 draw_blank_glyph_T
<uint32_t>(base
, pitch
, w
, color
, curstart
);
178 void draw_glyph(uint8_t* base
, uint32_t pitch
, uint32_t pbytes
, const uint32_t* gdata
, uint32_t w
,
179 uint32_t wleft
, uint32_t color
, uint32_t hilite_mode
)
186 uint32_t curstart
= 16;
194 draw_glyph_T
<uint8_t, true>(base
, pitch
, w
, gdata
, color
, curstart
);
196 draw_glyph_T
<uint8_t, false>(base
, pitch
, w
, gdata
, color
, curstart
);
200 draw_glyph_T
<uint16_t, true>(base
, pitch
, w
, gdata
, color
, curstart
);
202 draw_glyph_T
<uint16_t, false>(base
, pitch
, w
, gdata
, color
, curstart
);
206 draw_glyph_3
<true>(base
, pitch
, w
, gdata
, color
, curstart
);
208 draw_glyph_3
<false>(base
, pitch
, w
, gdata
, color
, curstart
);
212 draw_glyph_T
<uint32_t, true>(base
, pitch
, w
, gdata
, color
, curstart
);
214 draw_glyph_T
<uint32_t, false>(base
, pitch
, w
, gdata
, color
, curstart
);
219 void draw_string(uint8_t* base
, uint32_t pitch
, uint32_t pbytes
, std::vector
<uint32_t> s
, uint32_t x
,
220 uint32_t y
, uint32_t maxwidth
, uint32_t color
, uint32_t hilite_mode
= 0, uint32_t hilite_pos
= 0)
228 uint32_t old_x
= pos_x
;
229 uint32_t old_y
= pos_y
;
230 auto g
= find_glyph(si
, pos_x
, pos_y
, 0, pos_x
, pos_y
);
231 uint32_t mw
= maxwidth
- old_x
;
236 uint8_t* cbase
= base
+ (y
+ old_y
) * yo
+ (x
+ old_x
) * xo
;
238 draw_blank_glyph(cbase
, pitch
, pbytes
, g
.first
, mw
, color
,
239 (c
== hilite_pos
) ? hilite_mode
: 0);
241 draw_glyph(cbase
, pitch
, pbytes
, g
.second
, g
.first
, mw
, color
,
242 (c
== hilite_pos
) ? hilite_mode
: 0);
245 if(c
== hilite_pos
) {
246 uint32_t old_x
= pos_x
;
247 uint32_t mw
= maxwidth
- old_x
;
250 draw_blank_glyph(base
+ y
* yo
+ (x
+ old_x
) * xo
, pitch
, pbytes
, 8, mw
, 0xFFFFFFFFU
,
255 draw_blank_glyph(base
+ y
* yo
+ (x
+ pos_x
) * xo
, pitch
, pbytes
, maxwidth
- pos_x
,
256 maxwidth
- pos_x
, 0, 0);
259 void draw_string(uint8_t* base
, uint32_t pitch
, uint32_t pbytes
, std::string s
, uint32_t x
, uint32_t y
,
260 uint32_t maxwidth
, uint32_t color
, uint32_t hilite_mode
= 0, uint32_t hilite_pos
= 0)
262 draw_string(base
, pitch
, pbytes
, decode_utf8(s
), x
, y
, maxwidth
, color
, hilite_mode
, hilite_pos
);
266 void draw_box(SDL_Surface
* surf
, uint32_t x
, uint32_t y
, uint32_t w
, uint32_t h
, uint32_t color
)
270 uint32_t sx
, sy
, ex
, ey
;
271 uint32_t bsx
, bsy
, bex
, bey
;
272 uint32_t pbytes
= surf
->format
->BytesPerPixel
;
273 uint32_t lstride
= surf
->pitch
;
274 uint8_t* p
= reinterpret_cast<uint8_t*>(surf
->pixels
);
275 size_t xo
= surf
->format
->BytesPerPixel
;
276 size_t yo
= surf
->pitch
;
277 sx
= (x
< 6) ? 0 : (x
- 6);
278 sy
= (y
< 6) ? 0 : (y
- 6);
279 ex
= (x
+ w
+ 6 > surf
->w
) ? surf
->w
: (x
+ w
+ 6);
280 ey
= (y
+ h
+ 6 > surf
->h
) ? surf
->h
: (y
+ h
+ 6);
281 bsx
= (x
< 4) ? 0 : (x
- 4);
282 bsy
= (y
< 4) ? 0 : (y
- 4);
283 bex
= (x
+ w
+ 4 > surf
->w
) ? surf
->w
: (x
+ w
+ 4);
284 bey
= (y
+ h
+ 4 > surf
->h
) ? surf
->h
: (y
+ h
+ 4);
285 //First, blank the area.
286 for(uint32_t j
= sy
; j
< ey
; j
++)
287 memset(p
+ j
* yo
+ sx
* xo
, 0, (ex
- sx
) * xo
);
290 paint_line(p
+ bsy
* yo
+ (x
- 4) * xo
, bey
- bsy
, yo
, xo
, color
);
292 paint_line(p
+ bsy
* yo
+ (x
- 3) * xo
, bey
- bsy
, yo
, xo
, color
);
294 paint_line(p
+ (y
- 4) * yo
+ bsx
* xo
, bex
- bsx
, xo
, xo
, color
);
296 paint_line(p
+ (y
- 3) * yo
+ bsx
* xo
, bex
- bsx
, xo
, xo
, color
);
297 if(x
+ w
+ 3 < surf
->w
)
298 paint_line(p
+ bsy
* yo
+ (x
+ w
+ 2) * xo
, bey
- bsy
, yo
, xo
, color
);
299 if(x
+ w
+ 4 < surf
->w
)
300 paint_line(p
+ bsy
* yo
+ (x
+ w
+ 3) * xo
, bey
- bsy
, yo
, xo
, color
);
301 if(y
+ h
+ 3 < surf
->h
)
302 paint_line(p
+ (y
+ h
+ 2) * yo
+ bsx
* xo
, bex
- bsx
, xo
, xo
, color
);
303 if(y
+ h
+ 4 < surf
->h
)
304 paint_line(p
+ (y
+ h
+ 3) * yo
+ bsx
* xo
, bex
- bsx
, xo
, xo
, color
);
307 sdlw_display_parameters::sdlw_display_parameters()
311 fullscreen_console
= false;
312 virtual_screen_w
= 512;
313 virtual_screen_h
= 448;
314 display_w
= virtual_screen_w
+ 278;
315 display_h
= virtual_screen_h
+ 16 * MAXMESSAGES
+ 48;
318 statusarea_x
= virtual_screen_w
+ 16;
322 cmdline_y
= display_h
- 22;
323 cmdline_w
= display_w
- 12;
324 messagearea_w
= display_w
- 12;
325 screenarea_w
= virtual_screen_w
;
326 screenarea_h
= virtual_screen_h
;
328 statusarea_lines
= virtual_screen_h
/ 16;
329 messagearea_y
= virtual_screen_h
+ 16;
330 messagearea_lines
= MAXMESSAGES
;
331 messagearea_trailing_y
= messagearea_y
+ MAXMESSAGES
;
332 messagearea_trailing_h
= 0;
333 statusarea_h
= statusarea_lines
* 16;
334 messagearea_h
= messagearea_lines
* 16 + messagearea_trailing_h
;
337 sdlw_display_parameters::sdlw_display_parameters(uint32_t rscrw
, uint32_t rscrh
, bool cactive
)
339 real_screen_w
= rscrw
;
340 real_screen_h
= rscrh
;
341 fullscreen_console
= cactive
;
342 virtual_screen_w
= (((real_screen_w
< 512) ? 512 : real_screen_w
) + 15) >> 4 << 4;
343 virtual_screen_h
= (((real_screen_w
< 448) ? 448 : real_screen_h
) + 15) >> 4 << 4;
344 display_w
= virtual_screen_w
+ 278;
345 display_h
= virtual_screen_h
+ 16 * MAXMESSAGES
+ 48;
348 statusarea_x
= virtual_screen_w
+ 16;
352 cmdline_y
= display_h
- 22;
353 cmdline_w
= display_w
- 12;
354 messagearea_w
= display_w
- 12;
355 if(fullscreen_console
) {
359 statusarea_lines
= 0;
361 messagearea_lines
= (display_h
- 38) / 16;
362 messagearea_trailing_y
= messagearea_y
+ 16 * messagearea_lines
;
363 messagearea_trailing_h
= (display_h
- 38) % 16;
365 screenarea_w
= virtual_screen_w
;
366 screenarea_h
= virtual_screen_h
;
368 statusarea_lines
= virtual_screen_h
/ 16;
369 messagearea_y
= virtual_screen_h
+ 16;
370 messagearea_lines
= MAXMESSAGES
;
371 messagearea_trailing_y
= messagearea_y
+ MAXMESSAGES
;
372 messagearea_trailing_h
= 0;
374 statusarea_h
= statusarea_lines
* 16;
375 messagearea_h
= messagearea_lines
* 16 + messagearea_trailing_h
;
378 bool paint_command(SDL_Surface
* surf
, const sdlw_display_parameters
& p
, bool full
)
380 static bool cached_command_active
= false;
381 static bool cached_overwrite
= false;
382 static uint32_t cached_rawcursor
= 0;
383 static std::string cached_command
;
385 //Query status of command line.
386 auto cmd
= get_current_command();
389 draw_box(surf
, p
.cmdline_x
, p
.cmdline_y
, p
.cmdline_w
, 16, surf
->format
->Gmask
);
390 cached_command_active
= false;
391 cached_overwrite
= false;
392 cached_rawcursor
= 0;
395 if(cached_command_active
== cmd
.active
&& cached_overwrite
== cmd
.overwrite
&&
396 cached_rawcursor
== cmd
.rawpos
&& cached_command
== cmd
.encoded
)
400 //FIXME, scroll text if too long.
401 uint32_t hilite_mode
= cmd
.overwrite
? 2 : 1;
402 auto s2
= decode_utf8(sdlw_decode_string(cmd
.encoded
));
403 draw_string(reinterpret_cast<uint8_t*>(surf
->pixels
), surf
->pitch
, surf
->format
->BytesPerPixel
,
404 s2
, p
.cmdline_x
, p
.cmdline_y
, p
.cmdline_w
, 0xFFFFFFFFU
, hilite_mode
, cmd
.rawpos
/ 4);
406 draw_string(reinterpret_cast<uint8_t*>(surf
->pixels
), surf
->pitch
, surf
->format
->BytesPerPixel
,
407 "", p
.cmdline_x
, p
.cmdline_y
, p
.cmdline_w
, 0xFFFFFFFFU
);
408 cached_command_active
= cmd
.active
;
409 cached_overwrite
= cmd
.overwrite
;
410 cached_rawcursor
= cmd
.rawpos
;
411 cached_command
= cmd
.encoded
;
417 bool paint_messages(SDL_Surface
* surf
, const sdlw_display_parameters
& p
, bool full
)
419 static uint64_t cached_first
= 0;
420 static uint64_t cached_messages
= 0;
422 draw_box(surf
, p
.messagearea_x
, p
.messagearea_y
, p
.messagearea_w
, p
.messagearea_h
,
423 surf
->format
->Gmask
);
427 uint32_t message_y
= p
.messagearea_y
;
428 size_t maxmessages
= window::msgbuf
.get_max_window_size();
429 size_t msgnum
= window::msgbuf
.get_visible_first();
430 size_t visible
= window::msgbuf
.get_visible_count();
431 if((!visible
&& cached_messages
== 0) || (msgnum
== cached_first
&& visible
== cached_messages
))
433 if(cached_messages
== 0)
434 cached_first
= msgnum
; //Little trick.
435 for(size_t j
= 0; j
< maxmessages
; j
++)
437 if(msgnum
== cached_first
&& j
< cached_messages
)
438 continue; //Don't draw lines that stayed the same.
439 if(j
>= visible
&& j
>= cached_messages
)
440 continue; //Don't draw blank lines.
441 std::ostringstream o
;
443 o
<< (msgnum
+ j
+ 1) << ": " << window::msgbuf
.get_message(msgnum
+ j
);
444 draw_string(reinterpret_cast<uint8_t*>(surf
->pixels
), surf
->pitch
,
445 surf
->format
->BytesPerPixel
, o
.str(), p
.messagearea_x
,
446 message_y
+ 16 * j
, p
.messagearea_w
, 0xFFFFFFFFU
);
449 if(window::msgbuf
.is_more_messages())
451 draw_string(reinterpret_cast<uint8_t*>(surf
->pixels
), surf
->pitch
,
452 surf
->format
->BytesPerPixel
, "--More--",
453 p
.messagearea_x
+ p
.messagearea_w
- 64, message_y
+ 16 * maxmessages
- 16, 64,
457 cached_first
= msgnum
;
458 cached_messages
= visible
;
462 bool paint_status(SDL_Surface
* surf
, const sdlw_display_parameters
& p
, bool full
)
464 auto& status
= window::get_emustatus();
466 std::ostringstream y
;
467 y
<< get_framerate();
468 status
["FPS"] = y
.str();
471 if(!p
.statusarea_w
|| !p
.statusarea_h
)
473 uint32_t y
= p
.statusarea_y
;
475 static std::map
<std::string
, std::string
> old_status
;
476 size_t old_lines
= old_status
.size();
479 draw_box(surf
, p
.statusarea_x
, p
.statusarea_y
, p
.statusarea_w
, p
.statusarea_h
,
480 surf
->format
->Gmask
);
482 bool paint_any
= false;
483 bool desynced
= false;
484 for(auto i
: status
) {
485 if(!old_status
.count(i
.first
))
487 if(!desynced
&& old_status
[i
.first
] == i
.second
) {
495 std::string str
= i
.first
+ " " + i
.second
;
496 draw_string(reinterpret_cast<uint8_t*>(surf
->pixels
), surf
->pitch
,
497 surf
->format
->BytesPerPixel
, str
, p
.statusarea_x
, y
, p
.statusarea_w
,
499 old_status
[i
.first
] = i
.second
;
505 for(size_t i
= lines
; i
< old_lines
; i
++) {
506 draw_string(reinterpret_cast<uint8_t*>(surf
->pixels
), surf
->pitch
,
507 surf
->format
->BytesPerPixel
, "", p
.statusarea_x
, y
, p
.statusarea_w
, 0);
510 return paint_any
|| full
;
513 bool paint_screen(SDL_Surface
* surf
, const sdlw_display_parameters
& p
, bool full
)
516 draw_box(surf
, p
.screenarea_x
, p
.screenarea_y
, p
.screenarea_w
, p
.screenarea_h
,
517 surf
->format
->Gmask
);
521 void paint_modal_dialog(SDL_Surface
* surf
, const std::string
& text
, bool confirm
)
523 std::string realtext
;
525 realtext
= text
+ "\n\nHit Enter to confirm, Esc to cancel";
527 realtext
= text
+ "\n\nHit Enter or Esc to dismiss";
528 unsigned extent_w
= 0;
529 unsigned extent_h
= 0;
532 auto s2
= decode_utf8(realtext
);
534 auto g
= find_glyph(i
, pos_x
, pos_y
, 0, pos_x
, pos_y
);
535 if(pos_x
+ g
.first
> extent_w
)
536 extent_w
= static_cast<uint32_t>(pos_x
+ g
.first
);
537 if(pos_y
+ 16 > static_cast<int32_t>(extent_h
))
538 extent_h
= static_cast<uint32_t>(pos_y
+ 16);
544 if(extent_w
+ 12 >= static_cast<uint32_t>(surf
->w
)) {
549 x1
= (surf
->w
- extent_w
) / 2;
552 if(extent_h
+ 12 >= static_cast<uint32_t>(surf
->h
)) {
557 y1
= (surf
->h
- extent_h
) / 2;
560 uint32_t color
= surf
->format
->Rmask
| ((surf
->format
->Gmask
>> 1) & surf
->format
->Gmask
);
561 draw_box(surf
, x1
, y1
, extent_w
, extent_h
, color
);
562 draw_string(reinterpret_cast<uint8_t*>(surf
->pixels
), surf
->pitch
, surf
->format
->BytesPerPixel
, s2
,
563 x1
, y1
, extent_w
, color
);
566 void sdlw_paint_modal_dialog(const std::string
& text
, bool confirm
)
568 modal_dialog_shown
= true;
569 modal_dialog_text
= text
;
570 modal_dialog_confirm
= confirm
;
571 SDL_LockSurface(hwsurf
);
572 paint_modal_dialog(hwsurf
, text
, confirm
);
573 SDL_UnlockSurface(hwsurf
);
574 SDL_UpdateRect(hwsurf
, 0, 0, 0, 0);
577 void sdlw_clear_modal_dialog()
579 modal_dialog_shown
= false;
585 class painter_listener
: public information_dispatch
589 void on_screen_resize(screen
& scr
, uint32_t w
, uint32_t h
);
590 void on_render_update_start();
591 void on_render_update_end();
592 void on_status_update();
595 painter_listener::painter_listener() : information_dispatch("SDL-painter-listener") {}
597 void painter_listener::on_screen_resize(screen
& scr
, uint32_t w
, uint32_t h
)
599 if(w
!= dp
.real_screen_w
|| h
!= dp
.real_screen_h
|| !hwsurf
||
600 fullscreen_console_active
!= dp
.fullscreen_console
) {
601 dp
= sdlw_display_parameters(w
, h
, fullscreen_console_active
);
602 SDL_Surface
* hwsurf2
= SDL_SetVideoMode(dp
.display_w
, dp
.display_h
, 32, SDL_SWSURFACE
);
604 //We are in too fucked up state to even print error as message.
605 std::cout
<< "PANIC: Can't create/resize window: " << SDL_GetError() << std::endl
;
610 scr
.set_palette(hwsurf
->format
->Rshift
, hwsurf
->format
->Gshift
, hwsurf
->format
->Bshift
);
611 if(fullscreen_console_active
)
612 //We have to render to memory buffer.
613 scr
.reallocate(w
, h
, false);
615 //Render direct to screen. But delay setting the buffer.
620 void painter_listener::on_render_update_start()
622 if(fullscreen_console_active
)
624 SDL_LockSurface(hwsurf
);
626 our_screen
->set(reinterpret_cast<uint32_t*>(reinterpret_cast<uint8_t*>(hwsurf
->pixels
) +
627 dp
.screenarea_y
* hwsurf
->pitch
+ dp
.screenarea_y
* hwsurf
->format
->BytesPerPixel
),
628 dp
.real_screen_w
, dp
.real_screen_h
, hwsurf
->pitch
);
629 our_screen
->set_palette(hwsurf
->format
->Rshift
, hwsurf
->format
->Gshift
, hwsurf
->format
->Bshift
);
632 void painter_listener::on_render_update_end()
636 SDL_UnlockSurface(hwsurf
);
637 video_locked
= false;
638 if(screen_paintable
) {
639 SDL_UpdateRect(hwsurf
, 6, 6, dp
.real_screen_w
, dp
.real_screen_h
);
640 screen_paintable
= false;
643 have_received_frames
= true;
646 void painter_listener::on_status_update()
648 SDL_LockSurface(hwsurf
);
649 bool update
= paint_status(hwsurf
, dp
, false);
650 SDL_UnlockSurface(hwsurf
);
652 SDL_UpdateRect(hwsurf
, dp
.statusarea_x
, dp
.statusarea_y
, dp
.statusarea_w
, dp
.statusarea_h
);
656 void sdlw_command_updated()
658 SDL_LockSurface(hwsurf
);
659 bool update
= paint_command(hwsurf
, dp
, false);
660 SDL_UnlockSurface(hwsurf
);
662 SDL_UpdateRect(hwsurf
, dp
.cmdline_x
, dp
.cmdline_y
, dp
.cmdline_w
, 16);
665 void sdlw_screen_paintable()
668 SDL_UpdateRect(hwsurf
, 6, 6, dp
.real_screen_w
, dp
.real_screen_h
);
669 screen_dirty
= false;
671 screen_paintable
= true;
674 void window::notify_message() throw(std::bad_alloc
, std::runtime_error
)
676 SDL_LockSurface(hwsurf
);
677 bool update
= paint_messages(hwsurf
, dp
, false);
678 SDL_UnlockSurface(hwsurf
);
680 SDL_UpdateRect(hwsurf
, dp
.messagearea_x
, dp
.messagearea_y
, dp
.messagearea_w
, dp
.messagearea_h
);
683 void sdlw_fullscreen_console(bool enable
)
685 fullscreen_console_active
= enable
;
686 window::msgbuf
.set_max_window_size(dp
.messagearea_lines
);
690 void sdlw_force_paint()
694 dp
= sdlw_display_parameters(0, 0, fullscreen_console_active
);
695 SDL_Surface
* hwsurf2
= SDL_SetVideoMode(dp
.display_w
, dp
.display_h
, 32, SDL_SWSURFACE
);
697 //We are in too fucked up state to even print error as message.
698 std::cout
<< "PANIC: Can't create/resize window: " << SDL_GetError() << std::endl
;
703 SDL_LockSurface(hwsurf
);
704 paint_screen(hwsurf
, dp
, true);
705 paint_status(hwsurf
, dp
, true);
706 paint_messages(hwsurf
, dp
, true);
707 paint_command(hwsurf
, dp
, true);
708 SDL_UnlockSurface(hwsurf
);
709 SDL_UpdateRect(hwsurf
, 0, 0, 0, 0);
710 if(have_received_frames
)
711 redraw_framebuffer();
712 if(modal_dialog_shown
) {
713 SDL_LockSurface(hwsurf
);
714 paint_modal_dialog(hwsurf
, modal_dialog_text
, modal_dialog_confirm
);
715 SDL_UnlockSurface(hwsurf
);
716 SDL_UpdateRect(hwsurf
, 0, 0, 0, 0);
720 std::string
sdlw_decode_string(std::string e
)
723 for(size_t i
= 0; i
< e
.length(); i
+= 4) {
725 uint32_t c1
= e
[i
] - 33;
726 uint32_t c2
= e
[i
+ 1] - 33;
727 uint32_t c3
= e
[i
+ 2] - 33;
728 uint32_t c4
= e
[i
+ 3] - 33;
729 uint32_t c
= (c1
<< 18) | (c2
<< 12) | (c3
<< 6) | c4
;
732 } else if(c
< 0x800) {
733 tmp
[0] = 0xC0 | (c
>> 6);
734 tmp
[1] = 0x80 | (c
& 0x3F);
735 } else if(c
< 0x10000) {
736 tmp
[0] = 0xE0 | (c
>> 12);
737 tmp
[1] = 0x80 | ((c
>> 6) & 0x3F);
738 tmp
[2] = 0x80 | (c
& 0x3F);
740 tmp
[0] = 0xF0 | (c
>> 18);
741 tmp
[1] = 0x80 | ((c
>> 12) & 0x3F);
742 tmp
[2] = 0x80 | ((c
>> 6) & 0x3F);
743 tmp
[3] = 0x80 | (c
& 0x3F);