- 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 ()
@ -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
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)
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 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);
renderframe(framenumber, anim->thepage);
loadpage(anim, findpage(anim, framenumber), &anim->thepage);
renderframe(anim, framenumber, anim->thepage);
}
// <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;
if (length < 0)
return -1;
anim = (anim_t *)M_Realloc(anim, sizeof(anim_t));
anim->curlpnum = 0xffff;
anim->currentframe = -1;
@ -267,25 +265,11 @@ int32_t ANIM_LoadAnim(uint8_t *buffer, int32_t length)
lp->nRecords = LittleShort(lp->nRecords);
lp->nBytes = LittleShort(lp->nBytes);
}
return 0;
return ANIM_NumFrames(anim) <= 0 ? -1 : 0;
}
void ANIM_FreeAnim(void)
{
M_Free(anim);
anim = nullptr;
}
int32_t ANIM_NumFrames(void)
{
return anim->lpheader->nRecords;
}
uint8_t * ANIM_DrawFrame(int32_t framenumber)
uint8_t * ANIM_DrawFrame(anim_t *anim, int32_t framenumber)
{
uint32_t cnt = anim->currentframe;
@ -293,7 +277,7 @@ uint8_t * ANIM_DrawFrame(int32_t framenumber)
if (cnt > (uint32_t)framenumber)
cnt = 0;
do drawframe(cnt++);
do drawframe(anim, cnt++);
while (cnt < (uint32_t)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
that use any of this directly */
typedef struct lpfileheaderstruct
struct lpfileheader
{
uint32_t id; /* 4 uint8_tacter ID == "LPF " */
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. */
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. */
}
lpfileheader; /* (comments from original source) */
};
// 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 nRecords; // Number of records in lp.
// bit 15 of "nRecords" == "has continuation from previous lp".
// bit 14 of "nRecords" == "final record continues on next lp".
uint16_t nBytes; // Total number of bytes of contents, excluding header.
} lp_descriptor;
};
#pragma pack(pop)
#define IMAGEBUFFERSIZE 0x10000
typedef struct
struct anim_t
{
uint16_t framecount; // current frame of anim
lpfileheader * lpheader; // file header will be loaded into this structure
@ -95,7 +94,7 @@ typedef struct
uint8_t * buffer;
uint8_t pal[768];
int32_t currentframe;
} anim_t;
};
//****************************************************************************
//
@ -105,17 +104,7 @@ typedef struct
//
//****************************************************************************
int32_t ANIM_LoadAnim(uint8_t *buffer, int32_t length);
//****************************************************************************
//
// ANIM_FreeAnim ()
//
// Free up internal anim data structure
//
//****************************************************************************
void ANIM_FreeAnim(void);
int32_t ANIM_LoadAnim(anim_t *anim, uint8_t *buffer, int32_t length);
//****************************************************************************
//
@ -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
//****************************************************************************
uint8_t * ANIM_GetPalette(void);
inline uint8_t* ANIM_GetPalette(anim_t* anim)
{
return anim->pal;
}
#endif

View file

@ -405,6 +405,7 @@ int32_t Anim_Play(const char *fn)
int32_t ogltexfiltermode = gl_texture_filter;
TArray<uint8_t> buffer;
auto fr = fileSystem.OpenFileReader(fn);
anim_t anm;
if (!fr.isOpen())
goto end_anim;
@ -423,16 +424,12 @@ int32_t Anim_Play(const char *fn)
int32_t numframes;
// "LPF " (.anm)
if (firstfour != B_LITTLE32(0x2046504Cu) ||
ANIM_LoadAnim(anim->animbuf, buffer.Size()-1) < 0 ||
(numframes = ANIM_NumFrames()) <= 0)
if (ANIM_LoadAnim(&anm, anim->animbuf, buffer.Size()-1) < 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);
goto end_anim;
}
numframes = ANIM_NumFrames(&anm);
if ((anim->frameflags & CUTSCENE_TEXTUREFILTER && gl_texture_filter == TEXFILTER_ON) || anim->frameflags & CUTSCENE_FORCEFILTER)
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);
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()))
{
@ -526,7 +523,6 @@ end_anim_restore_gl:
end_anim:
inputState.ClearAllInput();
anim->animbuf = nullptr;
ANIM_FreeAnim();
tileDelete(TILE_ANIM);

View file

@ -461,17 +461,14 @@ int32_t Anim_Play(const char *fn)
goto end_anim;
int32_t numframes;
anim_t anm;
// "LPF " (.anm)
if (firstfour != B_LITTLE32(0x2046504C) ||
ANIM_LoadAnim(anim->animbuf, buffer.Size()-1) < 0 ||
(numframes = ANIM_NumFrames()) <= 0)
if (ANIM_LoadAnim(&anm, anim->animbuf, buffer.Size() - 1) < 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);
goto end_anim;
}
numframes = ANIM_NumFrames(&anm);
ototalclock = totalclock;
@ -495,7 +492,7 @@ int32_t Anim_Play(const char *fn)
if (totalclock < ototalclock - 1)
continue;
animtex.SetFrame(ANIM_GetPalette(), ANIM_DrawFrame(i));
animtex.SetFrame(ANIM_GetPalette(&anm), ANIM_DrawFrame(&anm, i));
if (inputState.CheckAllInput())
{
@ -566,7 +563,6 @@ end_anim_restore_gl:
end_anim:
inputState.ClearAllInput();
anim->animbuf = nullptr;
ANIM_FreeAnim();
tileDelete(TILE_ANIM);
return !running;

View file

@ -252,9 +252,16 @@ playanm(short anim_num)
DSPRINTF(ds,"PlayAnm - Palette Stuff");
MONO_PRINT(ds);
anim_t anm;
ANIM_LoadAnim(buffer.Data(), buffer.Size()-1);
ANIMnumframes = ANIM_NumFrames();
if (ANIM_LoadAnim(&anm, buffer.Data(), buffer.Size() - 1) < 0)
{
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;
@ -266,7 +273,7 @@ playanm(short anim_num)
if (ANIMnum == 1)
{
// 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());
}
@ -310,7 +317,7 @@ playanm(short anim_num)
}
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());
videoNextPage();
handleevents();
@ -332,6 +339,5 @@ ENDOFANIMLOOP:
videoNextPage();
inputState.ClearAllInput();
ANIM_FreeAnim();
}
END_SW_NS