ref: 40402e51183b677122198d5bb16ce31a87e40a9f
parent: e0318617afc836d3756390ffd3f9d6cb3d5f52ca
author: Sigrid Solveig Haflínudóttir <sigrid@ftrv.se>
date: Sat Nov 25 15:12:38 EST 2023
rewrite sprite loading; move to its own file
--- a/Makefile
+++ b/Makefile
@@ -46,6 +46,7 @@
model_brush.o\
model_bsp.o\
model_bsp2.o\
+ model_sprite.o\
net_loop.o\
net_main.o\
pal.o\
--- a/mkfile
+++ b/mkfile
@@ -44,6 +44,7 @@
model_brush.$O\
model_bsp.$O\
model_bsp2.$O\
+ model_sprite.$O\
nanosec.$O\
net_dgrm.$O\
net_loop.$O\
--- a/model.c
+++ b/model.c
@@ -2,8 +2,8 @@
static char loadname[32]; // for hunk tags
-void Mod_LoadSpriteModel (model_t *mod, void *buffer);
-void Mod_LoadBrushModel (model_t *mod, void *buffer, int total);
+void Mod_LoadSpriteModel (model_t *mod, byte *buffer, int total);
+void Mod_LoadBrushModel (model_t *mod, byte *buffer, int total);
void Mod_LoadAliasModel (model_t *mod, void *buffer);
model_t *Mod_LoadModel (model_t *mod, bool crash);
@@ -259,7 +259,7 @@
break;
case IDSPRITEHEADER:
- Mod_LoadSpriteModel(mod, buf);
+ Mod_LoadSpriteModel(mod, buf, len);
break;
default:
@@ -663,168 +663,6 @@
Hunk_CacheFrom(&mod->cache, pheader);
}
-
-void *
-Mod_LoadSpriteFrame(void * pin, mspriteframe_t **ppframe)
-{
- int width, height, size, origin[2];
- dspriteframe_t *pinframe;
- mspriteframe_t *pspriteframe;
-
- pinframe = (dspriteframe_t *)pin;
-
- width = LittleLong(pinframe->width);
- height = LittleLong(pinframe->height);
- size = width * height;
-
- pspriteframe = Hunk_Alloc(size + sizeof *pspriteframe);
-
- memset(pspriteframe, 0, size + sizeof *pspriteframe);
- *ppframe = pspriteframe;
-
- pspriteframe->width = width;
- pspriteframe->height = height;
- origin[0] = LittleLong (pinframe->origin[0]);
- origin[1] = LittleLong (pinframe->origin[1]);
-
- pspriteframe->up = origin[1];
- pspriteframe->down = origin[1] - height;
- pspriteframe->left = origin[0];
- pspriteframe->right = width + origin[0];
-
- memcpy(&pspriteframe->pixels[0], (uchar *)(pinframe + 1), size);
- return (void *)((byte *)pinframe + size + sizeof *pinframe);
-}
-
-
-/*
-=================
-Mod_LoadSpriteGroup
-=================
-*/
-void * Mod_LoadSpriteGroup (void * pin, mspriteframe_t **ppframe)
-{
- dspritegroup_t *pingroup;
- mspritegroup_t *pspritegroup;
- int i, numframes;
- dspriteinterval_t *pin_intervals;
- float *poutintervals;
- void *ptemp;
-
- pingroup = (dspritegroup_t *)pin;
-
- numframes = LittleLong (pingroup->numframes);
-
- pspritegroup = Hunk_Alloc(sizeof(*pspritegroup) +
- (numframes - 1) * sizeof pspritegroup->frames[0]);
-
- pspritegroup->numframes = numframes;
-
- *ppframe = (mspriteframe_t *)pspritegroup;
-
- pin_intervals = (dspriteinterval_t *)(pingroup + 1);
-
- poutintervals = Hunk_Alloc(numframes * sizeof *poutintervals);
-
- pspritegroup->intervals = poutintervals;
-
- for (i=0 ; i<numframes ; i++)
- {
- *poutintervals = LittleFloat (pin_intervals->interval);
- if (*poutintervals <= 0.0)
- Host_Error("Mod_LoadSpriteGroup: interval<=0");
-
- poutintervals++;
- pin_intervals++;
- }
-
- ptemp = (void *)pin_intervals;
-
- for (i=0 ; i<numframes ; i++)
- {
- ptemp = Mod_LoadSpriteFrame (ptemp, &pspritegroup->frames[i]);
- }
-
- return ptemp;
-}
-
-
-/*
-=================
-Mod_LoadSpriteModel
-=================
-*/
-void Mod_LoadSpriteModel (model_t *mod, void *buffer)
-{
- int i;
- int version;
- dsprite_t *pin;
- msprite_t *psprite;
- int numframes;
- int size;
- dspriteframetype_t *pframetype;
-
- pin = (dsprite_t *)buffer;
-
- version = LittleLong (pin->version);
- if (version != SPRITE_VERSION)
- Host_Error("%s has wrong version number "
- "(%d should be %d)", mod->name, version, SPRITE_VERSION);
-
- numframes = LittleLong (pin->numframes);
-
- size = sizeof (msprite_t) + (numframes - 1) * sizeof (psprite->frames);
-
- psprite = Hunk_Alloc(size);
-
- mod->cache.data = psprite;
-
- psprite->type = LittleLong (pin->type);
- psprite->maxwidth = LittleLong (pin->width);
- psprite->maxheight = LittleLong (pin->height);
- psprite->beamlength = LittleFloat (pin->beamlength);
- mod->synctype = LittleLong (pin->synctype);
- psprite->numframes = numframes;
-
- mod->mins[0] = mod->mins[1] = -psprite->maxwidth/2;
- mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2;
- mod->mins[2] = -psprite->maxheight/2;
- mod->maxs[2] = psprite->maxheight/2;
-
- // load the frames
- if (numframes < 1)
- Host_Error("Mod_LoadSpriteModel: Invalid # of frames: %d\n", numframes);
-
- mod->numframes = numframes;
- mod->flags = 0;
-
- pframetype = (dspriteframetype_t *)(pin + 1);
-
- for (i=0 ; i<numframes ; i++)
- {
- spriteframetype_t frametype;
-
- frametype = LittleLong (pframetype->type);
- psprite->frames[i].type = frametype;
-
- if (frametype == SPR_SINGLE)
- {
- pframetype = (dspriteframetype_t *)
- Mod_LoadSpriteFrame (pframetype + 1,
- &psprite->frames[i].frameptr);
- }
- else
- {
- pframetype = (dspriteframetype_t *)
- Mod_LoadSpriteGroup (pframetype + 1,
- &psprite->frames[i].frameptr);
- }
- }
-
- mod->type = mod_sprite;
-}
-
-//=============================================================================
/*
================
--- a/model.h
+++ b/model.h
@@ -186,24 +186,28 @@
{
int numframes;
float *intervals;
- mspriteframe_t *frames[1];
+ mspriteframe_t *frames[0];
} mspritegroup_t;
typedef struct
{
spriteframetype_t type;
- mspriteframe_t *frameptr;
+ union {
+ mspriteframe_t *frameptr;
+ mspritegroup_t *framegrp;
+ };
} mspriteframedesc_t;
typedef struct
{
int type;
+ float boundingradius;
int maxwidth;
int maxheight;
int numframes;
float beamlength; // remove?
void *cachespot; // remove?
- mspriteframedesc_t frames[1];
+ mspriteframedesc_t frames[0];
} msprite_t;
--- a/model_brush.c
+++ b/model_brush.c
@@ -43,11 +43,11 @@
}
void
-Mod_LoadBrushModel(model_t *mod, void *buffer, int total)
+Mod_LoadBrushModel(model_t *mod, byte *in0, int total)
{
int i, j, ver, off, sz;
model_t *submod;
- byte *in, *in0;
+ byte *in;
submodel_t *bm;
char name[16];
int (*loadf[HEADER_LUMPS])(model_t *, byte *, int) = {
@@ -85,7 +85,7 @@
LUMP_MODELS,
};
- in0 = in = buffer;
+ in = in0;
ver = le32(in);
if(ver == BSPVERSION){
loadf[LUMP_EDGES] = BSP_LoadEdges;
--- /dev/null
+++ b/model_sprite.c
@@ -1,0 +1,143 @@
+#include "quakedef.h"
+
+static byte *
+Mod_LoadSpriteFrame(byte *in, byte *e, mspriteframe_t **ppframe)
+{
+ int w, h, size, origin[2];
+ mspriteframe_t *pspriteframe;
+
+ if(e-in < 4*4){
+toosmall:
+ werrstr("truncated?");
+ return nil;
+ }
+
+ origin[0] = le32(in);
+ origin[1] = le32(in);
+ w = le32(in);
+ h = le32(in);
+ if(w < 0 || h < 0){
+ werrstr("invalid dimensions: %dx%d", w, h);
+ return nil;
+ }
+ if(e-in < (size = w*h))
+ goto toosmall;
+
+ *ppframe = pspriteframe = Hunk_Alloc(sizeof(*pspriteframe) + size);
+ pspriteframe->width = w;
+ pspriteframe->height = h;
+ pspriteframe->up = origin[1];
+ pspriteframe->down = origin[1] - h;
+ pspriteframe->left = origin[0];
+ pspriteframe->right = w + origin[0];
+ memmove(pspriteframe->pixels, in, size);
+ in += size;
+
+ return in;
+}
+
+static byte *
+Mod_LoadSpriteGroup(byte *in, byte *e, mspritegroup_t **ppgroup)
+{
+ mspritegroup_t *spgrp;
+ float *poutintervals;
+ int i, numframes;
+
+ if(e-in < 4){
+toosmall:
+ werrstr("truncated?");
+ return nil;
+ }
+ if((numframes = le32(in)) < 0){
+ werrstr("invalid number of frames: %d", numframes);
+ return nil;
+ }
+ *ppgroup = spgrp = Hunk_Alloc(
+ sizeof(*spgrp) +
+ numframes*(sizeof(*spgrp->frames) + sizeof(*spgrp->intervals))
+ );
+ spgrp->numframes = numframes;
+
+ poutintervals = (void*)(spgrp->frames + numframes);
+ for(i = 0; i < numframes; i++){
+ if(e-in < 4)
+ goto toosmall;
+ if((*poutintervals++ = f32(in)) <= 0.0){
+ werrstr("interval <= 0");
+ return nil;
+ }
+ }
+
+ for(i = 0; i < numframes; i++){
+ in = Mod_LoadSpriteFrame(in, e, &spgrp->frames[i]);
+ if(in == nil)
+ break;
+ }
+
+ return in;
+}
+
+void
+Mod_LoadSpriteModel(model_t *mod, byte *in0, int total)
+{
+ int version, numframes, i;
+ msprite_t *psprite;
+ byte *in, *e;
+
+ if(total < 9*4){
+toosmall:
+ werrstr("file too small");
+ goto err;
+ }
+
+ in = in0 + 4;
+ e = in0 + total;
+ if((version = le32(in)) != SPRITE_VERSION){
+ werrstr("wrong version number (%d should be %d)", version, SPRITE_VERSION);
+ goto err;
+ }
+
+ in = in0 + 24;
+ if((numframes = le32(in)) < 1){
+ werrstr("invalid number of frames: %d", numframes);
+ goto err;
+ }
+
+ psprite = Hunk_Alloc(sizeof(*psprite) + numframes*sizeof(*psprite->frames));
+ mod->cache.data = psprite;
+
+ in = in0 + 8;
+ psprite->type = le32(in);
+ psprite->boundingradius = f32(in);
+ psprite->maxwidth = le32(in);
+ psprite->maxheight = le32(in);
+ psprite->numframes = le32(in);
+ psprite->beamlength = f32(in);
+ mod->synctype = le32(in);
+
+ mod->maxs[0] = mod->maxs[1] = psprite->maxwidth/2;
+ mod->maxs[2] = psprite->maxheight/2;
+ mod->mins[0] = mod->mins[1] = -mod->maxs[0];
+ mod->mins[2] = -mod->maxs[2];
+
+ mod->type = mod_sprite;
+ mod->numframes = numframes;
+ mod->flags = 0;
+
+ for(i = 0; i < numframes; i++){
+ if(e-in < 4)
+ goto toosmall;
+ if((psprite->frames[i].type = le32(in)) == SPR_SINGLE)
+ in = Mod_LoadSpriteFrame(in, e, &psprite->frames[i].frameptr);
+ else
+ in = Mod_LoadSpriteGroup(in, e, &psprite->frames[i].framegrp);
+ if(in == nil){
+ werrstr("frame(group) %d: %s", i, lerr());
+ goto err;
+ }
+ }
+ return;
+
+err:
+ Host_Error("Mod_LoadSpriteModel: %s: %s", mod->name, lerr());
+}