mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-21 20:11:12 +00:00
Remove lumpmod tool
Superceded by far superior tools
This commit is contained in:
parent
7a5f1dec9e
commit
405c2101c2
5 changed files with 0 additions and 1418 deletions
|
@ -1,16 +0,0 @@
|
||||||
# Makfile for SRB2 Lumpmod
|
|
||||||
# by Alam Arias et al.
|
|
||||||
|
|
||||||
SRC=lumpmod.c lump.c
|
|
||||||
OBJ=$(SRC:.c=.o)# replaces the .c from SRC with .o
|
|
||||||
EXE=lumpmod
|
|
||||||
|
|
||||||
.PHONY : all # .PHONY ignores files named all
|
|
||||||
all: $(EXE) # all is dependent on $(BIN) to be complete
|
|
||||||
|
|
||||||
$(EXE): $(OBJ) # $(EXE) is dependent on all of the files in $(OBJ) to exist
|
|
||||||
$(CC) $(OBJ) $(LDFLAGS) -o $@
|
|
||||||
|
|
||||||
.PHONY : clean # .PHONY ignores files named clean
|
|
||||||
clean:
|
|
||||||
-$(RM) $(OBJ) $(EXE)
|
|
|
@ -1,473 +0,0 @@
|
||||||
/*
|
|
||||||
LumpMod v0.2.1, a command-line utility for working with lumps in wad
|
|
||||||
files.
|
|
||||||
Copyright (C) 2003 Thunder Palace Entertainment.
|
|
||||||
|
|
||||||
This program 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
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
lump.c: Provides functions for dealing with lumps
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <ctype.h>
|
|
||||||
#include "lump.h"
|
|
||||||
|
|
||||||
/* Read contents of a wad file and store them in memory.
|
|
||||||
* fpoint is the file to read, opened with "rb" mode.
|
|
||||||
* A pointer to a new wadfile struct will be returned, or NULL on error.
|
|
||||||
*/
|
|
||||||
struct wadfile *read_wadfile(FILE *fpoint) {
|
|
||||||
struct wadfile *wfptr;
|
|
||||||
struct lumplist *curlump;
|
|
||||||
long diroffset, filelen;
|
|
||||||
unsigned long count;
|
|
||||||
|
|
||||||
/* Allocate memory for wadfile struct */
|
|
||||||
wfptr = malloc(sizeof(struct wadfile));
|
|
||||||
if(wfptr == NULL) return NULL;
|
|
||||||
|
|
||||||
/* Read first four characters (PWAD or IWAD) */
|
|
||||||
if(fread(wfptr->id, 4, 1, fpoint) < 1) {
|
|
||||||
free(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read number of lumps */
|
|
||||||
if(fread(&(wfptr->numlumps), 4, 1, fpoint) < 1) {
|
|
||||||
free(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If number of lumps is zero, nothing more needs to be done */
|
|
||||||
if(wfptr->numlumps == 0) {
|
|
||||||
wfptr->head = NULL;
|
|
||||||
return wfptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read offset of directory */
|
|
||||||
if(fread(&diroffset, 4, 1, fpoint) < 1) {
|
|
||||||
free(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Verify that the directory as long as it needs to be */
|
|
||||||
fseek(fpoint, 0, SEEK_END);
|
|
||||||
filelen = ftell(fpoint);
|
|
||||||
if((filelen - diroffset) / DIRENTRYLEN < wfptr->numlumps) {
|
|
||||||
free(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for head lumplist item and set head pointer */
|
|
||||||
curlump = malloc(sizeof(struct lumplist));
|
|
||||||
if(curlump == NULL) {
|
|
||||||
free(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
wfptr->head = curlump;
|
|
||||||
curlump->cl = NULL;
|
|
||||||
|
|
||||||
/* Read directory entries and lumps */
|
|
||||||
for(count = 0; count < wfptr->numlumps; count++) {
|
|
||||||
long lumpdataoffset;
|
|
||||||
|
|
||||||
/* Advance to a new list item */
|
|
||||||
curlump->next = malloc(sizeof(struct lumplist));
|
|
||||||
if(curlump->next == NULL) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
curlump = curlump->next;
|
|
||||||
curlump->next = NULL;
|
|
||||||
|
|
||||||
/* Allocate memory for the lump info */
|
|
||||||
curlump->cl = malloc(sizeof(struct lump));
|
|
||||||
if(curlump->cl == NULL) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Seek to the proper position in the file */
|
|
||||||
if(fseek(fpoint, diroffset + (count * DIRENTRYLEN), SEEK_SET) != 0) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read offset of lump data */
|
|
||||||
if(fread(&lumpdataoffset, 4, 1, fpoint) < 1) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read size of lump in bytes */
|
|
||||||
if(fread(&(curlump->cl->len), 4, 1, fpoint) < 1) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read lump name */
|
|
||||||
if(fread(curlump->cl->name, 8, 1, fpoint) < 1) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read actual lump data, unless lump size is 0 */
|
|
||||||
if(curlump->cl->len > 0) {
|
|
||||||
if(fseek(fpoint, lumpdataoffset, SEEK_SET) != 0) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Allocate memory for data */
|
|
||||||
curlump->cl->data = malloc(curlump->cl->len);
|
|
||||||
if(curlump->cl->data == NULL) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Fill the data buffer */
|
|
||||||
if(fread(curlump->cl->data, curlump->cl->len, 1, fpoint) < 1) {
|
|
||||||
free_wadfile(wfptr);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
} else curlump->cl->data = NULL;
|
|
||||||
} /* End of directory reading loop */
|
|
||||||
|
|
||||||
return wfptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free a wadfile from memory as well as all related structures.
|
|
||||||
*/
|
|
||||||
void free_wadfile(struct wadfile *wfptr) {
|
|
||||||
struct lumplist *curlump, *nextlump;
|
|
||||||
|
|
||||||
if(wfptr == NULL) return;
|
|
||||||
curlump = wfptr->head;
|
|
||||||
|
|
||||||
/* Free items in the lump list */
|
|
||||||
while(curlump != NULL) {
|
|
||||||
|
|
||||||
/* Free the actual lump and its data, if necessary */
|
|
||||||
if(curlump->cl != NULL) {
|
|
||||||
if(curlump->cl->data != NULL) free(curlump->cl->data);
|
|
||||||
free(curlump->cl);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to next lump and free this one */
|
|
||||||
nextlump = curlump->next;
|
|
||||||
free(curlump);
|
|
||||||
curlump = nextlump;
|
|
||||||
}
|
|
||||||
|
|
||||||
free(wfptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Write complete wadfile to a file stream, opened with "wb" mode.
|
|
||||||
* fpoint is the stream to write to.
|
|
||||||
* wfptr is a pointer to the wadfile structure to use.
|
|
||||||
* Return zero on success, nonzero on failure.
|
|
||||||
*/
|
|
||||||
int write_wadfile(FILE *fpoint, struct wadfile *wfptr) {
|
|
||||||
struct lumplist *curlump;
|
|
||||||
long lumpdataoffset, diroffset;
|
|
||||||
|
|
||||||
if(wfptr == NULL) return 1;
|
|
||||||
|
|
||||||
/* Write four-character ID ("PWAD" or "IWAD") */
|
|
||||||
if(fwrite(wfptr->id, 4, 1, fpoint) < 1) return 2;
|
|
||||||
|
|
||||||
/* Write number of lumps */
|
|
||||||
if(fwrite(&(wfptr->numlumps), 4, 1, fpoint) < 1) return 3;
|
|
||||||
|
|
||||||
/* Offset of directory is not known yet. For now, write number of lumps
|
|
||||||
* again, just to fill the space.
|
|
||||||
*/
|
|
||||||
if(fwrite(&(wfptr->numlumps), 4, 1, fpoint) < 1) return 4;
|
|
||||||
|
|
||||||
/* Loop through lump list, writing lump data */
|
|
||||||
for(curlump = wfptr->head; curlump != NULL; curlump = curlump->next) {
|
|
||||||
|
|
||||||
/* Don't write anything for the head of the lump list or for lumps of
|
|
||||||
zero length */
|
|
||||||
if(curlump->cl == NULL || curlump->cl->data == NULL) continue;
|
|
||||||
|
|
||||||
/* Write the data */
|
|
||||||
if(fwrite(curlump->cl->data, curlump->cl->len, 1, fpoint) < 1)
|
|
||||||
return 5;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Current position is where directory will start */
|
|
||||||
diroffset = ftell(fpoint);
|
|
||||||
|
|
||||||
/* Offset for the first lump's data is always 12 */
|
|
||||||
lumpdataoffset = 12;
|
|
||||||
|
|
||||||
/* Loop through lump list again, this time writing directory entries */
|
|
||||||
for(curlump = wfptr->head; curlump != NULL; curlump = curlump->next) {
|
|
||||||
|
|
||||||
/* Don't write anything for the head of the lump list */
|
|
||||||
if(curlump->cl == NULL) continue;
|
|
||||||
|
|
||||||
/* Write offset for lump data */
|
|
||||||
if(fwrite(&lumpdataoffset, 4, 1, fpoint) < 1) return 6;
|
|
||||||
|
|
||||||
/* Write size of lump data */
|
|
||||||
if(fwrite(&(curlump->cl->len), 4, 1, fpoint) < 1) return 7;
|
|
||||||
|
|
||||||
/* Write lump name */
|
|
||||||
if(fwrite(curlump->cl->name, 8, 1, fpoint) < 1) return 8;
|
|
||||||
|
|
||||||
/* Increment lumpdataoffset variable as appropriate */
|
|
||||||
lumpdataoffset += curlump->cl->len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Go back to header and write the proper directory offset */
|
|
||||||
fseek(fpoint, 8, SEEK_SET);
|
|
||||||
if(fwrite(&diroffset, 4, 1, fpoint) < 1) return 9;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the name of a lump, as a null-terminated string.
|
|
||||||
* item is a pointer to the lump (not lumplist) whose name will be obtained.
|
|
||||||
* Return NULL on error.
|
|
||||||
*/
|
|
||||||
char *get_lump_name(struct lump *item) {
|
|
||||||
char convname[9], *retname;
|
|
||||||
|
|
||||||
if(item == NULL) return NULL;
|
|
||||||
memcpy(convname, item->name, 8);
|
|
||||||
convname[8] = '\0';
|
|
||||||
|
|
||||||
retname = malloc(strlen(convname) + 1);
|
|
||||||
if(retname != NULL) strcpy(retname, convname);
|
|
||||||
return retname;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the lump after start and before end having a certain name.
|
|
||||||
* Return a pointer to the list item for that lump, or return NULL if no lump
|
|
||||||
* by that name is found or lumpname is too long.
|
|
||||||
* lumpname is a null-terminated string.
|
|
||||||
* If end parameter is NULL, search to the end of the entire list.
|
|
||||||
*/
|
|
||||||
struct lumplist *find_previous_lump(struct lumplist *start, struct lumplist
|
|
||||||
*end, char *lumpname) {
|
|
||||||
struct lumplist *curlump, *lastlump;
|
|
||||||
char *curname;
|
|
||||||
int found = 0;
|
|
||||||
|
|
||||||
/* Verify that parameters are valid */
|
|
||||||
if(start==NULL || start==end || lumpname==NULL || strlen(lumpname) > 8)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
/* Loop through the list from start parameter */
|
|
||||||
lastlump = start;
|
|
||||||
for(curlump = start->next; curlump != end && curlump != NULL;
|
|
||||||
curlump = curlump->next) {
|
|
||||||
|
|
||||||
/* Skip header lump */
|
|
||||||
if(curlump->cl == NULL) continue;
|
|
||||||
|
|
||||||
/* Find name of this lump */
|
|
||||||
curname = get_lump_name(curlump->cl);
|
|
||||||
if(curname == NULL) continue;
|
|
||||||
|
|
||||||
/* Compare names to see if this is the lump we want */
|
|
||||||
if(strcmp(curname, lumpname) == 0) {
|
|
||||||
found = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Free memory allocated to curname */
|
|
||||||
free(curname);
|
|
||||||
|
|
||||||
lastlump = curlump;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(found) return lastlump;
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Remove a lump from the list, free it, and free its data.
|
|
||||||
* before is the lump immediately preceding the lump to be removed.
|
|
||||||
* wfptr is a pointer to the wadfile structure to which the removed lump
|
|
||||||
* belongs, so that numlumps can be decreased.
|
|
||||||
*/
|
|
||||||
void remove_next_lump(struct wadfile *wfptr, struct lumplist *before) {
|
|
||||||
struct lumplist *removed;
|
|
||||||
|
|
||||||
/* Verify that parameters are valid */
|
|
||||||
if(before == NULL || before->next == NULL || wfptr == NULL) return;
|
|
||||||
|
|
||||||
/* Update linked list to omit removed lump */
|
|
||||||
removed = before->next;
|
|
||||||
before->next = removed->next;
|
|
||||||
|
|
||||||
/* Free lump info and data if necessary */
|
|
||||||
if(removed->cl != NULL) {
|
|
||||||
if(removed->cl->data != NULL) free(removed->cl->data);
|
|
||||||
free(removed->cl);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(removed);
|
|
||||||
|
|
||||||
/* Decrement numlumps */
|
|
||||||
wfptr->numlumps--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add a lump.
|
|
||||||
* The lump will follow prev in the list and be named name, with a data size
|
|
||||||
* of len.
|
|
||||||
* A copy will be made of the data.
|
|
||||||
* Return zero on success or nonzero on failure.
|
|
||||||
*/
|
|
||||||
int add_lump(struct wadfile *wfptr, struct lumplist *prev, char *name, long
|
|
||||||
len, unsigned char *data) {
|
|
||||||
struct lump *newlump;
|
|
||||||
struct lumplist *newlumplist;
|
|
||||||
unsigned char *copydata;
|
|
||||||
|
|
||||||
/* Verify that parameters are valid */
|
|
||||||
if(wfptr == NULL || prev == NULL || name == NULL || strlen(name) > 8)
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Allocate space for newlump and newlumplist */
|
|
||||||
newlump = malloc(sizeof(struct lump));
|
|
||||||
newlumplist = malloc(sizeof(struct lumplist));
|
|
||||||
if(newlump == NULL || newlumplist == NULL) return 2;
|
|
||||||
|
|
||||||
/* Copy lump data and set up newlump */
|
|
||||||
if(len == 0 || data == NULL) {
|
|
||||||
newlump->len = 0;
|
|
||||||
newlump->data = NULL;
|
|
||||||
} else {
|
|
||||||
newlump->len = len;
|
|
||||||
copydata = malloc(len);
|
|
||||||
if(copydata == NULL) return 3;
|
|
||||||
memcpy(copydata, data, len);
|
|
||||||
newlump->data = copydata;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set name of newlump */
|
|
||||||
memset(newlump->name, '\0', 8);
|
|
||||||
if(strlen(name) == 8) memcpy(newlump->name, name, 8);
|
|
||||||
else strcpy(newlump->name, name);
|
|
||||||
|
|
||||||
/* Set up newlumplist and alter prev appropriately */
|
|
||||||
newlumplist->cl = newlump;
|
|
||||||
newlumplist->next = prev->next;
|
|
||||||
prev->next = newlumplist;
|
|
||||||
|
|
||||||
/* Increment numlumps */
|
|
||||||
wfptr->numlumps++;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Rename a lump.
|
|
||||||
* renamed is a pointer to the lump (not lumplist) that needs renaming.
|
|
||||||
* newname is a null-terminated string with the new name.
|
|
||||||
* Return zero on success or nonzero on failure.
|
|
||||||
*/
|
|
||||||
int rename_lump(struct lump *renamed, char *newname) {
|
|
||||||
|
|
||||||
/* Verify that parameters are valid. */
|
|
||||||
if(newname == NULL || renamed == NULL || strlen(newname) > 8) return 1;
|
|
||||||
|
|
||||||
/* Do the renaming. */
|
|
||||||
memset(renamed->name, '\0', 8);
|
|
||||||
if(strlen(newname) == 8) memcpy(renamed->name, newname, 8);
|
|
||||||
else strcpy(renamed->name, newname);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the last lump in a wadfile structure.
|
|
||||||
* Return this lump or NULL on failure.
|
|
||||||
*/
|
|
||||||
struct lumplist *find_last_lump(struct wadfile *wfptr) {
|
|
||||||
struct lumplist *curlump;
|
|
||||||
|
|
||||||
if(wfptr == NULL || wfptr->head == NULL) return NULL;
|
|
||||||
curlump = wfptr->head;
|
|
||||||
|
|
||||||
while(curlump->next != NULL) curlump = curlump->next;
|
|
||||||
return curlump;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the last lump between start and end.
|
|
||||||
* Return this lump or NULL on failure.
|
|
||||||
*/
|
|
||||||
struct lumplist *find_last_lump_between(struct lumplist *start, struct
|
|
||||||
lumplist *end) {
|
|
||||||
struct lumplist *curlump;
|
|
||||||
|
|
||||||
if(start == NULL) return NULL;
|
|
||||||
curlump = start;
|
|
||||||
|
|
||||||
while(curlump->next != end) {
|
|
||||||
curlump = curlump->next;
|
|
||||||
if(curlump == NULL) break;
|
|
||||||
}
|
|
||||||
|
|
||||||
return curlump;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the next section lump. A section lump is MAPxx (0 <= x <= 9), ExMy
|
|
||||||
* (0 <= x <= 9, 0 <= y <= 9), or any lump whose name ends in _START or _END.
|
|
||||||
* Return NULL if there are no section lumps after start.
|
|
||||||
*/
|
|
||||||
struct lumplist *find_next_section_lump(struct lumplist *start) {
|
|
||||||
struct lumplist *curlump, *found = NULL;
|
|
||||||
char *curname;
|
|
||||||
|
|
||||||
/* Verify that parameter is valid */
|
|
||||||
if(start == NULL || start->next == NULL) return NULL;
|
|
||||||
|
|
||||||
/* Loop through the list from start parameter */
|
|
||||||
for(curlump = start->next; curlump != NULL && found == NULL;
|
|
||||||
curlump = curlump->next) {
|
|
||||||
|
|
||||||
/* Skip header lump */
|
|
||||||
if(curlump->cl == NULL) continue;
|
|
||||||
|
|
||||||
/* Find name of this lump */
|
|
||||||
curname = get_lump_name(curlump->cl);
|
|
||||||
if(curname == NULL) continue;
|
|
||||||
|
|
||||||
/* Check to see if this is a section lump */
|
|
||||||
if(strlen(curname) == 5 && strncmp("MAP", curname, 3) == 0 &&
|
|
||||||
isdigit(curname[3]) && isdigit(curname[4]))
|
|
||||||
found = curlump;
|
|
||||||
else if(strlen(curname) == 4 && curname[0] == 'E' && curname[2] ==
|
|
||||||
'M' && isdigit(curname[1]) && isdigit(curname[3]))
|
|
||||||
found = curlump;
|
|
||||||
else if(strlen(curname) == 7 && strcmp("_START", &curname[1]) == 0)
|
|
||||||
found = curlump;
|
|
||||||
else if(strlen(curname) == 8 && strcmp("_START", &curname[2]) == 0)
|
|
||||||
found = curlump;
|
|
||||||
else if(strlen(curname) == 5 && strcmp("_END", &curname[1]) == 0)
|
|
||||||
found = curlump;
|
|
||||||
else if(strlen(curname) == 6 && strcmp("_END", &curname[2]) == 0)
|
|
||||||
found = curlump;
|
|
||||||
|
|
||||||
/* Free memory allocated to curname */
|
|
||||||
free(curname);
|
|
||||||
}
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
|
@ -1,62 +0,0 @@
|
||||||
/*
|
|
||||||
LumpMod v0.2.1, a command-line utility for working with lumps in wad
|
|
||||||
files.
|
|
||||||
Copyright (C) 2003 Thunder Palace Entertainment.
|
|
||||||
|
|
||||||
This program 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
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
lump.h: Defines constants, structures, and functions used in lump.c
|
|
||||||
*/
|
|
||||||
|
|
||||||
#ifndef __LUMP_H
|
|
||||||
#define __LUMP_H
|
|
||||||
|
|
||||||
/* Entries in the wadfile directory are 16 bytes */
|
|
||||||
#define DIRENTRYLEN 16
|
|
||||||
|
|
||||||
/* Lumps and associated info */
|
|
||||||
struct lump {
|
|
||||||
long len;
|
|
||||||
unsigned char *data;
|
|
||||||
char name[8];
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Linked list of lumps */
|
|
||||||
struct lumplist {
|
|
||||||
struct lump *cl; /* actual content of the lump */
|
|
||||||
struct lumplist *next;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Structure to contain all wadfile data */
|
|
||||||
struct wadfile {
|
|
||||||
char id[4]; /* IWAD or PWAD */
|
|
||||||
long numlumps; /* 32-bit integer */
|
|
||||||
struct lumplist *head; /* points to first entry */
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Function declarations */
|
|
||||||
struct wadfile *read_wadfile(FILE *);
|
|
||||||
void free_wadfile(struct wadfile *);
|
|
||||||
int write_wadfile(FILE *, struct wadfile *);
|
|
||||||
char *get_lump_name(struct lump *);
|
|
||||||
struct lumplist *find_previous_lump(struct lumplist *, struct lumplist *, char *);
|
|
||||||
void remove_next_lump(struct wadfile *, struct lumplist *);
|
|
||||||
int add_lump(struct wadfile *, struct lumplist *, char *, long, unsigned char *);
|
|
||||||
int rename_lump(struct lump *, char *);
|
|
||||||
struct lumplist *find_last_lump(struct wadfile *);
|
|
||||||
struct lumplist *find_last_lump_between(struct lumplist *, struct lumplist *);
|
|
||||||
struct lumplist *find_next_section_lump(struct lumplist *);
|
|
||||||
|
|
||||||
#endif
|
|
|
@ -1,785 +0,0 @@
|
||||||
/*
|
|
||||||
LumpMod v0.2.1, a command-line utility for working with lumps in wad
|
|
||||||
files.
|
|
||||||
Copyright (C) 2003 Thunder Palace Entertainment.
|
|
||||||
|
|
||||||
This program 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
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
||||||
|
|
||||||
lumpmod.c: Provides program functionality; depends on lump.c and lump.h
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include "lump.h"
|
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
|
||||||
enum commands { C_ADD, C_ADDSECT, C_DELETE, C_DELSECT, C_EXTRACT, C_LIST,
|
|
||||||
C_RENAME, C_UPDATE } cmd;
|
|
||||||
struct wadfile *wfptr;
|
|
||||||
struct lumplist *startitem, *enditem = NULL;
|
|
||||||
FILE *fpoint;
|
|
||||||
char *progname, **params;
|
|
||||||
char *startname = NULL, *endname = NULL;
|
|
||||||
int numargs, numparams, insection = 0;
|
|
||||||
|
|
||||||
progname = argv[0];
|
|
||||||
numargs = argc - 1;
|
|
||||||
|
|
||||||
/* Verify that there are enough arguments */
|
|
||||||
if(numargs < 2) {
|
|
||||||
fprintf(stderr, "%s: not enough arguments\n", progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Identify the command used */
|
|
||||||
if(strcmp(argv[2], "add" ) == 0) cmd = C_ADD;
|
|
||||||
else if(strcmp(argv[2], "addsect") == 0) cmd = C_ADDSECT;
|
|
||||||
else if(strcmp(argv[2], "delete" ) == 0) cmd = C_DELETE;
|
|
||||||
else if(strcmp(argv[2], "delsect") == 0) cmd = C_DELSECT;
|
|
||||||
else if(strcmp(argv[2], "extract") == 0) cmd = C_EXTRACT;
|
|
||||||
else if(strcmp(argv[2], "list" ) == 0) cmd = C_LIST;
|
|
||||||
else if(strcmp(argv[2], "rename" ) == 0) cmd = C_RENAME;
|
|
||||||
else if(strcmp(argv[2], "update" ) == 0) cmd = C_UPDATE;
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "%s: invalid command %s\n", progname, argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Check for -s option */
|
|
||||||
if(numargs >= 4 && strcmp(argv[3], "-s") == 0) {
|
|
||||||
if(cmd == C_ADDSECT || cmd == C_DELSECT) {
|
|
||||||
fprintf(stderr, "%s: no option -s for command %s\n", progname, argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
insection = 1;
|
|
||||||
params = &argv[5];
|
|
||||||
numparams = numargs - 4;
|
|
||||||
|
|
||||||
/* Assume a map name if length > 2 */
|
|
||||||
if(strlen(argv[4]) > 2) startname = argv[4];
|
|
||||||
else {
|
|
||||||
startname = malloc(strlen(argv[4]) + 7);
|
|
||||||
endname = malloc(strlen(argv[4]) + 5);
|
|
||||||
if(startname == NULL || endname == NULL) {
|
|
||||||
fprintf(stderr, "%s: out of memory\n", progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
sprintf(startname, "%s_START", argv[4]);
|
|
||||||
sprintf(endname, "%s_END", argv[4]);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
params = &argv[3];
|
|
||||||
numparams = numargs - 2;
|
|
||||||
} /* end of check for -s option */
|
|
||||||
|
|
||||||
/* Load the wadfile into memory, since all commands require this */
|
|
||||||
fpoint = fopen(argv[1], "rb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: unable to open file %s\n", progname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
wfptr = read_wadfile(fpoint);
|
|
||||||
fclose(fpoint);
|
|
||||||
if(wfptr == NULL) {
|
|
||||||
fprintf(stderr, "%s: %s is not a valid wadfile\n", progname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find startitem and enditem, using startname and endname */
|
|
||||||
if(startname == NULL) startitem = wfptr->head;
|
|
||||||
else {
|
|
||||||
startitem = find_previous_lump(wfptr->head, NULL, startname);
|
|
||||||
if(startitem == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't find lump %s in %s", progname,
|
|
||||||
startname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
startitem = startitem->next;
|
|
||||||
if(endname == NULL) {
|
|
||||||
if(startitem->next != NULL) {
|
|
||||||
char *itemname;
|
|
||||||
|
|
||||||
enditem = startitem->next;
|
|
||||||
itemname = get_lump_name(enditem->cl);
|
|
||||||
while( strcmp(itemname, "THINGS" ) == 0 ||
|
|
||||||
strcmp(itemname, "LINEDEFS") == 0 ||
|
|
||||||
strcmp(itemname, "SIDEDEFS") == 0 ||
|
|
||||||
strcmp(itemname, "VERTEXES") == 0 ||
|
|
||||||
strcmp(itemname, "SEGS" ) == 0 ||
|
|
||||||
strcmp(itemname, "SSECTORS") == 0 ||
|
|
||||||
strcmp(itemname, "NODES" ) == 0 ||
|
|
||||||
strcmp(itemname, "SECTORS" ) == 0 ||
|
|
||||||
strcmp(itemname, "REJECT" ) == 0 ||
|
|
||||||
strcmp(itemname, "BLOCKMAP") == 0) {
|
|
||||||
enditem = enditem->next;
|
|
||||||
if(enditem == NULL) break;
|
|
||||||
free(itemname);
|
|
||||||
itemname = get_lump_name(enditem->cl);
|
|
||||||
}
|
|
||||||
free(itemname);
|
|
||||||
if(enditem != NULL) enditem = enditem->next;
|
|
||||||
} else enditem = NULL;
|
|
||||||
} else {
|
|
||||||
enditem = find_previous_lump(startitem, NULL, endname);
|
|
||||||
if(enditem == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't find lump %s in %s", progname,
|
|
||||||
endname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
enditem = enditem->next;
|
|
||||||
}
|
|
||||||
} /* end of finding startitem and enditem */
|
|
||||||
|
|
||||||
/* Do stuff specific to each command */
|
|
||||||
switch(cmd) {
|
|
||||||
case C_ADD: {
|
|
||||||
struct lumplist *startitem2, *before, *existing;
|
|
||||||
int overwrite = 1, firstentry = 0, canduplicate = 0;
|
|
||||||
char *startname2 = NULL;
|
|
||||||
|
|
||||||
/* Parse options: -a, -b, -d, -n */
|
|
||||||
while(numparams > 2) {
|
|
||||||
if(params[0][0] != '-') break;
|
|
||||||
if(strcmp(params[0], "-n") == 0) overwrite = 0;
|
|
||||||
else if(strcmp(params[0], "-d") == 0) canduplicate = 1;
|
|
||||||
else if(strcmp(params[0], "-b") == 0) firstentry = 1;
|
|
||||||
else if(strcmp(params[0], "-a") == 0) {
|
|
||||||
params = ¶ms[1];
|
|
||||||
numparams--;
|
|
||||||
startname2 = params[0];
|
|
||||||
} else {
|
|
||||||
fprintf(stderr, "%s: no option %s for command %s",
|
|
||||||
progname, params[0], argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
params = ¶ms[1];
|
|
||||||
numparams--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(numparams < 2) {
|
|
||||||
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
|
||||||
argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find the lump after which to add */
|
|
||||||
if(firstentry) before = startitem;
|
|
||||||
else if(startname2 != NULL) {
|
|
||||||
before = find_previous_lump(startitem, enditem, startname2);
|
|
||||||
if(before == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't find lump %s in %s", progname,
|
|
||||||
startname2, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
before = before->next;
|
|
||||||
} else {
|
|
||||||
if(insection) {
|
|
||||||
before = find_last_lump_between(startitem, enditem);
|
|
||||||
if(before == NULL) before = startitem;
|
|
||||||
} else before = find_last_lump(wfptr);
|
|
||||||
}
|
|
||||||
startitem2 = before;
|
|
||||||
|
|
||||||
/* Add LUMPNAME FILENAME pairs */
|
|
||||||
printf("Adding lumps in %s...\n", argv[1]);
|
|
||||||
for(;;) {
|
|
||||||
long newlumpsize;
|
|
||||||
unsigned char *newlumpdata;
|
|
||||||
|
|
||||||
/* Check whether the lump already exists, unless -d is used */
|
|
||||||
if(canduplicate) existing = NULL;
|
|
||||||
else existing = find_previous_lump(startitem, enditem, params[0]);
|
|
||||||
if(existing != NULL) existing = existing->next;
|
|
||||||
if(existing != NULL && overwrite == 0) {
|
|
||||||
printf("Lump %s already exists. Taking no action.\n", params[0]);
|
|
||||||
numparams -= 2;
|
|
||||||
if(numparams < 2) break;
|
|
||||||
params = ¶ms[2];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Read the file with new lump data */
|
|
||||||
fpoint = fopen(params[1], "rb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't open file %s\n", progname,
|
|
||||||
params[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find size of lump data */
|
|
||||||
fseek(fpoint, 0, SEEK_END);
|
|
||||||
newlumpsize = ftell(fpoint);
|
|
||||||
fseek(fpoint, 0, SEEK_SET);
|
|
||||||
|
|
||||||
/* Copy lump data to memory */
|
|
||||||
if(newlumpsize == 0) newlumpdata = NULL;
|
|
||||||
else {
|
|
||||||
newlumpdata = malloc(newlumpsize);
|
|
||||||
if(newlumpdata == NULL) {
|
|
||||||
fprintf(stderr, "%s: out of memory\n", progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(fread(newlumpdata, newlumpsize, 1, fpoint) < 1) {
|
|
||||||
fprintf(stderr, "%s: unable to read file %s\n",
|
|
||||||
progname, params[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the file */
|
|
||||||
fclose(fpoint);
|
|
||||||
|
|
||||||
/* Add or update lump */
|
|
||||||
if(existing == NULL) {
|
|
||||||
if(add_lump(wfptr, before, params[0], newlumpsize,
|
|
||||||
newlumpdata) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to add lump %s\n",
|
|
||||||
progname, params[0]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
printf("Lump %s added.\n", params[0]);
|
|
||||||
|
|
||||||
/* Other lumps will be added after the new one */
|
|
||||||
before = before->next;
|
|
||||||
} else {
|
|
||||||
existing->cl->len = newlumpsize;
|
|
||||||
free(existing->cl->data);
|
|
||||||
existing->cl->data = malloc(newlumpsize);
|
|
||||||
if(existing->cl->data == NULL) {
|
|
||||||
fprintf(stderr, "%s: out of memory\n", progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
memcpy(existing->cl->data, newlumpdata, newlumpsize);
|
|
||||||
printf("Lump %s updated.\n", params[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Advance to the next pair, if there is a next pair */
|
|
||||||
numparams -= 2;
|
|
||||||
if(numparams < 2) break;
|
|
||||||
params = ¶ms[2];
|
|
||||||
} /* end of adding LUMPNAME FILENAME pairs */
|
|
||||||
|
|
||||||
/* Save the modified wadfile */
|
|
||||||
fpoint = fopen(argv[1], "wb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
|
||||||
progname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(write_wadfile(fpoint, wfptr) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
|
||||||
progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
fclose(fpoint);
|
|
||||||
printf("File %s successfully updated.\n", argv[1]);
|
|
||||||
} /* end of C_ADD */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_UPDATE: {
|
|
||||||
struct lumplist *existing;
|
|
||||||
|
|
||||||
/* Parse options (none) */
|
|
||||||
if(numparams > 2 && params[0][0] == '-') {
|
|
||||||
fprintf(stderr, "%s: no option %s for command %s",
|
|
||||||
progname, params[0], argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(numparams < 2) {
|
|
||||||
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
|
||||||
argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Update LUMPNAME FILENAME pairs */
|
|
||||||
printf("Updating lumps in %s...\n", argv[1]);
|
|
||||||
for(;;) {
|
|
||||||
long newlumpsize;
|
|
||||||
unsigned char *newlumpdata;
|
|
||||||
|
|
||||||
/* Check whether the lump already exists */
|
|
||||||
existing = find_previous_lump(startitem, enditem, params[0]);
|
|
||||||
if(existing == NULL) {
|
|
||||||
printf("Lump %s does not exist. Taking no action.\n",
|
|
||||||
params[0]);
|
|
||||||
numparams -= 2;
|
|
||||||
if(numparams < 2) break;
|
|
||||||
params = ¶ms[2];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
existing = existing->next;
|
|
||||||
|
|
||||||
/* Read the file with new lump data */
|
|
||||||
fpoint = fopen(params[1], "rb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't open file %s\n", progname,
|
|
||||||
params[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find size of lump data */
|
|
||||||
fseek(fpoint, 0, SEEK_END);
|
|
||||||
newlumpsize = ftell(fpoint);
|
|
||||||
fseek(fpoint, 0, SEEK_SET);
|
|
||||||
|
|
||||||
/* Copy lump data to memory */
|
|
||||||
if(newlumpsize == 0) newlumpdata = NULL;
|
|
||||||
else {
|
|
||||||
newlumpdata = malloc(newlumpsize);
|
|
||||||
if(newlumpdata == NULL) {
|
|
||||||
fprintf(stderr, "%s: out of memory\n", progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(fread(newlumpdata, newlumpsize, 1, fpoint) < 1) {
|
|
||||||
fprintf(stderr, "%s: unable to read file %s\n",
|
|
||||||
progname, params[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the file */
|
|
||||||
fclose(fpoint);
|
|
||||||
|
|
||||||
/* Update lump */
|
|
||||||
existing->cl->len = newlumpsize;
|
|
||||||
free(existing->cl->data);
|
|
||||||
existing->cl->data = malloc(newlumpsize);
|
|
||||||
if(existing->cl->data == NULL) {
|
|
||||||
fprintf(stderr, "%s: out of memory\n", progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
memcpy(existing->cl->data, newlumpdata, newlumpsize);
|
|
||||||
printf("Lump %s updated.\n", params[0]);
|
|
||||||
|
|
||||||
/* Advance to the next pair, if there is a next pair */
|
|
||||||
numparams -= 2;
|
|
||||||
if(numparams < 2) break;
|
|
||||||
params = ¶ms[2];
|
|
||||||
} /* end of updating LUMPNAME FILENAME pairs */
|
|
||||||
|
|
||||||
/* Save the modified wadfile */
|
|
||||||
fpoint = fopen(argv[1], "wb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
|
||||||
progname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(write_wadfile(fpoint, wfptr) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
|
||||||
progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
fclose(fpoint);
|
|
||||||
printf("File %s successfully updated.\n", argv[1]);
|
|
||||||
} /* end of C_UPDATE */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_DELETE: {
|
|
||||||
struct lumplist *before;
|
|
||||||
|
|
||||||
/* Parse options (none) */
|
|
||||||
if(numparams > 1 && params[0][0] == '-') {
|
|
||||||
fprintf(stderr, "%s: no option %s for command %s",
|
|
||||||
progname, params[0], argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(numparams < 1) {
|
|
||||||
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
|
||||||
argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete LUMPNAME lumps */
|
|
||||||
printf("Deleting lumps in %s...\n", argv[1]);
|
|
||||||
for(;;) {
|
|
||||||
|
|
||||||
/* Find the lump to delete */
|
|
||||||
before = find_previous_lump(startitem, enditem, params[0]);
|
|
||||||
if(before == NULL) {
|
|
||||||
printf("Lump %s does not exist. Taking no action.\n",
|
|
||||||
params[0]);
|
|
||||||
numparams--;
|
|
||||||
if(numparams < 1) break;
|
|
||||||
params = ¶ms[1];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete it */
|
|
||||||
remove_next_lump(wfptr, before);
|
|
||||||
printf("Lump %s deleted.\n", params[0]);
|
|
||||||
|
|
||||||
/* Advance to the next item to delete, if there is one */
|
|
||||||
numparams--;
|
|
||||||
if(numparams < 1) break;
|
|
||||||
params = ¶ms[1];
|
|
||||||
} /* end of deleting LUMPNAME lumps */
|
|
||||||
|
|
||||||
/* Save the modified wadfile */
|
|
||||||
fpoint = fopen(argv[1], "wb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
|
||||||
progname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(write_wadfile(fpoint, wfptr) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
|
||||||
progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
fclose(fpoint);
|
|
||||||
printf("File %s successfully updated.\n", argv[1]);
|
|
||||||
} /* end of C_DELETE */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_RENAME: {
|
|
||||||
struct lumplist *renamed;
|
|
||||||
|
|
||||||
/* Parse options (none) */
|
|
||||||
if(numparams > 2 && params[0][0] == '-') {
|
|
||||||
fprintf(stderr, "%s: no option %s for command %s",
|
|
||||||
progname, params[0], argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(numparams < 2) {
|
|
||||||
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
|
||||||
argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Rename OLDNAME NEWNAME pairs */
|
|
||||||
printf("Renaming lumps in %s...\n", argv[1]);
|
|
||||||
for(;;) {
|
|
||||||
|
|
||||||
/* Find the lump to rename */
|
|
||||||
renamed = find_previous_lump(startitem, enditem, params[0]);
|
|
||||||
if(renamed == NULL) {
|
|
||||||
printf("Lump %s does not exist. Taking no action.\n",
|
|
||||||
params[0]);
|
|
||||||
numparams -= 2;
|
|
||||||
if(numparams < 2) break;
|
|
||||||
params = ¶ms[2];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
renamed = renamed->next;
|
|
||||||
|
|
||||||
/* Rename lump */
|
|
||||||
memset(renamed->cl->name, '\0', 8);
|
|
||||||
if(strlen(params[1]) >= 8) memcpy(renamed->cl->name,
|
|
||||||
params[1], 8);
|
|
||||||
else strcpy(renamed->cl->name, params[1]);
|
|
||||||
|
|
||||||
printf("Lump %s renamed to %s.\n", params[0], params[1]);
|
|
||||||
|
|
||||||
/* Advance to the next pair, if there is a next pair */
|
|
||||||
numparams -= 2;
|
|
||||||
if(numparams < 2) break;
|
|
||||||
params = ¶ms[2];
|
|
||||||
} /* end of renaming OLDNAME NEWNAME pairs */
|
|
||||||
|
|
||||||
/* Save the modified wadfile */
|
|
||||||
fpoint = fopen(argv[1], "wb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
|
||||||
progname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(write_wadfile(fpoint, wfptr) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
|
||||||
progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
fclose(fpoint);
|
|
||||||
printf("File %s successfully updated.\n", argv[1]);
|
|
||||||
} /* end of C_RENAME */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_EXTRACT: {
|
|
||||||
struct lumplist *extracted;
|
|
||||||
|
|
||||||
/* Parse options (none) */
|
|
||||||
if(numparams > 2 && params[0][0] == '-') {
|
|
||||||
fprintf(stderr, "%s: no option %s for command %s",
|
|
||||||
progname, params[0], argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(numparams < 2) {
|
|
||||||
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
|
||||||
argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract LUMPNAME FILENAME pairs */
|
|
||||||
printf("Extracting lumps from %s...\n", argv[1]);
|
|
||||||
for(;;) {
|
|
||||||
|
|
||||||
/* Find the lump to extract */
|
|
||||||
extracted = find_previous_lump(startitem, enditem, params[0]);
|
|
||||||
if(extracted == NULL) {
|
|
||||||
printf("Lump %s does not exist. Taking no action.\n",
|
|
||||||
params[0]);
|
|
||||||
numparams -= 2;
|
|
||||||
if(numparams < 2) break;
|
|
||||||
params = ¶ms[2];
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
extracted = extracted->next;
|
|
||||||
|
|
||||||
/* Open the file to extract to */
|
|
||||||
fpoint = fopen(params[1], "wb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't open file %s for writing\n",
|
|
||||||
progname, params[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Extract lump */
|
|
||||||
if(fwrite(extracted->cl->data, extracted->cl->len, 1, fpoint)
|
|
||||||
< 1) {
|
|
||||||
fprintf(stderr, "%s: unable to write lump %s to disk\n",
|
|
||||||
progname, params[0]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Close the file */
|
|
||||||
fclose(fpoint);
|
|
||||||
printf("Lump %s saved as %s.\n", params[0], params[1]);
|
|
||||||
|
|
||||||
/* Advance to the next pair, if there is a next pair */
|
|
||||||
numparams -= 2;
|
|
||||||
if(numparams < 2) break;
|
|
||||||
params = ¶ms[2];
|
|
||||||
} /* end of extracting LUMPNAME FILENAME pairs */
|
|
||||||
|
|
||||||
printf("Finished extracting lumps from file %s.\n", argv[1]);
|
|
||||||
} /* end of C_EXTRACT */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_LIST: {
|
|
||||||
struct lumplist *curlump;
|
|
||||||
int verbose = 0, i = 0;
|
|
||||||
|
|
||||||
/* Parse options: -v */
|
|
||||||
while(numparams > 0) {
|
|
||||||
if(params[0][0] != '-') break;
|
|
||||||
if(strcmp(params[0], "-v") == 0) verbose = 1;
|
|
||||||
else {
|
|
||||||
fprintf(stderr, "%s: no option %s for command %s",
|
|
||||||
progname, params[0], argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
params = ¶ms[1];
|
|
||||||
numparams--;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Loop through the lump list, printing lump info */
|
|
||||||
for(curlump = startitem->next; curlump != enditem; curlump =
|
|
||||||
curlump->next) {
|
|
||||||
i++;
|
|
||||||
if(verbose) printf("%5i %-8s %7li\n", i,
|
|
||||||
get_lump_name(curlump->cl), curlump->cl->len);
|
|
||||||
else printf("%s\n", get_lump_name(curlump->cl));
|
|
||||||
}
|
|
||||||
} /* end of C_LIST */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_DELSECT: {
|
|
||||||
|
|
||||||
/* Parse options (none) */
|
|
||||||
if(numparams > 1 && params[0][0] == '-') {
|
|
||||||
fprintf(stderr, "%s: no option %s for command %s",
|
|
||||||
progname, params[0], argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(numparams < 1) {
|
|
||||||
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
|
||||||
argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Delete sections */
|
|
||||||
printf("Deleting sections in %s...\n", argv[1]);
|
|
||||||
for(;;) {
|
|
||||||
struct lumplist *curlump;
|
|
||||||
|
|
||||||
/* Assume a map name if length > 2 */
|
|
||||||
if(strlen(params[0]) > 2) startname = params[0];
|
|
||||||
else {
|
|
||||||
startname = malloc(strlen(params[0]) + 7);
|
|
||||||
endname = malloc(strlen(params[0]) + 5);
|
|
||||||
if(startname == NULL || endname == NULL) {
|
|
||||||
fprintf(stderr, "%s: out of memory\n", progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
sprintf(startname, "%s_START", params[0]);
|
|
||||||
sprintf(endname, "%s_END", params[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Find startitem and enditem, using startname and endname */
|
|
||||||
startitem = find_previous_lump(wfptr->head, NULL, startname);
|
|
||||||
if(startitem == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't find lump %s in %s", progname,
|
|
||||||
startname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(endname == NULL && startitem->next != NULL) {
|
|
||||||
char *itemname;
|
|
||||||
|
|
||||||
enditem = startitem->next;
|
|
||||||
itemname = get_lump_name(enditem->cl);
|
|
||||||
do {
|
|
||||||
enditem = enditem->next;
|
|
||||||
if(enditem == NULL) break;
|
|
||||||
free(itemname);
|
|
||||||
itemname = get_lump_name(enditem->cl);
|
|
||||||
} while(strcmp(itemname, "THINGS" ) == 0 ||
|
|
||||||
strcmp(itemname, "LINEDEFS") == 0 ||
|
|
||||||
strcmp(itemname, "SIDEDEFS") == 0 ||
|
|
||||||
strcmp(itemname, "VERTEXES") == 0 ||
|
|
||||||
strcmp(itemname, "SEGS" ) == 0 ||
|
|
||||||
strcmp(itemname, "SSECTORS") == 0 ||
|
|
||||||
strcmp(itemname, "NODES" ) == 0 ||
|
|
||||||
strcmp(itemname, "SECTORS" ) == 0 ||
|
|
||||||
strcmp(itemname, "REJECT" ) == 0 ||
|
|
||||||
strcmp(itemname, "BLOCKMAP") == 0);
|
|
||||||
free(itemname);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
enditem = find_previous_lump(startitem, NULL, endname);
|
|
||||||
if(enditem == NULL) {
|
|
||||||
fprintf(stderr, "%s: can't find lump %s in %s",
|
|
||||||
progname, endname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
enditem = enditem->next->next;
|
|
||||||
} /* end of finding startitem and enditem */
|
|
||||||
|
|
||||||
/* Loop through the section lumps, deleting them */
|
|
||||||
curlump = startitem;
|
|
||||||
while(curlump->next != enditem)
|
|
||||||
remove_next_lump(wfptr, curlump);
|
|
||||||
printf("Deleted section %s.\n", params[0]);
|
|
||||||
|
|
||||||
/* Move to next parameter, if it exists */
|
|
||||||
numparams--;
|
|
||||||
if(numparams < 1) break;
|
|
||||||
params = ¶ms[1];
|
|
||||||
} /* end of deleting sections */
|
|
||||||
|
|
||||||
/* Save the modified wadfile */
|
|
||||||
fpoint = fopen(argv[1], "wb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
|
||||||
progname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(write_wadfile(fpoint, wfptr) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
|
||||||
progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
fclose(fpoint);
|
|
||||||
printf("File %s successfully updated.\n", argv[1]);
|
|
||||||
} /* end of C_DELSECT */
|
|
||||||
break;
|
|
||||||
|
|
||||||
case C_ADDSECT: {
|
|
||||||
|
|
||||||
/* Parse options (none) */
|
|
||||||
if(numparams > 1 && params[0][0] == '-') {
|
|
||||||
fprintf(stderr, "%s: no option %s for command %s",
|
|
||||||
progname, params[0], argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(numparams < 1) {
|
|
||||||
fprintf(stderr, "%s: not enough parameters for %s", progname,
|
|
||||||
argv[2]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add sections */
|
|
||||||
printf("Adding sections in %s...\n", argv[1]);
|
|
||||||
for(;;) {
|
|
||||||
struct lumplist *curlump;
|
|
||||||
|
|
||||||
/* Assume a map name if length > 2 */
|
|
||||||
if(strlen(params[0]) > 2) startname = params[0];
|
|
||||||
else {
|
|
||||||
startname = malloc(strlen(params[0]) + 7);
|
|
||||||
endname = malloc(strlen(params[0]) + 5);
|
|
||||||
if(startname == NULL || endname == NULL) {
|
|
||||||
fprintf(stderr, "%s: out of memory\n", progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
sprintf(startname, "%s_START", params[0]);
|
|
||||||
sprintf(endname, "%s_END", params[0]);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add section, unless it already exists */
|
|
||||||
if(find_previous_lump(wfptr->head, NULL, startname) == NULL) {
|
|
||||||
struct lumplist *last;
|
|
||||||
|
|
||||||
last = find_last_lump(wfptr);
|
|
||||||
if(add_lump(wfptr, last, startname, 0, NULL) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to add lump %s\n",
|
|
||||||
progname, startname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(endname != NULL) {
|
|
||||||
last = last->next;
|
|
||||||
if(add_lump(wfptr, last, endname, 0, NULL) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to add lump %s\n",
|
|
||||||
progname, endname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Added section %s.\n", params[0]);
|
|
||||||
} else
|
|
||||||
printf("Section %s already exists. Taking no action.\n",
|
|
||||||
params[0]);
|
|
||||||
|
|
||||||
/* Move to next parameter, if it exists */
|
|
||||||
numparams--;
|
|
||||||
if(numparams < 1) break;
|
|
||||||
params = ¶ms[1];
|
|
||||||
} /* end of adding sections */
|
|
||||||
|
|
||||||
/* Save the modified wadfile */
|
|
||||||
fpoint = fopen(argv[1], "wb");
|
|
||||||
if(fpoint == NULL) {
|
|
||||||
fprintf(stderr, "%s: unable to open file %s for writing\n",
|
|
||||||
progname, argv[1]);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
if(write_wadfile(fpoint, wfptr) != 0) {
|
|
||||||
fprintf(stderr, "%s: unable to write wadfile to disk\n",
|
|
||||||
progname);
|
|
||||||
return EXIT_FAILURE;
|
|
||||||
}
|
|
||||||
fclose(fpoint);
|
|
||||||
printf("File %s successfully updated.\n", argv[1]);
|
|
||||||
} /* end of C_ADDSECT */
|
|
||||||
} /* end of command-specific stuff */
|
|
||||||
|
|
||||||
return EXIT_SUCCESS;
|
|
||||||
}
|
|
|
@ -1,82 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
|
|
||||||
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
|
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en">
|
|
||||||
<head><meta http-equiv="content-type"
|
|
||||||
content="application/xhtml+xml; charset=utf-8" />
|
|
||||||
<title>LumpMod v0.2.1 Documentation</title></head><body>
|
|
||||||
<h1>LumpMod v0.2.1</h1>
|
|
||||||
<p>LumpMod is a small command-line utility for working with lumps in wad
|
|
||||||
files in the format used by DOOM and DOOM 2. It can add, delete, extract,
|
|
||||||
rename, list, and update individual lumps. It can also add sections
|
|
||||||
(XX_START and XX_END, for instance) and delete entire sections.</p>
|
|
||||||
<h2>Usage</h2>
|
|
||||||
<p><code>lumpmod [wadfile] [command] [-s section] [parameters]</code></p>
|
|
||||||
<p>Sections are MAPxx (xx = 01-99, where that map exists in the file), ExMy
|
|
||||||
(x, y = 1-9, where that map exists in the file), and anything else will be
|
|
||||||
the section between WHATEVER_START and WHATEVER_END. Sections that do not
|
|
||||||
exist in the wad file cannot be used. The section part can be left out to
|
|
||||||
work with the whole file. Any section specified here while using the addsect
|
|
||||||
or delsect commands will cause an error.</p>
|
|
||||||
<p>Note that the []... parameters in the command listings can be repeated.
|
|
||||||
For example, you can use <code>lumpmod clowns.wad add CLOWNS clowns.lmp</code> to
|
|
||||||
add a CLOWNS lump, or <code>lumpmod clowns.wad add CLOWN1 clown1.lmp CLOWN2
|
|
||||||
clown2.lmp</code> to add two clown-related lumps.</p>
|
|
||||||
<p>Note also that lump names and commands are case sensitive. There is an
|
|
||||||
<code>update</code> command, but no <code>UPDATE</code> command.</p>
|
|
||||||
<h2>Commands</h2>
|
|
||||||
<p><code>add [-a lumpname] [-b] [-d] [-n] [LUMPNAME FILENAME]...</code></p>
|
|
||||||
<p>Add a lump to the end of the wad, or after the lump specified with the -a
|
|
||||||
option. If the lump already exists, it will be overwritten (with its position
|
|
||||||
unchanged) unless the -n option is specified, in which case no action will be
|
|
||||||
taken, or the -d option is specified, in which case an additional lump with
|
|
||||||
the same name will be added. If the lump specified in the -a option does not
|
|
||||||
exist, an error will occur. The -b option will add the lump at the beginning,
|
|
||||||
overriding the -a option.</p>
|
|
||||||
<p><code>addsect [SECTNAME]...</code></p>
|
|
||||||
<p>Add a section. The name must be one or two characters long. If section
|
|
||||||
name is HX, zero-length entries HX_START and HX_END will be added to the end
|
|
||||||
of the wad file. If this section already exists, no action will be taken.</p>
|
|
||||||
<p><code>delete [LUMPNAME]...</code></p>
|
|
||||||
<p>Remove LUMPNAME from the wad.</p>
|
|
||||||
<p><code>delsect [SECTNAME]...</code></p>
|
|
||||||
<p>Delete a section and anything inside it. If the section doesn't exist, no
|
|
||||||
action will be taken.</p>
|
|
||||||
<p><code>extract [LUMPNAME FILENAME]...</code></p>
|
|
||||||
<p>Save the contents of LUMPNAME to the file named FILENAME. (Wad file will
|
|
||||||
not be changed in any way.)</p>
|
|
||||||
<p><code>list [-v]</code></p>
|
|
||||||
<p>List all lumps in the wad, in the order they appear in the directory.
|
|
||||||
With the -v option, include numbers and lump lengths.</p>
|
|
||||||
<p><code>rename [OLDNAME NEWNAME]...</code></p>
|
|
||||||
<p>Rename a lump in the wad.</p>
|
|
||||||
<p><code>update [LUMPNAME FILENAME]...</code></p>
|
|
||||||
<p>Update LUMPNAME with the contents of FILENAME. If no lump named LUMPNAME
|
|
||||||
exists in the wad, no action will be taken.</p>
|
|
||||||
<h2>Changes</h2>
|
|
||||||
<p>Version 0.2.1 adds the -d option to the add command.</p>
|
|
||||||
<p>Version 0.2 contains a fix to a bug involving empty sections. The initial
|
|
||||||
public release was version 0.1.</p>
|
|
||||||
<h2>Bugs</h2>
|
|
||||||
<p>LumpMod currently chokes on completely empty wad files (i.e., those that
|
|
||||||
contain absolutely no lumps). Let me know if you find any other bugs.</p>
|
|
||||||
<h2>Author</h2>
|
|
||||||
<p>Catatonic Porpoise, <<a href="mailto:graue@oceanbase.org">graue@oceanbase.org</a>>.
|
|
||||||
Updates can be found at <a href="http://www.thunderpalace.com/software/">http://www.thunderpalace.com/software/</a>.</p>
|
|
||||||
<h2>Thanks</h2>
|
|
||||||
<p>Thanks to Matthew S. Fell for writing "The Unofficial DOOM
|
|
||||||
Specs," which were very helpful in making this program.</p>
|
|
||||||
<h2>License</h2>
|
|
||||||
<p>Copyright © 2003 Thunder Palace Entertainment.</p>
|
|
||||||
<p>This program 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.</p>
|
|
||||||
<p>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.</p>
|
|
||||||
<p>You should have received a copy of the GNU General Public License
|
|
||||||
along with this program; if not, write to the Free Software
|
|
||||||
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.</p>
|
|
||||||
</body></html>
|
|
Loading…
Reference in a new issue