2443 lines
63 KiB
C++
2443 lines
63 KiB
C++
![]() |
/*
|
||
|
** Command & Conquer Red Alert(tm)
|
||
|
** Copyright 2025 Electronic Arts 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 3 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.
|
||
|
**
|
||
|
** You should have received a copy of the GNU General Public License
|
||
|
** along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||
|
*/
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* C O N F I D E N T I A L -- W E S T W O O D S T U D I O S
|
||
|
*
|
||
|
*----------------------------------------------------------------------------
|
||
|
*
|
||
|
* PROJECT
|
||
|
* VQAPlay32 library. (32-Bit protected mode)
|
||
|
*
|
||
|
* FILE
|
||
|
* drawer.c
|
||
|
*
|
||
|
* DESCRIPTION
|
||
|
* Frame drawing and page flip control.
|
||
|
*
|
||
|
* PROGRAMMER
|
||
|
* Bill Randolph
|
||
|
* Denzil E. Long, Jr.
|
||
|
*
|
||
|
* DATE
|
||
|
* June 26, 1995
|
||
|
*
|
||
|
*----------------------------------------------------------------------------
|
||
|
*
|
||
|
* PUBLIC
|
||
|
* VQA_Configure_Drawer - Configure the drawer routines.
|
||
|
*
|
||
|
* PRIVATE
|
||
|
* Select_Frame - Selects frame to draw and preforms frame
|
||
|
* skip.
|
||
|
* Prepare_Frame - Process/Decompress frame information.
|
||
|
* DrawFrame_Xmode - Draws a frame directly to Xmode screen.
|
||
|
* DrawFrame_XmodeBuf - Draws a frame in Xmode format to a buffer.
|
||
|
* DrawFrame_XmodeVRAM - Draws a frame in Xmode with resident
|
||
|
* Codebook.
|
||
|
* PageFlip_Xmode - Page flip Xmode display.
|
||
|
* DrawFrame_MCGA - Draws a frame directly to MCGA screen.
|
||
|
* PageFlip_MCGA - Page flip MCGA display.
|
||
|
* DrawFrame_MCGABuf - Draws a frame in MCGA format to a buffer.
|
||
|
* PageFlip_MCGABuf - Page flip a buffered MCGA display.
|
||
|
* DrawFrame_VESA640 - Draws a frame in VESA640 format.
|
||
|
* DrawFrame_VESA320_32K - Draws a frame to VESA320_32K screen.
|
||
|
* DrawFrame_VESA320_32KBuf - Draws a frame in VESA320_32K format to a
|
||
|
* buffer.
|
||
|
* PageFlip_VESA - Page flip VESA display.
|
||
|
* DrawFrame_Buffer - Draw a frame to a buffer.
|
||
|
* PageFlip_Nop - Do nothing page flip.
|
||
|
* UnVQ_Nop - Do nothing UnVQ.
|
||
|
* Mask_Rect - Sets non-drawable rectangle in image.
|
||
|
* Mask_Pointers - Mask vector pointer that are in the mask
|
||
|
* rectangle.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <malloc.h>
|
||
|
#include <conio.h>
|
||
|
#include <dos.h>
|
||
|
#include <mem.h>
|
||
|
#include "vq.h"
|
||
|
#include "unvq.h"
|
||
|
#include "vqaplayp.h"
|
||
|
#include <vqm32\all.h>
|
||
|
#include "caption.h"
|
||
|
|
||
|
/*---------------------------------------------------------------------------
|
||
|
* PRIVATE DECLARATIONS
|
||
|
*-------------------------------------------------------------------------*/
|
||
|
static long Select_Frame(VQAHandleP *vqap);
|
||
|
static void Prepare_Frame(VQAData *vqabuf);
|
||
|
|
||
|
#if(VQAMCGA_ON)
|
||
|
static long DrawFrame_MCGABuf(VQAHandle *vqa);
|
||
|
static long PageFlip_MCGABuf(VQAHandle *vqa);
|
||
|
static long DrawFrame_MCGA(VQAHandle *vqa);
|
||
|
static long PageFlip_MCGA(VQAHandle *vqa);
|
||
|
#endif /* VQAMCGA_ON */
|
||
|
|
||
|
#if(VQAXMODE_ON)
|
||
|
static long DrawFrame_XmodeBuf(VQAHandle *vqa);
|
||
|
static long DrawFrame_Xmode(VQAHandle *vqa);
|
||
|
static long DrawFrame_XmodeVRAM(VQAHandle *vqa);
|
||
|
static void PageFlip_Xmode(VQAHandle *vqabuf);
|
||
|
#endif /* VQAXMODE_ON */
|
||
|
|
||
|
#if(VQAVESA_ON)
|
||
|
static long DrawFrame_VESA640(VQAHandle *vqa);
|
||
|
static long DrawFrame_VESA320_32K(VQAHandle *vqa);
|
||
|
static long DrawFrame_VESA320_32KBuf(VQAHandle *vqa);
|
||
|
static void PageFlip_VESA(VQAHandle *vqabuf);
|
||
|
#endif /* VQAVESA_ON */
|
||
|
|
||
|
static long DrawFrame_Buffer(VQAHandle *vqa);
|
||
|
static long PageFlip_Nop(VQAHandle *vqa);
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
static void __cdecl UnVQ_Nop(unsigned char *codebook, unsigned char *pointers,
|
||
|
unsigned char *buffer, unsigned long blocksperrow,
|
||
|
unsigned long numrows, unsigned long bufwidth);
|
||
|
#else
|
||
|
static void __cdecl UnVQ_Nop(unsigned char *codebook, unsigned char *pointers,
|
||
|
FARPTR buffer, unsigned long blocksperrow, unsigned long numrows,
|
||
|
unsigned long bufwidth);
|
||
|
#endif
|
||
|
|
||
|
#if(0)
|
||
|
static void Mask_Rect(VQAHandle *vqa, unsigned long x1, unsigned long y1,
|
||
|
unsigned long x2, unsigned long y2);
|
||
|
static void Mask_Pointers(VQAData *vqabuf);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* VQA_GetPalette - Get the palette used in the movie.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Palette = VQA_GetPalette(VQA)
|
||
|
*
|
||
|
* char *VQA_GetPalette(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Retrieve the address of the current palette used in the movie. If there
|
||
|
* isn't a palette available then a NULL value will be returned.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle to get palette for.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Palette - Pointer to palette or NULL if no palette available.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
unsigned char *VQA_GetPalette(VQAHandle *vqa)
|
||
|
{
|
||
|
VQADrawer *drawer;
|
||
|
unsigned char *palette = NULL;
|
||
|
|
||
|
/* Dereference commonly used data members for quick access. */
|
||
|
drawer = &((VQAHandleP *)vqa)->VQABuf->Drawer;
|
||
|
|
||
|
if (drawer->CurPalSize > 0) {
|
||
|
palette = drawer->Palette_24;
|
||
|
}
|
||
|
|
||
|
return (palette);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* VQA_GetPaletteSize - Get the size of the palette used in the movie.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* PalSize = VQA_GetPaletteSize(VQA)
|
||
|
*
|
||
|
* long VQA_GetPaletteSize(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Retrieve the size of the current palette used in the movie. If there
|
||
|
* isn't a palette available then a zero size will be returned.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle to get palette for.
|
||
|
*
|
||
|
* RESULT
|
||
|
* PalSize - Size in bytes of the current palette.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
long VQA_GetPaletteSize(VQAHandle *vqa)
|
||
|
{
|
||
|
VQADrawer *drawer;
|
||
|
|
||
|
/* Dereference commonly used data members for quick access. */
|
||
|
drawer = &((VQAHandleP *)vqa)->VQABuf->Drawer;
|
||
|
|
||
|
return (drawer->CurPalSize);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* VQA_Set_DrawBuffer - Set the buffer to draw the images to.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* VQA_Set_DrawBuffer(VQA, Buffer, Width, Height, XPos, YPos)
|
||
|
*
|
||
|
* void VQA_Set_DrawBuffer(VQAHandle *, unsigned char *,
|
||
|
* unsigned long, unsigned long, unsigned long,
|
||
|
* unsigned long);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Set the draw buffer to the buffer provided by the client.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle to set buffer for.
|
||
|
* Buffer - Pointer to new image buffer.
|
||
|
* Width - Width of the buffer in pixels.
|
||
|
* Height - Height of the buffer in pixels.
|
||
|
* XPos - X pixel position in buffer to draw image.
|
||
|
* YPos - Y pixel position in buffer to draw image.
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
void VQA_Set_DrawBuffer(VQAHandle *vqa, unsigned char *buffer,
|
||
|
unsigned long width, unsigned long height,
|
||
|
long xpos, long ypos)
|
||
|
{
|
||
|
VQAHeader *header;
|
||
|
VQADrawer *drawer;
|
||
|
VQAConfig *config;
|
||
|
long origin;
|
||
|
|
||
|
/* Dereference commonly used data members for quick access. */
|
||
|
header = &((VQAHandleP *)vqa)->Header;
|
||
|
drawer = &((VQAHandleP *)vqa)->VQABuf->Drawer;
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
origin = (config->DrawFlags & VQACFGF_ORIGIN);
|
||
|
|
||
|
/* Set the drawer buffer information. */
|
||
|
drawer->ImageBuf = buffer;
|
||
|
drawer->ImageWidth = width;
|
||
|
drawer->ImageHeight = height;
|
||
|
|
||
|
/*-------------------------------------------------------------------------
|
||
|
* SET THE DRAW POSITION OF THE MOVIE.
|
||
|
*
|
||
|
* X1 = -1 -- Center image of the X axis, otherwise use X1 value.
|
||
|
* Y1 = -1 -- Center image of the Y axis, otherwise use Y1 value.
|
||
|
*-----------------------------------------------------------------------*/
|
||
|
if ((xpos == -1) && (ypos == -1)) {
|
||
|
|
||
|
#if(VQAVIDEO_ON)
|
||
|
drawer->X1 = ((drawer->Display->XRes - header->image_width) / 2);
|
||
|
drawer->Y1 = ((drawer->Display->YRes - header->image_height) / 2);
|
||
|
#else /* VQAVIDEO_ON */
|
||
|
drawer->X1 = ((width - header->ImageWidth) / 2);
|
||
|
drawer->Y1 = ((height - header->ImageHeight) / 2);
|
||
|
#endif /* VQAVIDEO_ON */
|
||
|
|
||
|
drawer->X2 = ((drawer->X1 + header->ImageWidth) - 1);
|
||
|
drawer->Y2 = ((drawer->Y1 + header->ImageHeight) - 1);
|
||
|
} else {
|
||
|
switch (origin) {
|
||
|
default:
|
||
|
case VQACFGF_TOPLEFT:
|
||
|
drawer->X1 = xpos;
|
||
|
drawer->Y1 = ypos;
|
||
|
drawer->X2 = ((drawer->X1 + header->ImageWidth) - 1);
|
||
|
drawer->Y2 = ((drawer->Y1 + header->ImageHeight) - 1);
|
||
|
break;
|
||
|
|
||
|
case VQACFGF_BOTLEFT:
|
||
|
drawer->X1 = xpos;
|
||
|
drawer->Y1 = (height - ypos);
|
||
|
drawer->X2 = ((drawer->X1 + header->ImageWidth) - 1);
|
||
|
drawer->Y2 = ((drawer->Y2 - header->ImageHeight) - 1);
|
||
|
break;
|
||
|
|
||
|
case VQACFGF_BOTRIGHT:
|
||
|
drawer->X1 = (width - xpos);
|
||
|
drawer->Y1 = (height - ypos);
|
||
|
drawer->X2 = (drawer->X1 - header->ImageWidth);
|
||
|
drawer->Y2 = (drawer->Y1 - header->ImageHeight);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Pre-compute the draw offset for speed. */
|
||
|
drawer->ScreenOffset = ((width * drawer->Y1) + drawer->X1);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* VQA_Configure_Drawer - Configure the drawer routines.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* VQA_Configure_Drawer(VQA)
|
||
|
*
|
||
|
* void VQA_Configure_Drawer(VQAHandleP *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Configure the drawing system for the current movie and configuration
|
||
|
* options.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to private VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
void VQA_Configure_Drawer(VQAHandleP *vqap)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQAConfig *config;
|
||
|
VQAHeader *header;
|
||
|
VQADrawer *drawer;
|
||
|
long origin;
|
||
|
long blkdim;
|
||
|
|
||
|
/* Dereference commonly used data members for quicker access. */
|
||
|
vqabuf = vqap->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
header = &vqap->Header;
|
||
|
config = &vqap->Config;
|
||
|
origin = (config->DrawFlags & VQACFGF_ORIGIN);
|
||
|
|
||
|
/*-------------------------------------------------------------------------
|
||
|
* SET THE DRAW POSITION OF THE MOVIE.
|
||
|
*
|
||
|
* X1 = -1 -- Center image of the X axis, otherwise use X1 value.
|
||
|
* Y1 = -1 -- Center image of the Y axis, otherwise use Y1 value.
|
||
|
*-----------------------------------------------------------------------*/
|
||
|
if ((config->X1 == -1) && (config->Y1 == -1)) {
|
||
|
|
||
|
#if(VQAVIDEO_ON)
|
||
|
drawer->X1 = ((drawer->Display->XRes - header->image_width) / 2);
|
||
|
drawer->Y1 = ((drawer->Display->YRes - header->image_height) / 2);
|
||
|
#else /* VQAVIDEO_ON */
|
||
|
drawer->X1 = ((drawer->ImageWidth - header->ImageWidth) / 2);
|
||
|
drawer->Y1 = ((drawer->ImageHeight - header->ImageHeight) / 2);
|
||
|
#endif /* VQAVIDEO_ON */
|
||
|
|
||
|
drawer->X2 = ((drawer->X1 + header->ImageWidth) - 1);
|
||
|
drawer->Y2 = ((drawer->Y1 + header->ImageHeight) - 1);
|
||
|
} else {
|
||
|
switch (origin) {
|
||
|
default:
|
||
|
case VQACFGF_TOPLEFT:
|
||
|
drawer->X1 = config->X1;
|
||
|
drawer->Y1 = config->Y1;
|
||
|
drawer->X2 = ((drawer->X1 + header->ImageWidth) - 1);
|
||
|
drawer->Y2 = ((drawer->Y1 + header->ImageHeight) - 1);
|
||
|
break;
|
||
|
|
||
|
case VQACFGF_BOTLEFT:
|
||
|
drawer->X1 = config->X1;
|
||
|
drawer->Y1 = (drawer->ImageHeight - config->Y1);
|
||
|
drawer->X2 = ((drawer->X1 + header->ImageWidth) - 1);
|
||
|
drawer->Y2 = ((drawer->Y2 - header->ImageHeight) - 1);
|
||
|
break;
|
||
|
|
||
|
case VQACFGF_BOTRIGHT:
|
||
|
drawer->X1 = (drawer->ImageWidth - config->X1);
|
||
|
drawer->Y1 = (drawer->ImageHeight - config->Y1);
|
||
|
drawer->X2 = (drawer->X1 - header->ImageWidth);
|
||
|
drawer->Y2 = (drawer->Y1 - header->ImageHeight);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*-------------------------------------------------------------------------
|
||
|
* INITIALIZE THE UNVQ ROUTINE FOR THE SPECIFIED VIDEO MODE AND BLOCK SIZE.
|
||
|
*-----------------------------------------------------------------------*/
|
||
|
|
||
|
/* Pre-compute commonly used values for speed. */
|
||
|
drawer->BlocksPerRow = header->ImageWidth / header->BlockWidth;
|
||
|
drawer->NumRows = header->ImageHeight / header->BlockHeight;
|
||
|
drawer->NumBlocks = drawer->BlocksPerRow * drawer->NumRows;
|
||
|
blkdim = BLOCK_DIM(header->BlockWidth, header->BlockHeight);
|
||
|
|
||
|
/* Initialize draw routine vectors to a NOP routine in order to prevent
|
||
|
* a crash.
|
||
|
*/
|
||
|
vqabuf->UnVQ = UnVQ_Nop;
|
||
|
vqabuf->Page_Flip = PageFlip_Nop;
|
||
|
|
||
|
/* If the client specifies buffering then go ahead an set the unvq
|
||
|
* vector. All of the buffered modes use the same unvq routines.
|
||
|
*/
|
||
|
if (config->DrawFlags & VQACFGF_BUFFER) {
|
||
|
switch (blkdim) {
|
||
|
#if(VQABLOCK_2X2)
|
||
|
case BLOCK_2X2:
|
||
|
vqabuf->UnVQ = UnVQ_2x2;
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if(VQABLOCK_2X3)
|
||
|
case BLOCK_2X3:
|
||
|
vqabuf->UnVQ = UnVQ_2x3;
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if(VQABLOCK_4X2)
|
||
|
case BLOCK_4X2:
|
||
|
vqabuf->UnVQ = UnVQ_4x2;
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if(VQABLOCK_4X4)
|
||
|
case BLOCK_4X4:
|
||
|
vqabuf->UnVQ = UnVQ_4x4;
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Initialize the draw vectors for the specified video mode. */
|
||
|
switch (config->Vmode) {
|
||
|
|
||
|
/* MCGA */
|
||
|
#if(VQAMCGA_ON)
|
||
|
case MCGA:
|
||
|
if (config->DrawFlags & VQACFGF_BUFFER) {
|
||
|
vqabuf->Draw_Frame = DrawFrame_MCGABuf;
|
||
|
vqabuf->Page_Flip = PageFlip_MCGABuf;
|
||
|
} else {
|
||
|
vqabuf->Draw_Frame = DrawFrame_MCGA;
|
||
|
vqabuf->Page_Flip = PageFlip_MCGA;
|
||
|
|
||
|
/* MCGA uses the same unvq routines that are used for unvqing
|
||
|
* to a buffer because MCGA mode is just another buffer. However,
|
||
|
* instead of drawing to an allocated RAM buffer we are drawing
|
||
|
* directly to the VRAM video buffer.
|
||
|
*/
|
||
|
switch (blkdim) {
|
||
|
#if(VQABLOCK_2X2)
|
||
|
case BLOCK_2X2:
|
||
|
vqabuf->UnVQ = UnVQ_2x2;
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if(VQABLOCK_2X3)
|
||
|
case BLOCK_2X3:
|
||
|
vqabuf->UnVQ = UnVQ_2x3;
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if(VQABLOCK_4X2)
|
||
|
case BLOCK_4X2:
|
||
|
#if(!VQAWOOFER_ON)
|
||
|
vqabuf->UnVQ = UnVQ_4x2;
|
||
|
#else
|
||
|
if (config->DrawFlags & VQACFGF_WOOFER) {
|
||
|
vqabuf->UnVQ = UnVQ_4x2_Woofer;
|
||
|
} else {
|
||
|
vqabuf->UnVQ = UnVQ_4x2;
|
||
|
}
|
||
|
#endif
|
||
|
break;
|
||
|
#endif
|
||
|
|
||
|
#if(VQABLOCK_4X4)
|
||
|
case BLOCK_4X4:
|
||
|
vqabuf->UnVQ = UnVQ_4x4;
|
||
|
break;
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Pre-compute the draw offset for speed. */
|
||
|
drawer->ScreenOffset = ((320 * drawer->Y1) + drawer->X1);
|
||
|
break;
|
||
|
#endif /* VQAMCGA_ON */
|
||
|
|
||
|
/* XMODE */
|
||
|
#if(VQAXMODE_ON)
|
||
|
case XMODE_320X200:
|
||
|
case XMODE_320X240:
|
||
|
if (config->DrawFlags & VQACFGF_BUFFER) {
|
||
|
vqabuf->Draw_Frame = DrawFrame_XmodeBuf;
|
||
|
vqabuf->Page_Flip = PageFlip_Xmode;
|
||
|
} else {
|
||
|
vqabuf->Page_Flip = PageFlip_Xmode;
|
||
|
|
||
|
if (config->DrawFlags & VQACFGF_VRAMCB) {
|
||
|
vqabuf->Draw_Frame = DrawFrame_XmodeVRAM;
|
||
|
|
||
|
switch (blkdim) {
|
||
|
#if(VQABLOCK_4X2)
|
||
|
case BLOCK_4X2:
|
||
|
vqabuf->UnVQ = UnVQ_4x2_XmodeCB;
|
||
|
break;
|
||
|
#endif /* VQABLOCK_4X2 */
|
||
|
}
|
||
|
} else {
|
||
|
vqabuf->Draw_Frame = DrawFrame_Xmode;
|
||
|
|
||
|
switch (blkdim) {
|
||
|
#if(VQABLOCK_4X2)
|
||
|
case BLOCK_4X2:
|
||
|
vqabuf->UnVQ = UnVQ_4x2_Xmode;
|
||
|
break;
|
||
|
#endif /* VQABLOCK_4X2 */
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Pre-compute the draw offset for speed. */
|
||
|
drawer->ScreenOffset = (((320 / 4) * drawer->Y1) + (drawer->X1 / 4));
|
||
|
break;
|
||
|
#endif /* VQAXMODE_ON */
|
||
|
|
||
|
/* VESA */
|
||
|
#if(VQAVESA_ON)
|
||
|
|
||
|
/* Currently this is a buffered mode, but should be optimized for
|
||
|
* for screen direct.
|
||
|
*/
|
||
|
case VESA_640X480_256:
|
||
|
vqabuf->Draw_Frame = DrawFrame_VESA640;
|
||
|
vqabuf->Page_Flip = PageFlip_VESA;
|
||
|
break;
|
||
|
|
||
|
case VESA_320X200_32K_1:
|
||
|
if (config->DrawFlags & VQACFGF_BUFFER) {
|
||
|
vqabuf->Draw_Frame = DrawFrame_VESA320_32KBuf;
|
||
|
} else {
|
||
|
vqabuf->Draw_Frame = DrawFrame_VESA320_32K;
|
||
|
|
||
|
switch (blkdim) {
|
||
|
#if(VQABLOCK_4X2)
|
||
|
case BLOCK_4X2:
|
||
|
vqabuf->UnVQ = UnVQ_4x2_VESA320_32K;
|
||
|
break;
|
||
|
#endif
|
||
|
}
|
||
|
}
|
||
|
break;
|
||
|
#endif /* VQAVESA_ON */
|
||
|
|
||
|
/* Purely buffered (Video refresh is up to the client. */
|
||
|
default:
|
||
|
vqabuf->Draw_Frame = DrawFrame_Buffer;
|
||
|
|
||
|
/* Pre-compute the draw offset for speed. */
|
||
|
drawer->ScreenOffset = ((drawer->ImageWidth * drawer->Y1)+drawer->X1);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* Select_Frame - Selects frame to draw and preforms frame skip.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = Select_Frame(VQA)
|
||
|
*
|
||
|
* long Select_Frame(VQAHandleP *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Select a frame to draw. This is were the frame skipping/delay is
|
||
|
* performed.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to private VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long Select_Frame(VQAHandleP *vqap)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAConfig *config;
|
||
|
VQAFrameNode *curframe;
|
||
|
long desiredframe;
|
||
|
// MEG 11.29.95 - changed from long to unsigned long
|
||
|
unsigned long curtime;
|
||
|
|
||
|
/* Dereference commonly used data members for quicker access. */
|
||
|
config = &vqap->Config;
|
||
|
vqabuf = vqap->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Make sure the current frame is drawable. If the frame is not ready
|
||
|
* then we must wait for the loader to catch up.
|
||
|
*/
|
||
|
if ((curframe->Flags & VQAFRMF_LOADED) == 0) {
|
||
|
drawer->WaitsOnLoader++;
|
||
|
return (VQAERR_NOBUFFER);
|
||
|
}
|
||
|
|
||
|
/* If single stepping then return with the next frame.*/
|
||
|
if (config->OptionFlags & VQAOPTF_STEP) {
|
||
|
drawer->LastFrame = curframe->FrameNum;
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
/* Find the frame # we should play (rounded to nearest frame): */
|
||
|
curtime = VQA_GetTime(vqap);
|
||
|
// desiredframe = ((curtime * config->FrameRate) / VQA_TIMETICKS);
|
||
|
// MEG MOD 06.22.95 - Should look for the desired frame to draw, not load,
|
||
|
// right?
|
||
|
desiredframe = ((curtime * config->DrawRate) / VQA_TIMETICKS);
|
||
|
|
||
|
#if(VQAMONO_ON)
|
||
|
drawer->DesiredFrame = desiredframe;
|
||
|
#endif
|
||
|
|
||
|
/* Handle the cases where the player is going so fast that it's not time
|
||
|
* to draw this frame yet.
|
||
|
*
|
||
|
* - If the Drawer is using a slower frame rate than the Loader, use a
|
||
|
* delta-time-based wait; otherwise, use the frame number as the wait.
|
||
|
*/
|
||
|
if (config->DrawRate != config->FrameRate) {
|
||
|
if (curtime - drawer->LastTime < (VQA_TIMETICKS / config->DrawRate)) {
|
||
|
return (VQAERR_NOT_TIME);
|
||
|
}
|
||
|
} else {
|
||
|
if (curframe->FrameNum > desiredframe) {
|
||
|
return (VQAERR_NOT_TIME);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Make sure we draw at least 5 frames per second */
|
||
|
if ((curframe->FrameNum - drawer->LastFrame) >= (config->FrameRate / 5)) {
|
||
|
drawer->LastFrame = curframe->FrameNum;
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
/* If frame skipping is disabled then draw every frame. */
|
||
|
if (config->DrawFlags & VQACFGF_NOSKIP) {
|
||
|
drawer->LastFrame = curframe->FrameNum;
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
/* Handle the case where the player is going too slow, so we have to skip
|
||
|
* some frames:
|
||
|
*
|
||
|
* - If this is a Key Frame, draw it
|
||
|
* - If this frame's # is less than what we're supposed to draw, skip it
|
||
|
* (Because the 1st 'desiredframe' will be 0, FrameNum MUST be typecast
|
||
|
* to signed WORD for the comparison; otherwise, the comparison uses
|
||
|
* UWORDs, and the first frame is always skipped.)
|
||
|
* - If this is a palette-set frame, set the palette before skipping it
|
||
|
* - Loop until we get the frame we need, or there's no frames available
|
||
|
*/
|
||
|
while (1) {
|
||
|
|
||
|
/* No frame available; return */
|
||
|
if ((curframe->Flags & VQAFRMF_LOADED) == 0) {
|
||
|
return (VQAERR_NOBUFFER);
|
||
|
}
|
||
|
|
||
|
/* Force drawing of a Key Frame */
|
||
|
if (curframe->Flags & VQAFRMF_KEY) {
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Skip the frame */
|
||
|
if (curframe->FrameNum < desiredframe) {
|
||
|
|
||
|
/* Handle a palette in a skipped frame:
|
||
|
*
|
||
|
* - Stash the palette in Drawer.Palette_24
|
||
|
* - Set the Drawer.Flags VQADRWF_SETPAL bit, to tell the page-flip
|
||
|
* routines that this palette must be set
|
||
|
*/
|
||
|
if (curframe->Flags & VQAFRMF_PALETTE) {
|
||
|
|
||
|
/* Un-LCW if needed */
|
||
|
if (curframe->Flags & VQAFRMF_PALCOMP) {
|
||
|
curframe->PaletteSize = LCW_Uncompress((char *)curframe->Palette
|
||
|
+ curframe->PalOffset, (char *)curframe->Palette,
|
||
|
vqabuf->Max_Pal_Size);
|
||
|
|
||
|
curframe->Flags &= ~VQAFRMF_PALCOMP;
|
||
|
}
|
||
|
|
||
|
/* Stash the palette */
|
||
|
memcpy(drawer->Palette_24, curframe->Palette, curframe->PaletteSize);
|
||
|
drawer->CurPalSize = curframe->PaletteSize;
|
||
|
drawer->Flags |= VQADRWF_SETPAL;
|
||
|
}
|
||
|
|
||
|
/* Invoke callback with NULL screen ptr */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(NULL, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Skip the frame */
|
||
|
curframe->Flags = 0L;
|
||
|
curframe = curframe->Next;
|
||
|
drawer->CurFrame = curframe;
|
||
|
drawer->NumSkipped++;
|
||
|
} else {
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
drawer->LastFrame = curframe->FrameNum;
|
||
|
drawer->LastTime = curtime;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* Prepare_Frame - Process/Decompress frame information.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Prepare_Frame(VQAData)
|
||
|
*
|
||
|
* void Prepare_Frame(VQAData *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Decompress and preprocess the various frame elements (codebook,
|
||
|
* pointers, palette, etc...)
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQAData - Pointer to VQAData structure.
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static void Prepare_Frame(VQAData *vqabuf)
|
||
|
{
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQACBNode *codebook;
|
||
|
|
||
|
/* Dereference commonly used data members for quicker access. */
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
curframe = drawer->CurFrame;
|
||
|
codebook = curframe->Codebook;
|
||
|
|
||
|
/* Decompress the codebook, if needed */
|
||
|
if (codebook->Flags & VQACBF_CBCOMP) {
|
||
|
|
||
|
/* Decompress the codebook. */
|
||
|
LCW_Uncompress((char *)codebook->Buffer + codebook->CBOffset,
|
||
|
(char *)codebook->Buffer, vqabuf->Max_CB_Size);
|
||
|
|
||
|
/* Mark as uncompressed for the next time we use it */
|
||
|
codebook->Flags &= (~VQACBF_CBCOMP);
|
||
|
}
|
||
|
|
||
|
/* Decompress the palette, if needed */
|
||
|
if (curframe->Flags & VQAFRMF_PALCOMP) {
|
||
|
curframe->PaletteSize = LCW_Uncompress((char *)curframe->Palette +
|
||
|
curframe->PalOffset,(char *)curframe->Palette,vqabuf->Max_Pal_Size);
|
||
|
|
||
|
/* Mark as uncompressed */
|
||
|
curframe->Flags &= ~VQAFRMF_PALCOMP;
|
||
|
}
|
||
|
|
||
|
/* Decompress the pointer data, if needed */
|
||
|
if (curframe->Flags & VQAFRMF_PTRCOMP) {
|
||
|
LCW_Uncompress((char *)curframe->Pointers + curframe->PtrOffset,
|
||
|
(char *)curframe->Pointers, vqabuf->Max_Ptr_Size);
|
||
|
|
||
|
/* Mark as uncompressed */
|
||
|
curframe->Flags &= ~VQAFRMF_PTRCOMP;
|
||
|
}
|
||
|
|
||
|
/* Mask the pointers */
|
||
|
#if(0)
|
||
|
Mask_Pointers(vqabuf);
|
||
|
#endif
|
||
|
}
|
||
|
|
||
|
|
||
|
#if(VQAXMODE_ON)
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_Xmode - Draws a frame in Xmode format (Screen direct).
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_Xmode(VQA)
|
||
|
*
|
||
|
* long DrawFrame_Xmode(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Algorithm:
|
||
|
* - Skip frames
|
||
|
* - UnLCW frame
|
||
|
* - Un-VQ into video RAM
|
||
|
* - Wait on Update_Enabled
|
||
|
* - Set the Flipper's CurFrame
|
||
|
* - Set Update_Enabled
|
||
|
* - Go to next frame
|
||
|
* - User_Update:
|
||
|
* Flip X-Page
|
||
|
* Set Palette from Flipper.CurFrame
|
||
|
*
|
||
|
* This function implements a sort of cooperative multitasking. If the
|
||
|
* Drawer hits a "wait state", where it has to wait for Update_Enabled
|
||
|
* to toggle, it sets a flag and returns. This flag is checked on entry
|
||
|
* to see if we need to jump to the proper execution point. This should
|
||
|
* improve performance on some platforms.
|
||
|
*
|
||
|
* This routine handles small images by UnVQ'ing into the correct spot on
|
||
|
* the Xmode screen.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long DrawFrame_Xmode(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAConfig *config;
|
||
|
unsigned char *scrn;
|
||
|
long rc;
|
||
|
|
||
|
/* Dereference data members for quick access */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Find the frame to draw */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
|
||
|
/* Dereference current frame for quicker access */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Un-VQ the image */
|
||
|
scrn = GetXHidPage();
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers,
|
||
|
scrn + drawer->ScreenOffset, drawer->BlocksPerRow,
|
||
|
drawer->NumRows, 320);
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(scrn, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Wait for Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
drawer->WaitsOnFlipper++;
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
}
|
||
|
|
||
|
/* Dereference current frame for quicker access */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_XmodeBuf - Draws a frame in Xmode format to a buffer.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_XmodeBuf(VQA)
|
||
|
*
|
||
|
* long DrawFrame_XmodeBuf(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Algorithm:
|
||
|
* - Skip frames
|
||
|
* - UnLCW frame
|
||
|
* - Un-VQ into ImageBuf
|
||
|
* - Copy ImageBuf to video RAM
|
||
|
* - Wait on Update_Enabled
|
||
|
* - Set the Flipper's CurFrame
|
||
|
* - Set Update_Enabled
|
||
|
* - Go to next frame
|
||
|
* - User_Update:
|
||
|
* Flip X-Page
|
||
|
* Set Palette from Flipper.CurFrame
|
||
|
*
|
||
|
* This function implements a sort of cooperative multitasking. If the
|
||
|
* Drawer hits a "wait state", where it has to wait for Update_Enabled
|
||
|
* to toggle, it sets a flag and returns. This flag is checked on entry
|
||
|
* to see if we need to jump to the proper execution point. This should
|
||
|
* improve performance on some platforms.
|
||
|
*
|
||
|
* This routine handles small images by UnVQ'ing into the upper-left
|
||
|
* corner of ImageBuf, then copying ImageBuf into the correct part of the
|
||
|
* Xmode screen.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long DrawFrame_XmodeBuf(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAHeader *header;
|
||
|
VQAConfig *config;
|
||
|
unsigned char *scrn;
|
||
|
long rc;
|
||
|
|
||
|
/* Dereference data members for quicker access */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
header = &((VQAHandleP *)vqa)->Header;
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Find the frame to draw */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
|
||
|
/* Dereference current frame for quicker access. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Un-VQ the image */
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers,
|
||
|
drawer->ImageBuf, drawer->BlocksPerRow, drawer->NumRows,
|
||
|
header->ImageWidth);
|
||
|
|
||
|
/* Copy the buffer */
|
||
|
scrn = GetXHidPage();
|
||
|
|
||
|
if ((header->ImageWidth < 320) || (header->ImageHeight < 200)) {
|
||
|
Xmode_Blit(drawer->ImageBuf, scrn + drawer->ScreenOffset,
|
||
|
header->ImageWidth, header->ImageHeight);
|
||
|
} else {
|
||
|
Xmode_BufferCopy_320x200(drawer->ImageBuf,scrn + drawer->ScreenOffset);
|
||
|
}
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(scrn, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Wait for Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
drawer->WaitsOnFlipper++;
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
}
|
||
|
|
||
|
/* Dereference current frame for quicker access. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_XmodeVRAM - Draws a frame in Xmode with resident Codebook.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_XmodeVRAM(VQA)
|
||
|
*
|
||
|
* long DrawFrame_XmodeVRAM(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Algorithm:
|
||
|
* - Download Codebook if it isn't already (do this before skipping
|
||
|
* frames, so Select_Frame will smooth out the delay)
|
||
|
* - Skip frames
|
||
|
* - UnLCW frame
|
||
|
* - Convert Pointers to VRAM format
|
||
|
* - Un-VQ by copying codebook blocks within VRAM
|
||
|
* - Wait on Update_Enabled
|
||
|
* - Set the Flipper's CurFrame
|
||
|
* - Set Update_Enabled
|
||
|
* - Go to next frame
|
||
|
* - User_Update:
|
||
|
* Flip X-Page
|
||
|
* Set Palette from Flipper.CurFrame
|
||
|
*
|
||
|
* This function implements a sort of cooperative multitasking. If the
|
||
|
* Drawer hits a "wait state", where it has to wait for Update_Enabled
|
||
|
* to toggle, it sets a flag and returns. This flag is checked on entry
|
||
|
* to see if we need to jump to the proper execution point. This should
|
||
|
* improve performance on some platforms.
|
||
|
*
|
||
|
* This routine handles small images by UnVQ'ing into the correct spot on
|
||
|
* the Xmode screen.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long DrawFrame_XmodeVRAM(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAConfig *config;
|
||
|
unsigned char *scrn;
|
||
|
long rc;
|
||
|
|
||
|
/* Dereference data members for quicker access */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Find the frame to draw */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
|
||
|
/* Dereference current frame for quicker access. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Download codebook to VRAM */
|
||
|
if ((curframe->Codebook->Flags & VQACBF_DOWNLOADED) == 0) {
|
||
|
Upload_4x2CB(curframe->Codebook->Buffer,
|
||
|
((VQAHandleP *)vqa)->Header.CBentries
|
||
|
+ ((VQAHandleP *)vqa)->Header.Num1Colors);
|
||
|
|
||
|
curframe->Codebook->Flags |= VQACBF_DOWNLOADED;
|
||
|
}
|
||
|
|
||
|
/* Convert pointers to VRAM format */
|
||
|
XlatePointers(curframe->Pointers, drawer->NumBlocks);
|
||
|
|
||
|
/* Un-VQ the image */
|
||
|
scrn = GetXHidPage();
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers,
|
||
|
scrn + drawer->ScreenOffset, drawer->BlocksPerRow,
|
||
|
drawer->NumRows, 320);
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(scrn, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Wait for Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
drawer->WaitsOnFlipper++;
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
}
|
||
|
|
||
|
/* Dereference current frame for quicker access. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* PageFlip_Xmode - Page flip Xmode display.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* PageFlip_Xmode(VQA)
|
||
|
*
|
||
|
* void PageFlip_Xmode(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static void PageFlip_Xmode(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
unsigned char *pal;
|
||
|
VQAConfig *config;
|
||
|
long palsize;
|
||
|
long slowpal;
|
||
|
|
||
|
/* Dereference commonly used data members for quicker access. */
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
curframe = vqabuf->Flipper.CurFrame;
|
||
|
|
||
|
/* Pre-decode 'vqa' for speed */
|
||
|
pal = curframe->Palette;
|
||
|
palsize = curframe->PaletteSize;
|
||
|
slowpal = (config->OptionFlags & VQAOPTF_SLOWPAL) ? 1 : 0;
|
||
|
|
||
|
/* - If this is a palette-set frame:
|
||
|
* - Wait for NoVB (active scan)
|
||
|
* - Flip the page (doesn't take effect until next active scan
|
||
|
* - Wait for VB
|
||
|
* - Set the palette
|
||
|
* - Otherwise, just flip the page
|
||
|
*/
|
||
|
if (curframe->Flags & VQAFRMF_PALETTE) {
|
||
|
WaitNoVB(vqabuf->VBIBit);
|
||
|
FlipXPage();
|
||
|
WaitVB(vqabuf->VBIBit);
|
||
|
|
||
|
if (!(config->OptionFlags & VQAOPTF_PALOFF)) {
|
||
|
SetPalette(pal, palsize, slowpal);
|
||
|
}
|
||
|
|
||
|
/* Notify the client of the palette change. */
|
||
|
if ((config->NotifyFlags & VQAEVENT_PALETTE)
|
||
|
&& (config->EventHandler != NULL)) {
|
||
|
config->EventHandler(VQAEVENT_PALETTE, (void *)pal, (long)palsize);
|
||
|
}
|
||
|
}
|
||
|
else if (drawer->Flags & VQADRWF_SETPAL) {
|
||
|
drawer->Flags &= (~VQADRWF_SETPAL);
|
||
|
WaitNoVB(vqabuf->VBIBit);
|
||
|
FlipXPage();
|
||
|
WaitVB(vqabuf->VBIBit);
|
||
|
|
||
|
if (!(config->OptionFlags & VQAOPTF_PALOFF)) {
|
||
|
SetPalette(drawer->Palette_24, drawer->CurPalSize, slowpal);
|
||
|
}
|
||
|
|
||
|
/* Notify the client of the palette change. */
|
||
|
if ((config->NotifyFlags & VQAEVENT_PALETTE)
|
||
|
&& (config->EventHandler != NULL)) {
|
||
|
|
||
|
config->EventHandler(VQAEVENT_PALETTE, (void *)drawer->Palette_24,
|
||
|
(long)drawer->CurPalSize);
|
||
|
}
|
||
|
} else {
|
||
|
FlipXPage();
|
||
|
}
|
||
|
}
|
||
|
#endif /* VQAXMODE_ON */
|
||
|
|
||
|
|
||
|
#if(VQAMCGA_ON)
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_MCGA - Draws a frame directly to MCGA screen.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_MCGA(VQA)
|
||
|
*
|
||
|
* long DrawFrame_MCGA(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Algorithm:
|
||
|
* - Skip frames
|
||
|
* - UnLCW frame
|
||
|
* - Wait on Update_Enabled
|
||
|
* - Set Update_Enabled
|
||
|
* - Go to next frame
|
||
|
* - User_Update:
|
||
|
* set palette
|
||
|
* UnVQ to screen
|
||
|
*
|
||
|
* This function implements a sort of cooperative multitasking. If the
|
||
|
* Drawer hits a "wait state", where it has to wait for Update_Enabled
|
||
|
* to toggle, it sets a flag and returns. This flag is checked on entry
|
||
|
* to see if we need to jump to the proper execution point. This should
|
||
|
* improve performance on some platforms.
|
||
|
*
|
||
|
* This routine handles small images by UnVQ'ing into the correct spot on
|
||
|
* the screen.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long DrawFrame_MCGA(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
long rc;
|
||
|
|
||
|
/* Dereference commonly used data members for quicker access */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Select the frame to draw. */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
}
|
||
|
|
||
|
/* Wait for Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
drawer->WaitsOnFlipper++;
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
}
|
||
|
|
||
|
/* Dereference current frame for quicker access. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* PageFlip_MCGA - Page flip MCGA display.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* PageFlip_MCGA(VQA)
|
||
|
*
|
||
|
* long PageFlip_MCGA(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Since the MCGA mode only has one buffer, the drawing is actually done
|
||
|
* at this point.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle structure.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successfull, otherwise VQAERR_???
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long PageFlip_MCGA(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAConfig *config;
|
||
|
unsigned char *pal;
|
||
|
unsigned char *ptrs;
|
||
|
unsigned char *cb;
|
||
|
long palsize;
|
||
|
long slowpal;
|
||
|
long blocksperrow;
|
||
|
long numrows;
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
unsigned char *scrn;
|
||
|
#else
|
||
|
FARPTR scrn;
|
||
|
#endif
|
||
|
|
||
|
/* Dereference commonly used data members for quicker access. */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
curframe = vqabuf->Flipper.CurFrame;
|
||
|
|
||
|
/*-------------------------------------------------------------------------
|
||
|
* WAIT FOR THE VERTICAL BLANK TO SET THE PALETTE.
|
||
|
*-----------------------------------------------------------------------*/
|
||
|
if ((curframe->Flags & VQAFRMF_PALETTE)
|
||
|
|| (drawer->Flags & VQADRWF_SETPAL)) {
|
||
|
|
||
|
pal = curframe->Palette;
|
||
|
palsize = curframe->PaletteSize;
|
||
|
slowpal = (config->OptionFlags & VQAOPTF_SLOWPAL) ? 1 : 0;
|
||
|
|
||
|
/* Wait for the VBlank. */
|
||
|
WaitNoVB(vqabuf->VBIBit);
|
||
|
WaitVB(vqabuf->VBIBit);
|
||
|
|
||
|
/* Set the palette. */
|
||
|
if (curframe->Flags & VQAFRMF_PALETTE) {
|
||
|
if (!(config->OptionFlags & VQAOPTF_PALOFF)) {
|
||
|
SetPalette(pal, palsize, slowpal);
|
||
|
}
|
||
|
|
||
|
/* Notify the client of the palette change. */
|
||
|
if ((config->NotifyFlags & VQAEVENT_PALETTE)
|
||
|
&& (config->EventHandler != NULL)) {
|
||
|
|
||
|
config->EventHandler(VQAEVENT_PALETTE, (void *)pal, (long)palsize);
|
||
|
}
|
||
|
}
|
||
|
else if (drawer->Flags & VQADRWF_SETPAL) {
|
||
|
drawer->Flags &= (~VQADRWF_SETPAL);
|
||
|
|
||
|
if (!(config->OptionFlags & VQAOPTF_PALOFF)) {
|
||
|
SetPalette(drawer->Palette_24, drawer->CurPalSize, slowpal);
|
||
|
}
|
||
|
|
||
|
/* Notify the client of the palette change. */
|
||
|
if ((config->NotifyFlags & VQAEVENT_PALETTE)
|
||
|
&& (config->EventHandler != NULL)) {
|
||
|
|
||
|
config->EventHandler(VQAEVENT_PALETTE, (void *)drawer->Palette_24,
|
||
|
(long)drawer->CurPalSize);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/*-------------------------------------------------------------------------
|
||
|
* UNVQ THE FRAME DIRECTLY TO THE MCGA SCREEN.
|
||
|
*-----------------------------------------------------------------------*/
|
||
|
|
||
|
/* Get screen address, blocks per row and number of rows. */
|
||
|
#ifndef PHARLAP_TNT
|
||
|
scrn = (unsigned char *)(0xA0000 + (unsigned long)drawer->ScreenOffset);
|
||
|
#else
|
||
|
FP_SET(scrn, drawer->ScreenOffset, 0x1C);
|
||
|
#endif
|
||
|
|
||
|
blocksperrow = drawer->BlocksPerRow;
|
||
|
numrows = drawer->NumRows;
|
||
|
ptrs = curframe->Pointers;
|
||
|
cb = curframe->Codebook->Buffer;
|
||
|
vqabuf->UnVQ(cb, ptrs, scrn, blocksperrow, numrows, 320);
|
||
|
|
||
|
#if(VQACAPTIONS_ON)
|
||
|
/* Process captions. */
|
||
|
if ((((VQAHandleP *)vqa)->Caption != NULL)
|
||
|
&& (config->OptionFlags & VQAOPTF_CAPTIONS)) {
|
||
|
DoCaptions(((VQAHandleP *)vqa)->Caption, curframe->FrameNum);
|
||
|
}
|
||
|
|
||
|
if ((((VQAHandleP *)vqa)->EVA != NULL)
|
||
|
&& (config->OptionFlags & VQAOPTF_EVA)) {
|
||
|
DoCaptions(((VQAHandleP *)vqa)->EVA, curframe->FrameNum);
|
||
|
}
|
||
|
|
||
|
#endif
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(NULL, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_MCGABuf - Draws a frame in MCGA format to a buffer.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_MCGABuf(VQA)
|
||
|
*
|
||
|
* long DrawFrame_MCGABuf(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
* Algorithm:
|
||
|
* - Skip frames
|
||
|
* - UnLCW frame
|
||
|
* - Wait on Update_Enabled (can't use imgbuf til User_Update's done)
|
||
|
* - Un-VQ into ImageBuf
|
||
|
* - Set the Flipper's CurFrame
|
||
|
* - Set Update_Enabled
|
||
|
* - Go to next frame
|
||
|
* - User_Update:
|
||
|
* set Palette from Flipper.CurFrame
|
||
|
* copy ImageBuf to screen
|
||
|
*
|
||
|
* This function implements a sort of cooperative multitasking. If the
|
||
|
* Drawer hits a "wait state", where it has to wait for Update_Enabled
|
||
|
* to toggle, it sets a flag and returns. This flag is checked on entry
|
||
|
* to see if we need to jump to the proper execution point. This should
|
||
|
* improve performance on some platforms.
|
||
|
*
|
||
|
* This routine handles small images by UnVQ'ing into the upper-left
|
||
|
* corner of ImageBuf, then copying ImageBuf onto the screen.
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long DrawFrame_MCGABuf(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
long rc;
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
unsigned char *scrn;
|
||
|
#else
|
||
|
FARPTR scrn;
|
||
|
#endif
|
||
|
|
||
|
/* Dereference commonly used data members for quicker access. */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Find the frame to draw */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
}
|
||
|
|
||
|
/* Wait for Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
drawer->WaitsOnFlipper++;
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
}
|
||
|
|
||
|
/* Dereference current frame for quicker access. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
scrn = drawer->ImageBuf;
|
||
|
#else
|
||
|
FP_SET(scrn, drawer->ImageBuf, 0x14);
|
||
|
#endif
|
||
|
|
||
|
/* Un-VQ the image */
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers, scrn,
|
||
|
drawer->BlocksPerRow, drawer->NumRows,
|
||
|
((VQAHandleP *)vqa)->Header.ImageWidth);
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* PageFlip_MCGABuf - Page flip a buffered MCGA display.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* PageFlip_MCGABuf(VQA)
|
||
|
*
|
||
|
* void PageFlip_MCGABuf(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successfull, otherwise VQAERR_???
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long PageFlip_MCGABuf(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAConfig *config;
|
||
|
unsigned char *pal;
|
||
|
unsigned char *buf;
|
||
|
unsigned char *scrn;
|
||
|
long palsize;
|
||
|
long slowpal;
|
||
|
long imgwidth;
|
||
|
long imgheight;
|
||
|
|
||
|
/* Derefernce commonly used data members for quicker access. */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
curframe = vqabuf->Flipper.CurFrame;
|
||
|
|
||
|
/* Pre-decode 'vqa' for speed */
|
||
|
pal = curframe->Palette;
|
||
|
palsize = curframe->PaletteSize;
|
||
|
slowpal = (config->OptionFlags & VQAOPTF_SLOWPAL) ? 1 : 0;
|
||
|
|
||
|
/* - If this is a palette-set frame:
|
||
|
* - Wait for the vertical blank
|
||
|
* - Set the palette
|
||
|
* - Copy ImageBuf to SEENPAGE:
|
||
|
* - use blit routine if image is smaller than full-screen, since the
|
||
|
* buffer copy assumes a full-screen image
|
||
|
*/
|
||
|
if (curframe->Flags & VQAFRMF_PALETTE) {
|
||
|
WaitNoVB(vqabuf->VBIBit);
|
||
|
WaitVB(vqabuf->VBIBit);
|
||
|
|
||
|
if (!(config->OptionFlags & VQAOPTF_PALOFF)) {
|
||
|
SetPalette(pal, palsize, slowpal);
|
||
|
}
|
||
|
|
||
|
/* Notify the client of the palette change. */
|
||
|
if ((config->NotifyFlags & VQAEVENT_PALETTE)
|
||
|
&& (config->EventHandler != NULL)) {
|
||
|
|
||
|
config->EventHandler(VQAEVENT_PALETTE, (void *)pal, (long)palsize);
|
||
|
}
|
||
|
}
|
||
|
else if (drawer->Flags & VQADRWF_SETPAL) {
|
||
|
drawer->Flags &= (~VQADRWF_SETPAL);
|
||
|
WaitNoVB(vqabuf->VBIBit);
|
||
|
WaitVB(vqabuf->VBIBit);
|
||
|
|
||
|
if (!(config->OptionFlags & VQAOPTF_PALOFF)) {
|
||
|
SetPalette(drawer->Palette_24, drawer->CurPalSize, slowpal);
|
||
|
}
|
||
|
|
||
|
/* Notify the client of the palette change. */
|
||
|
if ((config->NotifyFlags & VQAEVENT_PALETTE)
|
||
|
&& (config->EventHandler != NULL)) {
|
||
|
|
||
|
config->EventHandler(VQAEVENT_PALETTE, (void *)drawer->Palette_24,
|
||
|
(long)drawer->CurPalSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Draw image to the screen. */
|
||
|
imgwidth = ((VQAHandleP *)vqa)->Header.ImageWidth;
|
||
|
imgheight = ((VQAHandleP *)vqa)->Header.ImageHeight;
|
||
|
buf = drawer->ImageBuf;
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
scrn = (unsigned char *)0xA0000;
|
||
|
#endif
|
||
|
|
||
|
if ((imgwidth < 320) || (imgheight < 200)) {
|
||
|
#ifndef PHARLAP_TNT
|
||
|
scrn += drawer->ScreenOffset;
|
||
|
#else
|
||
|
scrn = (unsigned char *)drawer->ScreenOffset;
|
||
|
#endif
|
||
|
|
||
|
MCGA_Blit(buf, scrn, imgwidth, imgheight);
|
||
|
} else {
|
||
|
MCGA_BufferCopy(buf, NULL);
|
||
|
}
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(NULL, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
#endif /* VQAMCGA_ON */
|
||
|
|
||
|
|
||
|
#if(VQAVESA_ON)
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_VESA640 - Draws a frame in VESA 640 format.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_VESA640(VQA)
|
||
|
*
|
||
|
* long DrawFrame_VESA640(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long DrawFrame_VESA640(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
long rc;
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
unsigned char *scrn;
|
||
|
#else
|
||
|
FARPTR scrn;
|
||
|
#endif
|
||
|
|
||
|
/* Dereference data members for quicker access. */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Find the frame to draw */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
}
|
||
|
|
||
|
/* Dereference current frame. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Wait for Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
vqabuf->Drawer.WaitsOnFlipper++;
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
}
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
scrn = drawer->ImageBuf + drawer->ScreenOffset;
|
||
|
#else
|
||
|
FP_SET(scrn, drawer->ImageBuf + drawer->ScreenOffset, 0x14);
|
||
|
#endif
|
||
|
|
||
|
/* Un-VQ the image */
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers, scrn,
|
||
|
drawer->BlocksPerRow, drawer->NumRows, drawer->ImageWidth);
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_VESA320_32K - Draws a frame in VESA 320 format.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_VESA320_32K(VQA)
|
||
|
*
|
||
|
* long DrawFrame_VESA320_32K(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long DrawFrame_VESA320_32K(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAConfig *config;
|
||
|
long rc;
|
||
|
long grain;
|
||
|
|
||
|
/* Dereference data members for quicker access. */
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Find the frame to draw */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
|
||
|
/* Dereference current frame. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Translate palette to 15-bit */
|
||
|
if (curframe->Flags & VQAFRMF_PALETTE) {
|
||
|
TranslatePalette(curframe->Palette, drawer->Palette_15,
|
||
|
curframe->PaletteSize);
|
||
|
}
|
||
|
else if (drawer->Flags & VQADRWF_SETPAL) {
|
||
|
TranslatePalette(drawer->Palette_24, drawer->Palette_15,
|
||
|
drawer->CurPalSize);
|
||
|
}
|
||
|
|
||
|
/* UnVQ directly to screen */
|
||
|
grain = ((VESAModeInfo *)(drawer->Display->Extended))->WinSize
|
||
|
/ ((VESAModeInfo *)(drawer->Display->Extended))->WinGranularity;
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers,
|
||
|
drawer->Palette_15, grain, 0, 0);
|
||
|
#else
|
||
|
{
|
||
|
FARPTR temp;
|
||
|
|
||
|
FP_SET(temp, drawer->Palette_15, 0x14);
|
||
|
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers, temp,
|
||
|
grain, 0, 0);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(0, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Wait for VQ_Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
drawer->WaitsOnFlipper++;
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
}
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_VESA320_32KBuf - Draws a frame in VESA320_32K format to a
|
||
|
* buffer.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_VESA320_32KBuf(VQA)
|
||
|
*
|
||
|
* long DrawFrame_VESA320_32KBuf(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, or VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long DrawFrame_VESA320_32KBuf(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAConfig *config;
|
||
|
long rc;
|
||
|
long grain;
|
||
|
|
||
|
/* Dereference data members for quicker access. */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Find the frame to draw */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
|
||
|
/* UnVQ buffered mode */
|
||
|
#ifndef PHARLAP_TNT
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers,
|
||
|
drawer->ImageBuf, drawer->BlocksPerRow, drawer->NumRows,
|
||
|
((VQAHandleP *)vqa)->Header.image_width);
|
||
|
#else
|
||
|
{
|
||
|
FARPTR scrn;
|
||
|
|
||
|
FP_SET(scrn, drawer->ImageBuf, 0x14);
|
||
|
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers, scrn,
|
||
|
drawer->BlocksPerRow, drawer->NumRows,
|
||
|
((VQAHandleP *)vqa)->Header.image_width);
|
||
|
}
|
||
|
#endif
|
||
|
|
||
|
/* Translate the palette to 15-bit */
|
||
|
if (curframe->Flags & VQAFRMF_PALETTE) {
|
||
|
TranslatePalette(curframe->Palette, drawer->Palette_15,
|
||
|
curframe->PaletteSize);
|
||
|
}
|
||
|
else if (drawer->Flags & VQADRWF_SETPAL) {
|
||
|
TranslatePalette(drawer->Palette_24, drawer->Palette_15,
|
||
|
drawer->CurPalSize);
|
||
|
}
|
||
|
|
||
|
/* Copy the buffer */
|
||
|
grain = ((VESAModeInfo *)(drawer->Display->Extended))->WinSize
|
||
|
/ ((VESAModeInfo *)(drawer->Display->Extended))->WinGranularity;
|
||
|
|
||
|
Buf_320x200_To_VESA_32K(drawer->ImageBuf, drawer->Palette_15, grain);
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(0, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Wait for Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
drawer->WaitsOnFlipper++;
|
||
|
}
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* PageFlip_VESA - Page flip VESA display.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* PageFlip_VESA(VQA)
|
||
|
*
|
||
|
* void PageFlip_VESA(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQAHandle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static void PageFlip_VESA(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAConfig *config;
|
||
|
unsigned char *pal;
|
||
|
long palsize;
|
||
|
long slowpal;
|
||
|
long grain;
|
||
|
|
||
|
/* Dereference date members for quicker access. */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
curframe = vqabuf->Flipper.CurFrame;
|
||
|
|
||
|
/* Pre-decode 'vqa' for speed */
|
||
|
pal = curframe->Palette;
|
||
|
palsize = curframe->PaletteSize;
|
||
|
slowpal = (config->OptionFlags & VQAOPTF_SLOWPAL) ? 1 : 0;
|
||
|
|
||
|
/* Set the palette */
|
||
|
if (curframe->Flags & VQAFRMF_PALETTE) {
|
||
|
WaitNoVB(vqabuf->VBIBit);
|
||
|
WaitVB(vqabuf->VBIBit);
|
||
|
|
||
|
if (!(config->OptionFlags & VQAOPTF_PALOFF)) {
|
||
|
SetPalette(pal, palsize, slowpal);
|
||
|
}
|
||
|
|
||
|
/* Notify the client of the palette change. */
|
||
|
if ((config->NotifyFlags & VQAEVENT_PALETTE)
|
||
|
&& (config->EventHandler != NULL)) {
|
||
|
|
||
|
config->EventHandler(VQAEVENT_PALETTE, (void *)pal, (long)palsize);
|
||
|
}
|
||
|
}
|
||
|
else if (drawer->Flags & VQADRWF_SETPAL) {
|
||
|
drawer->Flags &= (~VQADRWF_SETPAL);
|
||
|
WaitNoVB(vqabuf->VBIBit);
|
||
|
WaitVB(vqabuf->VBIBit);
|
||
|
|
||
|
if (!(config->OptionFlags & VQAOPTF_PALOFF)) {
|
||
|
SetPalette(drawer->Palette_24, drawer->CurPalSize, slowpal);
|
||
|
}
|
||
|
|
||
|
/* Notify the client of the palette change. */
|
||
|
if ((config->NotifyFlags & VQAEVENT_PALETTE)
|
||
|
&& (config->EventHandler != NULL)) {
|
||
|
|
||
|
config->EventHandler(VQAEVENT_PALETTE, (void *)drawer->Palette_24,
|
||
|
(long)drawer->CurPalSize);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Copy the buffer */
|
||
|
grain = ((VESAModeInfo *)(drawer->Display->Extended))->WinSize
|
||
|
/ ((VESAModeInfo *)(drawer->Display->Extended))->WinGranularity;
|
||
|
|
||
|
switch (((VQAHandleP *)vqa)->Header.image_width) {
|
||
|
case 320:
|
||
|
if (config->DrawFlags & VQACFGF_SCALEX2) {
|
||
|
Buf_320x200_To_VESA_640x400(drawer->ImageBuf, grain);
|
||
|
} else {
|
||
|
Buf_320x200_To_VESA_320x200(drawer->ImageBuf, grain);
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
VESA_Blit_640x480(drawer->Display, drawer->ImageBuf, drawer->X1,
|
||
|
drawer->Y1, ((VQAHandleP *)vqa)->Header.image_width,
|
||
|
((VQAHandleP *)vqa)->Header.image_height);
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(drawer->ImageBuf, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
#endif /* VQAVESA_ON */
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* DrawFrame_Buffer - Draw a frame to a buffer.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Error = DrawFrame_Buffer(VQA)
|
||
|
*
|
||
|
* long DrawFrame_Buffere(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQA handle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* Error - 0 if successful, otherwise VQAERR_??? error code.
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
extern void __cdecl Set_Palette(void *palette);
|
||
|
extern void Flag_To_Set_Palette(unsigned char *palette,long numbytes,unsigned long slowpal);
|
||
|
static long DrawFrame_Buffer(VQAHandle *vqa)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
VQAConfig *config;
|
||
|
long rc;
|
||
|
unsigned char *pal;
|
||
|
long palsize;
|
||
|
long slowpal;
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
unsigned char *buff;
|
||
|
#else
|
||
|
FARPTR buff;
|
||
|
#endif
|
||
|
|
||
|
/* Dereference data members for quicker access. */
|
||
|
config = &((VQAHandleP *)vqa)->Config;
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
|
||
|
/* Check our "sleep" state */
|
||
|
if (!(vqabuf->Flags & VQADATF_DSLEEP)) {
|
||
|
|
||
|
/* Find the frame to draw */
|
||
|
if ((rc = Select_Frame((VQAHandleP *)vqa)) != 0) {
|
||
|
return (rc);
|
||
|
}
|
||
|
|
||
|
/* Uncompress the frame data */
|
||
|
Prepare_Frame(vqabuf);
|
||
|
}
|
||
|
|
||
|
/* Wait for Update_Enabled to be set low */
|
||
|
if (vqabuf->Flags & VQADATF_UPDATE) {
|
||
|
vqabuf->Flags |= VQADATF_DSLEEP;
|
||
|
return (VQAERR_SLEEPING);
|
||
|
}
|
||
|
|
||
|
if (vqabuf->Flags & VQADATF_DSLEEP) {
|
||
|
drawer->WaitsOnFlipper++;
|
||
|
vqabuf->Flags &= (~VQADATF_DSLEEP);
|
||
|
}
|
||
|
|
||
|
/* Dereference current frame for quicker access. */
|
||
|
curframe = drawer->CurFrame;
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
buff = (unsigned char *)(drawer->ImageBuf + drawer->ScreenOffset);
|
||
|
#else
|
||
|
FP_SET(buff, drawer->ImageBuf + drawer->ScreenOffset, 0x14);
|
||
|
#endif
|
||
|
|
||
|
|
||
|
pal = curframe->Palette;
|
||
|
palsize = curframe->PaletteSize;
|
||
|
slowpal = (config->OptionFlags & VQAOPTF_SLOWPAL) ? 1 : 0;
|
||
|
|
||
|
/* Set the palette if neccessary */
|
||
|
if ((curframe->Flags & VQAFRMF_PALETTE)
|
||
|
|| (drawer->Flags & VQADRWF_SETPAL)) {
|
||
|
Flag_To_Set_Palette(pal, palsize, slowpal);
|
||
|
curframe->Flags &= ~VQAFRMF_PALETTE;
|
||
|
drawer->Flags &= ~VQADRWF_SETPAL;
|
||
|
}
|
||
|
|
||
|
|
||
|
/* Un-VQ the image */
|
||
|
vqabuf->UnVQ(curframe->Codebook->Buffer, curframe->Pointers, buff,
|
||
|
drawer->BlocksPerRow, drawer->NumRows, drawer->ImageWidth);
|
||
|
|
||
|
/* Update data for mono output */
|
||
|
drawer->LastFrameNum = curframe->FrameNum;
|
||
|
|
||
|
/* Tell the flipper which frame to use */
|
||
|
vqabuf->Flipper.CurFrame = curframe;
|
||
|
|
||
|
/* Set the page-avail flag for the flipper */
|
||
|
vqabuf->Flags |= VQADATF_UPDATE;
|
||
|
|
||
|
/* Invoke user's callback routine */
|
||
|
if (config->DrawerCallback != NULL) {
|
||
|
if ((config->DrawerCallback(drawer->ImageBuf, curframe->FrameNum)) != 0) {
|
||
|
return (VQAERR_EOF);
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* Move to the next frame */
|
||
|
drawer->CurFrame = curframe->Next;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* UnVQ_Nop - Do nothing UnVQ.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* UnVQ_Nop(Codebook, Pointers, Buffer, BPR, Rows, BufWidth)
|
||
|
*
|
||
|
* void UnVQ_Nop(unsigned char *, unsigned char *, unsigned char *,
|
||
|
* unsigned long, unsigned long, unsigned long);
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* Codebook - Not used. (Prototype placeholder)
|
||
|
* Pointers - Not used. (Prototype placeholder)
|
||
|
* Buffer - Not used. (Prototype placeholder)
|
||
|
* BPR - Not used. (Prototype placeholder)
|
||
|
* Rows - Not used. (Prototype placeholder)
|
||
|
* BufWidth - Not used. (Prototype placeholder)
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
#ifndef PHARLAP_TNT
|
||
|
static void __cdecl UnVQ_Nop(unsigned char *codebook, unsigned char *pointers,
|
||
|
unsigned char *buffer, unsigned long blocksperrow,
|
||
|
unsigned long numrows, unsigned long bufwidth)
|
||
|
#else
|
||
|
static void __cdecl UnVQ_Nop(unsigned char *codebook, unsigned char *pointers,
|
||
|
FARPTR buffer, unsigned long blocksperrow, unsigned long numrows,
|
||
|
unsigned long bufwidth)
|
||
|
#endif
|
||
|
{
|
||
|
/* Suppress compiler warnings */
|
||
|
codebook = codebook;
|
||
|
pointers = pointers;
|
||
|
buffer = buffer;
|
||
|
blocksperrow = blocksperrow;
|
||
|
numrows = numrows;
|
||
|
bufwidth = bufwidth;
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* PageFlip_Nop - Do nothing page flip.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* PageFlip_Nop(VQA)
|
||
|
*
|
||
|
* void PageFlip_Nop(VQAHandle *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQA handle.
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static long PageFlip_Nop(VQAHandle *vqa)
|
||
|
{
|
||
|
vqa = vqa;
|
||
|
|
||
|
return (0);
|
||
|
}
|
||
|
|
||
|
|
||
|
#if(0)
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* Mask_Rect - Sets non-drawable rectangle in image.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Mask_Rect(VQA, X1, Y1, X2, Y2)
|
||
|
*
|
||
|
* void Mask_Rect(VQAHandle *, unsigned long, unsigned long,
|
||
|
* unsigned long, unsigned long);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQA - Pointer to VQA handle.
|
||
|
* X1 - X coordinate of upper-left corner
|
||
|
* Y1 - Y coordinate of upper-left corner
|
||
|
* X2 - X coordinate of lower-right corner
|
||
|
* Y2 - Y coordinate of lower-right corner
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static void Mask_Rect(VQAHandle *vqa, unsigned long x1, unsigned long y1,
|
||
|
unsigned long x2, unsigned long y2)
|
||
|
{
|
||
|
VQAData *vqabuf;
|
||
|
VQADrawer *drawer;
|
||
|
VQAHeader *header;
|
||
|
long blocks_per_row;
|
||
|
|
||
|
/* Dereference data members for quicker access. */
|
||
|
vqabuf = ((VQAHandleP *)vqa)->VQABuf;
|
||
|
header = &((VQAHandleP *)vqa)->Header;
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
|
||
|
/* Clip coords to image size */
|
||
|
if (x1 < vqabuf->Drawer.X1) {
|
||
|
x1 = vqabuf->Drawer.X1;
|
||
|
}
|
||
|
|
||
|
if (y1 < vqabuf->Drawer.Y1) {
|
||
|
y1 = vqabuf->Drawer.Y1;
|
||
|
}
|
||
|
|
||
|
if (x2 > vqabuf->Drawer.X2) {
|
||
|
x2 = vqabuf->Drawer.X2;
|
||
|
}
|
||
|
|
||
|
if (y2 > vqabuf->Drawer.Y2) {
|
||
|
y2 = vqabuf->Drawer.Y2;
|
||
|
}
|
||
|
|
||
|
/* Convert pixel coords to block coords */
|
||
|
x1 /= header->block_width;
|
||
|
x2 /= header->block_width;
|
||
|
y1 /= header->block_height;
|
||
|
y2 /= header->block_height;
|
||
|
|
||
|
/* Compute the mask values */
|
||
|
blocks_per_row = (header->image_width / header->block_width);
|
||
|
vqabuf->Drawer.MaskStart = blocks_per_row * y1 + x1;
|
||
|
|
||
|
if (x1 == x2) {
|
||
|
drawer->MaskWidth = 0;
|
||
|
} else {
|
||
|
drawer->MaskWidth = x2 - x1 + 1;
|
||
|
}
|
||
|
|
||
|
if (y1 == y2) {
|
||
|
drawer->MaskHeight = 0;
|
||
|
} else {
|
||
|
drawer->MaskHeight = y2 - y1 + 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
/****************************************************************************
|
||
|
*
|
||
|
* NAME
|
||
|
* Mask_Pointers - Mask vector pointer that are in the mask rectangle.
|
||
|
*
|
||
|
* SYNOPSIS
|
||
|
* Mask_Pointers(VQAData)
|
||
|
*
|
||
|
* void Mask_Pointers(VQAData *);
|
||
|
*
|
||
|
* FUNCTION
|
||
|
*
|
||
|
* INPUTS
|
||
|
* VQAData - Pointer to VQAData structure.
|
||
|
*
|
||
|
* RESULT
|
||
|
* NONE
|
||
|
*
|
||
|
****************************************************************************/
|
||
|
|
||
|
static void Mask_Pointers(VQAData *vqabuf)
|
||
|
{
|
||
|
VQADrawer *drawer;
|
||
|
VQAFrameNode *curframe;
|
||
|
unsigned long *ptr;
|
||
|
unsigned long i,j;
|
||
|
unsigned long start;
|
||
|
|
||
|
/* Dereference data members for quicker access. */
|
||
|
drawer = &vqabuf->Drawer;
|
||
|
curframe = drawer->CurFrame;
|
||
|
start = vqabuf->Drawer.MaskStart;
|
||
|
|
||
|
for (i = 0; i < drawer->MaskHeight; i++) {
|
||
|
ptr = (unsigned long *)(curframe->Pointers) + start;
|
||
|
|
||
|
for (j = 0; j < drawer->MaskWidth; j++) {
|
||
|
ptr[j] = VQA_MASK_POINTER;
|
||
|
}
|
||
|
|
||
|
start += drawer->BlocksPerRow;
|
||
|
}
|
||
|
}
|
||
|
#endif
|
||
|
|