Subversion Repositories Kolibri OS

Rev

Rev 5131 | Blame | Compare with Previous | Last modification | View Log | RSS feed

  1. // vid_sdl.h -- sdl video driver
  2.  
  3. #include "SDL.h"
  4. #include "quakedef.h"
  5. #include "d_local.h"
  6.  
  7. #ifdef _KOLIBRI
  8. #include <sys/ksys.h>
  9. #endif
  10.  
  11.  
  12. viddef_t    vid;                // global video state
  13. unsigned short  d_8to16table[256];
  14.  
  15. // The original defaults
  16. //#define    BASEWIDTH    320
  17. //#define    BASEHEIGHT   200
  18. // Much better for high resolution displays
  19. #define    BASEWIDTH    (320*2)
  20. #define    BASEHEIGHT   (200*2)
  21.  
  22. int    VGA_width, VGA_height, VGA_rowbytes, VGA_bufferrowbytes = 0;
  23. byte    *VGA_pagebase;
  24.  
  25. static SDL_Surface *screen = NULL;
  26.  
  27. static qboolean mouse_avail;
  28. static float   mouse_x, mouse_y;
  29. static int mouse_oldbuttonstate = 0;
  30.  
  31. // No support for option menus
  32. void (*vid_menudrawfn)(void) = NULL;
  33. void (*vid_menukeyfn)(int key) = NULL;
  34.  
  35. void    VID_SetPalette (unsigned char *palette)
  36. {
  37.     int i;
  38.     SDL_Color colors[256];
  39.  
  40.     for ( i=0; i<256; ++i )
  41.     {
  42.         colors[i].r = *palette++;
  43.         colors[i].g = *palette++;
  44.         colors[i].b = *palette++;
  45.     }
  46.     SDL_SetColors(screen, colors, 0, 256);
  47. }
  48.  
  49. void    VID_ShiftPalette (unsigned char *palette)
  50. {
  51.     VID_SetPalette(palette);
  52. }
  53.  
  54. void    VID_Init (unsigned char *palette)
  55. {
  56.     int pnum, chunk;
  57.     byte *cache;
  58.     int cachesize;
  59.     Uint8 video_bpp;
  60.     Uint16 video_w, video_h;
  61.     Uint32 flags;
  62.  
  63.     // Load the SDL library
  64. #ifdef _KOLIBRI
  65.     if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO) < 0)
  66. #else
  67.     if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_AUDIO|SDL_INIT_CDROM) < 0)
  68. #endif
  69.         Sys_Error("VID: Couldn't load SDL: %s", SDL_GetError());
  70.  
  71.     // Set up display mode (width and height)
  72.     vid.width = BASEWIDTH;
  73.     vid.height = BASEHEIGHT;
  74.     vid.maxwarpwidth = WARP_WIDTH;
  75.     vid.maxwarpheight = WARP_HEIGHT;
  76.     if ((pnum=COM_CheckParm("-winsize")))
  77.     {
  78.         if (pnum >= com_argc-2)
  79.             Sys_Error("VID: -winsize <width> <height>\n");
  80.         vid.width = Q_atoi(com_argv[pnum+1]);
  81.         vid.height = Q_atoi(com_argv[pnum+2]);
  82.         if (!vid.width || !vid.height)
  83.             Sys_Error("VID: Bad window width/height\n");
  84.     }
  85.  
  86.     flags = (SDL_SWSURFACE|SDL_HWPALETTE);
  87. #ifndef _KOLIBRI
  88.     // Set video width, height and flags
  89.     if ( COM_CheckParm ("-fullscreen") )
  90.         flags |= SDL_FULLSCREEN;
  91. #endif
  92.  
  93.     // Initialize display
  94.     if (!(screen = SDL_SetVideoMode(vid.width, vid.height, 8, flags)))
  95.         Sys_Error("VID: Couldn't set video mode: %s\n", SDL_GetError());
  96.     VID_SetPalette(palette);
  97.     SDL_WM_SetCaption("sdlquake","sdlquake");
  98.     // now know everything we need to know about the buffer
  99.     VGA_width = vid.conwidth = vid.width;
  100.     VGA_height = vid.conheight = vid.height;
  101.     vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0);
  102.     vid.numpages = 1;
  103.     vid.colormap = host_colormap;
  104.     vid.fullbright = 256 - LittleLong (*((int *)vid.colormap + 2048));
  105.     VGA_pagebase = vid.buffer = screen->pixels;
  106.     VGA_rowbytes = vid.rowbytes = screen->pitch;
  107.     vid.conbuffer = vid.buffer;
  108.     vid.conrowbytes = vid.rowbytes;
  109.     vid.direct = 0;
  110.    
  111.     // allocate z buffer and surface cache
  112.     chunk = vid.width * vid.height * sizeof (*d_pzbuffer);
  113.     cachesize = D_SurfaceCacheForRes (vid.width, vid.height);
  114.     chunk += cachesize;
  115.     d_pzbuffer = Hunk_HighAllocName(chunk, "video");
  116.     if (d_pzbuffer == NULL)
  117.         Sys_Error ("Not enough memory for video mode\n");
  118.  
  119.     // initialize the cache memory
  120.         cache = (byte *) d_pzbuffer
  121.                 + vid.width * vid.height * sizeof (*d_pzbuffer);
  122.     D_InitCaches (cache, cachesize);
  123.  
  124.     // initialize the mouse
  125.     SDL_ShowCursor(0);
  126. }
  127.  
  128. void    VID_Shutdown (void)
  129. {
  130.     SDL_Quit();
  131. }
  132.  
  133. void    VID_Update (vrect_t *rects)
  134. {
  135.     SDL_Rect *sdlrects;
  136.     int n, i;
  137.     vrect_t *rect;
  138.  
  139.     // Two-pass system, since Quake doesn't do it the SDL way...
  140.  
  141.     // First, count the number of rectangles
  142.     n = 0;
  143.     for (rect = rects; rect; rect = rect->pnext)
  144.         ++n;
  145.  
  146.     // Second, copy them to SDL rectangles and update
  147.     if (!(sdlrects = (SDL_Rect *)alloca(n*sizeof(*sdlrects))))
  148.         Sys_Error("Out of memory");
  149.     i = 0;
  150.     for (rect = rects; rect; rect = rect->pnext)
  151.     {
  152.         sdlrects[i].x = rect->x;
  153.         sdlrects[i].y = rect->y;
  154.         sdlrects[i].w = rect->width;
  155.         sdlrects[i].h = rect->height;
  156.         ++i;
  157.     }
  158.     SDL_UpdateRects(screen, n, sdlrects);
  159. }
  160.  
  161. /*
  162. ================
  163. D_BeginDirectRect
  164. ================
  165. */
  166. void D_BeginDirectRect (int x, int y, byte *pbitmap, int width, int height)
  167. {
  168.     Uint8 *offset;
  169.  
  170.  
  171.     if (!screen) return;
  172.     if ( x < 0 ) x = screen->w+x-1;
  173.     offset = (Uint8 *)screen->pixels + y*screen->pitch + x;
  174.     while ( height-- )
  175.     {
  176.         memcpy(offset, pbitmap, width);
  177.         offset += screen->pitch;
  178.         pbitmap += width;
  179.     }
  180. }
  181.  
  182.  
  183. /*
  184. ================
  185. D_EndDirectRect
  186. ================
  187. */
  188. void D_EndDirectRect (int x, int y, int width, int height)
  189. {
  190.     if (!screen) return;
  191.     if (x < 0) x = screen->w+x-1;
  192.     SDL_UpdateRect(screen, x, y, width, height);
  193. }
  194.  
  195.  
  196. /*
  197. ================
  198. Sys_SendKeyEvents
  199. ================
  200. */
  201.  
  202. void Sys_SendKeyEvents(void)
  203. {
  204.     SDL_Event event;
  205.     int sym, state;
  206.      int modstate;
  207.  
  208.     while (SDL_PollEvent(&event))
  209.     {
  210.         switch (event.type) {
  211.  
  212.             case SDL_KEYDOWN:
  213.             case SDL_KEYUP:
  214.                 sym = event.key.keysym.sym;
  215.                 state = event.key.state;
  216.                 modstate = SDL_GetModState();
  217.                 switch(sym)
  218.                 {
  219.                    case SDLK_DELETE: sym = K_DEL; break;
  220.                    case SDLK_BACKSPACE: sym = K_BACKSPACE; break;
  221.                    case SDLK_F1: sym = K_F1; break;
  222.                    case SDLK_F2: sym = K_F2; break;
  223.                    case SDLK_F3: sym = K_F3; break;
  224.                    case SDLK_F4: sym = K_F4; break;
  225.                    case SDLK_F5: sym = K_F5; break;
  226.                    case SDLK_F6: sym = K_F6; break;
  227.                    case SDLK_F7: sym = K_F7; break;
  228.                    case SDLK_F8: sym = K_F8; break;
  229.                    case SDLK_F9: sym = K_F9; break;
  230.                    case SDLK_F10: sym = K_F10; break;
  231.                    case SDLK_F11: sym = K_F11; break;
  232.                    case SDLK_F12: sym = K_F12; break;
  233.                    case SDLK_BREAK:
  234.                    case SDLK_PAUSE: sym = K_PAUSE; break;
  235.                    case SDLK_UP: sym = K_UPARROW; break;
  236.                    case SDLK_DOWN: sym = K_DOWNARROW; break;
  237.                    case SDLK_RIGHT: sym = K_RIGHTARROW; break;
  238.                    case SDLK_LEFT: sym = K_LEFTARROW; break;
  239.                    case SDLK_INSERT: sym = K_INS; break;
  240.                    case SDLK_HOME: sym = K_HOME; break;
  241.                    case SDLK_END: sym = K_END; break;
  242.                    case SDLK_PAGEUP: sym = K_PGUP; break;
  243.                    case SDLK_PAGEDOWN: sym = K_PGDN; break;
  244.                    case SDLK_RSHIFT:
  245.                    case SDLK_LSHIFT: sym = K_SHIFT; break;
  246.                    case SDLK_RCTRL:
  247.                    case SDLK_LCTRL: sym = K_CTRL; break;
  248.                    case SDLK_RALT:
  249.                    case SDLK_LALT: sym = K_ALT; break;
  250.                    case SDLK_KP0:
  251.                        if(modstate & KMOD_NUM) sym = K_INS;
  252.                        else sym = SDLK_0;
  253.                        break;
  254.                    case SDLK_KP1:
  255.                        if(modstate & KMOD_NUM) sym = K_END;
  256.                        else sym = SDLK_1;
  257.                        break;
  258.                    case SDLK_KP2:
  259.                        if(modstate & KMOD_NUM) sym = K_DOWNARROW;
  260.                        else sym = SDLK_2;
  261.                        break;
  262.                    case SDLK_KP3:
  263.                        if(modstate & KMOD_NUM) sym = K_PGDN;
  264.                        else sym = SDLK_3;
  265.                        break;
  266.                    case SDLK_KP4:
  267.                        if(modstate & KMOD_NUM) sym = K_LEFTARROW;
  268.                        else sym = SDLK_4;
  269.                        break;
  270.                    case SDLK_KP5: sym = SDLK_5; break;
  271.                    case SDLK_KP6:
  272.                        if(modstate & KMOD_NUM) sym = K_RIGHTARROW;
  273.                        else sym = SDLK_6;
  274.                        break;
  275.                    case SDLK_KP7:
  276.                        if(modstate & KMOD_NUM) sym = K_HOME;
  277.                        else sym = SDLK_7;
  278.                        break;
  279.                    case SDLK_KP8:
  280.                        if(modstate & KMOD_NUM) sym = K_UPARROW;
  281.                        else sym = SDLK_8;
  282.                        break;
  283.                    case SDLK_KP9:
  284.                        if(modstate & KMOD_NUM) sym = K_PGUP;
  285.                        else sym = SDLK_9;
  286.                        break;
  287.                    case SDLK_KP_PERIOD:
  288.                        if(modstate & KMOD_NUM) sym = K_DEL;
  289.                        else sym = SDLK_PERIOD;
  290.                        break;
  291.                    case SDLK_KP_DIVIDE: sym = SDLK_SLASH; break;
  292.                    case SDLK_KP_MULTIPLY: sym = SDLK_ASTERISK; break;
  293.                    case SDLK_KP_MINUS: sym = SDLK_MINUS; break;
  294.                    case SDLK_KP_PLUS: sym = SDLK_PLUS; break;
  295.                    case SDLK_KP_ENTER: sym = SDLK_RETURN; break;
  296.                    case SDLK_KP_EQUALS: sym = SDLK_EQUALS; break;
  297.                 }
  298.                 // If we're not directly handled and still above 255
  299.                 // just force it to 0
  300.                 if(sym > 255) sym = 0;
  301.                 Key_Event(sym, state);
  302.                 break;
  303.  
  304.             case SDL_MOUSEMOTION:
  305.                 if ( (event.motion.x != (vid.width/2)) ||
  306.                      (event.motion.y != (vid.height/2)) ) {
  307.                     mouse_x = event.motion.xrel*10;
  308.                     mouse_y = event.motion.yrel*10;
  309.                     if ( (event.motion.x < ((vid.width/2)-(vid.width/4))) ||
  310.                          (event.motion.x > ((vid.width/2)+(vid.width/4))) ||
  311.                          (event.motion.y < ((vid.height/2)-(vid.height/4))) ||
  312.                          (event.motion.y > ((vid.height/2)+(vid.height/4))) ) {
  313.                         SDL_WarpMouse(vid.width/2, vid.height/2);
  314.                     }
  315.                 }
  316.                 break;
  317.  
  318.             case SDL_QUIT:
  319.                 CL_Disconnect ();
  320.                 Host_ShutdownServer(false);        
  321.                 Sys_Quit ();
  322.                 break;
  323.             default:
  324.                 break;
  325.         }
  326.     }
  327. }
  328.  
  329. void IN_Init (void)
  330. {
  331.     if ( COM_CheckParm ("-nomouse") )
  332.         return;
  333.  
  334.     SDL_WM_GrabInput(SDL_GRAB_ON);
  335.     mouse_x = mouse_y = 0.0;
  336.     mouse_avail = 1;
  337. }
  338.  
  339. void IN_Shutdown (void)
  340. {
  341.     SDL_WM_GrabInput(SDL_GRAB_OFF);
  342.     mouse_avail = 0;
  343. }
  344.  
  345. void IN_Commands (void)
  346. {
  347.     int i;
  348.     int mouse_buttonstate;
  349.    
  350.     if (!mouse_avail) return;
  351.  
  352.     SDL_WM_GrabInput(SDL_GRAB_ON);
  353.  
  354.     i = SDL_GetMouseState(NULL, NULL);
  355.     /* Quake swaps the second and third buttons */
  356.     mouse_buttonstate = (i & ~0x06) | ((i & 0x02)<<1) | ((i & 0x04)>>1);
  357.     for (i=0 ; i<3 ; i++) {
  358.         if ( (mouse_buttonstate & (1<<i)) && !(mouse_oldbuttonstate & (1<<i)) )
  359.             Key_Event (K_MOUSE1 + i, true);
  360.  
  361.         if ( !(mouse_buttonstate & (1<<i)) && (mouse_oldbuttonstate & (1<<i)) )
  362.             Key_Event (K_MOUSE1 + i, false);
  363.     }
  364.     mouse_oldbuttonstate = mouse_buttonstate;
  365. }
  366.  
  367. void IN_Move (usercmd_t *cmd)
  368. {
  369.     if (!mouse_avail)
  370.         return;
  371.  
  372.     mouse_x *= sensitivity.value;
  373.     mouse_y *= sensitivity.value;
  374.    
  375.     if ( (in_strafe.state & 1) || (lookstrafe.value && (in_mlook.state & 1) ))
  376.         cmd->sidemove += m_side.value * mouse_x;
  377.     else
  378.         cl.viewangles[YAW] -= m_yaw.value * mouse_x;
  379.     if (in_mlook.state & 1)
  380.         V_StopPitchDrift ();
  381.    
  382.     if ( (in_mlook.state & 1) && !(in_strafe.state & 1)) {
  383.         cl.viewangles[PITCH] += m_pitch.value * mouse_y;
  384.         if (cl.viewangles[PITCH] > 80)
  385.             cl.viewangles[PITCH] = 80;
  386.         if (cl.viewangles[PITCH] < -70)
  387.             cl.viewangles[PITCH] = -70;
  388.     } else {
  389.         if ((in_strafe.state & 1) && noclip_anglehack)
  390.             cmd->upmove -= m_forward.value * mouse_y;
  391.         else
  392.             cmd->forwardmove -= m_forward.value * mouse_y;
  393.     }
  394.     mouse_x = mouse_y = 0.0;
  395. }
  396.  
  397. /*
  398. ================
  399. Sys_ConsoleInput
  400. ================
  401. */
  402. char *Sys_ConsoleInput (void)
  403. {
  404.     return 0;
  405. }
  406.