ref: bc4a39b2fe3f0883a7826fa998de6ea9825efada
dir: /src/heretic/deh_htext.c/
// Emacs style mode select -*- C++ -*-
//-----------------------------------------------------------------------------
//
// Copyright(C) 2005-2010 Simon Howard
//
// 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., 59 Temple Place - Suite 330, Boston, MA
// 02111-1307, USA.
//
//-----------------------------------------------------------------------------
//
// Parses Text substitution sections in dehacked files
//
//-----------------------------------------------------------------------------
#include <stdio.h>
#include <string.h>
#include "doomtype.h"
#include "dstrings.h"
#include "z_zone.h"
#include "deh_defs.h"
#include "deh_io.h"
#include "deh_main.h"
//
// Ok, Greg, the action pointers thing was bad enough, but this really
// takes the biscuit. Why does HHE's text replacement address strings
// by offset??!! The dehacked way was much nicer, why change it?
//
// Anyway, this is the Heretic 1.0 string table, which can be seen in
// HHE. This is the string and its offset from the start of the
// text section. Not all the strings are here; this is a redacted list
// that contains just the strings we support.
//
static const struct
{
unsigned int offset;
char *string;
}
string_table[] =
{
{ 0, NULL },
{ 4, NULL },
{ 64, NULL },
{ 104, NULL },
{ 160, NULL },
{ 200, NULL },
{ 220, NULL },
{ 228, "PLAYPAL" },
{ 236, NULL },
{ 244, NULL },
{ 252, NULL },
{ 272, NULL },
{ 288, NULL },
{ 296, NULL },
{ 316, NULL },
{ 332, NULL },
{ 372, NULL },
{ 436, NULL },
{ 504, NULL },
{ 536, NULL },
{ 544, NULL },
{ 560, NULL },
{ 576, NULL },
{ 584, "ENDTEXT" },
{ 592, NULL },
{ 612, NULL },
{ 640, NULL },
{ 664, NULL },
{ 712, NULL },
{ 744, NULL },
{ 764, NULL },
{ 808, NULL },
{ 820, NULL },
{ 828, NULL },
{ 840, NULL },
{ 876, NULL },
{ 884, NULL },
{ 908, NULL },
{ 952, NULL },
{ 992, NULL },
{ 1028, NULL },
{ 1036, NULL },
{ 1048, NULL },
{ 1088, NULL },
{ 1128, NULL },
{ 1160, NULL },
{ 1192, NULL },
{ 1212, NULL },
{ 1240, "E1M1: THE DOCKS" },
{ 1260, "E1M2: THE DUNGEONS" },
{ 1280, "E1M3: THE GATEHOUSE" },
{ 1304, "E1M4: THE GUARD TOWER" },
{ 1328, "E1M5: THE CITADEL" },
{ 1348, "E1M6: THE CATHEDRAL" },
{ 1372, "E1M7: THE CRYPTS" },
{ 1392, "E1M8: HELL'S MAW" },
{ 1412, "E1M9: THE GRAVEYARD" },
{ 1436, "E2M1: THE CRATER" },
{ 1456, "E2M2: THE LAVA PITS" },
{ 1480, "E2M3: THE RIVER OF FIRE" },
{ 1508, "E2M4: THE ICE GROTTO" },
{ 1532, "E2M5: THE CATACOMBS" },
{ 1556, "E2M6: THE LABYRINTH" },
{ 1580, "E2M7: THE GREAT HALL" },
{ 1604, "E2M8: THE PORTALS OF CHAOS" },
{ 1632, "E2M9: THE GLACIER" },
{ 1652, "E3M1: THE STOREHOUSE" },
{ 1676, "E3M2: THE CESSPOOL" },
{ 1696, "E3M3: THE CONFLUENCE" },
{ 1720, "E3M4: THE AZURE FORTRESS" },
{ 1748, "E3M5: THE OPHIDIAN LAIR" },
{ 1776, "E3M6: THE HALLS OF FEAR" },
{ 1804, "E3M7: THE CHASM" },
{ 1824, "E3M8: D'SPARIL'S KEEP" },
{ 1848, "E3M9: THE AQUIFER" },
{ 1868, "AUTOPAGE" },
{ 1880, "FOLLOW MODE ON" },
{ 1896, "FOLLOW MODE OFF" },
{ 1912, "GREEN: " },
{ 1936, "YELLOW: " },
{ 1948, "RED: " },
{ 1956, "BLUE: " },
{ 1964, "FONTA_S" },
{ 1972, "-MESSAGE SENT-" },
{ 1988, "THERE ARE NO OTHER PLAYERS IN THE GAME!" },
{ 2028, "FONTA59" },
{ 2036, "PAUSED" },
{ 2044, NULL },
{ 2056, NULL },
{ 2072, "ADVISOR" },
{ 2080, "TITLE" },
{ 2088, "demo1" },
{ 2096, "CREDIT" },
{ 2104, "demo2" },
{ 2112, "ORDER" },
{ 2120, "demo3" },
{ 2128, NULL },
{ 2140, NULL },
{ 2168, "hticsav%c.hsg" },
{ 2184, "heretic.wad" },
{ 2196, NULL },
{ 2212, NULL },
{ 2228, NULL },
{ 2240, "heretic.cfg" },
{ 2252, NULL },
{ 2264, NULL },
{ 2284, NULL },
{ 2304, "Exited from HERETIC.\n" },
{ 2328, NULL },
{ 2340, NULL },
{ 2352, NULL },
{ 2364, NULL },
{ 2372, NULL },
{ 2388, NULL },
{ 2404, NULL },
{ 2412, "c:\\heretic.cd" },
{ 2428, NULL },
{ 2436, NULL },
{ 2444, NULL },
{ 2464, NULL },
{ 2496, NULL },
{ 2508, NULL },
{ 2520, NULL },
{ 2528, "Playing demo %s.lmp.\n" },
{ 2552, NULL },
{ 2564, NULL },
{ 2572, NULL },
{ 2584, NULL },
{ 2592, "V_Init: allocate screens.\n" },
{ 2620, "M_LoadDefaults: Load system defaults.\n" },
{ 2660, "Z_Init: Init zone memory allocation daemon.\n" },
{ 2708, "W_Init: Init WADfiles.\n" },
{ 2732, "E2M1" },
{ 2740, "LOADING" },
{ 2748, "DeathMatch..." },
{ 2764, "No Monsters..." },
{ 2780, "Respawning..." },
{ 2796, "Warp to Episode %d, Map %d, Skill %d " },
{ 2836, "MN_Init: Init menu system.\n" },
{ 2864, "R_Init: Init Heretic refresh daemon." },
{ 2904, "Loading graphics" },
{ 2924, "P_Init: Init Playloop state." },
{ 2956, "Init game engine." },
{ 2976, "I_Init: Setting up machine state.\n" },
{ 3012, "D_CheckNetGame: Checking network game status.\n" },
{ 3060, "Checking network game status." },
{ 3092, "SB_Init: Loading patches.\n" },
{ 3120, NULL },
{ 3128, NULL },
{ 3140, NULL },
{ 3184, NULL },
{ 3220, NULL },
{ 3256, NULL },
{ 3280, NULL },
{ 3304, NULL },
{ 3320, NULL },
{ 3352, "PLAYER 1 HAS LEFT THE GAME" },
{ 3380, NULL },
{ 3432, NULL },
{ 3464, NULL },
{ 3508, NULL },
{ 3548, NULL },
{ 3600, NULL },
{ 3624, NULL },
{ 3664, NULL },
{ 3696, NULL },
{ 3736, "NET GAME" },
{ 3748, "SAVE GAME" },
{ 3760, "Only %i deathmatch spots, 4 required" },
{ 3800, "version %i" },
{ 3812, NULL },
{ 3828, NULL },
{ 3856, NULL },
{ 3872, NULL },
{ 3896, "GAME SAVED" },
{ 3908, "SKY1" },
{ 3916, "SKY2" },
{ 3924, "SKY3" },
{ 3932, NULL },
{ 3940, NULL },
{ 3976, NULL },
{ 3996, NULL },
{ 4016, E1TEXT },
{ 4536, E2TEXT },
{ 5068, E3TEXT },
{ 5632, "FLOOR25" },
{ 5640, "FLATHUH1" },
{ 5652, "FLTWAWA2" },
{ 5664, "FONTA_S" },
{ 5672, "FINAL1" },
{ 5680, "FINAL2" },
{ 5688, "E2PAL" },
{ 5696, "E2END" },
{ 5704, "PLAYPAL" },
{ 5712, "ORDER" },
{ 5720, "IMPX" },
{ 5728, "ACLO" },
{ 5736, "PTN1" },
{ 5744, "SHLD" },
{ 5752, "SHD2" },
{ 5760, "BAGH" },
{ 5768, "SPMP" },
{ 5776, "INVS" },
{ 5784, "PTN2" },
{ 5792, "SOAR" },
{ 5800, "INVU" },
{ 5808, "PWBK" },
{ 5816, "EGGC" },
{ 5824, "EGGM" },
{ 5832, "FX01" },
{ 5840, "SPHL" },
{ 5848, "TRCH" },
{ 5856, "FBMB" },
{ 5864, "XPL1" },
{ 5872, "ATLP" },
{ 5880, "PPOD" },
{ 5888, "AMG1" },
{ 5896, "SPSH" },
{ 5904, "LVAS" },
{ 5912, "SLDG" },
{ 5920, "SKH1" },
{ 5928, "SKH2" },
{ 5936, "SKH3" },
{ 5944, "SKH4" },
{ 5952, "CHDL" },
{ 5960, "SRTC" },
{ 5968, "SMPL" },
{ 5976, "STGS" },
{ 5984, "STGL" },
{ 5992, "STCS" },
{ 6000, "STCL" },
{ 6008, "KFR1" },
{ 6016, "BARL" },
{ 6024, "BRPL" },
{ 6032, "MOS1" },
{ 6040, "MOS2" },
{ 6048, "WTRH" },
{ 6056, "HCOR" },
{ 6064, "KGZ1" },
{ 6072, "KGZB" },
{ 6080, "KGZG" },
{ 6088, "KGZY" },
{ 6096, "VLCO" },
{ 6104, "VFBL" },
{ 6112, "VTFB" },
{ 6120, "SFFI" },
{ 6128, "TGLT" },
{ 6136, "TELE" },
{ 6144, "STFF" },
{ 6152, "PUF3" },
{ 6160, "PUF4" },
{ 6168, "BEAK" },
{ 6176, "WGNT" },
{ 6184, "GAUN" },
{ 6192, "PUF1" },
{ 6200, "WBLS" },
{ 6208, "BLSR" },
{ 6216, "FX18" },
{ 6224, "FX17" },
{ 6232, "WMCE" },
{ 6240, "MACE" },
{ 6248, "FX02" },
{ 6256, "WSKL" },
{ 6264, "HROD" },
{ 6272, "FX00" },
{ 6280, "FX20" },
{ 6288, "FX21" },
{ 6296, "FX22" },
{ 6304, "FX23" },
{ 6312, "GWND" },
{ 6320, "PUF2" },
{ 6328, "WPHX" },
{ 6336, "PHNX" },
{ 6344, "FX04" },
{ 6352, "FX08" },
{ 6360, "FX09" },
{ 6368, "WBOW" },
{ 6376, "CRBW" },
{ 6384, "FX03" },
{ 6392, "BLOD" },
{ 6400, "PLAY" },
{ 6408, "FDTH" },
{ 6416, "BSKL" },
{ 6424, "CHKN" },
{ 6432, "MUMM" },
{ 6440, "FX15" },
{ 6448, "BEAS" },
{ 6456, "FRB1" },
{ 6464, "SNKE" },
{ 6472, "SNFX" },
{ 6480, "HEAD" },
{ 6488, "FX05" },
{ 6496, "FX06" },
{ 6504, "FX07" },
{ 6512, "CLNK" },
{ 6520, "WZRD" },
{ 6528, "FX11" },
{ 6536, "FX10" },
{ 6544, "KNIG" },
{ 6552, "SPAX" },
{ 6560, "RAXE" },
{ 6568, "SRCR" },
{ 6576, "FX14" },
{ 6584, "SOR2" },
{ 6592, "SDTH" },
{ 6600, "FX16" },
{ 6608, "MNTR" },
{ 6616, "FX12" },
{ 6624, "FX13" },
{ 6632, "AKYY" },
{ 6640, "BKYY" },
{ 6648, "CKYY" },
{ 6656, "AMG2" },
{ 6664, "AMM1" },
{ 6672, "AMM2" },
{ 6680, "AMC1" },
{ 6688, "AMC2" },
{ 6696, "AMS1" },
{ 6704, "AMS2" },
{ 6712, "AMP1" },
{ 6720, "AMP2" },
{ 6728, "AMB1" },
{ 6736, "AMB2" },
{ 6768, "PLAYPAL" },
{ 6776, "MAPE1" },
{ 6784, "MAPE2" },
{ 6792, "MAPE3" },
{ 6800, "IN_X" },
{ 6808, "IN_YAH" },
{ 6816, "FONTB16" },
{ 6824, "FONTB_S" },
{ 6832, "FONTB13" },
{ 6840, "FONTB15" },
{ 6848, "FONTB05" },
{ 6856, "FACEA0" },
{ 6864, "FACEB0" },
{ 6872, NULL },
{ 6896, NULL },
{ 6940, "FLOOR16" },
{ 6948, "FINISHED" },
{ 6960, "NOW ENTERING:" },
{ 6976, "KILLS" },
{ 6984, "ITEMS" },
{ 6992, "SECRETS" },
{ 7000, "TIME" },
{ 7008, "BONUS" },
{ 7016, "SECRET" },
{ 7024, "TOTAL" },
{ 7032, "VICTIMS" },
{ 7044, "NEW GAME" },
{ 7056, "OPTIONS" },
{ 7064, "GAME FILES" },
{ 7076, "INFO" },
{ 7084, "QUIT GAME" },
{ 7096, "CITY OF THE DAMNED" },
{ 7116, "HELL'S MAW" },
{ 7128, "THE DOME OF D'SPARIL" },
{ 7152, "LOAD GAME" },
{ 7164, "SAVE GAME" },
{ 7176, "THOU NEEDETH A WET-NURSE" },
{ 7204, "YELLOWBELLIES-R-US" },
{ 7224, "BRINGEST THEM ONETH" },
{ 7244, "THOU ART A SMITE-MEISTER" },
{ 7272, "BLACK PLAGUE POSSESSES THEE" },
{ 7300, "END GAME" },
{ 7312, "MESSAGES : " },
{ 7324, "MOUSE SENSITIVITY" },
{ 7344, "MORE..." },
{ 7352, "SCREEN SIZE" },
{ 7364, "SFX VOLUME" },
{ 7376, "MUSIC VOLUME" },
{ 7392, "M_SKL00" },
{ 7400, "FONTA_S" },
{ 7408, "FONTB_S" },
{ 7416, "ARE YOU SURE YOU WANT TO QUIT?" },
{ 7448, "ARE YOU SURE YOU WANT TO END THE GAME?" },
{ 7488, "DO YOU WANT TO QUICKSAVE THE GAME NAMED" },
{ 7528, "DO YOU WANT TO QUICKLOAD THE GAME NAMED" },
{ 7572, "M_SLCTR1" },
{ 7584, "M_SLCTR2" },
{ 7596, "M_HTIC" },
{ 7604, NULL },
{ 7632, "hticsav%d.hsg" },
{ 7652, "M_FSLOT" },
{ 7668, "MESSAGES ON" },
{ 7680, "MESSAGES OFF" },
{ 7696, "YOU CAN'T START A NEW GAME FROM WITHIN A NETGAME!" },
{ 7748, "ONLY AVAILABLE IN THE REGISTERED VERSION" },
{ 7792, "PLAYPAL" },
{ 7800, "QUICKSAVING...." },
{ 7816, "QUICKLOADING...." },
{ 7836, "CHOOSE A QUICKSAVE SLOT" },
{ 7860, "CHOOSE A QUICKLOAD SLOT" },
{ 7884, "TITLE" },
{ 7892, "M_SLDLT" },
{ 7900, "M_SLDMD1" },
{ 7912, "M_SLDMD2" },
{ 7924, "M_SLDRT" },
{ 7932, "M_SLDKB" },
{ 7940, NULL },
{ 7968, NULL },
{ 7992, NULL },
{ 8020, NULL },
{ 8028, NULL },
{ 8056, NULL },
{ 8076, NULL },
{ 8088, NULL },
{ 8104, NULL },
{ 8116, NULL },
{ 8128, NULL },
{ 8136, NULL },
{ 8148, NULL },
{ 8164, NULL },
{ 8180, NULL },
{ 8192, NULL },
{ 8204, NULL },
{ 8220, NULL },
{ 8232, NULL },
{ 8248, NULL },
{ 8264, NULL },
{ 8276, NULL },
{ 8292, NULL },
{ 8308, NULL },
{ 8320, NULL },
{ 8328, NULL },
{ 8340, NULL },
{ 8352, NULL },
{ 8364, NULL },
{ 8376, NULL },
{ 8392, NULL },
{ 8408, NULL },
{ 8424, NULL },
{ 8436, NULL },
{ 8448, NULL },
{ 8460, NULL },
{ 8472, NULL },
{ 8488, NULL },
{ 8504, NULL },
{ 8520, NULL },
{ 8536, NULL },
{ 8548, NULL },
{ 8560, NULL },
{ 8572, NULL },
{ 8584, NULL },
{ 8596, NULL },
{ 8612, NULL },
{ 8624, NULL },
{ 8648, NULL },
{ 8660, NULL },
{ 8668, NULL },
{ 8680, NULL },
{ 8708, NULL },
{ 8720, NULL },
{ 8728, NULL },
{ 8740, NULL },
{ 8752, NULL },
{ 8764, NULL },
{ 8788, NULL },
{ 8800, NULL },
{ 8812, NULL },
{ 8824, NULL },
{ 8848, NULL },
{ 8880, NULL },
{ 8888, NULL },
{ 8896, NULL },
{ 8916, NULL },
{ 8968, "HRTIC00.pcx" },
{ 8980, NULL },
{ 9016, "SCREEN SHOT" },
{ 9028, "YOU NEED A BLUE KEY TO OPEN THIS DOOR" },
{ 9068, "YOU NEED A YELLOW KEY TO OPEN THIS DOOR" },
{ 9108, "YOU NEED A GREEN KEY TO OPEN THIS DOOR" },
{ 9148, NULL },
{ 9172, NULL },
{ 9220, NULL },
{ 9244, "CRYSTAL VIAL" },
{ 9260, "SILVER SHIELD" },
{ 9276, "ENCHANTED SHIELD" },
{ 9296, "BAG OF HOLDING" },
{ 9312, "MAP SCROLL" },
{ 9324, "BLUE KEY" },
{ 9336, "YELLOW KEY" },
{ 9348, "GREEN KEY" },
{ 9360, "QUARTZ FLASK" },
{ 9376, "WINGS OF WRATH" },
{ 9392, "RING OF INVINCIBILITY" },
{ 9416, "TOME OF POWER" },
{ 9432, "SHADOWSPHERE" },
{ 9448, "MORPH OVUM" },
{ 9460, "MYSTIC URN" },
{ 9472, "TORCH" },
{ 9480, "TIME BOMB OF THE ANCIENTS" },
{ 9508, "CHAOS DEVICE" },
{ 9524, "WAND CRYSTAL" },
{ 9540, "CRYSTAL GEODE" },
{ 9556, "MACE SPHERES" },
{ 9572, "PILE OF MACE SPHERES" },
{ 9596, "ETHEREAL ARROWS" },
{ 9612, "QUIVER OF ETHEREAL ARROWS" },
{ 9640, "CLAW ORB" },
{ 9652, "ENERGY ORB" },
{ 9664, "LESSER RUNES" },
{ 9680, "GREATER RUNES" },
{ 9696, "FLAME ORB" },
{ 9708, "INFERNO ORB" },
{ 9720, "FIREMACE" },
{ 9732, "ETHEREAL CROSSBOW" },
{ 9752, "DRAGON CLAW" },
{ 9764, "HELLSTAFF" },
{ 9776, "PHOENIX ROD" },
{ 9788, "GAUNTLETS OF THE NECROMANCER" },
{ 9820, NULL },
{ 9860, NULL },
{ 9892, NULL },
{ 9940, NULL },
{ 9972, NULL },
{ 10012, NULL },
{ 10052, NULL },
{ 10080, NULL },
{ 10088, "FLTWAWA1" },
{ 10100, "FLTFLWW1" },
{ 10112, "FLTLAVA1" },
{ 10124, "FLATHUH1" },
{ 10136, "FLTSLUD1" },
{ 10152, NULL },
{ 10192, NULL },
{ 10236, NULL },
{ 10248, NULL },
{ 10284, NULL },
{ 10320, NULL },
{ 10360, NULL },
{ 10392, NULL },
{ 10444, "PLAYPAL" },
{ 10452, NULL },
{ 10488, NULL },
{ 10508, NULL },
{ 10556, NULL },
{ 10596, "PNAMES" },
{ 10604, "TEXTURE1" },
{ 10616, "TEXTURE2" },
{ 10628, "S_END" },
{ 10636, "S_START" },
{ 10644, NULL },
{ 10684, NULL },
{ 10728, "F_START" },
{ 10736, "F_END" },
{ 10744, "COLORMAP" },
{ 10756, "\nR_InitTextures " },
{ 10776, "R_InitFlats\n" },
{ 10792, "R_InitSpriteLumps " },
{ 10812, NULL },
{ 10844, NULL },
{ 10880, NULL },
{ 10912, NULL },
{ 10948, "TINTTAB" },
{ 10956, NULL },
{ 10984, "FLOOR04" },
{ 10992, "FLAT513" },
{ 11000, "bordt" },
{ 11008, "bordb" },
{ 11016, "bordl" },
{ 11024, "bordr" },
{ 11032, "bordtl" },
{ 11040, "bordtr" },
{ 11048, "bordbr" },
{ 11056, "bordbl" },
{ 11064, "R_InitData " },
{ 11076, "R_InitPointToAngle\n" },
{ 11096, "R_InitTables " },
{ 11112, "R_InitPlanes\n" },
{ 11128, "R_InitLightTables " },
{ 11148, "R_InitSkyMap\n" },
{ 11164, "F_SKY1" },
{ 11172, NULL },
{ 11200, NULL },
{ 11232, NULL },
{ 11272, NULL },
{ 11312, NULL },
{ 11348, NULL },
{ 11380, NULL },
{ 11404, NULL },
{ 11436, NULL },
{ 11492, NULL },
{ 11548, NULL },
{ 11616, NULL },
{ 11684, NULL },
{ 11748, NULL },
{ 11792, NULL },
{ 11840, NULL },
{ 11896, NULL },
{ 11936, NULL },
{ 11980, NULL },
{ 12028, NULL },
{ 12072, NULL },
{ 12120, "LTFACE" },
{ 12128, "RTFACE" },
{ 12136, "BARBACK" },
{ 12144, "INVBAR" },
{ 12152, "CHAIN" },
{ 12160, "STATBAR" },
{ 12168, "LIFEBAR" },
{ 12176, "LIFEGEM2" },
{ 12188, "LIFEGEM0" },
{ 12200, "LTFCTOP" },
{ 12208, "RTFCTOP" },
{ 12216, "ARTIBOX" },
{ 12224, "SELECTBOX" },
{ 12236, "INVGEML1" },
{ 12248, "INVGEML2" },
{ 12260, "INVGEMR1" },
{ 12272, "INVGEMR2" },
{ 12284, "BLACKSQ" },
{ 12292, "ARMCLEAR" },
{ 12304, "CHAINBACK" },
{ 12320, "NEGNUM" },
{ 12328, "FONTB16" },
{ 12336, "SMALLIN0" },
{ 12348, "PLAYPAL" },
{ 12356, "SPINBK0" },
{ 12364, "SPFLY0" },
{ 12372, "LAME" },
{ 12408, "NAME" },
{ 12416, "MO.T" },
{ 12424, "MO.X" },
{ 12432, "MO.Y" },
{ 12448, "DIST" },
{ 12456, "------" },
{ 12472, "GOD1" },
{ 12480, "GOD2" },
{ 12488, "useartia" },
{ 12500, "ykeyicon" },
{ 12512, "gkeyicon" },
{ 12524, "bkeyicon" },
{ 12536, "GOD MODE ON" },
{ 12548, "GOD MODE OFF" },
{ 12564, "NO CLIPPING ON" },
{ 12580, "NO CLIPPING OFF" },
{ 12596, "ALL WEAPONS" },
{ 12608, "POWER OFF" },
{ 12620, "POWER ON" },
{ 12632, "FULL HEALTH" },
{ 12644, "ALL KEYS" },
{ 12656, "SOUND DEBUG ON" },
{ 12672, "SOUND DEBUG OFF" },
{ 12688, "TICKER ON" },
{ 12700, "TICKER OFF" },
{ 12712, "CHOOSE AN ARTIFACT ( A - J )" },
{ 12744, "HOW MANY ( 1 - 9 )" },
{ 12764, "YOU GOT IT" },
{ 12776, "BAD INPUT" },
{ 12788, "LEVEL WARP" },
{ 12800, "CHICKEN OFF" },
{ 12812, "CHICKEN ON" },
{ 12824, "MASSACRE" },
{ 12836, "CHEATER - YOU DON'T DESERVE WEAPONS" },
{ 12872, "TRYING TO CHEAT, EH? NOW YOU DIE!" },
{ 12908, "Bad V_DrawPatch" },
{ 12924, NULL },
{ 12960, NULL },
{ 12968, NULL },
{ 12976, NULL },
{ 13020, NULL },
{ 13048, NULL },
{ 13076, NULL },
{ 13104, NULL },
{ 13136, NULL },
{ 13168, NULL },
{ 13196, NULL },
{ 13240, NULL },
{ 13272, NULL },
{ 13296, NULL },
{ 13312, NULL },
{ 13324, NULL },
{ 13364, NULL },
{ 13408, NULL },
{ 13460, NULL },
{ 13492, NULL },
{ 13516, NULL },
{ 13560, NULL },
{ 13612, NULL },
{ 13664, NULL },
{ 13700, NULL },
{ 13744, NULL },
{ 13796, NULL },
{ 13848, NULL },
{ 13884, NULL },
{ 13940, NULL },
{ 13996, NULL },
{ 14040, NULL },
{ 14084, NULL },
{ 14140, NULL },
{ 14148, NULL },
{ 14164, NULL },
{ 14184, NULL },
{ 14192, NULL },
{ 14212, NULL },
{ 14256, NULL },
{ 14272, NULL },
{ 14284, NULL },
{ 14300, NULL },
{ 14312, NULL },
{ 14324, NULL },
{ 14348, NULL },
{ 14360, NULL },
{ 14372, NULL },
{ 14380, NULL },
{ 14392, NULL },
{ 14432, NULL },
{ 14444, NULL },
{ 14472, NULL },
{ 14496, NULL },
{ 14516, NULL },
{ 14536, NULL },
{ 14548, NULL },
{ 14560, NULL },
{ 14572, NULL },
{ 14580, NULL },
{ 14588, NULL },
{ 14596, NULL },
{ 14604, NULL },
{ 14612, NULL },
{ 14620, NULL },
{ 14636, NULL },
{ 14660, NULL },
{ 14704, NULL },
{ 14748, NULL },
{ 14760, NULL },
{ 14768, NULL },
};
static boolean GetStringByOffset(unsigned int offset, char **result)
{
int i;
for (i=0; i<arrlen(string_table); ++i)
{
if (string_table[i].offset == offset)
{
*result = string_table[i].string;
return true;
}
}
return false;
}
// Given a string length, find the maximum length of a
// string that can replace it.
static int MaxStringLength(int len)
{
// Enough bytes for the string and the NUL terminator
len += 1;
// All strings in doom.exe are on 4-byte boundaries, so we may be able
// to support a slightly longer string.
// Extend up to the next 4-byte boundary
len += (4 - (len % 4)) % 4;
// Less one for the NUL terminator.
return len - 1;
}
static void *DEH_TextStart(deh_context_t *context, char *line)
{
char *repl_text;
char *orig_text;
int orig_offset, repl_len;
int i;
if (sscanf(line, "Text %i %i", &orig_offset, &repl_len) != 2)
{
DEH_Warning(context, "Parse error on section start");
return NULL;
}
repl_text = Z_Malloc(repl_len + 1, PU_STATIC, NULL);
// read in the "to" text
for (i=0; i<repl_len; ++i)
{
int c;
c = DEH_GetChar(context);
repl_text[i] = c;
}
repl_text[repl_len] = '\0';
// Find the string to replace:
if (!GetStringByOffset(orig_offset, &orig_text))
{
DEH_Error(context, "Unknown string offset: %i", orig_offset);
}
// We don't support all strings, but at least recognise them:
else if (orig_text == NULL)
{
DEH_Warning(context, "Unsupported string replacement: %i", orig_offset);
}
// Only allow string replacements that are possible in Vanilla Doom.
// Chocolate Doom is unforgiving!
else if (!deh_allow_long_strings
&& repl_len > MaxStringLength(strlen(orig_text)))
{
DEH_Error(context, "Replacement string is longer than the maximum "
"possible in heretic.exe");
}
else
{
// Success.
DEH_AddStringReplacement(orig_text, repl_text);
return NULL;
}
// Failure.
Z_Free(repl_text);
return NULL;
}
static void DEH_TextParseLine(deh_context_t *context, char *line, void *tag)
{
// not used
}
deh_section_t deh_section_heretic_text =
{
"Text",
NULL,
DEH_TextStart,
DEH_TextParseLine,
NULL,
NULL,
};