summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/i_video.c
diff options
context:
space:
mode:
Diffstat (limited to 'apps/plugins/doom/i_video.c')
-rw-r--r--apps/plugins/doom/i_video.c454
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
41static fb_data palette[256] IBSS_ATTR;
42static 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*/
49static fb_data * xtable = 0;
50static fb_data * ytable1 = 0;
51static fb_data * ytable2 = 0;
52
53#define FLOOR4(a) \
54 (( a >> 2) << 2)
55
56static int video_w, video_h;
57
58static 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//
88void I_ShutdownGraphics(void)
89{
90}
91
92//
93// I_StartFrame (NOT USED)
94//
95void I_StartFrame (void)
96{
97}
98
99//
100// I_GetEvent (NOT USED)
101//
102void 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
131int 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
283event_t event;
284void I_StartTic (void)
285{
286 getkey(&event);
287}
288
289
290///////////////////////////////////////////////////////////
291// Palette stuff.
292//
293static 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//
338void I_UpdateNoBlit (void)
339{
340}
341
342//
343// I_FinishUpdate
344//
345
346void 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//
417void I_ReadScreen (byte* scr)
418{
419 memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
420}
421
422//
423// I_SetPalette
424//
425void I_SetPalette (int pal)
426{
427 I_UploadNewPalette(pal);
428}
429
430//
431// I_InitGraphics
432//
433void 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}