summaryrefslogtreecommitdiff
path: root/apps/plugins/doom/i_video.c
diff options
context:
space:
mode:
authorDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
committerDave Chapman <dave@dchapman.com>2006-03-28 15:44:01 +0000
commit47f4a458d636a889e955e68f896708f1276febc0 (patch)
tree99f770c02ef606f0abbdcd332ac39e69830d8007 /apps/plugins/doom/i_video.c
parentfff7d6157d56f233cad5c2003475e47a5ff809a7 (diff)
downloadrockbox-47f4a458d636a889e955e68f896708f1276febc0.zip
rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.gz
rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.bz2
rockbox-47f4a458d636a889e955e68f896708f1276febc0.tar.xz
Patch #2969 - Doom! Currently only working on the H300.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@9312 a1c6a512-1295-4272-9138-f99709370657
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 0000000..b77205f
--- /dev/null
+++ b/apps/plugins/doom/i_video.c
@@ -0,0 +1,454 @@
+/* Emacs style mode select -*- C++ -*-
+ *-----------------------------------------------------------------------------
+ *
+ * $Id$
+ *
+ * Copyright (C) 1993-1996 by id Software, Inc.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * $Log$
+ * Revision 1.1 2006/03/28 15:44:01 dave
+ * Patch #2969 - Doom! Currently only working on the H300.
+ *
+ *
+ * DESCRIPTION:
+ * DOOM graphics and buttons. H300 Port by Karl Kurbjun
+ * IPOD port by Dave Chapman and Paul Louden
+ * Additional work by Thom Johansen
+ *
+ *-----------------------------------------------------------------------------
+ */
+
+#include "doomstat.h"
+#include "i_system.h"
+#include "v_video.h"
+#include "m_argv.h"
+#include "d_main.h"
+
+#include "doomdef.h"
+
+#include "rockmacros.h"
+
+static fb_data palette[256] IBSS_ATTR;
+static fb_data *paldata=NULL;
+
+#if !defined(CPU_COLDFIRE) || defined(SIMULATOR)
+/*
+ This code is credit to the IDOOM port. It is not used for the H300, but
+ serves as a good reference point for other targets.
+*/
+static fb_data * xtable = 0;
+static fb_data * ytable1 = 0;
+static fb_data * ytable2 = 0;
+
+#define FLOOR4(a) \
+ (( a >> 2) << 2)
+
+static int video_w, video_h;
+
+static void genscalexytable(void)
+{
+ // shall we use uint8_t intead of ints?
+ int y = video_h-1;
+ int x = video_w-1;
+ int i = 1 + (x>y?x:y);
+ xtable = malloc(sizeof(int)*video_w );
+ ytable1 = malloc(sizeof(int)*video_h );
+ ytable2 = malloc(sizeof(int)*video_h );
+
+ while(i--)
+ {
+ if(y>=0)
+ {
+ ytable1[y] = ((y*SCREENHEIGHT) / video_h) * SCREENWIDTH;
+ ytable2[y] = y*video_w;
+ y--;
+ }
+ if(x>=0)
+ {
+ xtable[x] = (x*SCREENWIDTH) / video_w;
+ x--;
+ }
+ }
+}
+#endif
+
+//
+// I_ShutdownGraphics (NOT USED)
+//
+void I_ShutdownGraphics(void)
+{
+}
+
+//
+// I_StartFrame (NOT USED)
+//
+void I_StartFrame (void)
+{
+}
+
+//
+// I_GetEvent (NOT USED)
+//
+void I_GetEvent(void)
+{
+}
+
+//
+// I_StartTic
+//
+
+#if CONFIG_KEYPAD == IPOD_4G_PAD
+//#define DOOMBUTTON_SCROLLWHEEL
+#define DOOMBUTTON_UP BUTTON_MENU
+#define DOOMBUTTON_WEAPON BUTTON_SELECT
+#define DOOMBUTTON_LEFT BUTTON_LEFT
+#define DOOMBUTTON_RIGHT BUTTON_RIGHT
+#define DOOMBUTTON_SHOOT BUTTON_PLAY
+#define DOOMBUTTON_ENTER BUTTON_SELECT
+#define DOOMBUTTON_OPEN BUTTON_MENU
+#else
+#define DOOMBUTTON_UP BUTTON_UP
+#define DOOMBUTTON_DOWN BUTTON_DOWN
+#define DOOMBUTTON_LEFT BUTTON_LEFT
+#define DOOMBUTTON_RIGHT BUTTON_RIGHT
+#define DOOMBUTTON_SHOOT BUTTON_REC
+#define DOOMBUTTON_OPEN BUTTON_MODE
+#define DOOMBUTTON_ESC BUTTON_OFF
+#define DOOMBUTTON_ENTER BUTTON_SELECT
+#define DOOMBUTTON_WEAPON BUTTON_ON
+#endif
+
+int getkey(event_t * event)
+{
+ // Same button handling as rockboy
+ static unsigned int oldbuttonstate = 0, newbuttonstate=0;
+
+ static int released, pressed;
+
+#if CONFIG_KEYPAD == IRIVER_H300_PAD
+ static unsigned int holdbutton=0;
+ static int hswitch=0;
+ if (rb->button_hold()&~holdbutton)
+ {
+ if(hswitch==0)
+ {
+ event->type = ev_keydown;
+ hswitch=1;
+ }
+ else
+ {
+ event->type = ev_keyup;
+ hswitch=0;
+ }
+ event->data1=KEY_RSHIFT;
+ D_PostEvent(event);
+ }
+ holdbutton=rb->button_hold();
+#endif
+
+ newbuttonstate = rb->button_status();
+ released = ~newbuttonstate & oldbuttonstate;
+ pressed = newbuttonstate & ~oldbuttonstate;
+ oldbuttonstate = newbuttonstate;
+ if(released)
+ {
+ event->type = ev_keyup;
+ if(released & DOOMBUTTON_LEFT)
+ {
+ event->data1=KEY_LEFTARROW;
+ D_PostEvent(event);
+ }
+ if(released & DOOMBUTTON_RIGHT)
+ {
+ event->data1=KEY_RIGHTARROW;
+ D_PostEvent(event);
+ }
+#ifdef DOOMBUTTON_DOWN
+ if(released & DOOMBUTTON_DOWN)
+ {
+ event->data1=KEY_DOWNARROW;
+ D_PostEvent(event);
+ }
+#endif
+ if(released & DOOMBUTTON_UP)
+ {
+ event->data1=KEY_UPARROW;
+ D_PostEvent(event);
+ }
+ if(released & DOOMBUTTON_SHOOT)
+ {
+ event->data1=KEY_RCTRL;
+ D_PostEvent(event);
+ }
+ if(released & DOOMBUTTON_OPEN)
+ {
+ event->data1=' ';
+ D_PostEvent(event);
+ }
+#ifdef DOOMBUTTON_ESC
+ if(released & DOOMBUTTON_ESC)
+ {
+ event->data1=KEY_ESCAPE;
+ D_PostEvent(event);
+ }
+#endif
+#ifdef DOOMBUTTON_ENTER
+ if(released & DOOMBUTTON_ENTER)
+ {
+ event->data1=KEY_ENTER;
+ D_PostEvent(event);
+ }
+#endif
+#ifdef DOOMBUTTON_WEAPON
+ if(released & DOOMBUTTON_WEAPON)
+ {
+ event->data1 ='w';
+ D_PostEvent(event);
+ }
+#endif
+ }
+ if(pressed)
+ {
+ event->type = ev_keydown;
+ if(pressed & DOOMBUTTON_LEFT)
+ {
+ event->data1=KEY_LEFTARROW;
+ D_PostEvent(event);
+ }
+ if(pressed & DOOMBUTTON_RIGHT)
+ {
+ event->data1=KEY_RIGHTARROW;
+ D_PostEvent(event);
+ }
+#ifdef DOOMBUTTON_DOWN
+ if(pressed & DOOMBUTTON_DOWN)
+ {
+ event->data1=KEY_DOWNARROW;
+ D_PostEvent(event);
+ }
+#endif
+ if(pressed & DOOMBUTTON_UP)
+ {
+ event->data1=KEY_UPARROW;
+ D_PostEvent(event);
+ }
+ if(pressed & DOOMBUTTON_SHOOT)
+ {
+ event->data1=KEY_RCTRL;
+ D_PostEvent(event);
+ }
+ if(pressed & DOOMBUTTON_OPEN)
+ {
+ event->data1=' ';
+ D_PostEvent(event);
+ }
+#ifdef DOOMBUTTON_ESC
+ if(pressed & DOOMBUTTON_ESC)
+ {
+ event->data1=KEY_ESCAPE;
+ D_PostEvent(event);
+ }
+#endif
+#ifdef DOOMBUTTON_ENTER
+ if(pressed & DOOMBUTTON_ENTER)
+ {
+ event->data1=KEY_ENTER;
+ D_PostEvent(event);
+ }
+#endif
+#ifdef DOOMBUTTON_WEAPON
+ if(pressed & DOOMBUTTON_WEAPON)
+ {
+ event->data1='w';
+ D_PostEvent(event);
+ }
+#endif
+ }
+ if(pressed || released)
+ return 1;
+ else
+ return 0;
+}
+
+event_t event;
+void I_StartTic (void)
+{
+ getkey(&event);
+}
+
+
+///////////////////////////////////////////////////////////
+// Palette stuff.
+//
+static void I_UploadNewPalette(int pal)
+{
+ // This is used to replace the current 256 colour cmap with a new one
+ // Used by 256 colour PseudoColor modes
+ static int cachedgamma;
+ static size_t num_pals;
+
+ if ((paldata == NULL) || (cachedgamma != usegamma)) {
+ int lump = W_GetNumForName("PLAYPAL");
+ const byte *pall = W_CacheLumpNum(lump);
+ register const byte *const gtable = gammatable[cachedgamma = usegamma];
+ register int i;
+
+ num_pals = W_LumpLength(lump) / (3*256);
+ num_pals *= 256;
+
+ if (!paldata) {
+ // First call - allocate and prepare colour array
+ paldata = malloc(sizeof(*paldata)*num_pals);
+ }
+
+ // set the colormap entries
+ for (i=0 ; (size_t)i<num_pals ; i++) {
+ int r = gtable[pall[0]];
+ int g = gtable[pall[1]];
+ int b = gtable[pall[2]];
+ pall+=3;
+ paldata[i] = LCD_RGBPACK(r,g,b);
+ }
+
+ W_UnlockLumpNum(lump);
+ num_pals/=256;
+ }
+
+#ifdef RANGECHECK
+ if ((size_t)pal >= num_pals)
+ I_Error("I_UploadNewPalette: Palette number out of range (%d>=%d)",
+ pal, num_pals);
+#endif
+ memcpy(palette,paldata+256*pal,256*sizeof(fb_data));
+}
+
+//
+// I_UpdateNoBlit
+//
+void I_UpdateNoBlit (void)
+{
+}
+
+//
+// I_FinishUpdate
+//
+
+void I_FinishUpdate (void)
+{
+#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
+ /*
+ Faster screen update than the lookuptables -> I'm wasting 7 pixels of width
+ though. This code also doesn't use the framebuffer so rockbox's drawing
+ functions will not work on top of the doom drawing.
+ */
+
+ // Start the write
+ *(volatile unsigned short *) 0xf0000000 = 0x21; // register
+ *(volatile unsigned short *) 0xf0000002 = 0; // value
+ *(volatile unsigned short *) 0xf0000000 = 0x22; // GRAM
+
+ unsigned char *screenptr=screens[0];
+ int wcnt=0, hcnt=0;
+
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ *(volatile unsigned short *) 0xf0000002 = 0;
+
+ while(hcnt<LCD_HEIGHT)
+ {
+ while(wcnt<LCD_WIDTH-7)
+ {
+ if((wcnt&0x01))
+ screenptr++; // Skip every so many pixels in Doom buffer
+ *(volatile unsigned short *)0xf0000002 = palette[*screenptr];
+ screenptr++;
+ wcnt++;
+ }
+ screenptr++;
+ // move on past those 7 pixels
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ *(volatile unsigned short *) 0xf0000002 = 0;
+ wcnt=0;
+ hcnt++;
+ if((hcnt&0x07)==0x07)
+ screenptr+=SCREENWIDTH; // Skip every 7th line
+ }
+#else
+ // The IDOOM code for screen updates
+ unsigned char paletteIndex;
+ int x, y;
+
+ for (y = 0; y < video_h; y++)
+ {
+ for (x = 0; x < video_w; x++)
+ {
+#if LCD_HEIGHT >= SCREENHEIGHT
+ paletteIndex = screens[0][((y*SCREENHEIGHT) / video_h)
+ * SCREENWIDTH + x];
+ rb->lcd_framebuffer[y * video_w + x] = palette[paletteIndex];
+#else
+ paletteIndex = screens[0][ytable1[y] +xtable[x]];
+ rb->lcd_framebuffer[x + ytable2[y]] = palette[paletteIndex];
+#endif
+ }
+ }
+ rb->lcd_update();
+#endif
+}
+
+//
+// I_ReadScreen
+//
+void I_ReadScreen (byte* scr)
+{
+ memcpy (scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
+}
+
+//
+// I_SetPalette
+//
+void I_SetPalette (int pal)
+{
+ I_UploadNewPalette(pal);
+}
+
+//
+// I_InitGraphics
+//
+void I_InitGraphics(void)
+{
+ static int firsttime=1;
+
+ if (!firsttime)
+ return;
+ firsttime = 0;
+
+ printf("Starting Graphics engine\n");
+
+ /* Note: The other screens are initialized later */
+ screens[0] = malloc (SCREENWIDTH * SCREENHEIGHT * sizeof(unsigned char));
+
+#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
+ coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
+#else
+
+ video_h = LCD_HEIGHT;
+ video_w = FLOOR4(LCD_WIDTH); // From IDOOM, the width has to be a multiple of 4
+ genscalexytable();
+#endif
+}