8062f9184c
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@10514 a1c6a512-1295-4272-9138-f99709370657
544 lines
15 KiB
C
544 lines
15 KiB
C
/* 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.23 2006/08/10 18:34:43 amiconn
|
|
* Correct calculation of necessary buffer size to give maximum number of shades on iPod Mini.
|
|
*
|
|
* Revision 1.22 2006-08-07 02:44:18 amiconn
|
|
* Use striped buffering for grayscale targets to make the buffer fit on iPod g3/g4. Also slightly faster (at least on H1x0) with the buffer in IRAM.
|
|
*
|
|
* Revision 1.21 2006-08-07 01:57:29 amiconn
|
|
* Fix red iPod g3 build.
|
|
*
|
|
* Revision 1.20 2006-08-07 01:46:41 amiconn
|
|
* Grayscale library ported to the grayscale iPods, first version. Added C reference versions of gray_update_rect() for both horizontal and vertical pixel packing. gray_update_rect() and gray_ub_gray_bitmap_part() not yet assembler optimised. Grayscale screendump doesn't work yet. * Fixed button assignments for iPod in grayscale.c
|
|
*
|
|
* Revision 1.19 2006-08-03 20:17:22 bagder
|
|
* Barry Wardell's keymappings for H10
|
|
*
|
|
* Revision 1.18 2006-08-02 00:21:59 amiconn
|
|
* Grayscale library: LCD linearisation and gamma correction.
|
|
*
|
|
* Revision 1.17 2006-04-22 03:48:15 kkurbjun
|
|
* Better video update, add options to startup menu, change default screensize
|
|
*
|
|
* Revision 1.16 2006-04-20 19:39:56 kkurbjun
|
|
* Optimizations for doom: coldfire asm drawspan routine = not much, fixed point multiply changes = not much, H300 asm lcd update = some, IRAM sound updates and simplifications = more
|
|
*
|
|
* Revision 1.15 2006-04-16 23:14:04 kkurbjun
|
|
* Fix run so that it stays enabled across level loads. Removed some unused code and added some back in for hopeful future use.
|
|
*
|
|
* Revision 1.14 2006-04-15 22:08:36 kkurbjun
|
|
* Slight code cleanups, fixed sound parameter - now it saves. Old configurations will be reset.
|
|
*
|
|
* Revision 1.13 2006-04-06 21:31:49 kkurbjun
|
|
* Scaling code fixed by clamping down the width to a max of SCREENWIDTH. Removed some #ifdefs for glprboom
|
|
*
|
|
* Revision 1.12 2006-04-05 06:37:37 kkurbjun
|
|
* Fix finale text and try and prevent some data corruption due to the scaling code. Also allows the non-standard GP32 mods to work with some bounds checking. More comments are in v_video.c
|
|
*
|
|
* Revision 1.11 2006-04-04 19:39:31 amiconn
|
|
* Doom on H1x0: Don't waste memory, the grayscale lib doesn't need that much, but properly tell the lib how much memory it may use.
|
|
*
|
|
* Revision 1.10 2006-04-04 12:00:53 dave
|
|
* iPod: Make the hold switch bring up the in-game menu.
|
|
*
|
|
* Revision 1.9 2006-04-03 20:03:02 kkurbjun
|
|
* Updates doom menu w/ new graphics, now requires rockdoom.wad: http://alamode.mines.edu/~kkurbjun/rockdoom.wad
|
|
*
|
|
* Revision 1.8 2006-04-03 17:11:42 kkurbjun
|
|
* Finishing touches
|
|
*
|
|
* Revision 1.7 2006-04-03 16:30:12 kkurbjun
|
|
* Fix #if
|
|
*
|
|
* Revision 1.5 2006-04-03 08:51:08 bger
|
|
* Patch #4864 by Jonathan Gordon: text editor plugin, with some changes by me.
|
|
* Also correct a var clash between the rockbox's gui api and doom plugin
|
|
*
|
|
* Revision 1.4 2006-04-02 20:45:24 kkurbjun
|
|
* Properly ifdef H300 video code, fix commented line handling rockbox volume
|
|
*
|
|
* Revision 1.3 2006-04-02 01:52:44 kkurbjun
|
|
* Update adds prboom's high resolution support, also makes the scaling for
|
|
* platforms w/ resolution less then 320x200 much nicer. IDoom's lookup table
|
|
* code has been removed. Also fixed a pallete bug. Some graphic errors are
|
|
* present in menu and status bar. Also updates some headers and output
|
|
* formatting.
|
|
*
|
|
* Revision 1.2 2006-03-28 17:20:49 christian
|
|
* added good (tm) button mappings for x5, and added ifdef for HAS_BUTTON_HOLD
|
|
*
|
|
* 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
|
|
* H100 Port by Dave Chapman, Karl Kurbjun and Jens Arnold
|
|
* 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"
|
|
|
|
#ifndef HAVE_LCD_COLOR
|
|
#include "../lib/gray.h"
|
|
static unsigned char graybuffer[8*LCD_WIDTH] IBSS_ATTR; /* off screen buffer */
|
|
static unsigned char *gbuf;
|
|
#if LCD_PIXELFORMAT == HORIZONTAL_PACKING
|
|
#define GRAYBUFSIZE (((LCD_WIDTH+7)/8)*LCD_HEIGHT*32+200)
|
|
#else
|
|
#define GRAYBUFSIZE (LCD_WIDTH*((LCD_HEIGHT+7)/8)*32+200)
|
|
#endif
|
|
#endif
|
|
|
|
#if defined(CPU_COLDFIRE)
|
|
static char fastscreen[(LCD_WIDTH)*LCD_HEIGHT] IBSS_ATTR;
|
|
#endif
|
|
static fb_data palette[256] IBSS_ATTR;
|
|
static fb_data *paldata=NULL;
|
|
|
|
//
|
|
// I_ShutdownGraphics (NOT USED)
|
|
//
|
|
void I_ShutdownGraphics(void)
|
|
{
|
|
#ifndef HAVE_LCD_COLOR
|
|
gray_release();
|
|
#endif
|
|
noprintf=0;
|
|
}
|
|
|
|
//
|
|
// I_StartTic
|
|
//
|
|
|
|
#if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_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
|
|
#elif CONFIG_KEYPAD == IAUDIO_X5_PAD
|
|
#define DOOMBUTTON_UP BUTTON_UP
|
|
#define DOOMBUTTON_DOWN BUTTON_DOWN
|
|
#define DOOMBUTTON_LEFT BUTTON_LEFT
|
|
#define DOOMBUTTON_RIGHT BUTTON_RIGHT
|
|
#define DOOMBUTTON_SHOOT BUTTON_SELECT
|
|
#define DOOMBUTTON_OPEN BUTTON_PLAY
|
|
#define DOOMBUTTON_ESC BUTTON_POWER
|
|
#define DOOMBUTTON_ENTER BUTTON_SELECT
|
|
#define DOOMBUTTON_WEAPON BUTTON_REC
|
|
#elif CONFIG_KEYPAD == IRIVER_H10_PAD
|
|
#define DOOMBUTTON_UP BUTTON_SCROLL_UP
|
|
#define DOOMBUTTON_DOWN BUTTON_SCROLL_DOWN
|
|
#define DOOMBUTTON_LEFT BUTTON_LEFT
|
|
#define DOOMBUTTON_RIGHT BUTTON_RIGHT
|
|
#define DOOMBUTTON_SHOOT BUTTON_REW
|
|
#define DOOMBUTTON_OPEN BUTTON_PLAY
|
|
#define DOOMBUTTON_ESC BUTTON_POWER
|
|
#define DOOMBUTTON_ENTER BUTTON_PLAY
|
|
#define DOOMBUTTON_WEAPON BUTTON_FF
|
|
#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
|
|
|
|
inline void getkey()
|
|
{
|
|
event_t event;
|
|
/* Same button handling as rockboy */
|
|
static unsigned int oldbuttonstate IDATA_ATTR = 0;
|
|
|
|
unsigned int released, pressed, newbuttonstate;
|
|
|
|
#ifdef HAS_BUTTON_HOLD
|
|
static unsigned int holdbutton IDATA_ATTR=0;
|
|
static bool hswitch IDATA_ATTR=0;
|
|
if (rb->button_hold()&~holdbutton)
|
|
{
|
|
if(hswitch==0)
|
|
{
|
|
event.type = ev_keydown;
|
|
hswitch=1;
|
|
}
|
|
else
|
|
{
|
|
event.type = ev_keyup;
|
|
hswitch=0;
|
|
}
|
|
#if (CONFIG_KEYPAD == IPOD_4G_PAD) || (CONFIG_KEYPAD == IPOD_3G_PAD)
|
|
/* Bring up the menu */
|
|
event.data1=KEY_ESCAPE;
|
|
#else
|
|
/* Enable run */
|
|
event.data1=KEY_CAPSLOCK;
|
|
#endif
|
|
D_PostEvent(&event);
|
|
}
|
|
holdbutton=rb->button_hold();
|
|
#endif
|
|
|
|
newbuttonstate = rb->button_status();
|
|
if(newbuttonstate==oldbuttonstate) /* Don't continue, nothing left to do */
|
|
return;
|
|
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
|
|
}
|
|
}
|
|
|
|
inline void I_StartTic (void)
|
|
{
|
|
getkey();
|
|
}
|
|
|
|
|
|
///////////////////////////////////////////////////////////
|
|
// 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;
|
|
#ifndef HAVE_LCD_COLOR
|
|
paldata[i]=(3*r+6*g+b)/10;
|
|
#else
|
|
paldata[i] = LCD_RGBPACK(r,g,b);
|
|
#endif
|
|
}
|
|
|
|
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_FinishUpdate
|
|
//
|
|
|
|
void I_FinishUpdate (void)
|
|
{
|
|
#if (CONFIG_LCD == LCD_H300) && !defined(SIMULATOR)
|
|
|
|
#if 1
|
|
/* ASM screen update (drops 600 tics (100 asm)) */
|
|
asm (
|
|
"move.w #33,(%[LCD]) \n" /* Setup the LCD controller */
|
|
"clr.w (%[LCD2]) \n"
|
|
"move.w #34,(%[LCD]) \n" /* End LCD controller setup */
|
|
"move.l #220,%%d0 \n"
|
|
"move.l #176,%%d1 \n"
|
|
"clr.l %%d3 \n"
|
|
"clr.l %%d2 \n"
|
|
"widthloop: \n"
|
|
"move.l (%[screenptr])+, %%d2 \n"
|
|
"swap.w %%d2 \n"
|
|
"move.w %%d2, %%d3 \n"
|
|
"lsr.l #8,%%d3 \n"
|
|
"move.w (%[palette], %%d3.l:2), (%[LCD2]) \n"
|
|
"move.b %%d2,%%d3 \n"
|
|
"move.w (%[palette], %%d3.l:2), (%[LCD2]) \n"
|
|
"swap.w %%d2 \n"
|
|
"move.w %%d2, %%d3 \n"
|
|
"lsr.l #8,%%d3 \n"
|
|
"move.w (%[palette], %%d3.l:2), (%[LCD2]) \n"
|
|
"move.b %%d2,%%d3 \n"
|
|
"move.w (%[palette], %%d3.l:2), (%[LCD2]) \n"
|
|
"subq.l #4,%%d0 \n"
|
|
"bne widthloop \n"
|
|
"move.w #220,%%d0 \n"
|
|
"subq.l #1,%%d1 \n"
|
|
"bne widthloop \n"
|
|
: /* outputs */
|
|
: /* inputs */
|
|
[screenptr] "a" (d_screens[0]),
|
|
[palette] "a" (palette),
|
|
[LCD] "a" (0xf0000000),
|
|
[LCD2] "a" (0xf0000002)
|
|
: /* clobbers */
|
|
"d0", "d1", "d2", "d3"
|
|
);
|
|
#else
|
|
/* C version of above (drops 500 tics) */
|
|
|
|
// Start the write
|
|
*(volatile unsigned short *) 0xf0000000 = 0x21; // register
|
|
*(volatile unsigned short *) 0xf0000002 = 0; // value
|
|
*(volatile unsigned short *) 0xf0000000 = 0x22; // GRAM
|
|
|
|
unsigned char *screenptr=d_screens[0];
|
|
int wcnt=0, hcnt=0;
|
|
|
|
while(hcnt<LCD_HEIGHT)
|
|
{
|
|
while(wcnt<LCD_WIDTH)
|
|
{
|
|
*(volatile unsigned short *)0xf0000002 = palette[*screenptr];
|
|
screenptr++;
|
|
wcnt++;
|
|
}
|
|
wcnt=0;
|
|
hcnt++;
|
|
}
|
|
#endif
|
|
|
|
#else
|
|
unsigned char paletteIndex;
|
|
int x, y;
|
|
|
|
#ifdef HAVE_LCD_COLOR
|
|
for (y = 0; y < LCD_HEIGHT; y++)
|
|
{
|
|
for (x = 0; x < LCD_WIDTH; x++)
|
|
{
|
|
paletteIndex = d_screens[0][y*SCREENWIDTH + x];
|
|
rb->lcd_framebuffer[y * LCD_WIDTH + x] = palette[paletteIndex];
|
|
}
|
|
}
|
|
rb->lcd_update();
|
|
#else /* !HAVE_LCD_COLOR */
|
|
int yd = 0;
|
|
|
|
for (y = 0; y < LCD_HEIGHT; y++)
|
|
{
|
|
for (x = 0; x < LCD_WIDTH; x++)
|
|
{
|
|
paletteIndex = d_screens[0][y*SCREENWIDTH + x];
|
|
graybuffer[yd * LCD_WIDTH + x]=palette[paletteIndex];
|
|
}
|
|
if (++yd == 8)
|
|
{
|
|
gray_ub_gray_bitmap(graybuffer, 0, y & ~7, LCD_WIDTH, 8);
|
|
yd = 0;
|
|
}
|
|
}
|
|
if (yd > 0)
|
|
gray_ub_gray_bitmap(graybuffer, 0, y & ~7, LCD_WIDTH, yd);
|
|
#endif /* !HAVE_LCD_COLOR */
|
|
#endif
|
|
}
|
|
|
|
//
|
|
// I_ReadScreen
|
|
//
|
|
void I_ReadScreen (byte* scr)
|
|
{
|
|
memcpy (scr, d_screens[0], SCREENWIDTH*SCREENHEIGHT);
|
|
}
|
|
|
|
//
|
|
// I_SetPalette
|
|
//
|
|
void I_SetPalette (int pal)
|
|
{
|
|
I_UploadNewPalette(pal);
|
|
}
|
|
|
|
//
|
|
// I_InitGraphics
|
|
//
|
|
void I_InitGraphics(void)
|
|
{
|
|
printf("Starting Graphics engine\n");
|
|
|
|
noprintf=1;
|
|
|
|
/* Note: The other screens are allocated as needed */
|
|
|
|
#ifndef HAVE_LCD_COLOR
|
|
gbuf=malloc(GRAYBUFSIZE);
|
|
gray_init(rb, gbuf, GRAYBUFSIZE, false, LCD_WIDTH, LCD_HEIGHT, 32,
|
|
3<<7 /* 1.5 */, NULL);
|
|
/* switch on grayscale overlay */
|
|
gray_show(true);
|
|
#endif
|
|
|
|
#if defined(CPU_COLDFIRE) && !defined(SIMULATOR)
|
|
coldfire_set_macsr(EMAC_FRACTIONAL | EMAC_SATURATE);
|
|
d_screens[0] = fastscreen;
|
|
#else
|
|
// Don't know if this will fit in other IRAMs
|
|
d_screens[0] = malloc ((SCREENWIDTH) * SCREENHEIGHT * sizeof(unsigned char));
|
|
#endif
|
|
}
|