Main Page | Class Hierarchy | Compound List | File List | Compound Members | File Members | Related Pages

Display_svga.i

Go to the documentation of this file.
00001 /*
00002  *  Display_x.i - C64 graphics display, emulator window handling,
00003  *                X specific stuff
00004  *
00005  *  Frodo (C) 1994-1997 Christian Bauer
00006  *  SVGAlib stuff by Bernd Schmidt
00007  */
00008 
00009 #include <vga.h>
00010 #include <vgamouse.h>
00011 #include <vgakeyboard.h>
00012 
00013 #include "C64.h"
00014 
00015 
00016 #define SCODE_CURSORBLOCKUP 103         /* Cursor key block. */
00017 #define SCODE_CURSORBLOCKLEFT 105
00018 #define SCODE_CURSORBLOCKRIGHT 106
00019 #define SCODE_CURSORBLOCKDOWN 108
00020 
00021 #define SCODE_INSERT 110
00022 #define SCODE_HOME 102
00023 #define SCODE_PGUP 104
00024 #define SCODE_DELETE 111
00025 #define SCODE_END 107
00026 #define SCODE_PGDN 109
00027 
00028 #define SCODE_NUMLOCK 69
00029 
00030 #define SCODE_KEYPAD0  82
00031 #define SCODE_KEYPAD1  79
00032 #define SCODE_KEYPAD2  80
00033 #define SCODE_KEYPAD3  81
00034 #define SCODE_KEYPAD4  75
00035 #define SCODE_KEYPAD5  76
00036 #define SCODE_KEYPAD6  77
00037 #define SCODE_KEYPAD7  71
00038 #define SCODE_KEYPAD8  72
00039 #define SCODE_KEYPAD9  73
00040 #define SCODE_KEYPADENTER      96
00041 #define SCODE_KEYPADPLUS       78
00042 #define SCODE_KEYPADMINUS      74
00043 #define SCODE_KEYPADMULTIPLY   55
00044 #define SCODE_KEYPADDIVIDE     98
00045 
00046 #define SCODE_Q                16
00047 #define SCODE_W                17
00048 #define SCODE_E                18
00049 #define SCODE_R                19
00050 #define SCODE_T                20
00051 #define SCODE_Y                21
00052 #define SCODE_U                22
00053 #define SCODE_I                23
00054 #define SCODE_O                24
00055 #define SCODE_P                25
00056 
00057 #define SCODE_A                30
00058 #define SCODE_S                31
00059 #define SCODE_D                32
00060 #define SCODE_F                33
00061 #define SCODE_G                34
00062 #define SCODE_H                35
00063 #define SCODE_J                36
00064 #define SCODE_K                37
00065 #define SCODE_L                38
00066 
00067 #define SCODE_Z                44
00068 #define SCODE_X                45
00069 #define SCODE_C                46
00070 #define SCODE_V                47
00071 #define SCODE_B                48
00072 #define SCODE_N                49
00073 #define SCODE_M                50
00074 
00075 #define SCODE_ESCAPE           1
00076 #define SCODE_ENTER            28
00077 #define SCODE_RIGHTCONTROL     97
00078 #define SCODE_CONTROL  97
00079 #define SCODE_RIGHTALT 100
00080 #define SCODE_LEFTCONTROL      29
00081 #define SCODE_LEFTALT  56
00082 #define SCODE_SPACE            57
00083 
00084 #define SCODE_F1               59
00085 #define SCODE_F2               60
00086 #define SCODE_F3               61
00087 #define SCODE_F4               62
00088 #define SCODE_F5               63
00089 #define SCODE_F6               64
00090 #define SCODE_F7               65
00091 #define SCODE_F8               66
00092 #define SCODE_F9               67
00093 #define SCODE_F10              68
00094 
00095 #define SCODE_0 11
00096 #define SCODE_1 2
00097 #define SCODE_2 3
00098 #define SCODE_3 4
00099 #define SCODE_4 5 
00100 #define SCODE_5 6
00101 #define SCODE_6 7 
00102 #define SCODE_7 8
00103 #define SCODE_8 9
00104 #define SCODE_9 10
00105 
00106 #define SCODE_LEFTSHIFT 42
00107 #define SCODE_RIGHTSHIFT 54
00108 #define SCODE_TAB 15
00109 
00110 #define SCODE_F11 87
00111 #define SCODE_F12 88
00112 #define SCODE_NEXT 81
00113 #define SCODE_PRIOR 73
00114 #define SCODE_BS 14
00115 
00116 #define SCODE_asciicircum 41
00117 #define SCODE_bracketleft 26
00118 #define SCODE_bracketright 27
00119 #define SCODE_comma 51
00120 #define SCODE_period 52
00121 #define SCODE_slash 53
00122 #define SCODE_semicolon 39
00123 #define SCODE_grave 40
00124 #define SCODE_minus 12
00125 #define SCODE_equal 13
00126 #define SCODE_numbersign 43
00127 #define SCODE_ltgt 86
00128 #define SCODE_scrolllock 70
00129 
00130 static int bitdepth;
00131 static char *bufmem;
00132 static int hsize;
00133 static vga_modeinfo modeinfo;
00134 static char *linear_mem;
00135 
00136 static int keystate[256];
00137 static int f11pressed = 0, f12pressed = 0, quit = 0;
00138 static int joystate = 0xFF;
00139 static int numlock = 0;
00140 static UBYTE rev_matrix[8], key_matrix[8];
00141 
00142 /*
00143   C64 keyboard matrix:
00144 
00145     Bit 7   6   5   4   3   2   1   0
00146   0    CUD  F5  F3  F1  F7 CLR RET DEL
00147   1    SHL  E   S   Z   4   A   W   3
00148   2     X   T   F   C   6   D   R   5
00149   3     V   U   H   B   8   G   Y   7
00150   4     N   O   K   M   0   J   I   9
00151   5     ,   @   :   .   -   L   P   +
00152   6     /   ^   =  SHR HOM  ;   *   
00153   7    R/S  Q   C= SPC  2  CTL  <-  1
00154 */
00155 #define MATRIX(a,b) (((a) << 3) | (b))
00156 #define KEY_F10 512
00157 #define KEY_F11 513
00158 #define KEY_F12 514
00159 
00160 #define KEY_FIRE 515
00161 #define KEY_JUP 516
00162 #define KEY_JDN 517
00163 #define KEY_JLF 518
00164 #define KEY_JRT 519
00165 
00166 #define KEY_NUMLOCK 520
00167 
00168 #define KEY_KPPLUS 521
00169 #define KEY_KPMINUS 522
00170 #define KEY_KPMULT 523
00171 #define KEY_KPDIV 524
00172 
00173 static int scode2c64(int scancode)
00174 {
00175         switch (scancode) {
00176         case SCODE_asciicircum: return MATRIX(7,1);
00177         case SCODE_KEYPAD0: return KEY_FIRE;
00178         case SCODE_KEYPAD1: return -1;
00179         case SCODE_KEYPAD2: return KEY_JDN;
00180         case SCODE_KEYPAD3: return -1;
00181         case SCODE_KEYPAD4: return KEY_JLF;
00182         case SCODE_KEYPAD5: return -1;
00183         case SCODE_KEYPAD6: return KEY_JRT;
00184         case SCODE_KEYPAD7: return -1;
00185         case SCODE_KEYPAD8: return KEY_JUP;
00186         case SCODE_KEYPAD9: return -1;
00187                 
00188         case SCODE_NUMLOCK: return KEY_NUMLOCK;
00189         case SCODE_KEYPADMULTIPLY: return KEY_KPMULT;
00190         case SCODE_KEYPADDIVIDE: return KEY_KPDIV;
00191         case SCODE_KEYPADMINUS: return KEY_KPMINUS;
00192         case SCODE_KEYPADPLUS: return KEY_KPPLUS;
00193         case SCODE_KEYPADENTER: return MATRIX(0,1);
00194                
00195         case SCODE_F10: return KEY_F10;
00196         case SCODE_F11: return KEY_F11;
00197         case SCODE_F12: return KEY_F12;
00198                 
00199         case SCODE_comma: return MATRIX(5,7);
00200         case SCODE_period: return MATRIX(5,4);
00201                 
00202         case SCODE_A: return MATRIX(1,2);
00203         case SCODE_B: return MATRIX(3,4);
00204         case SCODE_C: return MATRIX(2,4);
00205         case SCODE_D: return MATRIX(2,2);
00206         case SCODE_E: return MATRIX(1,6);
00207         case SCODE_F: return MATRIX(2,5);
00208         case SCODE_G: return MATRIX(3,2);
00209         case SCODE_H: return MATRIX(3,5);
00210         case SCODE_I: return MATRIX(4,1);
00211         case SCODE_J: return MATRIX(4,2);
00212         case SCODE_K: return MATRIX(4,5);
00213         case SCODE_L: return MATRIX(5,2);
00214         case SCODE_M: return MATRIX(4,4);
00215         case SCODE_N: return MATRIX(4,7);
00216         case SCODE_O: return MATRIX(4,6);
00217         case SCODE_P: return MATRIX(5,1);
00218         case SCODE_Q: return MATRIX(7,6);
00219         case SCODE_R: return MATRIX(2,1);
00220         case SCODE_S: return MATRIX(1,5);
00221         case SCODE_T: return MATRIX(2,6);
00222         case SCODE_U: return MATRIX(3,6);
00223         case SCODE_V: return MATRIX(3,7);
00224         case SCODE_W: return MATRIX(1,1);
00225         case SCODE_X: return MATRIX(2,7);
00226         case SCODE_Y: return MATRIX(3,1);
00227         case SCODE_Z: return MATRIX(1,4);
00228                 
00229         case SCODE_BS: return MATRIX(0,0);
00230         case SCODE_DELETE: return MATRIX(0,0);
00231         case SCODE_LEFTCONTROL: return MATRIX(7,2);
00232         case SCODE_TAB: return MATRIX(7,1);
00233         case SCODE_ENTER: return MATRIX(0,1);
00234         case SCODE_SPACE: return MATRIX(7,4);
00235         case SCODE_LEFTSHIFT: return MATRIX(1,7);
00236         case SCODE_RIGHTSHIFT: return MATRIX(6,4);
00237         case SCODE_ESCAPE: return MATRIX(7,7);
00238         case SCODE_RIGHTCONTROL:
00239         case SCODE_LEFTALT:
00240         case SCODE_RIGHTALT: return MATRIX(7,5);
00241 
00242         case SCODE_INSERT: return MATRIX(0,0) | 0x80;
00243         case SCODE_HOME: return MATRIX(6,3);
00244         case SCODE_END: return MATRIX(6,0);
00245         case SCODE_PGUP: return MATRIX(6,6);
00246         case SCODE_PGDN: return MATRIX(6,5);
00247                 
00248         case SCODE_CURSORBLOCKUP: return MATRIX(0,7)| 0x80;
00249         case SCODE_CURSORBLOCKDOWN: return MATRIX(0,7);
00250         case SCODE_CURSORBLOCKLEFT: return MATRIX(0,2) | 0x80;
00251         case SCODE_CURSORBLOCKRIGHT: return MATRIX(0,2);
00252                 
00253         case SCODE_F1: return MATRIX(0,4);
00254         case SCODE_F2: return MATRIX(0,4) | 0x80;
00255         case SCODE_F3: return MATRIX(0,5);
00256         case SCODE_F4: return MATRIX(0,5) | 0x80;
00257         case SCODE_F5: return MATRIX(0,6);
00258         case SCODE_F6: return MATRIX(0,6) | 0x80;
00259         case SCODE_F7: return MATRIX(0,3);
00260         case SCODE_F8: return MATRIX(0,3) | 0x80;
00261                 
00262         case SCODE_0: return MATRIX(4,3);
00263         case SCODE_1: return MATRIX(7,0);
00264         case SCODE_2: return MATRIX(7,3);
00265         case SCODE_3: return MATRIX(1,0);
00266         case SCODE_4: return MATRIX(1,3);
00267         case SCODE_5: return MATRIX(2,0);
00268         case SCODE_6: return MATRIX(2,3);
00269         case SCODE_7: return MATRIX(3,0);
00270         case SCODE_8: return MATRIX(3,3);
00271         case SCODE_9: return MATRIX(4,0);
00272 
00273         case SCODE_bracketleft: return MATRIX(5,6);
00274         case SCODE_bracketright: return MATRIX(6,1);
00275         case SCODE_slash: return MATRIX(6,7);
00276         case SCODE_semicolon: return MATRIX(5,5);
00277         case SCODE_grave: return MATRIX(6,2);
00278         case SCODE_numbersign: return MATRIX(6,5);
00279         case SCODE_ltgt: return MATRIX(6,6);
00280         case SCODE_minus: return MATRIX(5,0);
00281         case SCODE_equal: return MATRIX(5,3);
00282         }
00283 }
00284 
00285 static void my_kbd_handler(int scancode, int newstate)
00286 {
00287         int kc = scode2c64(scancode);
00288 #if 0
00289         if (kc == -1) {
00290                 printf("%d\n",kc);
00291                 return;
00292         }
00293 #endif
00294         if (newstate == KEY_EVENTPRESS) {
00295                 switch (kc) {
00296                 case KEY_KPPLUS:
00297                         if (ThePrefs.SkipFrames < 10)
00298                                 ThePrefs.SkipFrames++;
00299                         break;
00300 
00301                 case KEY_KPMINUS:
00302                         if (ThePrefs.SkipFrames > 1)
00303                                 ThePrefs.SkipFrames--;
00304                         break;
00305 
00306                 case KEY_KPMULT:
00307                         ThePrefs.LimitSpeed = !ThePrefs.LimitSpeed;
00308                         break;
00309 
00310                 case KEY_KPDIV:
00311                         ThePrefs.JoystickSwap = !ThePrefs.JoystickSwap;
00312                         break;
00313 
00314                 case KEY_NUMLOCK:
00315                         numlock = !numlock;
00316                         break;
00317                         
00318                 case KEY_F10:
00319                         quit = 1;
00320                         break;
00321                                
00322                 case KEY_F11:
00323                         f11pressed = 1;
00324                         break;
00325                         
00326                 case KEY_F12:
00327                         f12pressed = 1;
00328                         break;
00329                         
00330                 case KEY_FIRE:
00331                         joystate &= ~0x10;
00332                         break;
00333                         
00334                 case KEY_JDN:
00335                         joystate &= ~0x2;
00336                         break;
00337                         
00338                 case KEY_JUP:
00339                         joystate &= ~0x1;
00340                         break;
00341                         
00342                 case KEY_JLF:
00343                         joystate &= ~0x4;
00344                         break;
00345                         
00346                 case KEY_JRT:
00347                         joystate &= ~0x8;
00348                         break;
00349                         
00350                 default:
00351                         if (keystate[kc])
00352                                 break;
00353                         keystate[kc] = 1;
00354                         int c64_byte, c64_bit, shifted;
00355                         c64_byte = kc >> 3;
00356                         c64_bit = kc & 7;
00357                         shifted = kc & 128;
00358                         c64_byte &= 7;
00359                         if (shifted) {
00360                                 key_matrix[6] &= 0xef;
00361                                 rev_matrix[4] &= 0xbf;
00362                         }
00363                         key_matrix[c64_byte] &= ~(1 << c64_bit);
00364                         rev_matrix[c64_bit] &= ~(1 << c64_byte);
00365                         break;
00366                 }
00367         } else {
00368                 switch (kc) {                   
00369                 case KEY_FIRE:
00370                         joystate |= 0x10;
00371                         break;
00372                         
00373                 case KEY_JDN:
00374                         joystate |= 0x2;
00375                         break;
00376                         
00377                 case KEY_JUP:
00378                         joystate |= 0x1;
00379                         break;
00380                         
00381                 case KEY_JLF:
00382                         joystate |= 0x4;
00383                         break;
00384                         
00385                 case KEY_JRT:
00386                         joystate |= 0x8;
00387                         break;
00388                         
00389                 default:
00390                         if (!keystate[kc])
00391                                 break;
00392                         keystate[kc] = 0;
00393                         int c64_byte, c64_bit, shifted;
00394                         c64_byte = kc >> 3;
00395                         c64_bit = kc & 7;
00396                         shifted = kc & 128;
00397                         c64_byte &= 7;
00398                         if (shifted) {
00399                                 key_matrix[6] |= 0x10;
00400                                 rev_matrix[4] |= 0x40;
00401                         }
00402                         key_matrix[c64_byte] |= (1 << c64_bit);
00403                         rev_matrix[c64_bit] |= (1 << c64_byte);
00404                         break;
00405                 }
00406                 
00407         }
00408 }
00409 
00410 
00411 C64Display::C64Display(C64 *the_c64) : TheC64(the_c64)
00412 {
00413     quit_requested = false;
00414 }
00415 
00416 
00417 C64Display::~C64Display()
00418 {
00419     sleep(1);
00420     vga_setmode(TEXT);
00421 }
00422 
00423 
00424 /*
00425  *  Prefs may have changed
00426  */
00427 
00428 void C64Display::NewPrefs(Prefs *prefs)
00429 {
00430 }
00431 
00432 
00433 void C64Display::Speedometer(int speed)
00434 {
00435 }
00436 
00437 
00438 int init_graphics(void)
00439 {      
00440     int vgamode = G640x480x256;
00441     modeinfo = *vga_getmodeinfo (vgamode);
00442 
00443     if (vga_setmode(vgamode) < 0) {
00444         sleep(1);
00445         vga_setmode(TEXT);
00446         fprintf(stderr, "SVGAlib doesn't like my video mode. Giving up.\n");
00447         return 0;
00448     }
00449 
00450     hsize = modeinfo.linewidth;
00451     if (hsize < DISPLAY_X)
00452         hsize = DISPLAY_X;
00453 
00454         bufmem = NULL;
00455     if ((modeinfo.flags & CAPABLE_LINEAR) && modeinfo.linewidth >= DISPLAY_X) {
00456         if (vga_setlinearaddressing() != -1) {
00457             linear_mem = (char *)vga_getgraphmem();
00458             printf("Using linear addressing: %p.\n", linear_mem);
00459             bufmem = linear_mem;
00460         }
00461     }
00462     if (bufmem == NULL)
00463         bufmem = (char *)malloc(hsize * DISPLAY_Y);
00464 
00465     if (keyboard_init() != 0)
00466         abort();
00467     keyboard_seteventhandler(my_kbd_handler);
00468     /*     keyboard_translatekeys(DONT_CATCH_CTRLC);*/
00469 
00470     memset(keystate, 0, sizeof(keystate));
00471     memset(key_matrix, 0xFF, 8);
00472     memset(rev_matrix, 0xFF, 8);
00473     return 1;
00474 }
00475 
00476 
00477 void C64Display::Update(void)
00478 {
00479     int y;
00480 
00481     if (linear_mem)
00482         return;
00483     
00484     for (y = 0; y < DISPLAY_Y; y++) {
00485         vga_drawscanline(y, bufmem + hsize * y);
00486     }
00487 }
00488 
00489 
00490 UBYTE *C64Display::BitmapBase(void)
00491 {
00492        return (UBYTE *)bufmem;
00493 }
00494 
00495 
00496 int C64Display::BitmapXMod(void)
00497 {
00498        return hsize;
00499 }
00500 
00501 
00502 void C64Display::PollKeyboard(UBYTE *CIA_key_matrix, UBYTE *CIA_rev_matrix, UBYTE *joystick)
00503 {
00504     keyboard_update();
00505     *joystick = joystate;
00506     memcpy(CIA_key_matrix, key_matrix, 8);
00507     memcpy(CIA_rev_matrix, rev_matrix, 8);
00508     if (f11pressed)
00509         TheC64->NMI();
00510     if (f12pressed)
00511         TheC64->Reset();
00512     if (quit)
00513         quit_requested = true;
00514     f11pressed = f12pressed = 0;
00515 }
00516 
00517 
00518 /*
00519  *  Check if NumLock is down (for switching the joystick keyboard emulation)
00520  */
00521 
00522 bool C64Display::NumLock(void)
00523 {
00524        return numlock;
00525 }
00526 
00527 
00528 /*
00529  *  Allocate C64 colors
00530  */
00531 
00532 static int colorval(int v)
00533 {
00534        return ((v & 255)*0x01010101) >> 26;
00535 }
00536 
00537 void C64Display::InitColors(UBYTE *colors)
00538 {
00539        int i;
00540 
00541        for (i=0; i< 256; i++) {
00542                vga_setpalette(i, colorval(palette_red[i & 0x0f]), colorval(palette_green[i & 0x0f]), colorval(palette_blue[i & 0x0f]));
00543                colors[i] = i;
00544        }
00545 }
00546 
00547 
00548 /*
00549  *  Show a requester (error message)
00550  */
00551 
00552 long int ShowRequester(char *a,char *b,char *)
00553 {
00554        printf("%s: %s\n", a, b);
00555        return 1;
00556 }

Generated on Tue Feb 8 04:07:49 2005 for E32frodo by doxygen 1.3.3