From 9e54684b11cf8e8e4ae19ebd2d754ee472c70089 Mon Sep 17 00:00:00 2001 From: Simon Howard Date: Tue, 30 Nov 2010 20:00:06 +0000 Subject: Add support for HACX v1.2 IWAD file. Subversion-branch: /trunk/chocolate-doom Subversion-revision: 2176 --- src/d_iwad.c | 35 ++++++++++----- src/d_main.c | 18 +++++++- src/deh_io.c | 139 +++++++++++++++++++++++++++++++++++++++++++++++---------- src/deh_io.h | 1 + src/deh_main.c | 54 ++++++++++++++++++++-- src/deh_main.h | 2 + src/doomdef.h | 1 + src/m_menu.c | 2 + 8 files changed, 213 insertions(+), 39 deletions(-) (limited to 'src') diff --git a/src/d_iwad.c b/src/d_iwad.c index ea0d29d0..89a7fba3 100644 --- a/src/d_iwad.c +++ b/src/d_iwad.c @@ -326,16 +326,22 @@ static struct {"doom.wad", doom}, {"doom1.wad", doom}, {"chex.wad", doom}, + {"hacx.wad", doom2}, }; - + // Hack for chex quest mode -static void CheckChex(char *iwad_name) +static void CheckSpecialIWADs(char *iwad_name) { - if (!strcmp(iwad_name, "chex.wad")) + if (!strcasecmp(iwad_name, "chex.wad")) { gameversion = exe_chex; } + + if (!strcasecmp(iwad_name, "hacx.wad")) + { + gameversion = exe_hacx; + } } // Returns true if the specified path is a path to a file @@ -408,7 +414,7 @@ static char *SearchDirectoryForIWAD(char *dir) if (filename != NULL) { - CheckChex(iwads[i].name); + CheckSpecialIWADs(iwads[i].name); gamemission = iwads[i].mission; return filename; @@ -441,7 +447,7 @@ static void IdentifyIWADByName(char *name) if (!strcasecmp(name + strlen(name) - strlen(iwadname), iwadname)) { - CheckChex(iwads[i].name); + CheckSpecialIWADs(iwads[i].name); gamemission = iwads[i].mission; break; } @@ -701,6 +707,13 @@ static char *SaveGameIWADName(void) return "chex.wad"; } + // Hacx hack + + if (gameversion == exe_hacx) + { + return "hacx.wad"; + } + // Find what subdirectory to use for savegames // // They should be stored in something like @@ -770,6 +783,10 @@ void D_SetSaveGameDir(void) static char *banners[] = { + // doom2.wad + " " + "DOOM 2: Hell on Earth v%i.%i" + " ", // doom1.wad " " "DOOM Shareware Startup v%i.%i" @@ -786,10 +803,6 @@ static char *banners[] = " " "The Ultimate DOOM Startup v%i.%i" " ", - // doom2.wad - " " - "DOOM 2: Hell on Earth v%i.%i" - " ", // tnt.wad " " "DOOM 2: TNT - Evilution v%i.%i" @@ -809,13 +822,13 @@ static char *GetGameName(char *gamename) { size_t i; char *deh_sub; - + for (i=0; i #include "i_system.h" +#include "w_wad.h" #include "z_zone.h" #include "deh_defs.h" #include "deh_io.h" +typedef enum +{ + DEH_INPUT_FILE, + DEH_INPUT_LUMP +} deh_input_type_t; + struct deh_context_s { - FILE *stream; + deh_input_type_t type; char *filename; + + // If the input comes from a memory buffer, pointer to the memory + // buffer. + + unsigned char *input_buffer; + size_t input_buffer_len; + unsigned int input_buffer_pos; + int lumpnum; + + // If the input comes from a file, the file stream for reading + // data. + + FILE *stream; + + // Current line number that we have reached: + int linenum; + + // Used by DEH_ReadLine: + boolean last_was_newline; char *readbuffer; int readbuffer_size; }; +static deh_context_t *DEH_NewContext(void) +{ + deh_context_t *context; + + context = Z_Malloc(sizeof(*context), PU_STATIC, NULL); + + // Initial read buffer size of 128 bytes + + context->readbuffer_size = 128; + context->readbuffer = Z_Malloc(context->readbuffer_size, PU_STATIC, NULL); + context->linenum = 0; + context->last_was_newline = true; + + return context; +} + // Open a dehacked file for reading // Returns NULL if open failed @@ -52,22 +94,41 @@ deh_context_t *DEH_OpenFile(char *filename) { FILE *fstream; deh_context_t *context; - + fstream = fopen(filename, "r"); if (fstream == NULL) return NULL; - context = Z_Malloc(sizeof(*context), PU_STATIC, NULL); + context = DEH_NewContext(); + + context->type = DEH_INPUT_FILE; context->stream = fstream; - - // Initial read buffer size of 128 bytes + context->filename = strdup(filename); - context->readbuffer_size = 128; - context->readbuffer = Z_Malloc(context->readbuffer_size, PU_STATIC, NULL); - context->filename = filename; - context->linenum = 0; - context->last_was_newline = true; + return context; +} + +// Open a WAD lump for reading. + +deh_context_t *DEH_OpenLump(int lumpnum) +{ + deh_context_t *context; + void *lump; + + lump = W_CacheLumpNum(lumpnum, PU_STATIC); + + context = DEH_NewContext(); + + context->type = DEH_INPUT_LUMP; + context->lumpnum = lumpnum; + context->input_buffer = lump; + context->input_buffer_len = W_LumpLength(lumpnum); + context->input_buffer_pos = 0; + + context->filename = malloc(9); + strncpy(context->filename, lumpinfo[lumpnum].name, 8); + context->filename[8] = '\0'; return context; } @@ -76,33 +137,65 @@ deh_context_t *DEH_OpenFile(char *filename) void DEH_CloseFile(deh_context_t *context) { - fclose(context->stream); + if (context->type == DEH_INPUT_FILE) + { + fclose(context->stream); + } + else if (context->type == DEH_INPUT_LUMP) + { + W_ReleaseLumpNum(context->lumpnum); + } + Z_Free(context->readbuffer); Z_Free(context); } +int DEH_GetCharFile(deh_context_t *context) +{ + if (feof(context->stream)) + { + // end of file + + return -1; + } + + return fgetc(context->stream); +} + +int DEH_GetCharLump(deh_context_t *context) +{ + int result; + + if (context->input_buffer_pos >= context->input_buffer_len) + { + return -1; + } + + result = context->input_buffer[context->input_buffer_pos]; + ++context->input_buffer_pos; + + return result; +} + // Reads a single character from a dehacked file int DEH_GetChar(deh_context_t *context) { int result; - + // Read characters, but ignore carriage returns // Essentially this is a DOS->Unix conversion - do + do { - if (feof(context->stream)) + switch (context->type) { - // end of file + case DEH_INPUT_FILE: + result = DEH_GetCharFile(context); - result = -1; + case DEH_INPUT_LUMP: + result = DEH_GetCharLump(context); } - else - { - result = fgetc(context->stream); - } - } while (result == '\r'); // Track the current line number @@ -111,9 +204,9 @@ int DEH_GetChar(deh_context_t *context) { ++context->linenum; } - + context->last_was_newline = result == '\n'; - + return result; } diff --git a/src/deh_io.h b/src/deh_io.h index 061a5a0e..9d22b360 100644 --- a/src/deh_io.h +++ b/src/deh_io.h @@ -30,6 +30,7 @@ #include "deh_defs.h" deh_context_t *DEH_OpenFile(char *filename); +deh_context_t *DEH_OpenLump(int lumpnum); void DEH_CloseFile(deh_context_t *context); int DEH_GetChar(deh_context_t *context); char *DEH_ReadLine(deh_context_t *context); diff --git a/src/deh_main.c b/src/deh_main.c index dcdfb00d..20498375 100644 --- a/src/deh_main.c +++ b/src/deh_main.c @@ -30,6 +30,7 @@ #include "doomtype.h" #include "d_iwad.h" #include "m_argv.h" +#include "w_wad.h" #include "deh_defs.h" #include "deh_io.h" @@ -281,9 +282,6 @@ static void DEH_ParseContext(deh_context_t *context) DEH_Error(context, "This is not a valid dehacked patch file!"); } - deh_allow_long_strings = false; - deh_allow_long_cheats = false; - // Read the file for (;;) @@ -295,7 +293,9 @@ static void DEH_ParseContext(deh_context_t *context) // end of file? if (line == NULL) + { return; + } while (line[0] != '\0' && isspace(line[0])) ++line; @@ -359,6 +359,11 @@ int DEH_LoadFile(char *filename) { deh_context_t *context; + // Vanilla dehacked files don't allow long string or cheat replacements. + + deh_allow_long_strings = false; + deh_allow_long_cheats = false; + printf(" loading %s\n", filename); context = DEH_OpenFile(filename); @@ -376,6 +381,48 @@ int DEH_LoadFile(char *filename) return 1; } +// Load dehacked file from WAD lump. + +int DEH_LoadLump(int lumpnum) +{ + deh_context_t *context; + + // If it's in a lump, it's probably designed for a modern source port, + // so allow it to do long string and cheat replacements. + + deh_allow_long_strings = true; + deh_allow_long_cheats = true; + + context = DEH_OpenLump(lumpnum); + + if (context == NULL) + { + fprintf(stderr, "DEH_LoadFile: Unable to open lump %i\n", lumpnum); + return 0; + } + + DEH_ParseContext(context); + + DEH_CloseFile(context); + + return 1; +} + +int DEH_LoadLumpByName(char *name) +{ + int lumpnum; + + lumpnum = W_CheckNumForName(name); + + if (lumpnum == -1) + { + fprintf(stderr, "DEH_LoadLumpByName: '%s' lump not found\n", name); + return 0; + } + + return DEH_LoadLump(lumpnum); +} + // Checks the command line for -deh argument void DEH_Init(void) @@ -418,4 +465,3 @@ void DEH_Init(void) } } - diff --git a/src/deh_main.h b/src/deh_main.h index 9248e982..4b58a1ad 100644 --- a/src/deh_main.h +++ b/src/deh_main.h @@ -42,6 +42,8 @@ void DEH_Init(void); int DEH_LoadFile(char *filename); +int DEH_LoadLump(int lumpnum); +int DEH_LoadLumpByName(char *name); boolean DEH_ParseAssignment(char *line, char **variable_name, char **value); diff --git a/src/doomdef.h b/src/doomdef.h index ff4d59a9..f9cd4fd9 100644 --- a/src/doomdef.h +++ b/src/doomdef.h @@ -104,6 +104,7 @@ typedef enum typedef enum { exe_doom_1_9, // Doom 1.9: used for shareware, registered and commercial + exe_hacx, // Hacx executable (Doom 1.9 with patch applied) exe_ultimate, // Ultimate Doom (retail) exe_final, // Final Doom exe_chex, // Chex Quest executable (based on Final Doom) diff --git a/src/m_menu.c b/src/m_menu.c index 5fb1ae7c..7b1c5a6e 100644 --- a/src/m_menu.c +++ b/src/m_menu.c @@ -784,6 +784,8 @@ void M_DrawReadThis1(void) switch (gameversion) { case exe_doom_1_9: + case exe_hacx: + if (gamemode == commercial) { // Doom 2 -- cgit v1.2.3