- cleanup of animlib.

* operate on a parameter-specified data structure instead of a global one
* moved error checks into the library code.
This commit is contained in:
Christoph Oelckers 2020-06-27 11:47:31 +02:00
parent 34c3838e62
commit e0ad1aa0cd
5 changed files with 47 additions and 74 deletions

View file

@ -35,8 +35,6 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
// //
//**************************************************************************** //****************************************************************************
static anim_t * anim = NULL;
//**************************************************************************** //****************************************************************************
// //
// findpage () // findpage ()
@ -44,7 +42,7 @@ static anim_t * anim = NULL;
// //
//**************************************************************************** //****************************************************************************
static inline uint16_t findpage(uint16_t framenumber) static inline uint16_t findpage(anim_t *anim, uint16_t framenumber)
{ {
// curlpnum is initialized to 0xffff, obviously // curlpnum is initialized to 0xffff, obviously
size_t i = anim->curlpnum & ~0xffff; size_t i = anim->curlpnum & ~0xffff;
@ -88,7 +86,7 @@ static inline uint16_t findpage(uint16_t framenumber)
// //
//**************************************************************************** //****************************************************************************
static inline void loadpage(uint16_t pagenumber, uint16_t **pagepointer) static inline void loadpage(anim_t *anim, uint16_t pagenumber, uint16_t **pagepointer)
{ {
if (anim->curlpnum == pagenumber) if (anim->curlpnum == pagenumber)
return; return;
@ -183,7 +181,7 @@ static void decodeframe(uint8_t * srcP, uint8_t * dstP)
// //
//**************************************************************************** //****************************************************************************
static void renderframe(uint16_t framenumber, uint16_t *pagepointer) static void renderframe(anim_t *anim, uint16_t framenumber, uint16_t *pagepointer)
{ {
uint16_t offset = 0; uint16_t offset = 0;
uint16_t frame = framenumber - anim->curlp->baseRecord; uint16_t frame = framenumber - anim->curlp->baseRecord;
@ -209,21 +207,21 @@ static void renderframe(uint16_t framenumber, uint16_t *pagepointer)
// //
//**************************************************************************** //****************************************************************************
static inline void drawframe(uint16_t framenumber) static inline void drawframe(anim_t *anim, uint16_t framenumber)
{ {
loadpage(findpage(framenumber), &anim->thepage); loadpage(anim, findpage(anim, framenumber), &anim->thepage);
renderframe(framenumber, anim->thepage); renderframe(anim, framenumber, anim->thepage);
} }
// <length> is the file size, for consistency checking. // <length> is the file size, for consistency checking.
int32_t ANIM_LoadAnim(uint8_t *buffer, int32_t length) int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, int32_t length)
{ {
if (memcmp(buffer, "LPF ", 4)) return -1;
length -= sizeof(lpfileheader)+128+768; length -= sizeof(lpfileheader)+128+768;
if (length < 0) if (length < 0)
return -1; return -1;
anim = (anim_t *)M_Realloc(anim, sizeof(anim_t));
anim->curlpnum = 0xffff; anim->curlpnum = 0xffff;
anim->currentframe = -1; anim->currentframe = -1;
@ -267,25 +265,11 @@ int32_t ANIM_LoadAnim(uint8_t *buffer, int32_t length)
lp->nRecords = LittleShort(lp->nRecords); lp->nRecords = LittleShort(lp->nRecords);
lp->nBytes = LittleShort(lp->nBytes); lp->nBytes = LittleShort(lp->nBytes);
} }
return ANIM_NumFrames(anim) <= 0 ? -1 : 0;
return 0;
} }
void ANIM_FreeAnim(void) uint8_t * ANIM_DrawFrame(anim_t *anim, int32_t framenumber)
{
M_Free(anim);
anim = nullptr;
}
int32_t ANIM_NumFrames(void)
{
return anim->lpheader->nRecords;
}
uint8_t * ANIM_DrawFrame(int32_t framenumber)
{ {
uint32_t cnt = anim->currentframe; uint32_t cnt = anim->currentframe;
@ -293,7 +277,7 @@ uint8_t * ANIM_DrawFrame(int32_t framenumber)
if (cnt > (uint32_t)framenumber) if (cnt > (uint32_t)framenumber)
cnt = 0; cnt = 0;
do drawframe(cnt++); do drawframe(anim, cnt++);
while (cnt < (uint32_t)framenumber); while (cnt < (uint32_t)framenumber);
anim->currentframe = framenumber; anim->currentframe = framenumber;
@ -301,7 +285,3 @@ uint8_t * ANIM_DrawFrame(int32_t framenumber)
} }
uint8_t * ANIM_GetPalette(void)
{
return anim->pal;
}

View file

@ -43,7 +43,7 @@ Modifications for JonoF's port by Jonathon Fowler (jf@jonof.id.au)
need to be in the header because there are no exposed functions need to be in the header because there are no exposed functions
that use any of this directly */ that use any of this directly */
typedef struct lpfileheaderstruct struct lpfileheader
{ {
uint32_t id; /* 4 uint8_tacter ID == "LPF " */ uint32_t id; /* 4 uint8_tacter ID == "LPF " */
uint16_t maxLps; /* max # largePages allowed. 256 FOR NOW. */ uint16_t maxLps; /* max # largePages allowed. 256 FOR NOW. */
@ -66,24 +66,23 @@ typedef struct lpfileheaderstruct
uint32_t nFrames; /* Number of actual frames in the file, includes ring frame. */ uint32_t nFrames; /* Number of actual frames in the file, includes ring frame. */
uint16_t framesPerSecond; /* Number of frames to play per second. */ uint16_t framesPerSecond; /* Number of frames to play per second. */
uint16_t pad2[29]; /* 58 bytes of filler to round up to 128 bytes total. */ uint16_t pad2[29]; /* 58 bytes of filler to round up to 128 bytes total. */
} };
lpfileheader; /* (comments from original source) */
// this is the format of a large page structure // this is the format of a large page structure
typedef struct struct lp_descriptor
{ {
uint16_t baseRecord; // Number of first record in this large page. uint16_t baseRecord; // Number of first record in this large page.
uint16_t nRecords; // Number of records in lp. uint16_t nRecords; // Number of records in lp.
// bit 15 of "nRecords" == "has continuation from previous lp". // bit 15 of "nRecords" == "has continuation from previous lp".
// bit 14 of "nRecords" == "final record continues on next lp". // bit 14 of "nRecords" == "final record continues on next lp".
uint16_t nBytes; // Total number of bytes of contents, excluding header. uint16_t nBytes; // Total number of bytes of contents, excluding header.
} lp_descriptor; };
#pragma pack(pop) #pragma pack(pop)
#define IMAGEBUFFERSIZE 0x10000 #define IMAGEBUFFERSIZE 0x10000
typedef struct struct anim_t
{ {
uint16_t framecount; // current frame of anim uint16_t framecount; // current frame of anim
lpfileheader * lpheader; // file header will be loaded into this structure lpfileheader * lpheader; // file header will be loaded into this structure
@ -95,7 +94,7 @@ typedef struct
uint8_t * buffer; uint8_t * buffer;
uint8_t pal[768]; uint8_t pal[768];
int32_t currentframe; int32_t currentframe;
} anim_t; };
//**************************************************************************** //****************************************************************************
// //
@ -105,17 +104,7 @@ typedef struct
// //
//**************************************************************************** //****************************************************************************
int32_t ANIM_LoadAnim(uint8_t *buffer, int32_t length); int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, int32_t length);
//****************************************************************************
//
// ANIM_FreeAnim ()
//
// Free up internal anim data structure
//
//****************************************************************************
void ANIM_FreeAnim(void);
//**************************************************************************** //****************************************************************************
// //
@ -125,7 +114,10 @@ void ANIM_FreeAnim(void);
// //
//**************************************************************************** //****************************************************************************
int32_t ANIM_NumFrames(void); inline int32_t ANIM_NumFrames(anim_t* anim)
{
return anim->lpheader->nRecords;
}
//**************************************************************************** //****************************************************************************
// //
@ -135,7 +127,7 @@ int32_t ANIM_NumFrames(void);
// //
//**************************************************************************** //****************************************************************************
uint8_t * ANIM_DrawFrame(int32_t framenumber); uint8_t * ANIM_DrawFrame(anim_t* anim, int32_t framenumber);
//**************************************************************************** //****************************************************************************
// //
@ -144,6 +136,9 @@ uint8_t * ANIM_DrawFrame(int32_t framenumber);
// return the palette of the anim // return the palette of the anim
//**************************************************************************** //****************************************************************************
uint8_t * ANIM_GetPalette(void); inline uint8_t* ANIM_GetPalette(anim_t* anim)
{
return anim->pal;
}
#endif #endif

View file

@ -405,6 +405,7 @@ int32_t Anim_Play(const char *fn)
int32_t ogltexfiltermode = gl_texture_filter; int32_t ogltexfiltermode = gl_texture_filter;
TArray<uint8_t> buffer; TArray<uint8_t> buffer;
auto fr = fileSystem.OpenFileReader(fn); auto fr = fileSystem.OpenFileReader(fn);
anim_t anm;
if (!fr.isOpen()) if (!fr.isOpen())
goto end_anim; goto end_anim;
@ -423,16 +424,12 @@ int32_t Anim_Play(const char *fn)
int32_t numframes; int32_t numframes;
// "LPF " (.anm) if (ANIM_LoadAnim(&anm, anim->animbuf, buffer.Size()-1) < 0)
if (firstfour != B_LITTLE32(0x2046504Cu) ||
ANIM_LoadAnim(anim->animbuf, buffer.Size()-1) < 0 ||
(numframes = ANIM_NumFrames()) <= 0)
{ {
// XXX: ANM_LoadAnim() still checks less than the bare minimum,
// e.g. ANM file could still be too small and not contain any frames.
Printf("Error: malformed ANM file \"%s\".\n", fn); Printf("Error: malformed ANM file \"%s\".\n", fn);
goto end_anim; goto end_anim;
} }
numframes = ANIM_NumFrames(&anm);
if ((anim->frameflags & CUTSCENE_TEXTUREFILTER && gl_texture_filter == TEXFILTER_ON) || anim->frameflags & CUTSCENE_FORCEFILTER) if ((anim->frameflags & CUTSCENE_TEXTUREFILTER && gl_texture_filter == TEXFILTER_ON) || anim->frameflags & CUTSCENE_FORCEFILTER)
gl_texture_filter = TEXFILTER_ON; gl_texture_filter = TEXFILTER_ON;
@ -461,7 +458,7 @@ int32_t Anim_Play(const char *fn)
i = VM_OnEventWithReturn(EVENT_PRECUTSCENE, g_player[screenpeek].ps->i, screenpeek, i); i = VM_OnEventWithReturn(EVENT_PRECUTSCENE, g_player[screenpeek].ps->i, screenpeek, i);
animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(i)); animtex.SetFrame(ANIM_GetPalette(&anm), ANIM_DrawFrame(&anm, i));
if (VM_OnEventWithReturn(EVENT_SKIPCUTSCENE, g_player[screenpeek].ps->i, screenpeek, inputState.CheckAllInput())) if (VM_OnEventWithReturn(EVENT_SKIPCUTSCENE, g_player[screenpeek].ps->i, screenpeek, inputState.CheckAllInput()))
{ {
@ -526,7 +523,6 @@ end_anim_restore_gl:
end_anim: end_anim:
inputState.ClearAllInput(); inputState.ClearAllInput();
anim->animbuf = nullptr; anim->animbuf = nullptr;
ANIM_FreeAnim();
tileDelete(TILE_ANIM); tileDelete(TILE_ANIM);

View file

@ -461,17 +461,14 @@ int32_t Anim_Play(const char *fn)
goto end_anim; goto end_anim;
int32_t numframes; int32_t numframes;
anim_t anm;
// "LPF " (.anm) if (ANIM_LoadAnim(&anm, anim->animbuf, buffer.Size() - 1) < 0)
if (firstfour != B_LITTLE32(0x2046504C) ||
ANIM_LoadAnim(anim->animbuf, buffer.Size()-1) < 0 ||
(numframes = ANIM_NumFrames()) <= 0)
{ {
// XXX: ANM_LoadAnim() still checks less than the bare minimum,
// e.g. ANM file could still be too small and not contain any frames.
Printf("Error: malformed ANM file \"%s\".\n", fn); Printf("Error: malformed ANM file \"%s\".\n", fn);
goto end_anim; goto end_anim;
} }
numframes = ANIM_NumFrames(&anm);
ototalclock = totalclock; ototalclock = totalclock;
@ -495,7 +492,7 @@ int32_t Anim_Play(const char *fn)
if (totalclock < ototalclock - 1) if (totalclock < ototalclock - 1)
continue; continue;
animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(i)); animtex.SetFrame(ANIM_GetPalette(&anm), ANIM_DrawFrame(&anm, i));
if (inputState.CheckAllInput()) if (inputState.CheckAllInput())
{ {
@ -566,7 +563,6 @@ end_anim_restore_gl:
end_anim: end_anim:
inputState.ClearAllInput(); inputState.ClearAllInput();
anim->animbuf = nullptr; anim->animbuf = nullptr;
ANIM_FreeAnim();
tileDelete(TILE_ANIM); tileDelete(TILE_ANIM);
return !running; return !running;

View file

@ -252,9 +252,16 @@ playanm(short anim_num)
DSPRINTF(ds,"PlayAnm - Palette Stuff"); DSPRINTF(ds,"PlayAnm - Palette Stuff");
MONO_PRINT(ds); MONO_PRINT(ds);
anim_t anm;
ANIM_LoadAnim(buffer.Data(), buffer.Size()-1); if (ANIM_LoadAnim(&anm, buffer.Data(), buffer.Size() - 1) < 0)
ANIMnumframes = ANIM_NumFrames(); {
Printf("Error: malformed ANM file \"%s\".\n", ANIMname[ANIMnum]);
goto ENDOFANIMLOOP;
}
ANIM_LoadAnim(&anm, buffer.Data(), buffer.Size()-1);
ANIMnumframes = ANIM_NumFrames(&anm);
numframes = ANIMnumframes; numframes = ANIMnumframes;
@ -266,7 +273,7 @@ playanm(short anim_num)
if (ANIMnum == 1) if (ANIMnum == 1)
{ {
// draw the first frame // draw the first frame
animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(1)); animtex.SetFrame(ANIM_GetPalette(&anm), ANIM_DrawFrame(&anm, 1));
rotatesprite_fs(160 << 16, 100 << 16, 65536, 0, -1, 0, 0, 2 | 8 | 64, animtex.GetFrame()); rotatesprite_fs(160 << 16, 100 << 16, 65536, 0, -1, 0, 0, 2 | 8 | 64, animtex.GetFrame());
} }
@ -310,7 +317,7 @@ playanm(short anim_num)
} }
videoClearViewableArea(0L); videoClearViewableArea(0L);
animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(i)); animtex.SetFrame(ANIM_GetPalette(&anm), ANIM_DrawFrame(&anm, i));
rotatesprite_fs(160 << 16, 100 << 16, 65536, 0, -1, 0, 0, 2 | 8 | 64, animtex.GetFrame()); rotatesprite_fs(160 << 16, 100 << 16, 65536, 0, -1, 0, 0, 2 | 8 | 64, animtex.GetFrame());
videoNextPage(); videoNextPage();
handleevents(); handleevents();
@ -332,6 +339,5 @@ ENDOFANIMLOOP:
videoNextPage(); videoNextPage();
inputState.ClearAllInput(); inputState.ClearAllInput();
ANIM_FreeAnim();
} }
END_SW_NS END_SW_NS