00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00076 #include "../StdAfx.h"
00077
00078 #if defined(HAVE_SDL)
00079 #include "gui.h"
00080 #include "keymap.h"
00081 #include "../VGA.h"
00082 #include "../System.h"
00083
00084
00085 #include "../Keyboard.h"
00086 #include "../Configurator.h"
00087
00088 #define _MULTI_THREAD
00089
00090
00091
00092
00093 #define BX_PLUGGABLE
00094
00095 #include <stdlib.h>
00096 #include <SDL.h>
00097 #include <SDL_endian.h>
00098 #include <SDL_thread.h>
00099
00100 #include "sdl_fonts.h"
00101
00105 class bx_sdl_gui_c : public bx_gui_c
00106 {
00107 public:
00108 bx_sdl_gui_c(CConfigurator* cfg);
00109 virtual void specific_init(unsigned x_tilesize,
00110 unsigned y_tilesize);
00111 virtual void text_update(u8* old_text, u8* new_text,
00112 unsigned long cursor_x,
00113 unsigned long cursor_y,
00114 bx_vga_tminfo_t tm_info,
00115 unsigned rows);
00116 virtual void graphics_tile_update(u8* snapshot, unsigned x,
00117 unsigned y);
00118 virtual void handle_events(void);
00119 virtual void flush(void);
00120 virtual void clear_screen(void);
00121 virtual bool palette_change(unsigned index, unsigned red,
00122 unsigned green, unsigned blue);
00123 virtual void dimension_update(unsigned x, unsigned y,
00124 unsigned fheight = 0,
00125 unsigned fwidth = 0,
00126 unsigned bpp = 8);
00127 virtual void mouse_enabled_changed_specific(bool val);
00128 virtual void exit(void);
00129 virtual bx_svga_tileinfo_t* graphics_tile_info(bx_svga_tileinfo_t* info);
00130 virtual u8* graphics_tile_get(unsigned x, unsigned y,
00131 unsigned* w, unsigned* h);
00132 virtual void graphics_tile_update_in_place(unsigned x,
00133 unsigned y,
00134 unsigned w,
00135 unsigned h);
00136 private:
00137 CConfigurator* myCfg;
00138 };
00139
00140
00141
00142 static bx_sdl_gui_c* theGui = NULL;
00143 IMPLEMENT_GUI_PLUGIN_CODE(sdl)
00144 static unsigned prev_cursor_x = 0;
00145 static unsigned prev_cursor_y = 0;
00146 static u32 convertStringToSDLKey(const char* string);
00147
00148 SDL_Thread* sdl_thread;
00149 SDL_Surface* sdl_screen;
00150 SDL_Event sdl_event;
00151 int sdl_grab;
00152 unsigned res_x, res_y;
00153 unsigned half_res_x, half_res_y;
00154 static unsigned int text_cols = 80, text_rows = 25;
00155 u8 h_panning = 0, v_panning = 0;
00156 u16 line_compare = 1023;
00157 int fontwidth = 8, fontheight = 16;
00158 static unsigned vga_bpp = 8;
00159 unsigned tilewidth, tileheight;
00160 u32 palette[256];
00161 u8 old_mousebuttons = 0, new_mousebuttons = 0;
00162 int old_mousex = 0, new_mousex = 0;
00163 int old_mousey = 0, new_mousey = 0;
00164 bool just_warped = false;
00165
00166 bx_sdl_gui_c::bx_sdl_gui_c(CConfigurator* cfg)
00167 {
00168 myCfg = cfg;
00169 bx_keymap = new bx_keymap_c(cfg);
00170 }
00171
00172 #ifdef __MORPHOS__
00173 void bx_sdl_morphos_exit(void)
00174 {
00175 SDL_Quit();
00176 if(PowerSDLBase)
00177 CloseLibrary(PowerSDLBase);
00178 }
00179 #endif
00180 void bx_sdl_gui_c::specific_init(unsigned x_tilesize, unsigned y_tilesize)
00181 {
00182 int i;
00183
00184 int j;
00185 u32 flags;
00186
00187 tilewidth = x_tilesize;
00188 tileheight = y_tilesize;
00189
00190 for(i = 0; i < 256; i++)
00191 for(j = 0; j < 16; j++)
00192 vga_charmap[i * 32 + j] = sdl_font8x16[i][j];
00193
00194 #ifdef __MORPHOS__
00195 if(!(PowerSDLBase = OpenLibrary("powersdl.library", 0)))
00196 {
00197 BX_PANIC(("Unable to open SDL libraries"));
00198 return;
00199 }
00200 #endif
00201 flags = SDL_INIT_VIDEO;
00202 if(SDL_Init(flags) < 0)
00203 {
00204 FAILURE(SDL, "Unable to initialize SDL libraries");
00205 }
00206
00207 #ifdef __MORPHOS__
00208 atexit(bx_sdl_morphos_exit);
00209 #else
00210 atexit(SDL_Quit);
00211 #endif
00212 sdl_screen = NULL;
00213
00214
00215 dimension_update(640, 480);
00216
00217 SDL_EnableKeyRepeat(250, 50);
00218 SDL_WarpMouse(half_res_x, half_res_y);
00219
00220
00221 if(myCfg->get_bool_value("keyboard.use_mapping", false))
00222 {
00223 bx_keymap->loadKeymap(convertStringToSDLKey);
00224 }
00225
00226 new_gfx_api = 1;
00227 }
00228
00229 void bx_sdl_gui_c::text_update(u8* old_text, u8* new_text,
00230 unsigned long cursor_x, unsigned long cursor_y,
00231 bx_vga_tminfo_t tm_info, unsigned nrows)
00232 {
00233 u8* pfont_row;
00234
00235 u8 *old_line;
00236
00237 u8 *new_line;
00238
00239 u8 *text_base;
00240 unsigned int cs_y;
00241 unsigned int i;
00242 unsigned int x;
00243 unsigned int y;
00244 unsigned int curs;
00245 unsigned int hchars;
00246 unsigned int offset;
00247 u8 fontline;
00248 u8 fontpixels;
00249 u8 fontrows;
00250 int rows;
00251 u32 fgcolor;
00252 u32 bgcolor;
00253 u32* buf;
00254 u32 *buf_row;
00255 u32 *buf_char;
00256 u32 disp;
00257 u16 font_row;
00258 u16 mask;
00259 u8 cfstart;
00260 u8 cfwidth;
00261 u8 cfheight;
00262 u8 split_fontrows;
00263 u8 split_textrow;
00264 bool cursor_visible;
00265 bool gfxcharw9;
00266 bool invert;
00267 bool forceUpdate;
00268 bool split_screen;
00269 u32 text_palette[16];
00270
00271
00272 forceUpdate = 0;
00273 if(charmap_updated)
00274 {
00275 forceUpdate = 1;
00276 charmap_updated = 0;
00277 }
00278
00279 for(i = 0; i < 16; i++)
00280 {
00281 text_palette[i] = palette[theVGA->get_actl_palette_idx(i)];
00282 }
00283
00284 if((tm_info.h_panning != h_panning) || (tm_info.v_panning != v_panning))
00285 {
00286 forceUpdate = 1;
00287 h_panning = tm_info.h_panning;
00288 v_panning = tm_info.v_panning;
00289 }
00290
00291 if(tm_info.line_compare != line_compare)
00292 {
00293 forceUpdate = 1;
00294 line_compare = tm_info.line_compare;
00295 }
00296
00297 disp = sdl_screen->pitch / 4;
00298 buf_row = (u32*) sdl_screen->pixels;
00299
00300
00301 if((prev_cursor_y < text_rows) && (prev_cursor_x < text_cols))
00302 {
00303 curs = prev_cursor_y * tm_info.line_offset + prev_cursor_x * 2;
00304 old_text[curs] = ~new_text[curs];
00305 }
00306
00307 cursor_visible =
00308 (
00309 (tm_info.cs_start <= tm_info.cs_end)
00310 && (tm_info.cs_start < fontheight)
00311 );
00312 if((cursor_visible) && (cursor_y < text_rows) && (cursor_x < text_cols))
00313 {
00314 curs = cursor_y * tm_info.line_offset + cursor_x * 2;
00315 old_text[curs] = ~new_text[curs];
00316 }
00317 else
00318 {
00319 curs = 0xffff;
00320 }
00321
00322 rows = text_rows;
00323 if(v_panning)
00324 rows++;
00325 y = 0;
00326 cs_y = 0;
00327 text_base = new_text - tm_info.start_address;
00328 split_textrow = (line_compare + v_panning) / fontheight;
00329 split_fontrows = ((line_compare + v_panning) % fontheight) + 1;
00330 split_screen = 0;
00331
00332 do
00333 {
00334 buf = buf_row;
00335 hchars = text_cols;
00336 if(h_panning)
00337 hchars++;
00338 cfheight = fontheight;
00339 cfstart = 0;
00340 if(split_screen)
00341 {
00342 if(rows == 1)
00343 {
00344 cfheight = (res_y - line_compare - 1) % fontheight;
00345 if(cfheight == 0)
00346 cfheight = fontheight;
00347 }
00348 }
00349 else if(v_panning)
00350 {
00351 if(y == 0)
00352 {
00353 cfheight -= v_panning;
00354 cfstart = v_panning;
00355 }
00356 else if(rows == 1)
00357 {
00358 cfheight = v_panning;
00359 }
00360 }
00361
00362 if(!split_screen && (y == split_textrow))
00363 {
00364 if((split_fontrows - cfstart) < cfheight)
00365 {
00366 cfheight = split_fontrows - cfstart;
00367 }
00368 }
00369
00370 new_line = new_text;
00371 old_line = old_text;
00372 x = 0;
00373 offset = cs_y * tm_info.line_offset;
00374 do
00375 {
00376 cfwidth = fontwidth;
00377 if(h_panning)
00378 {
00379 if(hchars > text_cols)
00380 {
00381 cfwidth -= h_panning;
00382 }
00383 else if(hchars == 1)
00384 {
00385 cfwidth = h_panning;
00386 }
00387 }
00388
00389
00390 if(forceUpdate || (old_text[0] != new_text[0])
00391 || (old_text[1] != new_text[1]))
00392 {
00393
00394
00395 fgcolor = text_palette[new_text[1] & 0x0F];
00396 bgcolor = text_palette[(new_text[1] >> 4) & 0x0F];
00397 invert = ((offset == curs) && (cursor_visible));
00398 gfxcharw9 = ((tm_info.line_graphics) && ((new_text[0] & 0xE0) == 0xC0));
00399
00400
00401 fontrows = cfheight;
00402 fontline = cfstart;
00403 if(y > 0)
00404 {
00405 pfont_row = (u8*) &vga_charmap[(new_text[0] << 5)];
00406 }
00407 else
00408 {
00409 pfont_row = (u8*) &vga_charmap[(new_text[0] << 5) + cfstart];
00410 }
00411
00412 buf_char = buf;
00413 do
00414 {
00415 font_row = *pfont_row++;
00416 if(gfxcharw9)
00417 {
00418 font_row = (font_row << 1) | (font_row & 0x01);
00419 }
00420 else
00421 {
00422 font_row <<= 1;
00423 }
00424
00425 if(hchars > text_cols)
00426 {
00427 font_row <<= h_panning;
00428 }
00429
00430 fontpixels = cfwidth;
00431 if((invert) && (fontline >= tm_info.cs_start)
00432 && (fontline <= tm_info.cs_end)) mask = 0x100;
00433 else
00434 mask = 0x00;
00435 do
00436 {
00437 if((font_row & 0x100) == mask)
00438 *buf = bgcolor;
00439 else
00440 *buf = fgcolor;
00441 buf++;
00442 font_row <<= 1;
00443 } while(--fontpixels);
00444 buf -= cfwidth;
00445 buf += disp;
00446 fontline++;
00447 } while(--fontrows);
00448
00449
00450 buf = buf_char;
00451 }
00452
00453
00454 buf += cfwidth;
00455
00456
00457 new_text += 2;
00458 old_text += 2;
00459 offset += 2;
00460 x++;
00461
00462
00463 } while(--hchars);
00464
00465
00466 buf_row += disp * cfheight;
00467 if(!split_screen && (y == split_textrow))
00468 {
00469 new_text = text_base;
00470 forceUpdate = 1;
00471 cs_y = 0;
00472 if(tm_info.split_hpanning)
00473 h_panning = 0;
00474 rows = ((res_y - line_compare + fontheight - 2) / fontheight) + 1;
00475 split_screen = 1;
00476 }
00477 else
00478 {
00479 new_text = new_line + tm_info.line_offset;
00480 old_text = old_line + tm_info.line_offset;
00481 cs_y++;
00482 y++;
00483 }
00484 } while(--rows);
00485 h_panning = tm_info.h_panning;
00486 prev_cursor_x = cursor_x;
00487 prev_cursor_y = cursor_y;
00488 }
00489
00490 void bx_sdl_gui_c::graphics_tile_update(u8* snapshot, unsigned x, unsigned y)
00491 {
00492 u32* buf;
00493
00494 u32 disp;
00495 u32* buf_row;
00496 int i;
00497 int j;
00498
00499 disp = sdl_screen->pitch / 4;
00500 buf = (u32*) sdl_screen->pixels + x;
00501
00502 i = tileheight;
00503 if(i + y > res_y)
00504 i = res_y - y;
00505
00506
00507 if(i <= 0)
00508 return;
00509
00510 switch(vga_bpp)
00511 {
00512 case 8:
00513 do
00514 {
00515 buf_row = buf;
00516 j = tilewidth;
00517 do
00518 {
00519 *buf++ = palette[*snapshot++];
00520 } while(--j);
00521 buf = buf_row + disp;
00522 } while(--i);
00523 break;
00524
00525 default:
00526 BX_PANIC(("%u bpp modes handled by new graphics API", vga_bpp));
00527 return;
00528 }
00529 }
00530
00531 bx_svga_tileinfo_t* bx_sdl_gui_c::graphics_tile_info(bx_svga_tileinfo_t* info)
00532 {
00533 if(!info)
00534 {
00535 info = (bx_svga_tileinfo_t*) malloc(sizeof(bx_svga_tileinfo_t));
00536 if(!info)
00537 {
00538 return NULL;
00539 }
00540 }
00541
00542 info->bpp = sdl_screen->format->BitsPerPixel;
00543 info->pitch = sdl_screen->pitch;
00544 info->red_shift = sdl_screen->format->Rshift + 8 - sdl_screen->format->Rloss;
00545 info->green_shift = sdl_screen->format->Gshift +
00546 8 -
00547 sdl_screen->format->Gloss;
00548 info->blue_shift = sdl_screen->format->Bshift + 8 - sdl_screen->format->Bloss;
00549 info->red_mask = sdl_screen->format->Rmask;
00550 info->green_mask = sdl_screen->format->Gmask;
00551 info->blue_mask = sdl_screen->format->Bmask;
00552 info->is_indexed = (sdl_screen->format->palette != NULL);
00553
00554 #ifdef BX_LITTLE_ENDIAN
00555 info->is_little_endian = 1;
00556 #else
00557 info->is_little_endian = 0;
00558 #endif
00559 return info;
00560 }
00561
00562 u8* bx_sdl_gui_c::graphics_tile_get(unsigned x0, unsigned y0, unsigned* w,
00563 unsigned* h)
00564 {
00565 if(x0 + tilewidth > res_x)
00566 *w = res_x - x0;
00567 else
00568 *w = tilewidth;
00569
00570 if(y0 + tileheight > res_y)
00571 *h = res_y - y0;
00572 else
00573 *h = tileheight;
00574
00575 return (u8*) sdl_screen->pixels +
00576 sdl_screen->pitch *
00577 y0 +
00578 sdl_screen->format->BytesPerPixel *
00579 x0;
00580 }
00581
00582 void bx_sdl_gui_c::graphics_tile_update_in_place(unsigned x0, unsigned y0,
00583 unsigned w, unsigned h)
00584 { }
00585 static u32 sdl_sym_to_bx_key(SDLKey sym)
00586 {
00587 switch(sym)
00588 {
00589
00590
00591
00592 case SDLK_BACKSPACE:
00593 return BX_KEY_BACKSPACE;
00594
00595 case SDLK_TAB:
00596 return BX_KEY_TAB;
00597
00598
00599 case SDLK_RETURN:
00600 return BX_KEY_ENTER;
00601
00602 case SDLK_PAUSE:
00603 return BX_KEY_PAUSE;
00604
00605 case SDLK_ESCAPE:
00606 return BX_KEY_ESC;
00607
00608 case SDLK_SPACE:
00609 return BX_KEY_SPACE;
00610
00611
00612
00613
00614
00615
00616 case SDLK_QUOTE:
00617 return BX_KEY_SINGLE_QUOTE;
00618
00619
00620
00621
00622
00623 case SDLK_COMMA:
00624 return BX_KEY_COMMA;
00625
00626 case SDLK_MINUS:
00627 return BX_KEY_MINUS;
00628
00629 case SDLK_PERIOD:
00630 return BX_KEY_PERIOD;
00631
00632 case SDLK_SLASH:
00633 return BX_KEY_SLASH;
00634
00635 case SDLK_0:
00636 return BX_KEY_0;
00637
00638 case SDLK_1:
00639 return BX_KEY_1;
00640
00641 case SDLK_2:
00642 return BX_KEY_2;
00643
00644 case SDLK_3:
00645 return BX_KEY_3;
00646
00647 case SDLK_4:
00648 return BX_KEY_4;
00649
00650 case SDLK_5:
00651 return BX_KEY_5;
00652
00653 case SDLK_6:
00654 return BX_KEY_6;
00655
00656 case SDLK_7:
00657 return BX_KEY_7;
00658
00659 case SDLK_8:
00660 return BX_KEY_8;
00661
00662 case SDLK_9:
00663 return BX_KEY_9;
00664
00665
00666 case SDLK_SEMICOLON:
00667 return BX_KEY_SEMICOLON;
00668
00669
00670 case SDLK_EQUALS:
00671 return BX_KEY_EQUALS;
00672
00673
00674
00675
00676
00677
00678
00679
00680 case SDLK_LEFTBRACKET:
00681 return BX_KEY_LEFT_BRACKET;
00682
00683 case SDLK_BACKSLASH:
00684 return BX_KEY_BACKSLASH;
00685
00686 case SDLK_RIGHTBRACKET:
00687 return BX_KEY_RIGHT_BRACKET;
00688
00689
00690
00691 case SDLK_BACKQUOTE:
00692 return BX_KEY_GRAVE;
00693
00694 case SDLK_a:
00695 return BX_KEY_A;
00696
00697 case SDLK_b:
00698 return BX_KEY_B;
00699
00700 case SDLK_c:
00701 return BX_KEY_C;
00702
00703 case SDLK_d:
00704 return BX_KEY_D;
00705
00706 case SDLK_e:
00707 return BX_KEY_E;
00708
00709 case SDLK_f:
00710 return BX_KEY_F;
00711
00712 case SDLK_g:
00713 return BX_KEY_G;
00714
00715 case SDLK_h:
00716 return BX_KEY_H;
00717
00718 case SDLK_i:
00719 return BX_KEY_I;
00720
00721 case SDLK_j:
00722 return BX_KEY_J;
00723
00724 case SDLK_k:
00725 return BX_KEY_K;
00726
00727 case SDLK_l:
00728 return BX_KEY_L;
00729
00730 case SDLK_m:
00731 return BX_KEY_M;
00732
00733 case SDLK_n:
00734 return BX_KEY_N;
00735
00736 case SDLK_o:
00737 return BX_KEY_O;
00738
00739 case SDLK_p:
00740 return BX_KEY_P;
00741
00742 case SDLK_q:
00743 return BX_KEY_Q;
00744
00745 case SDLK_r:
00746 return BX_KEY_R;
00747
00748 case SDLK_s:
00749 return BX_KEY_S;
00750
00751 case SDLK_t:
00752 return BX_KEY_T;
00753
00754 case SDLK_u:
00755 return BX_KEY_U;
00756
00757 case SDLK_v:
00758 return BX_KEY_V;
00759
00760 case SDLK_w:
00761 return BX_KEY_W;
00762
00763 case SDLK_x:
00764 return BX_KEY_X;
00765
00766 case SDLK_y:
00767 return BX_KEY_Y;
00768
00769 case SDLK_z:
00770 return BX_KEY_Z;
00771
00772 case SDLK_DELETE:
00773 return BX_KEY_DELETE;
00774
00775
00776
00777
00778 case SDLK_KP0:
00779 return BX_KEY_KP_INSERT;
00780
00781 case SDLK_KP1:
00782 return BX_KEY_KP_END;
00783
00784 case SDLK_KP2:
00785 return BX_KEY_KP_DOWN;
00786
00787 case SDLK_KP3:
00788 return BX_KEY_KP_PAGE_DOWN;
00789
00790 case SDLK_KP4:
00791 return BX_KEY_KP_LEFT;
00792
00793 case SDLK_KP5:
00794 return BX_KEY_KP_5;
00795
00796 case SDLK_KP6:
00797 return BX_KEY_KP_RIGHT;
00798
00799 case SDLK_KP7:
00800 return BX_KEY_KP_HOME;
00801
00802 case SDLK_KP8:
00803 return BX_KEY_KP_UP;
00804
00805 case SDLK_KP9:
00806 return BX_KEY_KP_PAGE_UP;
00807
00808 case SDLK_KP_PERIOD:
00809 return BX_KEY_KP_DELETE;
00810
00811 case SDLK_KP_DIVIDE:
00812 return BX_KEY_KP_DIVIDE;
00813
00814 case SDLK_KP_MULTIPLY:
00815 return BX_KEY_KP_MULTIPLY;
00816
00817 case SDLK_KP_MINUS:
00818 return BX_KEY_KP_SUBTRACT;
00819
00820 case SDLK_KP_PLUS:
00821 return BX_KEY_KP_ADD;
00822
00823 case SDLK_KP_ENTER:
00824 return BX_KEY_KP_ENTER;
00825
00826
00827
00828
00829 case SDLK_UP:
00830 return BX_KEY_UP;
00831
00832 case SDLK_DOWN:
00833 return BX_KEY_DOWN;
00834
00835 case SDLK_RIGHT:
00836 return BX_KEY_RIGHT;
00837
00838 case SDLK_LEFT:
00839 return BX_KEY_LEFT;
00840
00841 case SDLK_INSERT:
00842 return BX_KEY_INSERT;
00843
00844 case SDLK_HOME:
00845 return BX_KEY_HOME;
00846
00847 case SDLK_END:
00848 return BX_KEY_END;
00849
00850 case SDLK_PAGEUP:
00851 return BX_KEY_PAGE_UP;
00852
00853 case SDLK_PAGEDOWN:
00854 return BX_KEY_PAGE_DOWN;
00855
00856
00857 case SDLK_F1:
00858 return BX_KEY_F1;
00859
00860 case SDLK_F2:
00861 return BX_KEY_F2;
00862
00863 case SDLK_F3:
00864 return BX_KEY_F3;
00865
00866 case SDLK_F4:
00867 return BX_KEY_F4;
00868
00869 case SDLK_F5:
00870 return BX_KEY_F5;
00871
00872 case SDLK_F6:
00873 return BX_KEY_F6;
00874
00875 case SDLK_F7:
00876 return BX_KEY_F7;
00877
00878 case SDLK_F8:
00879 return BX_KEY_F8;
00880
00881 case SDLK_F9:
00882 return BX_KEY_F9;
00883
00884 case SDLK_F10:
00885 return BX_KEY_F10;
00886
00887 case SDLK_F11:
00888 return BX_KEY_F11;
00889
00890 case SDLK_F12:
00891 return BX_KEY_F12;
00892
00893
00894
00895
00896
00897
00898 case SDLK_NUMLOCK:
00899 return BX_KEY_NUM_LOCK;
00900
00901 case SDLK_CAPSLOCK:
00902 return BX_KEY_CAPS_LOCK;
00903
00904 case SDLK_SCROLLOCK:
00905 return BX_KEY_SCRL_LOCK;
00906
00907 case SDLK_RSHIFT:
00908 return BX_KEY_SHIFT_R;
00909
00910 case SDLK_LSHIFT:
00911 return BX_KEY_SHIFT_L;
00912
00913 case SDLK_RCTRL:
00914 return BX_KEY_CTRL_R;
00915
00916 case SDLK_LCTRL:
00917 return BX_KEY_CTRL_L;
00918
00919 case SDLK_RALT:
00920 return BX_KEY_ALT_R;
00921
00922 case SDLK_LALT:
00923 return BX_KEY_ALT_L;
00924
00925 case SDLK_RMETA:
00926 return BX_KEY_ALT_R;
00927
00928 case SDLK_LMETA:
00929 return BX_KEY_WIN_L;
00930
00931 case SDLK_LSUPER:
00932 return BX_KEY_WIN_L;
00933
00934 case SDLK_RSUPER:
00935 return BX_KEY_WIN_R;
00936
00937
00938
00939
00940
00941 case SDLK_PRINT:
00942 return BX_KEY_PRINT;
00943
00944 case SDLK_BREAK:
00945 return BX_KEY_PAUSE;
00946
00947 case SDLK_MENU:
00948 return BX_KEY_MENU;
00949 #if 0
00950
00951 case SDLK_HELP:
00952 return BX_KEY_HELP;
00953
00954 case SDLK_SYSREQ:
00955 return BX_KEY_SYSREQ;
00956
00957 case SDLK_POWER:
00958 return BX_KEY_POWER;
00959
00960 case SDLK_EURO:
00961 return BX_KEY_EURO;
00962
00963 case SDLK_UNDO:
00964 return BX_KEY_UNDO;
00965 #endif
00966
00967 default:
00968 BX_ERROR(("sdl keysym %d not mapped", (int) sym));
00969 return BX_KEY_UNHANDLED;
00970 }
00971 }
00972
00973 void bx_sdl_gui_c::handle_events(void)
00974 {
00975 u32 key_event;
00976
00977
00978 int wheel_status;
00979
00980 while(SDL_PollEvent(&sdl_event))
00981 {
00982 wheel_status = 0;
00983 switch(sdl_event.type)
00984 {
00985 case SDL_VIDEOEXPOSE:
00986 SDL_UpdateRect(sdl_screen, 0, 0, res_x, res_y);
00987 break;
00988
00989 case SDL_MOUSEMOTION:
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021 case SDL_MOUSEBUTTONDOWN:
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050 case SDL_MOUSEBUTTONUP:
01051
01052
01053
01054
01055
01056
01057
01058
01059
01060
01061
01062
01063
01064
01065
01066
01067
01068
01069
01070
01071
01072
01073
01074 break;
01075
01076
01077 case SDL_KEYDOWN:
01078
01079
01080 if(sdl_event.key.keysym.sym > SDLK_LAST)
01081 break;
01082 if(!myCfg->get_bool_value("keyboard.use_mapping", false))
01083
01084
01085 {
01086 key_event = sdl_sym_to_bx_key(sdl_event.key.keysym.sym);
01087 #if defined(DEBUG_KBD)
01088 BX_DEBUG((
01089 "keypress scancode=%d, sym=%d, bx_key = %d", sdl_event.key.keysym.
01090 scancode, sdl_event.key.keysym.sym, key_event));
01091 #endif
01092 }
01093 else
01094 {
01095
01096
01097 BXKeyEntry* entry = bx_keymap->findHostKey(sdl_event.key.keysym.sym);
01098 if(!entry)
01099 {
01100 BX_ERROR(("host key %d (0x%x) not mapped!",
01101 (unsigned) sdl_event.key.keysym.sym,
01102 (unsigned) sdl_event.key.keysym.sym));
01103 break;
01104 }
01105
01106 key_event = entry->baseKey;
01107 }
01108
01109 if(key_event == BX_KEY_UNHANDLED)
01110 break;
01111 theKeyboard->gen_scancode(key_event);
01112 if((key_event == BX_KEY_NUM_LOCK) || (key_event == BX_KEY_CAPS_LOCK))
01113 {
01114 theKeyboard->gen_scancode(key_event | BX_KEY_RELEASED);
01115 }
01116 break;
01117
01118 case SDL_KEYUP:
01119
01120
01121 if((sdl_event.key.keysym.sym != SDLK_SCROLLOCK)
01122 && (sdl_event.key.keysym.sym < SDLK_LAST))
01123 {
01124
01125
01126 if(!myCfg->get_bool_value("keyboard.use_mapping", false))
01127 {
01128
01129
01130 key_event = sdl_sym_to_bx_key(sdl_event.key.keysym.sym);
01131 }
01132 else
01133 {
01134
01135
01136 BXKeyEntry* entry = bx_keymap->findHostKey(sdl_event.key.keysym.sym);
01137 if(!entry)
01138 {
01139 BX_ERROR(("host key %d (0x%x) not mapped!",
01140 (unsigned) sdl_event.key.keysym.sym,
01141 (unsigned) sdl_event.key.keysym.sym));
01142 break;
01143 }
01144
01145 key_event = entry->baseKey;
01146 }
01147
01148 if(key_event == BX_KEY_UNHANDLED)
01149 break;
01150 if((key_event == BX_KEY_NUM_LOCK) || (key_event == BX_KEY_CAPS_LOCK))
01151 {
01152 theKeyboard->gen_scancode(key_event);
01153 }
01154
01155 theKeyboard->gen_scancode(key_event | BX_KEY_RELEASED);
01156 }
01157 break;
01158
01159 case SDL_QUIT:
01160 FAILURE(Graceful, "User requested shutdown");
01161 }
01162 }
01163 }
01164
01168 void bx_sdl_gui_c::flush(void)
01169 {
01170 SDL_UpdateRect(sdl_screen, 0, 0, res_x, res_y);
01171 }
01172
01176 void bx_sdl_gui_c::clear_screen(void)
01177 {
01178 int i = res_y;
01179
01180 int j;
01181 u32 color;
01182 u32* buf;
01183 u32 *buf_row;
01184 u32 disp;
01185
01186 if(!sdl_screen)
01187 return;
01188
01189 color = SDL_MapRGB(sdl_screen->format, 0, 0, 0);
01190 disp = sdl_screen->pitch / 4;
01191 buf = (u32*) sdl_screen->pixels;
01192
01193 do
01194 {
01195 buf_row = buf;
01196 j = res_x;
01197 while(j--)
01198 *buf++ = color;
01199 buf = buf_row + disp;
01200 } while(--i);
01201
01202 flush();
01203 }
01204
01210 bool bx_sdl_gui_c::palette_change(unsigned index, unsigned red, unsigned green,
01211 unsigned blue)
01212 {
01213 unsigned char palred = red & 0xFF;
01214 unsigned char palgreen = green & 0xFF;
01215 unsigned char palblue = blue & 0xFF;
01216
01217 if(index > 255)
01218 return 0;
01219
01220 palette[index] = SDL_MapRGB(sdl_screen->format, palred, palgreen, palblue);
01221
01222 return 1;
01223 }
01224
01225 void bx_sdl_gui_c::dimension_update(unsigned x, unsigned y, unsigned fheight,
01226 unsigned fwidth, unsigned bpp)
01227 {
01228 if((bpp == 8) || (bpp == 15) || (bpp == 16) || (bpp == 24) || (bpp == 32))
01229 {
01230 vga_bpp = bpp;
01231 }
01232 else
01233 {
01234 FAILURE_1(SDL, "%d bpp graphics mode not supported.", bpp);
01235 }
01236
01237 if(fheight > 0)
01238 {
01239 fontheight = fheight;
01240 fontwidth = fwidth;
01241 text_cols = x / fontwidth;
01242 text_rows = y / fontheight;
01243 }
01244
01245 if((x == res_x) && (y == res_y))
01246 return;
01247
01248 if(sdl_screen)
01249 {
01250 SDL_FreeSurface(sdl_screen);
01251 sdl_screen = NULL;
01252 }
01253
01254 sdl_screen = SDL_SetVideoMode(x, y , 32,
01255 SDL_SWSURFACE);
01256 if(!sdl_screen)
01257 {
01258 FAILURE_3(SDL, "Unable to set requested videomode: %ix%i: %s \n", x, y,
01259 SDL_GetError());
01260 }
01261
01262 res_x = x;
01263 res_y = y;
01264 half_res_x = x / 2;
01265 half_res_y = y / 2;
01266 }
01267
01268 void bx_sdl_gui_c::mouse_enabled_changed_specific(bool val)
01269 {
01270 if(val == 1)
01271 {
01272 SDL_ShowCursor(0);
01273 SDL_WM_GrabInput(SDL_GRAB_ON);
01274 }
01275 else
01276 {
01277 SDL_ShowCursor(1);
01278 SDL_WM_GrabInput(SDL_GRAB_OFF);
01279 }
01280
01281 sdl_grab = val;
01282 }
01283
01284 void bx_sdl_gui_c::exit(void)
01285 {
01286 if(sdl_screen)
01287 SDL_FreeSurface(sdl_screen);
01288 }
01289
01291 typedef struct
01292 {
01293 const char* name;
01294 u32 value;
01295 } keyTableEntry;
01296
01297 #define DEF_SDL_KEY(key) \
01298 { \
01299 #key, key \
01300 },
01301
01302 keyTableEntry keytable[] = {
01303
01304 #include "sdlkeys.h"
01305
01306 { NULL, 0}
01307 };
01308
01309
01310
01311
01312
01313
01314 static u32 convertStringToSDLKey(const char* string)
01315 {
01316 keyTableEntry* ptr;
01317 for(ptr = &keytable[0]; ptr->name != NULL; ptr++)
01318 {
01319 #if defined(DEBUG_SDL_KEY)
01320 printf("SDL: comparing string '%s' to SDL key '%s' \n", string, ptr->name);
01321 #endif
01322 if(!strcmp(string, ptr->name))
01323 return ptr->value;
01324 }
01325
01326 return BX_KEYMAP_UNKNOWN;
01327 }
01328 #endif //defined(HAVE_SDL)