diff options
Diffstat (limited to 'apps/plugins/doom/i_video.c')
-rw-r--r-- | apps/plugins/doom/i_video.c | 454 |
1 files changed, 454 insertions, 0 deletions
diff --git a/apps/plugins/doom/i_video.c b/apps/plugins/doom/i_video.c new file mode 100644 index 0000000000..b77205ff84 --- /dev/null +++ b/apps/plugins/doom/i_video.c | |||
@@ -0,0 +1,454 @@ | |||
1 | /* Emacs style mode select -*- C++ -*- | ||
2 | *----------------------------------------------------------------------------- | ||
3 | * | ||
4 | * $Id$ | ||
5 | * | ||
6 | * Copyright (C) 1993-1996 by id Software, Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version 2 | ||
11 | * of the License, or (at your option) any later version. | ||
12 | * | ||
13 | * This program is distributed in the hope that it will be useful, | ||
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
16 | * GNU General Public License for more details. | ||
17 | * | ||
18 | * $Log$ | ||
19 | * Revision 1.1 2006/03/28 15:44:01 dave | ||
20 | * Patch #2969 - Doom! Currently only working on the H300. | ||
21 | * | ||
22 | * | ||
23 | * DESCRIPTION: | ||
24 | * DOOM graphics and buttons. H300 Port by Karl Kurbjun | ||
25 | * IPOD port by Dave Chapman and Paul Louden | ||
26 | * Additional work by Thom Johansen | ||
27 | * | ||
28 | *----------------------------------------------------------------------------- | ||
29 | */ | ||
30 | |||
31 | #include "doomstat.h" | ||
32 | #include "i_system.h" | ||
33 | #include "v_video.h" | ||
34 | #include "m_argv.h" | ||
35 | #include "d_main.h" | ||
36 | |||
37 | #include "doomdef.h" | ||
38 | |||
39 | #include "rockmacros.h" | ||
40 | |||
41 | static fb_data palette[256] IBSS_ATTR; | ||
42 | static fb_data *paldata=NULL; | ||
43 | |||
44 | #if !defined(CPU_COLDFIRE) || defined(SIMULATOR) | ||
45 | /* | ||
46 | This code is credit to the IDOOM port. It is not used for the H300, but | ||
47 | serves as a good reference point for other targets. | ||
48 | */ | ||
49 | static fb_data * xtable = 0; | ||
50 | static fb_data * ytable1 = 0; | ||
51 | static fb_data * ytable2 = 0; | ||
52 | |||
53 | #define FLOOR4(a) \ | ||
54 | (( a >> 2) << 2) | ||
55 | |||
56 | static int video_w, video_h; | ||
57 | |||
58 | static void genscalexytable(void) | ||
59 | { | ||
60 | // shall we use uint8_t intead of ints? | ||
61 | int y = video_h-1; | ||
62 | int x = video_w-1; | ||
63 | int i = 1 + (x>y?x:y); | ||
64 | xtable = malloc(sizeof(int)*video_w ); | ||
65 | ytable1 = malloc(sizeof(int)*video_h ); | ||
66 | ytable2 = malloc(sizeof(int)*video_h ); | ||
67 | |||
68 | while(i--) | ||
69 | { | ||
70 | if(y>=0) | ||
71 | { | ||
72 | ytable1[y] = ((y*SCREENHEIGHT) / video_h) * SCREENWIDTH; | ||
73 | ytable2[y] = y*video_w; | ||
74 | y--; | ||
75 | } | ||
76 | if(x>=0) | ||
77 | { | ||
78 | xtable[x] = (x*SCREENWIDTH) / video_w; | ||
79 | x--; | ||
80 | } | ||
81 | } | ||
82 | } | ||
83 | #endif | ||
84 | |||
85 | // | ||
86 | // I_ShutdownGraphics (NOT USED) | ||
87 | // | ||
88 | void I_ShutdownGraphics(void) | ||
89 | { | ||
90 | } | ||
91 | |||
92 | // | ||
93 | // I_StartFrame (NOT USED) | ||
94 | // | ||
95 | void I_StartFrame (void) | ||
96 | { | ||
97 | } | ||
98 | |||
99 | // | ||
100 | // I_GetEvent (NOT USED) | ||
101 | // | ||
102 | void I_GetEvent(void) | ||
103 | { | ||
104 | } | ||
105 | |||
106 | // | ||
107 | // I_StartTic | ||
108 | // | ||
109 | |||
110 | #if CONFIG_KEYPAD == IPOD_4G_PAD | ||
111 | //#define DOOMBUTTON_SCROLLWHEEL | ||
112 | #define DOOMBUTTON_UP BUTTON_MENU | ||
113 | #define DOOMBUTTON_WEAPON BUTTON_SELECT | ||
114 | #define DOOMBUTTON_LEFT BUTTON_LEFT | ||
115 | #define DOOMBUTTON_RIGHT BUTTON_RIGHT | ||
116 | #define DOOMBUTTON_SHOOT BUTTON_PLAY | ||
117 | #define DOOMBUTTON_ENTER BUTTON_SELECT | ||
118 | #define DOOMBUTTON_OPEN BUTTON_MENU | ||
119 | #else | ||
120 | #define DOOMBUTTON_UP BUTTON_UP | ||
121 | #define DOOMBUTTON_DOWN BUTTON_DOWN | ||
122 | #define DOOMBUTTON_LEFT BUTTON_LEFT | ||
123 | #define DOOMBUTTON_RIGHT BUTTON_RIGHT | ||
124 | #define DOOMBUTTON_SHOOT BUTTON_REC | ||
125 | #define DOOMBUTTON_OPEN BUTTON_MODE | ||
126 | #define DOOMBUTTON_ESC BUTTON_OFF | ||
127 | #define DOOMBUTTON_ENTER BUTTON_SELECT | ||
128 | #define DOOMBUTTON_WEAPON BUTTON_ON | ||
129 | #endif | ||
130 | |||
131 | int getkey(event_t * event) | ||
132 | { | ||
133 | // Same button handling as rockboy | ||
134 | static unsigned int oldbuttonstate = 0, newbuttonstate=0; | ||
135 | |||
136 | static int released, pressed; | ||
137 | |||
138 | #if CONFIG_KEYPAD == IRIVER_H300_PAD | ||
139 | static unsigned int holdbutton=0; | ||
140 | static int hswitch=0; | ||
141 | if (rb->button_hold()&~holdbutton) | ||
142 | { | ||
143 | if(hswitch==0) | ||
144 | { | ||
145 | event->type = ev_keydown; | ||
146 | hswitch=1; | ||
147 | } | ||
148 | else | ||
149 | { | ||
150 | event->type = ev_keyup; | ||
151 | hswitch=0; | ||
152 | } | ||
153 | event->data1=KEY_RSHIFT; | ||
154 | D_PostEvent(event); | ||
155 | } | ||
156 | holdbutton=rb->button_hold(); | ||
157 | #endif | ||
158 | |||
159 | newbuttonstate = rb->button_status(); | ||
160 | released = ~newbuttonstate & oldbuttonstate; | ||
161 | pressed = newbuttonstate & ~oldbuttonstate; | ||
162 | oldbuttonstate = newbuttonstate; | ||
163 | if(released) | ||
164 | { | ||
165 | event->type = ev_keyup; | ||
166 | if(released & DOOMBUTTON_LEFT) | ||
167 | { | ||
168 | event->data1=KEY_LEFTARROW; | ||
169 | D_PostEvent(event); | ||
170 | } | ||
171 | if(released & DOOMBUTTON_RIGHT) | ||
172 | { | ||
173 | event->data1=KEY_RIGHTARROW; | ||
174 | D_PostEvent(event); | ||
175 | } | ||
176 | #ifdef DOOMBUTTON_DOWN | ||
177 | if(released & DOOMBUTTON_DOWN) | ||
178 | { | ||
179 | event->data1=KEY_DOWNARROW; | ||
180 | D_PostEvent(event); | ||
181 | } | ||
182 | #endif | ||
183 | if(released & DOOMBUTTON_UP) | ||
184 | { | ||
185 | event->data1=KEY_UPARROW; | ||
186 | D_PostEvent(event); | ||
187 | } | ||
188 | if(released & DOOMBUTTON_SHOOT) | ||
189 | { | ||
190 | event->data1=KEY_RCTRL; | ||
191 | D_PostEvent(event); | ||
192 | } | ||
193 | if(released & DOOMBUTTON_OPEN) | ||
194 | { | ||
195 | event->data1=' '; | ||
196 | D_PostEvent(event); | ||
197 | } | ||
198 | #ifdef DOOMBUTTON_ESC | ||
199 | if(released & DOOMBUTTON_ESC) | ||
200 | { | ||
201 | event->data1=KEY_ESCAPE; | ||
202 | D_PostEvent(event); | ||
203 | } | ||
204 | #endif | ||
205 | #ifdef DOOMBUTTON_ENTER | ||
206 | if(released & DOOMBUTTON_ENTER) | ||
207 | { | ||
208 | event->data1=KEY_ENTER; | ||
209 | D_PostEvent(event); | ||
210 | } | ||
211 | #endif | ||
212 | #ifdef DOOMBUTTON_WEAPON | ||
213 | if(released & DOOMBUTTON_WEAPON) | ||
214 | { | ||
215 | event->data1 ='w'; | ||
216 | D_PostEvent(event); | ||
217 | } | ||
218 | #endif | ||
219 | } | ||
220 | if(pressed) | ||
221 | { | ||
222 | event->type = ev_keydown; | ||
223 | if(pressed & DOOMBUTTON_LEFT) | ||
224 | { | ||
225 | event->data1=KEY_LEFTARROW; | ||
226 | D_PostEvent(event); | ||
227 | } | ||
228 | if(pressed & DOOMBUTTON_RIGHT) | ||
229 | { | ||
230 | event->data1=KEY_RIGHTARROW; | ||
231 | D_PostEvent(event); | ||
232 | } | ||
233 | #ifdef DOOMBUTTON_DOWN | ||
234 | if(pressed & DOOMBUTTON_DOWN) | ||
235 | { | ||
236 | event->data1=KEY_DOWNARROW; | ||
237 | D_PostEvent(event); | ||
238 | } | ||
239 | #endif | ||
240 | if(pressed & DOOMBUTTON_UP) | ||
241 | { | ||
242 | event->data1=KEY_UPARROW; | ||
243 | D_PostEvent(event); | ||
244 | } | ||
245 | if(pressed & DOOMBUTTON_SHOOT) | ||
246 | { | ||
247 | event->data1=KEY_RCTRL; | ||
248 | D_PostEvent(event); | ||
249 | } | ||
250 | if(pressed & DOOMBUTTON_OPEN) | ||
251 | { | ||
252 | event->data1=' '; | ||
253 | D_PostEvent(event); | ||
254 | } | ||
255 | #ifdef DOOMBUTTON_ESC | ||
256 | if(pressed & DOOMBUTTON_ESC) | ||
257 | { | ||
258 | event->data1=KEY_ESCAPE; | ||
259 | D_PostEvent(event); | ||
260 | } | ||
261 | #endif | ||
262 | #ifdef DOOMBUTTON_ENTER | ||
263 | if(pressed & DOOMBUTTON_ENTER) | ||
264 | { | ||
265 | event->data1=KEY_ENTER; | ||
266 | D_PostEvent(event); | ||
267 | } | ||
268 | #endif | ||
269 | #ifdef DOOMBUTTON_WEAPON | ||
270 | if(pressed & DOOMBUTTON_WEAPON) | ||
271 | { | ||
272 | event->data1='w'; | ||
273 | D_PostEvent(event); | ||
274 | } | ||
275 | #endif | ||
276 | } | ||
277 | if(pressed || released) | ||
278 | return 1; | ||
279 | else | ||
280 | return 0; | ||
281 | } | ||
282 | |||
283 | event_t event; | ||
284 | void I_StartTic (void) | ||
285 | { | ||
286 | getkey(&event); | ||
287 | } | ||
288 | |||
289 | |||
290 | /////////////////////////////////////////////////////////// | ||
291 | // Palette stuff. | ||
292 | // | ||
293 | static void I_UploadNewPalette(int pal) | ||
294 | { | ||
295 | // This is used to replace the current 256 colour cmap with a new one | ||
296 | // Used by 256 colour PseudoColor modes | ||
297 | static int cachedgamma; | ||
298 | static size_t num_pals; | ||
299 | |||
300 | if ((paldata == NULL) || (cachedgamma != usegamma)) { | ||
301 | int lump = W_GetNumForName("PLAYPAL"); | ||
302 | const byte *pall = W_CacheLumpNum(lump); | ||
303 | register const byte *const gtable = gammatable[cachedgamma = usegamma]; | ||
304 | register int i; | ||
305 | |||
306 | num_pals = W_LumpLength(lump) / (3*256); | ||
307 | num_pals *= 256; | ||
308 | |||
309 | if (!paldata) { | ||
310 | // First call - allocate and prepare colour array | ||
311 | paldata = malloc(sizeof(*paldata)*num_pals); | ||
312 | } | ||
313 | |||
314 | // set the colormap entries | ||
315 | for (i=0 ; (size_t)i<num_pals ; i++) { | ||
316 | int r = gtable[pall[0]]; | ||
317 | int g = gtable[pall[1]]; | ||
318 | int b = gtable[pall[2]]; | ||
319 | pall+=3; | ||
320 | paldata[i] = LCD_RGBPACK(r,g,b); | ||
321 | } | ||
322 | |||
323 | W_UnlockLumpNum(lump); | ||
324 | num_pals/=256; | ||
325 | } | ||
326 | |||
327 | #ifdef RANGECHECK | ||
328 | if ((size_t)pal >= num_pals) | ||
329 | I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)", | ||
330 | pal, num_pals); | ||
331 | #endif | ||
332 | memcpy(palette,paldata+256*pal,256*sizeof(fb_data)); | ||
333 | } | ||
334 | |||
335 | // | ||
336 | // I_UpdateNoBlit | ||
337 | // | ||
338 | void I_UpdateNoBlit (void) | ||
339 | { | ||
340 | } | ||
341 | |||
342 | // | ||
343 | // I_FinishUpdate | ||
344 | // | ||
345 | |||
346 | void I_FinishUpdate (void) | ||
347 | { | ||
348 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) | ||
349 | /* | ||
350 | Faster screen update than the lookuptables -> I'm wasting 7 pixels of width | ||
351 | though. This code also doesn't use the framebuffer so rockbox's drawing | ||
352 | functions will not work on top of the doom drawing. | ||
353 | */ | ||
354 | |||
355 | // Start the write | ||
356 | *(volatile unsigned short *) 0xf0000000 = 0x21; // register | ||
357 | *(volatile unsigned short *) 0xf0000002 = 0; // value | ||
358 | *(volatile unsigned short *) 0xf0000000 = 0x22; // GRAM | ||
359 | |||
360 | unsigned char *screenptr=screens[0]; | ||
361 | int wcnt=0, hcnt=0; | ||
362 | |||
363 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
364 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
365 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
366 | |||
367 | while(hcnt<LCD_HEIGHT) | ||
368 | { | ||
369 | while(wcnt<LCD_WIDTH-7) | ||
370 | { | ||
371 | if((wcnt&0x01)) | ||
372 | screenptr++; // Skip every so many pixels in Doom buffer | ||
373 | *(volatile unsigned short *)0xf0000002 = palette[*screenptr]; | ||
374 | screenptr++; | ||
375 | wcnt++; | ||
376 | } | ||
377 | screenptr++; | ||
378 | // move on past those 7 pixels | ||
379 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
380 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
381 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
382 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
383 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
384 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
385 | *(volatile unsigned short *) 0xf0000002 = 0; | ||
386 | wcnt=0; | ||
387 | hcnt++; | ||
388 | if((hcnt&0x07)==0x07) | ||
389 | screenptr+=SCREENWIDTH; // Skip every 7th line | ||
390 | } | ||
391 | #else | ||
392 | // The IDOOM code for screen updates | ||
393 | unsigned char paletteIndex; | ||
394 | int x, y; | ||
395 | |||
396 | for (y = 0; y < video_h; y++) | ||
397 | { | ||
398 | for (x = 0; x < video_w; x++) | ||
399 | { | ||
400 | #if LCD_HEIGHT >= SCREENHEIGHT | ||
401 | paletteIndex = screens[0][((y*SCREENHEIGHT) / video_h) | ||
402 | * SCREENWIDTH + x]; | ||
403 | rb->lcd_framebuffer[y * video_w + x] = palette[paletteIndex]; | ||
404 | #else | ||
405 | paletteIndex = screens[0][ytable1[y] +xtable[x]]; | ||
406 | rb->lcd_framebuffer[x + ytable2[y]] = palette[paletteIndex]; | ||
407 | #endif | ||
408 | } | ||
409 | } | ||
410 | rb->lcd_update(); | ||
411 | #endif | ||
412 | } | ||
413 | |||
414 | // | ||
415 | // I_ReadScreen | ||
416 | // | ||
417 | void I_ReadScreen (byte* scr) | ||
418 | { | ||
419 | memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT); | ||
420 | } | ||
421 | |||
422 | // | ||
423 | // I_SetPalette | ||
424 | // | ||
425 | void I_SetPalette (int pal) | ||
426 | { | ||
427 | I_UploadNewPalette(pal); | ||
428 | } | ||
429 | |||
430 | // | ||
431 | // I_InitGraphics | ||
432 | // | ||
433 | void I_InitGraphics(void) | ||
434 | { | ||
435 | static int firsttime=1; | ||
436 | |||
437 | if (!firsttime) | ||
438 | return; | ||
439 | firsttime = 0; | ||
440 | |||
441 | printf("Starting Graphics engine\n"); | ||
442 | |||
443 | /* Note: The other screens are initialized later */ | ||
444 | screens[0] = malloc (SCREENWIDTH * SCREENHEIGHT * sizeof(unsigned char)); | ||
445 | |||
446 | #if defined(CPU_COLDFIRE) && !defined(SIMULATOR) | ||
447 | coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE); | ||
448 | #else | ||
449 | |||
450 | video_h = LCD_HEIGHT; | ||
451 | video_w = FLOOR4(LCD_WIDTH); // From IDOOM, the width has to be a multiple of 4 | ||
452 | genscalexytable(); | ||
453 | #endif | ||
454 | } | ||