Finished support for custom textures and robots, fixed some bugs, reformatted code and placed function calls to properly work for designated mission/level

This commit is contained in:
zicodxx 2010-10-16 11:13:11 +02:00
parent 4c7879b740
commit 940eaeb3db
3 changed files with 494 additions and 356 deletions

View file

@ -1,5 +1,9 @@
D1X-Rebirth Changelog D1X-Rebirth Changelog
20101016
--------
main/custom.c, main/gameseq.c: Finished support for custom textures and robots, fixed some bugs, reformatted code and placed function calls to properly work for designated mission/level
20101014 20101014
-------- --------
main/menu.c: Fixed compilation of menu.c when USE_SDLMIXER is not defined main/menu.c: Fixed compilation of menu.c when USE_SDLMIXER is not defined

View file

@ -1,8 +1,8 @@
/* /*
* Load custom textures & robot data * Load custom textures & robot data
*/ */
#include <string.h>
#include <string.h>
#include "gr.h" #include "gr.h"
#include "cfile.h" #include "cfile.h"
#include "pstypes.h" #include "pstypes.h"
@ -19,32 +19,19 @@
#endif #endif
#include "custom.h" #include "custom.h"
//#define D2TMAP_CONV // used for testing
extern hashtable AllBitmapsNames; extern hashtable AllBitmapsNames;
extern hashtable AllDigiSndNames; extern hashtable AllDigiSndNames;
#if 0 // removed memory saving extra bitmap structure hack struct snd_info
struct bm_info { {
short bm_w,bm_h;
ubyte bm_flags;
ubyte avg_color;
ubyte *bm_data;
};
#endif
struct snd_info {
unsigned int length; unsigned int length;
ubyte *data; ubyte *data;
}; };
grs_bitmap BitmapOriginal[MAX_BITMAP_FILES]; typedef struct DiskBitmapHeader2
struct snd_info SoundOriginal[MAX_SOUND_FILES]; {
extern void gr_bm_bitblt(int w, int h, int dx, int dy, int sx, int sy, grs_bitmap * src, grs_bitmap * dest);
//#define D2TMAP_CONV // used for testing
typedef struct DiskBitmapHeader2 {
char name[8]; char name[8];
ubyte dflags; ubyte dflags;
ubyte width; ubyte width;
@ -55,7 +42,8 @@ typedef struct DiskBitmapHeader2 {
int offset; int offset;
} __pack__ DiskBitmapHeader2; } __pack__ DiskBitmapHeader2;
typedef struct DiskBitmapHeader { typedef struct DiskBitmapHeader
{
char name[8]; char name[8];
ubyte dflags; ubyte dflags;
ubyte width; ubyte width;
@ -65,37 +53,47 @@ typedef struct DiskBitmapHeader {
int offset; int offset;
} __pack__ DiskBitmapHeader; } __pack__ DiskBitmapHeader;
typedef struct DiskSoundHeader { typedef struct DiskSoundHeader
{
char name[8]; char name[8];
int length; int length;
int data_length; int data_length;
int offset; int offset;
} __pack__ DiskSoundHeader; } __pack__ DiskSoundHeader;
static void change_ext(char *filename, const char *newext, int filename_size) { struct custom_info
{
int offset;
int repl_idx; // 0x80000000 -> sound, -1 -> n/a
unsigned int flags;
int width, height;
};
grs_bitmap BitmapOriginal[MAX_BITMAP_FILES];
struct snd_info SoundOriginal[MAX_SOUND_FILES];
static void change_ext(char *filename, const char *newext, int filename_size)
{
char *p; char *p;
int len, extlen; int len, extlen;
len = strlen(filename); len = strlen(filename);
extlen = strlen(newext); extlen = strlen(newext);
if ((p = strrchr(filename, '.'))) { if ((p = strrchr(filename, '.')))
{
len = p - filename; len = p - filename;
*p = 0; *p = 0;
} }
if (len + extlen + 1 < filename_size) {
if (len + extlen + 1 < filename_size)
{
strcat(filename, "."); strcat(filename, ".");
strcat(filename, newext); strcat(filename, newext);
} }
} }
struct custom_info { int load_pig1(CFILE *f, int num_bitmaps, int num_sounds, int *num_custom, struct custom_info **ci)
int offset; {
int repl_idx; // 0x80000000 -> sound, -1 -> n/a
unsigned int flags;
short width, height;
};
int load_pig1(CFILE *f, int num_bitmaps, int num_sounds, int *num_custom, struct custom_info **ci) {
int data_ofs; int data_ofs;
int i; int i;
struct custom_info *cip; struct custom_info *cip;
@ -104,46 +102,63 @@ int load_pig1(CFILE *f, int num_bitmaps, int num_sounds, int *num_custom, struct
char name[15]; char name[15];
*num_custom = 0; *num_custom = 0;
if ((unsigned int)num_bitmaps <= MAX_BITMAP_FILES) { // <v1.4 pig?
if ((unsigned int)num_bitmaps <= MAX_BITMAP_FILES) // <v1.4 pig?
{
cfseek(f, 8, SEEK_SET); cfseek(f, 8, SEEK_SET);
data_ofs = 8; data_ofs = 8;
} else if (num_bitmaps > 0 && num_bitmaps < cfilelength(f)) { // >=v1.4 pig? }
else if (num_bitmaps > 0 && num_bitmaps < cfilelength(f)) // >=v1.4 pig?
{
cfseek(f, num_bitmaps, SEEK_SET); cfseek(f, num_bitmaps, SEEK_SET);
data_ofs = num_bitmaps + 8; data_ofs = num_bitmaps + 8;
num_bitmaps = cfile_read_int(f); num_bitmaps = cfile_read_int(f);
num_sounds = cfile_read_int(f); num_sounds = cfile_read_int(f);
} else }
else
return -1; // invalid pig file return -1; // invalid pig file
if ((unsigned int)num_bitmaps >= MAX_BITMAP_FILES ||
(unsigned int)num_sounds >= MAX_SOUND_FILES) if ((unsigned int)num_bitmaps >= MAX_BITMAP_FILES || (unsigned int)num_sounds >= MAX_SOUND_FILES)
return -1; // invalid pig file return -1; // invalid pig file
if (!(*ci = cip = d_malloc((num_bitmaps + num_sounds) * sizeof(struct custom_info)))) if (!(*ci = cip = d_malloc((num_bitmaps + num_sounds) * sizeof(struct custom_info))))
return -1; // out of memory return -1; // out of memory
data_ofs += num_bitmaps * sizeof(DiskBitmapHeader) + num_sounds * sizeof(DiskSoundHeader); data_ofs += num_bitmaps * sizeof(DiskBitmapHeader) + num_sounds * sizeof(DiskSoundHeader);
i = num_bitmaps; i = num_bitmaps;
while (i--) {
if (cfread(&bmh, sizeof(DiskBitmapHeader), 1, f) < 1) { while (i--)
{
if (cfread(&bmh, sizeof(DiskBitmapHeader), 1, f) < 1)
{
d_free(*ci); d_free(*ci);
return -1; return -1;
} }
memcpy( name, bmh.name, 8 ); memcpy( name, bmh.name, 8 );
name[8] = 0; name[8] = 0;
if (bmh.dflags & DBM_FLAG_ABM) if (bmh.dflags & DBM_FLAG_ABM)
sprintf(strchr(name, 0), "#%d", bmh.dflags & 63); sprintf(strchr(name, 0), "#%d", bmh.dflags & 63);
cip->offset = bmh.offset + data_ofs; cip->offset = bmh.offset + data_ofs;
cip->repl_idx = hashtable_search(&AllBitmapsNames, name); cip->repl_idx = hashtable_search(&AllBitmapsNames, name);
cip->flags = bmh.flags & (BM_FLAG_TRANSPARENT | cip->flags = bmh.flags & (BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE);
BM_FLAG_SUPER_TRANSPARENT | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE);
cip->width = bmh.width + ((bmh.dflags & DBM_FLAG_LARGE) ? 256 : 0); cip->width = bmh.width + ((bmh.dflags & DBM_FLAG_LARGE) ? 256 : 0);
cip->height = bmh.height; cip->height = bmh.height;
cip++; cip++;
} }
i = num_sounds; i = num_sounds;
while (i--) {
if (cfread(&sndh, sizeof(DiskSoundHeader), 1, f) < 1) { while (i--)
{
if (cfread(&sndh, sizeof(DiskSoundHeader), 1, f) < 1)
{
d_free(*ci); d_free(*ci);
return -1; return -1;
} }
memcpy(name, sndh.name, 8); memcpy(name, sndh.name, 8);
name[8] = 0; name[8] = 0;
cip->offset = sndh.offset + data_ofs; cip->offset = sndh.offset + data_ofs;
@ -151,11 +166,14 @@ int load_pig1(CFILE *f, int num_bitmaps, int num_sounds, int *num_custom, struct
cip->width = sndh.length; cip->width = sndh.length;
cip++; cip++;
} }
*num_custom = num_bitmaps + num_sounds; *num_custom = num_bitmaps + num_sounds;
return 0; return 0;
} }
int load_pog(CFILE *f, int pog_sig, int pog_ver, int *num_custom, struct custom_info **ci) { int load_pog(CFILE *f, int pog_sig, int pog_ver, int *num_custom, struct custom_info **ci)
{
int data_ofs; int data_ofs;
int num_bitmaps; int num_bitmaps;
int no_repl = 0; int no_repl = 0;
@ -167,7 +185,8 @@ int load_pog(CFILE *f, int pog_sig, int pog_ver, int *num_custom, struct custom_
int x, j, N_d2tmap; int x, j, N_d2tmap;
int *d2tmap = NULL; int *d2tmap = NULL;
CFILE *f2 = NULL; CFILE *f2 = NULL;
if ((f2 = cfopen("d2tmap.bin", "rb"))) { if ((f2 = cfopen("d2tmap.bin", "rb")))
{
N_d2tmap = cfile_read_int(f2); N_d2tmap = cfile_read_int(f2);
if ((d2tmap = d_malloc(N_d2tmap * sizeof(d2tmap[0])))) if ((d2tmap = d_malloc(N_d2tmap * sizeof(d2tmap[0]))))
for (i = 0; i < N_d2tmap; i++) for (i = 0; i < N_d2tmap; i++)
@ -177,53 +196,72 @@ int load_pog(CFILE *f, int pog_sig, int pog_ver, int *num_custom, struct custom_
#endif #endif
*num_custom = 0; *num_custom = 0;
if (pog_sig == 0x47495050 && pog_ver == 2) /* PPIG */ if (pog_sig == 0x47495050 && pog_ver == 2) /* PPIG */
no_repl = 1; no_repl = 1;
else if (pog_sig != 0x474f5044 || pog_ver != 1) /* DPOG */ else if (pog_sig != 0x474f5044 || pog_ver != 1) /* DPOG */
return -1; // no pig2/pog file/unknown version return -1; // no pig2/pog file/unknown version
num_bitmaps = cfile_read_int(f); num_bitmaps = cfile_read_int(f);
if (!(*ci = cip = d_malloc(num_bitmaps * sizeof(struct custom_info)))) if (!(*ci = cip = d_malloc(num_bitmaps * sizeof(struct custom_info))))
return -1; // out of memory return -1; // out of memory
data_ofs = 12 + num_bitmaps * sizeof(DiskBitmapHeader2); data_ofs = 12 + num_bitmaps * sizeof(DiskBitmapHeader2);
if (!no_repl) {
if (!no_repl)
{
i = num_bitmaps; i = num_bitmaps;
while (i--) while (i--)
(cip++)->repl_idx = cfile_read_short(f); (cip++)->repl_idx = cfile_read_short(f);
cip = *ci; cip = *ci;
data_ofs += num_bitmaps * 2; data_ofs += num_bitmaps * 2;
} }
#ifdef D2TMAP_CONV #ifdef D2TMAP_CONV
if (d2tmap) if (d2tmap)
for (i = 0; i < num_bitmaps; i++) { for (i = 0; i < num_bitmaps; i++)
{
x = cip[i].repl_idx; x = cip[i].repl_idx;
cip[i].repl_idx = -1; cip[i].repl_idx = -1;
for (j = 0; j < N_d2tmap; j++) for (j = 0; j < N_d2tmap; j++)
if (x == d2tmap[j]) { if (x == d2tmap[j])
{
cip[i].repl_idx = Textures[j % NumTextures].index; cip[i].repl_idx = Textures[j % NumTextures].index;
break; break;
} }
} }
#endif #endif
i = num_bitmaps; i = num_bitmaps;
while (i--) {
if (cfread(&bmh, sizeof(DiskBitmapHeader2), 1, f) < 1) { while (i--)
{
if (cfread(&bmh, sizeof(DiskBitmapHeader2), 1, f) < 1)
{
d_free(*ci); d_free(*ci);
return -1; return -1;
} }
cip->offset = bmh.offset + data_ofs; cip->offset = bmh.offset + data_ofs;
cip->flags = bmh.flags & (BM_FLAG_TRANSPARENT | cip->flags = bmh.flags & (BM_FLAG_TRANSPARENT | BM_FLAG_SUPER_TRANSPARENT | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE);
BM_FLAG_SUPER_TRANSPARENT | BM_FLAG_NO_LIGHTING | BM_FLAG_RLE);
cip->width = bmh.width + ((bmh.hi_wh & 15) << 8); cip->width = bmh.width + ((bmh.hi_wh & 15) << 8);
cip->height = bmh.height + ((bmh.hi_wh >> 4) << 8); cip->height = bmh.height + ((bmh.hi_wh >> 4) << 8);
cip++; cip++;
} }
*num_custom = num_bitmaps; *num_custom = num_bitmaps;
return 0; return 0;
} }
// load custom textures/sounds from pog/pig file // load custom textures/sounds from pog/pig file
// returns 0 if ok, <0 on error // returns 0 if ok, <0 on error
int load_pigpog(char *pogname) { int load_pigpog(char *pogname)
{
int num_custom; int num_custom;
grs_bitmap *bmp; grs_bitmap *bmp;
digi_sound *snd; digi_sound *snd;
@ -235,42 +273,60 @@ int load_pigpog(char *pogname) {
if (!(f = cfopen((char *)pogname, "rb"))) if (!(f = cfopen((char *)pogname, "rb")))
return -1; // pog file doesn't exist return -1; // pog file doesn't exist
i = cfile_read_int(f); i = cfile_read_int(f);
x = cfile_read_int(f); x = cfile_read_int(f);
if (load_pog(f, i, x, &num_custom, &custom_info) &&
load_pig1(f, i, x, &num_custom, &custom_info)) if (load_pog(f, i, x, &num_custom, &custom_info) && load_pig1(f, i, x, &num_custom, &custom_info))
goto err; // unknown format/read error {
if (num_custom)
d_free(custom_info);
cfclose(f);
return rc;
}
cip = custom_info; cip = custom_info;
i = num_custom; i = num_custom;
while (i--) {
if ((x = cip->repl_idx) >= 0) { while (i--)
{
x = cip->repl_idx;
if (cip->repl_idx >= 0)
{
cfseek( f, cip->offset, SEEK_SET ); cfseek( f, cip->offset, SEEK_SET );
if ( cip->flags & BM_FLAG_RLE ) if ( cip->flags & BM_FLAG_RLE )
j = cfile_read_int(f); j = cfile_read_int(f);
else else
j = cip->width * cip->height; j = cip->width * cip->height;
if (!(p = d_malloc(j))) if (!(p = d_malloc(j)))
goto err; {
if (num_custom)
d_free(custom_info);
cfclose(f);
return rc;
}
bmp = &GameBitmaps[x]; bmp = &GameBitmaps[x];
if (BitmapOriginal[x].bm_flags & 0x80) // already customized? if (BitmapOriginal[x].bm_flags & 0x80) // already customized?
gr_free_bitmap_data(bmp); gr_free_bitmap_data(bmp);
// free(bmp->bm_data); else
else { {
// save original bitmap info // save original bitmap info
BitmapOriginal[x] = *bmp; BitmapOriginal[x] = *bmp;
BitmapOriginal[x].bm_flags |= 0x80; BitmapOriginal[x].bm_flags |= 0x80;
if (GameBitmapOffset[x]) { // from pig? if (GameBitmapOffset[x]) // from pig?
{
BitmapOriginal[x].bm_flags |= BM_FLAG_PAGED_OUT; BitmapOriginal[x].bm_flags |= BM_FLAG_PAGED_OUT;
BitmapOriginal[x].bm_data = (ubyte *)(size_t)GameBitmapOffset[x]; BitmapOriginal[x].bm_data = (ubyte *)(size_t)GameBitmapOffset[x];
} }
} }
GameBitmapOffset[x] = 0; // not in pig GameBitmapOffset[x] = 0; // not in pig
#ifndef NDEBUG
memset(bmp, 0, sizeof(*bmp)); memset(bmp, 0, sizeof(*bmp));
#endif gr_init_bitmap (bmp, 0, 0, 0, cip->width, cip->height, cip->width, p);
gr_init_bitmap (bmp, 0, 0, 0, cip->width, cip->height,
cip->width, p);
gr_set_bitmap_flags(bmp, cip->flags & 255); gr_set_bitmap_flags(bmp, cip->flags & 255);
bmp->avg_color = cip->flags >> 8; bmp->avg_color = cip->flags >> 8;
@ -279,32 +335,46 @@ int load_pigpog(char *pogname) {
if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data )) if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
Error( "Error modifying selector base in custom.c\n" ); Error( "Error modifying selector base in custom.c\n" );
#endif #endif
if ( cip->flags & BM_FLAG_RLE ) { if ( cip->flags & BM_FLAG_RLE )
{
int *ip = (int *)p; int *ip = (int *)p;
*ip = j; *ip = j;
p += 4; p += 4;
j -= 4; j -= 4;
} }
if (cfread(p, 1, j, f) < 1) if (cfread(p, 1, j, f) < 1)
goto err; {
#ifdef D1XD3D if (num_custom)
// needed to store rle flag d_free(custom_info);
gr_set_bitmap_data(bmp, bmp->bm_data); cfclose(f);
#endif return rc;
} else if ((x + 1) < 0) { }
}
else if ((cip->repl_idx + 1) < 0)
{
cfseek( f, cip->offset, SEEK_SET ); cfseek( f, cip->offset, SEEK_SET );
snd = &GameSounds[x & 0x7fffffff]; snd = &GameSounds[x & 0x7fffffff];
if (!(p = d_malloc(j = cip->width))) if (!(p = d_malloc(j = cip->width)))
goto err; {
if (SoundOriginal[x].length & 0x80000000) // already customized? if (num_custom)
d_free(custom_info);
cfclose(f);
return rc;
}
if (SoundOriginal[x & 0x7fffffff].length & 0x80000000) // already customized?
d_free(snd->data); d_free(snd->data);
else { else
{
#ifdef ALLEGRO #ifdef ALLEGRO
SoundOriginal[x].length = snd->len | 0x80000000; SoundOriginal[x & 0x7fffffff].length = snd->len | 0x80000000;
#else #else
SoundOriginal[x].length = snd->length | 0x80000000; SoundOriginal[x & 0x7fffffff].length = snd->length | 0x80000000;
#endif #endif
SoundOriginal[x].data = snd->data; SoundOriginal[x & 0x7fffffff].data = snd->data;
} }
#ifdef ALLEGRO #ifdef ALLEGRO
@ -313,15 +383,24 @@ int load_pigpog(char *pogname) {
snd->length = j; snd->length = j;
#endif #endif
snd->data = p; snd->data = p;
if (cfread(p, j, 1, f) < 1) if (cfread(p, j, 1, f) < 1)
goto err; {
if (num_custom)
d_free(custom_info);
cfclose(f);
return rc;
}
} }
cip++; cip++;
} }
rc = 0; rc = 0;
err:
if (num_custom) d_free(custom_info); if (num_custom)
d_free(custom_info);
cfclose(f); cfclose(f);
return rc; return rc;
} }
@ -330,6 +409,7 @@ int read_d2_robot_info(CFILE *fp, robot_info *ri)
int j, k; int j, k;
ri->model_num = cfile_read_int(fp); ri->model_num = cfile_read_int(fp);
for (j = 0; j < MAX_GUNS; j++) for (j = 0; j < MAX_GUNS; j++)
cfile_read_vector(&ri->gun_points[j], fp); cfile_read_vector(&ri->gun_points[j], fp);
for (j = 0; j < MAX_GUNS; j++) for (j = 0; j < MAX_GUNS; j++)
@ -400,17 +480,21 @@ int read_d2_robot_info(CFILE *fp, robot_info *ri)
/*ri->behavior =*/ cfile_read_byte(fp); /*ri->behavior =*/ cfile_read_byte(fp);
/*ri->aim =*/ cfile_read_byte(fp); /*ri->aim =*/ cfile_read_byte(fp);
for (j = 0; j < MAX_GUNS + 1; j++) { for (j = 0; j < MAX_GUNS + 1; j++)
for (k = 0; k < N_ANIM_STATES; k++) { {
for (k = 0; k < N_ANIM_STATES; k++)
{
ri->anim_states[j][k].n_joints = cfile_read_short(fp); ri->anim_states[j][k].n_joints = cfile_read_short(fp);
ri->anim_states[j][k].offset = cfile_read_short(fp); ri->anim_states[j][k].offset = cfile_read_short(fp);
} }
} }
ri->always_0xabcd = cfile_read_int(fp); ri->always_0xabcd = cfile_read_int(fp);
return 1; return 1;
} }
void load_hxm(char *hxmname) { void load_hxm(char *hxmname)
{
unsigned int repl_num; unsigned int repl_num;
int i; int i;
CFILE *f; CFILE *f;
@ -418,58 +502,100 @@ void load_hxm(char *hxmname) {
if (!(f = cfopen((char *)hxmname, "rb"))) if (!(f = cfopen((char *)hxmname, "rb")))
return; // hxm file doesn't exist return; // hxm file doesn't exist
if (cfile_read_int(f) != 0x21584d48) /* HMX! */ if (cfile_read_int(f) != 0x21584d48) /* HMX! */
goto err; // invalid hxm file {
cfclose(f); // invalid hxm file
return;
}
if (cfile_read_int(f) != 1) if (cfile_read_int(f) != 1)
goto err; // unknown version {
cfclose(f); // unknown version
return;
}
// read robot info // read robot info
if ((n_items = cfile_read_int(f)) != 0) { if ((n_items = cfile_read_int(f)) != 0)
for (i = 0; i < n_items; i++) { {
for (i = 0; i < n_items; i++)
{
repl_num = cfile_read_int(f); repl_num = cfile_read_int(f);
if (repl_num >= MAX_ROBOT_TYPES) if (repl_num >= MAX_ROBOT_TYPES)
{
cfseek(f, 480, SEEK_CUR); /* sizeof d2_robot_info */ cfseek(f, 480, SEEK_CUR); /* sizeof d2_robot_info */
}
else else
{
if (!(read_d2_robot_info(f, &Robot_info[repl_num]))) if (!(read_d2_robot_info(f, &Robot_info[repl_num])))
goto err; {
cfclose(f);
return;
}
}
} }
} }
// read joint positions // read joint positions
if ((n_items = cfile_read_int(f)) != 0) { if ((n_items = cfile_read_int(f)) != 0)
for (i = 0; i < n_items; i++) { {
for (i = 0; i < n_items; i++)
{
repl_num = cfile_read_int(f); repl_num = cfile_read_int(f);
if (repl_num >= MAX_ROBOT_JOINTS) if (repl_num >= MAX_ROBOT_JOINTS)
cfseek(f, sizeof(jointpos), SEEK_CUR); cfseek(f, sizeof(jointpos), SEEK_CUR);
else else
{
if (cfread(&Robot_joints[repl_num], sizeof(jointpos), 1, f) < 1) if (cfread(&Robot_joints[repl_num], sizeof(jointpos), 1, f) < 1)
goto err; {
cfclose(f);
return;
}
}
} }
} }
// read polygon models // read polygon models
if ((n_items = cfile_read_int(f)) != 0) { if ((n_items = cfile_read_int(f)) != 0)
for (i = 0; i < n_items; i++) { {
for (i = 0; i < n_items; i++)
{
polymodel *pm; polymodel *pm;
repl_num = cfile_read_int(f); repl_num = cfile_read_int(f);
if (repl_num >= MAX_POLYGON_MODELS) { if (repl_num >= MAX_POLYGON_MODELS)
{
cfile_read_int(f); // skip n_models cfile_read_int(f); // skip n_models
cfseek(f, 734 - 8 + cfile_read_int(f) + 8, SEEK_CUR); cfseek(f, 734 - 8 + cfile_read_int(f) + 8, SEEK_CUR);
} else { }
else
{
pm = &Polygon_models[repl_num]; pm = &Polygon_models[repl_num];
if (pm->model_data) if (pm->model_data)
d_free(pm->model_data); d_free(pm->model_data);
if (cfread(pm, sizeof(polymodel), 1, f) < 1) {
if (cfread(pm, sizeof(polymodel), 1, f) < 1)
{
pm->model_data = NULL; pm->model_data = NULL;
goto err; cfclose(f);
return;
} }
if (!(pm->model_data = d_malloc(pm->model_data_size))) if (!(pm->model_data = d_malloc(pm->model_data_size)))
goto err; {
if (cfread(pm->model_data, pm->model_data_size, 1, f) < 1) { cfclose(f);
pm->model_data = NULL; return;
goto err;
} }
if (cfread(pm->model_data, pm->model_data_size, 1, f) < 1)
{
pm->model_data = NULL;
cfclose(f);
return;
}
Dying_modelnums[repl_num] = cfile_read_int(f); Dying_modelnums[repl_num] = cfile_read_int(f);
Dead_modelnums[repl_num] = cfile_read_int(f); Dead_modelnums[repl_num] = cfile_read_int(f);
} }
@ -477,49 +603,55 @@ void load_hxm(char *hxmname) {
} }
// read object bitmaps // read object bitmaps
if ((n_items = cfile_read_int(f)) != 0) { if ((n_items = cfile_read_int(f)) != 0)
for (i = 0; i < n_items; i++) { {
for (i = 0; i < n_items; i++)
{
repl_num = cfile_read_int(f); repl_num = cfile_read_int(f);
if (repl_num >= MAX_OBJ_BITMAPS) if (repl_num >= MAX_OBJ_BITMAPS)
cfseek(f, 2, SEEK_CUR); cfseek(f, 2, SEEK_CUR);
else { else
ObjBitmaps[repl_num].index = cfile_read_short(f); ObjBitmaps[repl_num].index = cfile_read_short(f);
} }
} }
}
err:
cfclose(f); cfclose(f);
} }
// undo customized items // undo customized items
void custom_remove() { void custom_remove()
{
int i; int i;
grs_bitmap *bmo = BitmapOriginal; grs_bitmap *bmo = BitmapOriginal;
grs_bitmap *bmp = GameBitmaps; grs_bitmap *bmp = GameBitmaps;
for (i = 0; i < MAX_BITMAP_FILES; bmo++, bmp++, i++) for (i = 0; i < MAX_BITMAP_FILES; bmo++, bmp++, i++)
if (bmo->bm_flags & 0x80) { if (bmo->bm_flags & 0x80)
{
gr_free_bitmap_data(bmp); gr_free_bitmap_data(bmp);
*bmp = *bmo; *bmp = *bmo;
if (bmo->bm_flags & BM_FLAG_PAGED_OUT) {
if (bmo->bm_flags & BM_FLAG_PAGED_OUT)
{
GameBitmapOffset[i] = (int)(size_t)BitmapOriginal[i].bm_data; GameBitmapOffset[i] = (int)(size_t)BitmapOriginal[i].bm_data;
gr_set_bitmap_flags(bmp, BM_FLAG_PAGED_OUT); gr_set_bitmap_flags(bmp, BM_FLAG_PAGED_OUT);
gr_set_bitmap_data(bmp, Piggy_bitmap_cache_data); gr_set_bitmap_data(bmp, Piggy_bitmap_cache_data);
} else { }
else
{
gr_set_bitmap_flags(bmp, bmo->bm_flags & 0x7f); gr_set_bitmap_flags(bmp, bmo->bm_flags & 0x7f);
#ifdef BITMAP_SELECTOR #ifdef BITMAP_SELECTOR
if ( bmp->bm_selector ) if ( bmp->bm_selector )
if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data )) if (!dpmi_modify_selector_base( bmp->bm_selector, bmp->bm_data ))
Error( "Error modifying selector base in custom.c\n" ); Error( "Error modifying selector base in custom.c\n" );
#endif #endif
#ifdef D1XD3D
gr_set_bitmap_data(bmp, bmp->bm_data);
#endif
} }
bmo->bm_flags = 0; bmo->bm_flags = 0;
} }
for (i = 0; i < MAX_SOUND_FILES; i++) for (i = 0; i < MAX_SOUND_FILES; i++)
if (SoundOriginal[i].length & 0x80000000) { if (SoundOriginal[i].length & 0x80000000)
{
d_free(GameSounds[i].data); d_free(GameSounds[i].data);
GameSounds[i].data = SoundOriginal[i].data; GameSounds[i].data = SoundOriginal[i].data;
#ifdef ALLEGRO #ifdef ALLEGRO
@ -531,7 +663,8 @@ void custom_remove() {
} }
} }
void load_custom_data(char *level_name) { void load_custom_data(char *level_name)
{
char custom_file[64]; char custom_file[64];
custom_remove(); custom_remove();
@ -545,6 +678,7 @@ void load_custom_data(char *level_name) {
load_hxm(custom_file); load_hxm(custom_file);
} }
void custom_close() { void custom_close()
{
custom_remove(); custom_remove();
} }

View file

@ -697,6 +697,8 @@ void LoadLevel(int level_num)
load_endlevel_data(level_num); load_endlevel_data(level_num);
load_custom_data(level_name);
#ifdef NETWORK #ifdef NETWORK
reset_network_objects(); reset_network_objects();
#endif #endif
@ -1294,8 +1296,6 @@ void StartNewLevel(int level_num)
GameTime = 0; GameTime = 0;
load_custom_data(get_level_file(level_num));
if (!(Game_mode & GM_MULTI)) { if (!(Game_mode & GM_MULTI)) {
do_briefing_screens(Briefing_text_filename, level_num); do_briefing_screens(Briefing_text_filename, level_num);
} }