Subversion Repositories Kolibri OS

Rev

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