ravenengine/SOURCE/D_VIDEO.C

542 lines
8.9 KiB
C

// P_VIDEO.C
#include <BIOS.H>
#include <I32.H>
#include <STRING.H>
#include <MALLOC.H>
#include <STDLIB.H>
#include "d_global.h"
#include "d_ints.h"
#include "d_video.h"
#include "d_misc.h"
// added to allow drawing directly to buffer where frame is built
// TML 9-20-94
#include "r_public.h"
#define CRTCOFF (_inbyte(STATUS_REGISTER_1)&1)
void VI_CopyUpdate (void);
void VI_BlitMaskedPic (byte *source,byte *dest,int width,int height,int mask);
/*
=============================================================================
GLOBALS
=============================================================================
*/
byte *screen = (byte *)SCREEN;
byte *ylookup[SCREENHEIGHT]; // into video screen
/*
=============================================================================
VGA REGISTER MANAGEMENT ROUTINES
=============================================================================
*/
/*
=================
=
= VI_SetTextMode
=
=================
*/
void VI_SetTextMode (void)
{
union REGS r;
r.x.ax = 3;
int86 (0x10,(const union REGS *)&r,&r);
}
//=========================================================================
/*
=================
=
= VI_SetVGAMode
=
=================
*/
void VI_SetVGAMode (void)
{
union REGS r;
r.x.ax = 0x13;
int86 (0x10,(const union REGS *)&r,&r);
}
//=========================================================================
/*
=================
=
= VI_WaitVBL
=
=================
*/
void VI_WaitVBL (int vbls)
{
int old;
int i,stat;
while (vbls--)
{
// wait for display enabled, so we know it isn't just after vsync
waitdisplay:
CLI;
while (CRTCOFF)
;
// wait for display just turned off
waitbottom:
STI;
i--; // time for an interrupt
CLI;
for (i=0;i<10;i++)
{
stat = _inbyte(STATUS_REGISTER_1);
if (stat & 8)
goto waitdisplay; // vsync...
if (!(stat&1))
goto waitbottom;
}
STI;
}
}
/*
=============================================================================
PALETTE OPS
=============================================================================
*/
/*
=================
=
= VI_FillPalette
=
=================
*/
void VI_FillPalette (int red, int green, int blue)
{
int i;
_outbyte (PEL_WRITE_ADR,0);
for (i=0;i<256;i++)
{
_outbyte (PEL_DATA,red);
_outbyte (PEL_DATA,green);
_outbyte (PEL_DATA,blue);
}
}
//===========================================================================
/*
=================
=
= VI_SetColor
=
=================
*/
void VI_SetColor (int color, int red, int green, int blue)
{
_outbyte (PEL_WRITE_ADR,color);
_outbyte (PEL_DATA,red);
_outbyte (PEL_DATA,green);
_outbyte (PEL_DATA,blue);
}
//===========================================================================
/*
=================
=
= VI_GetColor
=
=================
*/
void VI_GetColor (int color, int *red, int *green, int *blue)
{
_outbyte (PEL_READ_ADR,color);
*red = _inbyte (PEL_DATA);
*green = _inbyte (PEL_DATA);
*blue = _inbyte (PEL_DATA);
}
//===========================================================================
/*
=================
=
= VI_SetPalette
=
=================
*/
void VI_SetPalette (byte *palette)
{
int i;
_outbyte (PEL_WRITE_ADR,0);
for (i=0;i<768;i++)
_outbyte(PEL_DATA,*palette++);
}
//===========================================================================
/*
=================
=
= VI_GetPalette
=
=================
*/
void VI_GetPalette (byte *palette)
{
int i;
_outbyte (PEL_READ_ADR,0);
for (i=0;i<768;i++)
*palette++ = _inbyte(PEL_DATA);
}
//===========================================================================
/*
=================
=
= VI_FadeOut
=
= Fades the current palette to the given color in the given number of steps
=
=================
*/
void VI_FadeOut (int start, int end, int red, int green, int blue, int steps)
{
byte basep[256][3],work[256][3];
int i,j,delta;
VI_GetPalette (&basep[0][0]);
//
// fade through intermediate frames
//
for (i=0;i<steps;i++)
{
for (j=start;j<=end;j++)
{
delta = red-basep[j][0];
work[j][0] = basep[j][0] + delta * i / steps;
delta = green-basep[j][1];
work[j][1] = basep[j][1] + delta * i / steps;
delta = blue-basep[j][2];
work[j][2] = basep[j][2] + delta * i / steps;
}
VI_WaitVBL(1);
VI_SetPalette (&work[0][0]);
}
//
// final color
//
VI_FillPalette (red,green,blue);
}
/*
=================
=
= VI_FadeIn
=
=================
*/
void VI_FadeIn (int start, int end, byte *palette, int steps)
{
byte basep[768],work[768];
int i,j,delta;
VI_GetPalette (basep);
start *= 3;
end *= 3;
//
// fade through intermediate frames
//
for (i=0;i<steps;i++)
{
for (j=start;j<=end;j++)
{
delta = palette[j]-basep[j];
work[j] = basep[j] + delta * i / steps;
}
VI_WaitVBL(1);
VI_SetPalette (work);
}
//
// final color
//
VI_SetPalette (palette);
}
/*
=================
=
= VI_ColorBorder
=
=================
*/
void VI_ColorBorder (int color)
{
_inbyte(STATUS_REGISTER_1);
_outbyte(ATR_INDEX,ATR_OVERSCAN);
_outbyte(ATR_INDEX,color);
_outbyte(ATR_INDEX,0x20);
}
/*
=============================================================================
PIXEL OPS
=============================================================================
*/
/*
=================
=
= VI_Plot
=
=================
*/
void VI_Plot (int x, int y, int color)
{
*(ylookup[y]+x) = color;
}
/*
=================
=
= VI_Hlin
=
=================
*/
void VI_Hlin (int x, int y, int width, int color)
{
memset (ylookup[y]+x,color,(size_t)width);
}
/*
=================
=
= VI_Vlin
=
=================
*/
void VI_Vlin (int x, int y, int height, int color)
{
byte *dest;
dest = ylookup[y]+x;
while (height--) {
*dest = color;
dest += SCREENWIDTH;
}
}
/*
=================
=
= VI_Bar
=
=================
*/
void VI_Bar (int x, int y, int width, int height, int color)
{
byte *dest;
dest = ylookup[y]+x;
while (height--) {
memset (dest,color,(size_t)width);
dest += SCREENWIDTH;
}
}
/*
=============================================================================
BLOCK OPS
=============================================================================
*/
/*
=================
=
= VI_DrawPic
=
= Draws a block shape (in planar format) to the screen
=
=================
*/
void VI_DrawPic (int x, int y, pic_t *pic)
{
byte *dest, *source;
int width,height;
width = pic->width;
height = pic->height;
source = &pic->data;
dest = ylookup[y]+x;
while (height--) {
memcpy (dest,source,(size_t)width);
source += width;
dest += SCREENWIDTH;
}
}
/*
=================
=
= VI_DrawMaskedPic
=
= Masks a block of main memory to the screen.
= Uses orgx,orgy to offset the block
= If the hot spot is inside the block shape, the offsets are positive
=
=================
*/
void VI_DrawMaskedPic (int x, int y, pic_t *pic)
{
byte *dest, *source;
int width,height,xcor,col;
x -= pic->orgx;
y -= pic->orgy;
height = pic->height;
source = &pic->data;
while (y<0) {
source += pic->width;
height--;
}
while (height--) {
if (y<200) {
dest = ylookup[y]+x;
xcor = x;
width = pic->width;
while (width--) {
if ((xcor>=0)&&(xcor<=319)) {
if (*source) *dest = *source;
}
xcor++;
source++;
dest++;
}
}
y++;
}
}
/*
=================
=
= VI_DrawMaskedPicToBuffer
=
= Masks a block of main memory to the offscreen buffer where frame is built
= Uses orgx,orgy to offset the block
= If the hot spot is inside the block shape, the offsets are positive
=
=================
*/
// TML - Added 9-20-94 (allows image transfer to viewbuffer)
void VI_DrawMaskedPicToBuffer2 (int x, int y, pic_t *pic)
{
byte *dest,*source;
int width,height,xcor,col;
x -= pic->orgx;
y -= pic->orgy;
height = pic->height;
source = &pic->data;
while (y<0) {
source += pic->width;
height--;
}
while (height--) {
if (y<200) {
// dest = ylookup[y]+x; // for blitting to video mem.
dest = viewbuffer+(y*MAX_VIEW_WIDTH+x);
xcor = x;
width = pic->width;
while (width--) {
if ((xcor>=0)&&(xcor<=319)) {
if (*source) *dest = *source;
}
xcor++;
source++;
dest++;
}
}
y++;
}
}
void VI_Init (void)
{
int y;
for (y=0;y<SCREENHEIGHT;y++)
ylookup[y] = screen + y*SCREENWIDTH;
VI_SetVGAMode ();
}