1
0
Fork 0
forked from len0rd/rockbox
foxbox/apps/plugins/sdl/progs/duke3d/Game/src/animlib.c
Franklin Wei a855d62025 Port of Duke Nukem 3D
This ports Fabien Sanglard's Chocolate Duke to run on a version of SDL
for Rockbox.

Change-Id: I8f2c4c78af19de10c1633ed7bb7a997b43256dd9
2017-12-23 21:01:26 -05:00

352 lines
9.1 KiB
C

//-------------------------------------------------------------------------
/*
Copyright (C) 1996, 2003 - 3D Realms Entertainment
This file is part of Duke Nukem 3D version 1.5 - Atomic Edition
Duke Nukem 3D 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.
You should have received a copy of the GNU General Public License
aint32_t with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
Original Source: 1996 - Todd Replogle
Prepared for public release: 03/21/2003 - Charlie Wiederhold, 3D Realms
*/
//-------------------------------------------------------------------------
#include <SDL.h>
#include "types.h"
#include "develop.h"
#include "util_lib.h"
//#include "_animlib.h"
#include "animlib.h"
//****************************************************************************
//
// GLOBALS
//
//****************************************************************************
//****************************************************************************
//
// LOCALS
//
//****************************************************************************
anim_t * anim=NULL;
static boolean Anim_Started = false;
//****************************************************************************
//
// CheckAnimStarted ()
//
//****************************************************************************
void CheckAnimStarted ( char * funcname )
{
if (!Anim_Started)
Error(EXIT_FAILURE, "ANIMLIB_%s: Anim has not been initialized\n",funcname);
}
//****************************************************************************
//
// findpage ()
// - given a frame number return the large page number it resides in
//
//****************************************************************************
uint16 findpage (uint16 framenumber)
{
uint16 i;
CheckAnimStarted ( "findpage" );
for(i=0; i<anim->lpheader.nLps; i++)
{
if
(
anim->LpArray[i].baseRecord <= framenumber &&
anim->LpArray[i].baseRecord + anim->LpArray[i].nRecords > framenumber
)
return(i);
}
return(i);
}
//****************************************************************************
//
// loadpage ()
// - seek out and load in the large page specified
//
//****************************************************************************
void loadpage (uint16 pagenumber, uint16 *pagepointer)
{
int32 size;
byte * buffer;
CheckAnimStarted ( "loadpage" );
buffer = anim->buffer;
if (anim->curlpnum != pagenumber)
{
anim->curlpnum = pagenumber;
buffer += 0xb00 + (pagenumber*0x10000);
size = sizeof(lp_descriptor);
memcpy(&anim->curlp,buffer,size);
buffer += size + sizeof(uint16);
memcpy(pagepointer,buffer,anim->curlp.nBytes+(anim->curlp.nRecords*2));
}
}
//****************************************************************************
//
// CPlayRunSkipDump ()
// - This version of the decompressor is here for portability to non PC's
//
//****************************************************************************
void CPlayRunSkipDump (byte *srcP, byte *dstP)
{
int8_t cnt;
uint16 wordCnt;
byte pixel;
nextOp:
cnt = (int8_t ) *srcP++;
//printf("op %d", cnt);
if (cnt > 0)
goto dump; /* dump following bytes */
if (cnt == 0)
goto run; /* repeating sequence */
cnt -= 0x80;
if (cnt == 0)
goto longOp;
/* shortSkip */
dstP += cnt; /* adding 7-bit count to 32-bit pointer */
goto nextOp;
dump:
do
{
*dstP++ = *srcP++;
} while (--cnt);
goto nextOp;
run:
wordCnt = (byte)*srcP++; /* 8-bit unsigned count */
pixel = *srcP++;
do
{
*dstP++ = pixel;
} while (--wordCnt);
goto nextOp;
longOp:
//printf("longop");
//wordCnt = *((uint16 *)srcP);
wordCnt = *srcP | (*(srcP+1) << 8);
srcP += sizeof(uint16);
if ((int16)wordCnt <= 0)
goto notLongSkip; /* Do SIGNED test. */
/* longSkip. */
dstP += wordCnt;
goto nextOp;
notLongSkip:
if (wordCnt == 0)
goto stop;
wordCnt -= 0x8000; /* Remove sign bit. */
if (wordCnt >= 0x4000)
goto longRun;
/* longDump. */
do
{
*dstP++ = *srcP++;
} while (--wordCnt);
goto nextOp;
longRun:
wordCnt -= 0x4000; /* Clear "longRun" bit. */
pixel = *srcP++;
do
{
*dstP++ = pixel;
} while (--wordCnt);
goto nextOp;
stop: /* all done */
;
}
//****************************************************************************
//
// renderframe ()
// - draw the frame sepcified from the large page in the buffer pointed to
//
//****************************************************************************
void renderframe (uint16 framenumber, uint16 *pagepointer)
{
uint16 offset=0;
uint16 i;
uint16 destframe;
byte *ppointer;
CheckAnimStarted ( "renderframe" );
destframe = framenumber - anim->curlp.baseRecord;
for(i = 0; i < destframe; i++)
offset += readLE16(pagepointer + i);
ppointer = (byte *)pagepointer;
ppointer+=anim->curlp.nRecords*2+offset;
//rb->splash(HZ, "point 1");
if(ppointer[1])
{
ppointer += 4;
uint16_t val = readLE16(ppointer + 2);
//rb->splashf(HZ, "val=%d", val);
ppointer += val + (val & 1);
//uint16_t val = readLE16(((uint16_t*)ppointer) + 1);
//ppointer += (4 + ( ( val + (val & 1 ))));
}
else
ppointer+=4;
//rb->splashf(HZ, "point 2 (d = %d)", (char*)ppointer - (char*)pagepointer);
CPlayRunSkipDump (ppointer, anim->imagebuffer);
}
//****************************************************************************
//
// drawframe ()
// - high level frame draw routine
//
//****************************************************************************
void drawframe (uint16 framenumber)
{
//rb->splashf(HZ, "draw %d", framenumber);
CheckAnimStarted ( "drawframe" );
loadpage(findpage(framenumber), anim->thepage);
//rb->splashf(HZ, "page: %08x", crc32(anim->thepage, sizeof(anim->thepage)));
renderframe(framenumber, anim->thepage);
//rb->splashf(HZ, "image: %08x", crc32(anim->imagebuffer, sizeof(anim->imagebuffer)));
}
//****************************************************************************
//
// ANIM_LoadAnim ()
//
//****************************************************************************
void ANIM_LoadAnim (byte * buffer)
{
uint16 i;
int32 size;
if (!Anim_Started) Anim_Started = true;
anim->buffer = buffer;
anim->curlpnum = 0xffff;
anim->currentframe = -1;
size = sizeof(lpfileheader);
assert(sizeof(lpfileheader) == 128);
assert(sizeof(lp_descriptor) == 6);
assert(sizeof(anim->LpArray) == 1536);
memcpy(&anim->lpheader, buffer, size );
buffer += size+128;
// load the color palette
for (i = 0; i < 768; i += 3)
{
anim->pal[i+2] = *buffer++;
anim->pal[i+1] = *buffer++;
anim->pal[i] = *buffer++;
buffer++;
}
// read in large page descriptors
size = sizeof(anim->LpArray);
memcpy(&anim->LpArray,buffer,size);
}
//****************************************************************************
//
// ANIM_FreeAnim ()
//
//****************************************************************************
void ANIM_FreeAnim ( void )
{
if (Anim_Started)
{
// SafeFree(anim);
Anim_Started = false;
}
}
//****************************************************************************
//
// ANIM_NumFrames ()
//
//****************************************************************************
int32 ANIM_NumFrames ( void )
{
CheckAnimStarted ( "NumFrames" );
return anim->lpheader.nRecords;
}
//****************************************************************************
//
// ANIM_DrawFrame ()
//
//****************************************************************************
byte * ANIM_DrawFrame (int32 framenumber)
{
int32 cnt;
CheckAnimStarted ( "DrawFrame" );
if ((anim->currentframe != -1) && (anim->currentframe<=framenumber))
{
for (cnt = anim->currentframe; cnt < framenumber; cnt++)
drawframe (cnt);
}
else
{
for (cnt = 0; cnt < framenumber; cnt++)
drawframe (cnt);
}
anim->currentframe = framenumber;
return anim->imagebuffer;
}
//****************************************************************************
//
// ANIM_GetPalette ()
//
//****************************************************************************
byte * ANIM_GetPalette ( void )
{
CheckAnimStarted ( "GetPalette" );
return anim->pal;
}