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