CGDoom/cgdoom/i_video.c

234 lines
5.2 KiB
C

// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// $Id:$
//
// Copyright (C) 1993-1996 by id Software, Inc.
//
// This source is available for distribution and/or modification
// only under the terms of the DOOM Source Code License as
// published by id Software. All rights reserved.
//
// The source is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// FITNESS FOR A PARTICULAR PURPOSE. See the DOOM Source Code License
// for more details.
//
// $Log:$
//
// DESCRIPTION:
// DOOM graphics stuff for fx-CG 50
//
//-----------------------------------------------------------------------------
#include "os.h"
#include "cgdoom.h"
#include "doomstat.h"
#include "i_system.h"
#include "v_video.h"
#include "d_main.h"
#include "doomdef.h"
/* Current palette data (after gamma transform) */
static uint16_t gPaletteData[256];
/* Reference to current palette (before gamma transform) */
static byte *gPalette = NULL;
void I_SetPalette(byte* pal)
{
/* If pal=NULL, just regenerate the current palette to account for changes
in the gamma level */
if (pal == NULL)
pal = gPalette;
else
gPalette = pal;
extern int usegamma;
const byte *gamma = gammatable[usegamma % 5];
for (int i = 0; i < 256; i++)
{
int r = pal[3*i];
int g = pal[3*i+1];
int b = pal[3*i+2];
r = gamma[r] >> 3;
g = gamma[g] >> 2;
b = gamma[b] >> 3;
gPaletteData[i] = (r << 11) | (g << 5) | b;
}
}
#ifdef CGDOOM_DIRECT_R61524
#define SYNCO() __asm__ volatile("synco":::"memory");
#define PRDR *(volatile uint8_t *)0xA405013C
#define LCDC *(volatile uint16_t *)0xB4000000
#define LCD_GRAM_X 0x200
#define LCD_GRAM_Y 0x201
#define LCD_GRAM 0x202
#define LCD_WINDOW_LEFT 0x210
#define LCD_WINDOW_RIGHT 0x211
#define LCD_WINDOW_TOP 0x212
#define LCD_WINDOW_BOTTOM 0x213
static void SelectLCDReg(unsigned short reg)
{
PRDR &= ~0x10;
SYNCO();
LCDC = reg;
SYNCO();
PRDR |= 0x10;
SYNCO();
}
static void WriteLCDReg(unsigned short reg, unsigned short value)
{
SelectLCDReg(reg);
LCDC = value;
}
static void SetWindow(int left, int top, int width, int height)
{
WriteLCDReg(LCD_WINDOW_LEFT, left);
WriteLCDReg(LCD_WINDOW_TOP, top);
WriteLCDReg(LCD_WINDOW_RIGHT, left + width - 1);
WriteLCDReg(LCD_WINDOW_BOTTOM, top + height - 1);
}
/* Whether the black background has been rendered. We could fill the screen
at initialization but it would flicker. Instead, we go the extra mile and
render the background at the same time as the first frame. This also allows
redrawing it after erros.*/
static int firstflipdone = 0;
void I_Flip (void)
{
prof_enter(CGD_Perf.DisplayInterface);
if (!firstflipdone)
{
SetWindow(0, 0, 396, 224);
WriteLCDReg(LCD_GRAM_X, 0);
WriteLCDReg(LCD_GRAM_Y, 0);
SelectLCDReg(LCD_GRAM);
/* Clear 12 lines, render VRAM, then clear 12 */
for (int n = 0; n < 396 * 12; n++)
LCDC = 0x0000;
byte *scr = screens[0];
for (int y = 0; y < SCREENHEIGHT; y++)
{
for(int x = 0; x < 38; x++)
LCDC = 0x0000;
for(int x = 0; x < SCREENWIDTH; x++)
LCDC = gPaletteData[*scr++];
for(int x = 0; x < 38; x++)
LCDC = 0x0000;
}
for (int n = 0; n < 396 * 12; n++)
LCDC = 0x0000;
/* Set the future window */
SetWindow((396 - SCREENWIDTH) / 2, (224 - SCREENHEIGHT) / 2,
SCREENWIDTH, SCREENHEIGHT);
firstflipdone = 1;
}
else
{
WriteLCDReg(LCD_GRAM_X, 0);
WriteLCDReg(LCD_GRAM_Y, 0);
SelectLCDReg(LCD_GRAM);
unsigned j=0, i=320*200;
while(i--)
{
LCDC = gPaletteData[screens[0][j]];
j++;
}
}
prof_leave(CGD_Perf.DisplayInterface);
}
void I_InitGraphics(void)
{
usegamma = 0;
}
void I_ShutdownGraphics(void)
{
SetWindow(6, 0, 384, 216);
}
void I_ReinitAfterError(void)
{
firstflipdone = 0;
/* Redraw status bar over help message */
extern boolean st_firsttime;
st_firsttime = true;
}
#else /* CGDOOM_DIRECT_R61524 */
void I_Flip (void)
{
prof_enter(CGD_Perf.DisplayInterface);
/* Set a black frame if the current one is white */
if ((Bdisp_FrameAndColor(0, 0) & 1) == 0)
{
Bdisp_FrameAndColor(3, 17);
Bdisp_FrameAndColor(1, 0);
}
int x,y;
for(y=0;y<SCREENHEIGHT;y++)
{
for(x=0;x<SCREENWIDTH;x++)
{
VRAM[(x+(WIDTH-SCREENWIDTH)/2)+(y+(HEIGHT-SCREENHEIGHT)/2)*WIDTH] =
gPaletteData[screens[0][x+y*SCREENWIDTH]];
}
}
Bdisp_PutDisp_DD();
prof_leave(CGD_Perf.DisplayInterface);
}
void I_InitGraphics(void)
{
usegamma = 0;
}
void I_ShutdownGraphics(void)
{
}
void I_ReinitAfterError(void)
{
/* Redraw status bar over help message */
extern boolean st_firsttime;
st_firsttime = true;
/* Restore full black screen */
memset(GetVRAMAddress(), 0, 384*216*2);
Bdisp_PutDisp_DD();
}
#endif /* CGDOOM_DIRECT_R61524 */
//
// I_ReadScreen
//
void I_ReadScreen (byte* scr)
{
memcpy(scr, screens[0], SCREENWIDTH*SCREENHEIGHT);
}