From 3237c6b4e83cb46b17018dfe65c94640a77d09c6 Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Sun, 23 Mar 2008 05:24:40 +0000 Subject: [PATCH] - Changed MIDI playback to not bother playing super short songs that don't contain enough music to fill the initial output buffers. - Removed the read barrier around ADehackedPickup::RealPickup. If the real pickup is picked up, it may very well destroy itself before the dehacked wrapper's stubs that use it are called. - Reverted revision 840. For a file we don't want end users to be touching, making DEHSUPP plain text sends out mixed messages: "Don't mess with this. Oh, by the way, it's plain text now to make it easier for you to edit." Is there some reason other than a desire to do away with binary lumps to make the distributed lump text? - Added a new speakermode for Stereo + HRTF: "Headphones". This is the only way to get the HRTF low pass filter effect now. - Fixed: No more than one sector could make noise at once. - Trying out sound without varying priorities again. - Fixed: Need to use setSpeakerMix to let 2D sounds (aka streamed music) use their full volume range. SVN r842 (trunk) --- Makefile.linux | 7 +- Makefile.mgw | 2 + docs/rh-log.txt | 21 +- src/d_dehacked.cpp | 906 ++++++++++---------- src/s_sound.cpp | 29 +- src/sc_man.cpp | 26 - src/sc_man.h | 1 - src/sound/fmodsound.cpp | 11 +- src/sound/music_midistream.cpp | 26 +- tools/dehsupp/Makefile | 55 ++ tools/dehsupp/dehsupp.c | 571 +++++++++++++ tools/dehsupp/dehsupp.h | 124 +++ tools/dehsupp/dehsupp.vcproj | 465 ++++++++++ tools/dehsupp/parse.c | 1471 ++++++++++++++++++++++++++++++++ tools/dehsupp/parse.h | 33 + tools/dehsupp/parse.y | 152 ++++ tools/dehsupp/scanner.c | 1091 +++++++++++++++++++++++ tools/dehsupp/scanner.re | 176 ++++ wadsrc/Makefile | 5 +- wadsrc/Makefile.mgw | 10 +- wadsrc/Makefile2 | 3 + wadsrc/dehsupp.lmp | Bin 0 -> 9569 bytes wadsrc/dehsupp.txt | 135 ++- wadsrc/wadsrc.vcproj | 8 +- wadsrc/zdoom.lst | 2 +- zdoom.sln | 21 +- 26 files changed, 4772 insertions(+), 579 deletions(-) create mode 100644 tools/dehsupp/Makefile create mode 100644 tools/dehsupp/dehsupp.c create mode 100644 tools/dehsupp/dehsupp.h create mode 100644 tools/dehsupp/dehsupp.vcproj create mode 100644 tools/dehsupp/parse.c create mode 100644 tools/dehsupp/parse.h create mode 100644 tools/dehsupp/parse.y create mode 100644 tools/dehsupp/scanner.c create mode 100644 tools/dehsupp/scanner.re create mode 100644 wadsrc/dehsupp.lmp diff --git a/Makefile.linux b/Makefile.linux index 4c98c45ec8..5a0fbc2477 100644 --- a/Makefile.linux +++ b/Makefile.linux @@ -94,7 +94,7 @@ src/xlat/xlat_parser.c: tools/lemon/lemon src/xlat/xlat_parser.y $(OBJDIR): mkdir $(OBJDIR) -toolsandpk3: ccdv tools/makewad/makewad tools/lemon/lemon +toolsandpk3: ccdv tools/makewad/makewad tools/dehsupp/dehsupp tools/lemon/lemon $(MAKE) -C wadsrc/ zdoom.pk3: toolsandpk3 @@ -106,6 +106,9 @@ snes_spc/libsnes_spc.a: tools/makewad/makewad: $(MAKE) -C tools/makewad/ +tools/dehsupp/dehsupp: + $(MAKE) -C tools/dehsupp/ + tools/lemon/lemon: $(MAKE) -C tools/lemon/ @@ -123,6 +126,8 @@ clean: cleanobjs cleantools: @$(MAKE) -C tools/makewad clean + @$(MAKE) -C tools/dehsupp clean + @$(MAKE) -C tools/xlatcc clean cleandebug: rm -f $(ZDOOMDEBUG) $(DEBUGOBJ)/*.o $(DEBUGOBJ)/*.d diff --git a/Makefile.mgw b/Makefile.mgw index 218af75d08..d21668bd4d 100644 --- a/Makefile.mgw +++ b/Makefile.mgw @@ -23,6 +23,7 @@ basetools: ccdv.exe $(MAKE) -C tools/re2c $(MAKE) -C zlib -f Makefile.mgw $(MAKE) -C tools/makewad + $(MAKE) -C tools/dehsupp $(MAKE) -C tools/fixrtext $(MAKE) -C wadsrc -f Makefile.mgw $(MAKE) -C jpeg-6b -f Makefile.mgw @@ -34,6 +35,7 @@ cleanexe: clean: @$(MAKE) -C tools/lemon clean @$(MAKE) -C tools/re2c clean + @$(MAKE) -C tools/dehsupp clean @$(MAKE) -C tools/makewad clean @$(MAKE) -C tools/fixrtext clean @$(MAKE) -C wadsrc -f Makefile.mgw clean diff --git a/docs/rh-log.txt b/docs/rh-log.txt index efb25e6e8b..f42d1c18c1 100644 --- a/docs/rh-log.txt +++ b/docs/rh-log.txt @@ -1,9 +1,24 @@ +March 22, 2008 +- Changed MIDI playback to not bother playing super short songs that don't + contain enough music to fill the initial output buffers. +- Removed the read barrier around ADehackedPickup::RealPickup. If the real + pickup is picked up, it may very well destroy itself before the dehacked + wrapper's stubs that use it are called. +- Reverted revision 840. For a file we don't want end users to be touching, + making DEHSUPP plain text sends out mixed messages: "Don't mess with this. + Oh, by the way, it's plain text now to make it easier for you to edit." + Is there some reason other than a desire to do away with binary lumps to + make the distributed lump text? +- Added a new speakermode for Stereo + HRTF: "Headphones". This is the only + way to get the HRTF low pass filter effect now. +- Fixed: No more than one sector could make noise at once. +- Trying out sound without varying priorities again. +- Fixed: Need to use setSpeakerMix to let 2D sounds (aka streamed music) use + their full volume range. + March 22, 2008 (Changes by Graf Zahl) - Added sector type translation to xlat_parser and removed the old sectorx lump. -- Changed DEHSUPP loader so that it reads the text file directly. As a result - the DEHSUPP compiler is gone now. Unlike XLATCC I'm using FScanner though. - A fully featured parser seems like overkill for this simple text file. - Added Line_SetTextureOffset special. - Added 'allowprotection' keyword to terrain definitions to allow damaging flats that don't damage players with a radiation suit. diff --git a/src/d_dehacked.cpp b/src/d_dehacked.cpp index 63ef82eea2..e0eb7b6ab2 100644 --- a/src/d_dehacked.cpp +++ b/src/d_dehacked.cpp @@ -67,8 +67,6 @@ #include "vectors.h" #include "dobject.h" #include "r_translate.h" -#include "sc_man.h" -#include "doomerrors.h" // [SO] Just the way Randy said to do it :) // [RH] Made this CVAR_SERVERINFO @@ -77,87 +75,46 @@ CVAR (Int, infighting, 0, CVAR_SERVERINFO) static bool LoadDehSupp (); static void UnloadDehSupp (); - -// This is a list of all the action functions used by each of Doom's states. -static TArray Actions; - -// These are the original heights of every Doom 2 thing. They are used if a patch -// specifies that a thing should be hanging from the ceiling but doesn't specify -// a height for the thing, since these are the heights it probably wants. -static TArray OrgHeights; - -// DeHackEd made the erroneous assumption that if a state didn't appear in -// Doom with an action function, then it was incorrect to assign it one. -// This is a list of the states that had action functions, so we can figure -// out where in the original list of states a DeHackEd codepointer is. -// (DeHackEd might also have done this for compatibility between Doom -// versions, because states could move around, but actions would never -// disappear, but that doesn't explain why frame patches specify an exact -// state rather than a code pointer.) -static TArray CodePConv; - -// Sprite names in the order Doom originally had them. -struct DEHSprName +// Action functions available to patches +struct CodePtrMap { - char c[5]; -}; -static TArray OrgSprNames; - -// Map to where the orginal Doom states have moved to -static const char * StateBaseNames[]= -{ - "FirstState", - "SpawnState", - "DeathState", - NULL + short name; + WORD num; }; -enum EStateBase +static CodePtrMap *CodePtrNames; +static int NumCodePtrs; +static PSymbol ** CodePtrSymbols; + +static const char *const AmmoNames[12] = { - FirstState, - SpawnState, - DeathState + "Clip", + "Shell", + "Cell", + "RocketAmmo", + "GoldWandAmmo", + NULL, + "BlasterAmmo", + "SkullRodAmmo", + "PhoenixRodAmmo", + "MaceAmmo", + "Mana1", + "Mana2" }; -struct StateMapper +static const char *const WeaponNames[9] = { - FState *State; - int StateSpan; - const PClass *Owner; - bool OwnerIsPickup; + "Fist", + "Pistol", + "Shotgun", + "Chaingun", + "RocketLauncher", + "PlasmaRifle", + "BFG9000", + "Chainsaw", + "SuperShotgun" }; -static TArray StateMap; - -// Sound equivalences. When a patch tries to change a sound, -// use these sound names. -static TArray SoundMap; - -// Names of different actor types, in original Doom 2 order -static TArray InfoNames; - -// bit flags for PatchThing (a .bex extension): -struct BitName -{ - char Name[20]; - BYTE Bit; - BYTE WhichFlags; -}; - -static TArray BitNames; - -// Render styles -struct StyleName -{ - char Name[20]; - BYTE Num; -}; - -static TArray StyleNames; - -static TArray AmmoNames; -static TArray WeaponNames; - // Miscellaneous info that used to be constant DehInfo deh = { @@ -204,7 +161,7 @@ public: void DoPickupSpecial (AActor *toucher); private: const PClass *DetermineType (); - TObjPtr RealPickup; + AInventory *RealPickup; }; IMPLEMENT_POINTY_CLASS (ADehackedPickup) @@ -296,6 +253,80 @@ static WORD *NameOffs; static char *NameBase; static int NumNames; +// These are the original heights of every Doom 2 thing. They are used if a patch +// specifies that a thing should be hanging from the ceiling but doesn't specify +// a height for the thing, since these are the heights it probably wants. +static BYTE *OrgHeights; +static int NumOrgHeights; + +// This is a list of all the action functions used by each of Doom's states. +static BYTE *ActionList; +static int NumActions; + +// DeHackEd made the erroneous assumption that if a state didn't appear in +// Doom with an action function, then it was incorrect to assign it one. +// This is a list of the states that had action functions, so we can figure +// out where in the original list of states a DeHackEd codepointer is. +// (DeHackEd might also have done this for compatibility between Doom +// versions, because states could move around, but actions would never +// disappear, but that doesn't explain why frame patches specify an exact +// state rather than a code pointer.) +static short *CodePConv; +static int NumCodeP; + +// Sprite names in the order Doom originally had them. +static char **OrgSprNames; +static int NumSprites; + +// Map to where the orginal Doom states have moved to +enum EStateBase +{ + FirstState, + SpawnState, + DeathState +}; + +struct StateMapper +{ + FState *State; + int StateSpan; + const PClass *Owner; + bool OwnerIsPickup; +}; + +static StateMapper *StateMap; +static int NumStateMaps; + +// Render styles +struct StyleName +{ + short Name; + BYTE Num; +}; + +static StyleName *StyleNames; +static int NumStyleNames; + +// Sound equivalences. When a patch tries to change a sound, +// use these sound names. +static short *SoundMap; +static int NumSounds; + +// Names of different actor types, in original Doom 2 order +static short *InfoNames; +static int NumInfos; + +// bit flags for PatchThing (a .bex extension): +struct BitName +{ + short Name; + BYTE Bit; + BYTE WhichFlags; +}; + +static BitName *BitNames; +static int NumBitNames; + struct Key { const char *name; ptrdiff_t offset; @@ -425,25 +456,21 @@ static int FindSprite (const char *sprname) static FState *FindState (int statenum) { + int i; int stateacc; - unsigned i; if (statenum == 0) return NULL; - for (i = 0, stateacc = 1; i < StateMap.Size(); i++) + for (i = 0, stateacc = 1; i < NumStateMaps; i++) { if (stateacc <= statenum && stateacc + StateMap[i].StateSpan > statenum) { - if (StateMap[i].State != NULL) + if (StateMap[i].OwnerIsPickup) { - if (StateMap[i].OwnerIsPickup) - { - TouchedActors.Push (const_cast(StateMap[i].Owner)); - } - return StateMap[i].State + statenum - stateacc; + TouchedActors.Push (const_cast(StateMap[i].Owner)); } - else return NULL; + return StateMap[i].State + statenum - stateacc; } stateacc += StateMap[i].StateSpan; } @@ -452,9 +479,27 @@ static FState *FindState (int statenum) int FindStyle (const char *namestr) { - for(unsigned i = 0; i < StyleNames.Size(); i++) + int min = 0; + int max = NumStyleNames - 1; + int name = FindName (Line2); + if (name != -1) { - if (!stricmp(StyleNames[i].Name, namestr)) return StyleNames[i].Num; + while (min <= max) + { + int mid = (min + max) / 2; + if (StyleNames[mid].Name == name) + { + return StyleNames[mid].Num; + } + else if (StyleNames[mid].Name < name) + { + min = mid + 1; + } + else + { + max = mid - 1; + } + } } DPrintf("Unknown render style %s\n", namestr); return -1; @@ -667,7 +712,7 @@ static int PatchThing (int thingy) type = NULL; info = (AActor *)&dummy; ednum = &dummyed; - if (thingy > (int)InfoNames.Size() || thingy <= 0) + if (thingy > NumInfos || thingy <= 0) { Printf ("Thing %d out of range.\n", thingy); } @@ -676,13 +721,13 @@ static int PatchThing (int thingy) DPrintf ("Thing %d\n", thingy); if (thingy > 0) { - type = InfoNames[thingy - 1]; + type = PClass::FindClass (GetName (InfoNames[thingy - 1])); if (type == NULL) { info = (AActor *)&dummy; ednum = &dummyed; - // An error for the name has already been printed while loading DEHSUPP. - Printf ("Could not find thing %d\n", thingy); + Printf ("Could not find thing %s (index %d)\n", + GetName (InfoNames[thingy - 1]), thingy); } else { @@ -825,7 +870,7 @@ static int PatchThing (int thingy) { int snd; - if (val == 0 || val >= (unsigned long)SoundMap.Size()) + if (val == 0 || val >= (unsigned long)NumSounds) { if (endptr == Line2) { // Sound was not a (valid) number, @@ -840,7 +885,7 @@ static int PatchThing (int thingy) } else { - snd = SoundMap[val-1]; + snd = S_FindSound (GetName (SoundMap[val-1])); } if (!strnicmp (Line1, "Alert", 5)) @@ -879,19 +924,39 @@ static int PatchThing (int thingy) } else { - unsigned i; - for(i = 0; i < BitNames.Size(); i++) + int min, max; + int name = FindName (strval); + + if (name == -1) { - if (!stricmp(strval, BitNames[i].Name)) - { - vchanged[BitNames[i].WhichFlags] = true; - value[BitNames[i].WhichFlags] |= 1 << BitNames[i].Bit; - break; - } + DPrintf ("Unknown bit mnemonic %s\n", strval); } - if (i == BitNames.Size()) + else { - DPrintf("Unknown bit mnemonic %s\n", strval); + min = 0; + max = NumBitNames - 1; + while (min <= max) + { + int mid = (min + max) / 2; + if (BitNames[mid].Name == name) + { + vchanged[BitNames[mid].WhichFlags] = true; + value[BitNames[mid].WhichFlags] |= 1 << BitNames[mid].Bit; + break; + } + else if (BitNames[mid].Name < name) + { + min = mid + 1; + } + else + { + max = mid - 1; + } + } + if (min > max) + { + DPrintf("Unknown bit mnemonic %s\n", strval); + } } } } @@ -966,7 +1031,7 @@ static int PatchThing (int thingy) // don't specify a new height. if (info->flags & MF_SPAWNCEILING && !hadHeight && - thingy <= OrgHeights.Size() && thingy > 0) + thingy <= NumOrgHeights && thingy > 0) { info->height = OrgHeights[thingy - 1] * FRACUNIT; } @@ -1140,11 +1205,11 @@ static int PatchFrame (int frameNum) { unsigned int i; - if (val < OrgSprNames.Size()) + if (val < NumSprites) { for (i = 0; i < sprites.Size(); i++) { - if (memcmp (OrgSprNames[val].c, sprites[i].name, 4) == 0) + if (memcmp (OrgSprNames[val], sprites[i].name, 4) == 0) { info->sprite.index = (int)i; break; @@ -1153,7 +1218,7 @@ static int PatchFrame (int frameNum) if (i == sprites.Size ()) { Printf ("Frame %d: Sprite %d (%s) is undefined\n", - frameNum, val, OrgSprNames[val].c); + frameNum, val, OrgSprNames[val]); } } else @@ -1201,7 +1266,7 @@ static int PatchSprite (int sprNum) int result; int offset = 0; - if ((unsigned)sprNum < OrgSprNames.Size()) + if (sprNum >= 0 && sprNum < NumSprites) { DPrintf ("Sprite %d\n", sprNum); } @@ -1222,12 +1287,12 @@ static int PatchSprite (int sprNum) { // Calculate offset from beginning of sprite names. offset = (offset - toff[dversion] - 22044) / 8; - - if ((unsigned)offset < OrgSprNames.Size()) + + if (offset >= 0 && offset < NumSprites) { - sprNum = FindSprite (OrgSprNames[sprNum].c); + sprNum = FindSprite (OrgSprNames[sprNum]); if (sprNum != -1) - strncpy (sprites[sprNum].name, OrgSprNames[offset].c, 4); + strncpy (sprites[sprNum].name, OrgSprNames[offset], 4); } else { @@ -1240,32 +1305,28 @@ static int PatchSprite (int sprNum) static int PatchAmmo (int ammoNum) { - const PClass *ammoType = NULL; - AAmmo *defaultAmmo = NULL; + const PClass *ammoType; + AAmmo *defaultAmmo; int result; + int *max; + int *per; int oldclip; int dummy; - int *max = &dummy; - int *per = &dummy; - if (ammoNum >= 0 && ammoNum < 4 && (unsigned)ammoNum <= AmmoNames.Size()) + if (ammoNum >= 0 && ammoNum < 4) { DPrintf ("Ammo %d.\n", ammoNum); - ammoType = AmmoNames[ammoNum]; - if (ammoType != NULL) - { - defaultAmmo = (AAmmo *)GetDefaultByType (ammoType); - if (defaultAmmo != NULL) - { - max = &defaultAmmo->MaxAmount; - per = &defaultAmmo->Amount; - } - } + ammoType = PClass::FindClass (AmmoNames[ammoNum]); + defaultAmmo = (AAmmo *)GetDefaultByType (ammoType); + max = &defaultAmmo->MaxAmount; + per = &defaultAmmo->Amount; } - - if (ammoType == NULL) + else { Printf ("Ammo %d out of range.\n", ammoNum); + ammoType = NULL; + max = per = &dummy; + defaultAmmo = NULL; } oldclip = *per; @@ -1321,23 +1382,21 @@ static int PatchAmmo (int ammoNum) static int PatchWeapon (int weapNum) { int result; - const PClass *type = NULL; + const PClass *type; + AWeapon *info; BYTE dummy[sizeof(AWeapon)]; - AWeapon *info = (AWeapon *)&dummy; bool patchedStates = false; - if (weapNum >= 0 && weapNum < 9 && (unsigned)weapNum < WeaponNames.Size()) + if (weapNum >= 0 && weapNum < 9) { - type = WeaponNames[weapNum]; - if (type != NULL) - { - info = (AWeapon *)GetDefaultByType (type); - DPrintf ("Weapon %d\n", weapNum); - } + type = PClass::FindClass(WeaponNames[weapNum]); + info = (AWeapon *)GetDefaultByType (type); + DPrintf ("Weapon %d\n", weapNum); } - - if (type == NULL) + else { + info = (AWeapon *)&dummy; + type = NULL; Printf ("Weapon %d out of range.\n", weapNum); } @@ -1370,11 +1429,11 @@ static int PatchWeapon (int weapNum) } else if (stricmp (Line1, "Ammo type") == 0) { - if (val < 0 || val >= 12 || (unsigned)val >= AmmoNames.Size()) + if (val < 0 || val >= 12) { val = 5; } - info->AmmoType1 = AmmoNames[val]; + info->AmmoType1 = PClass::FindClass (AmmoNames[val]); if (info->AmmoType1 != NULL) { info->AmmoGive1 = ((AAmmo*)GetDefaultByType (info->AmmoType1))->Amount * 2; @@ -1431,15 +1490,27 @@ static int PatchWeapon (int weapNum) static void SetPointer(FState *state, PSymbol *sym) { - if (sym==NULL || sym->SymbolType != SYM_ActionFunction) + if (sym==NULL) { state->Action = NULL; + state->ParameterIndex=0; } - else + else switch (sym->SymbolType) { + case SYM_ActionFunction: state->Action = static_cast(sym)->Function; + state->ParameterIndex=0; // No parameters for patched code pointers + break; + /* + case SYM_ExternalFunction: + state->Action = A_CallExtFunction; + state->ParameterIndex = static_cast(sym->Data); + break; + */ + default: + state->Action = NULL; + state->ParameterIndex=0; } - state->ParameterIndex=0; } static int PatchPointer (int ptrNum) @@ -1455,17 +1526,17 @@ static int PatchPointer (int ptrNum) while ((result = GetLine ()) == 1) { - if ((unsigned)ptrNum < CodePConv.Size() && (!stricmp (Line1, "Codep Frame"))) + if ((unsigned)ptrNum < (unsigned)NumCodeP && (!stricmp (Line1, "Codep Frame"))) { FState *state = FindState (CodePConv[ptrNum]); if (state) { int index = atoi(Line2); - if ((unsigned)(index) >= Actions.Size()) - SetPointer(state, NULL); + if ((unsigned)(index) >= (unsigned)NumActions) + state->Action = NULL; else { - SetPointer(state, Actions[index]); + SetPointer(state, CodePtrSymbols[ActionList[index]]); } } else @@ -1747,42 +1818,53 @@ static int PatchCodePtrs (int dummy) int frame = atoi (Line1 + 5); FState *state = FindState (frame); - stripwhite (Line2); if (state == NULL) { Printf ("Frame %d out of range\n", frame); } - else if (!stricmp(Line2, "NULL")) - { - SetPointer(state, NULL); - } else { - FString symname; + int name; + stripwhite (Line2); if ((Line2[0] == 'A' || Line2[0] == 'a') && Line2[1] == '_') - symname = Line2; + name = FindName (Line2 + 2); else - symname.Format("A_%s", Line2); + name = FindName (Line2); - // This skips the action table and goes directly to the internal symbol table - // DEH compatible functions are easy to recognize. - PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(symname, true); - if (sym == NULL || sym->SymbolType != SYM_ActionFunction) + if (name == -1) { - Printf("Frame %d: Unknown code pointer '%s'\n", frame, Line2); + state->Action = NULL; + Printf ("Frame %d: Unknown code pointer: %s\n", frame, Line2); } else { - FString &args = static_cast(sym)->Arguments; - if (args.Len()!=0 && (args[0]<'a' || args[0]>'z')) + int min, max, mid; + + min = 0; + max = NumCodePtrs - 1; + while (min <= max) { - Printf("Frame %d: Incompatible code pointer '%s'\n", frame, Line2); - sym = NULL; + mid = (min + max) / 2; + if (CodePtrNames[mid].name == name) + break; + else if (CodePtrNames[mid].name < name) + min = mid + 1; + else + max = mid - 1; + } + if (min > max) + { + state->Action = NULL; + Printf ("Frame %d: Unknown code pointer: %s\n", frame, Line2); + } + else + { + SetPointer(state, CodePtrSymbols[CodePtrNames[mid].num]); + DPrintf ("Frame %d set to %s\n", frame, GetName (CodePtrNames[mid].name)); } } - SetPointer(state, sym); } } } @@ -2252,6 +2334,7 @@ static short *GetWordSpace (void *in, size_t size) } static int DehUseCount; +static BYTE *DehSuppLump; static void UnloadDehSupp () { @@ -2263,27 +2346,29 @@ static void UnloadDehSupp () // that was altered by the first. So we need to keep the // StateMap around until all patches have been applied. DehUseCount = 0; - Actions.Clear(); - Actions.ShrinkToFit(); - OrgHeights.Clear(); - OrgHeights.ShrinkToFit(); - CodePConv.Clear(); - CodePConv.ShrinkToFit(); - OrgSprNames.Clear(); - OrgSprNames.ShrinkToFit(); - SoundMap.Clear(); - SoundMap.ShrinkToFit(); - InfoNames.Clear(); - InfoNames.ShrinkToFit(); - BitNames.Clear(); - BitNames.ShrinkToFit(); - StyleNames.Clear(); - StyleNames.ShrinkToFit(); - WeaponNames.Clear(); - WeaponNames.ShrinkToFit(); - AmmoNames.Clear(); - AmmoNames.ShrinkToFit(); - + delete[] DehSuppLump; + DehSuppLump = NULL; + if (CodePtrSymbols != NULL) + { + delete[] CodePtrSymbols; + CodePtrSymbols = NULL; + } + if (OrgSprNames != NULL) + { + delete[] OrgSprNames[0]; + delete[] OrgSprNames; + OrgSprNames = NULL; + } + if (BitNames != NULL) + { + delete[] BitNames; + BitNames = NULL; + } + if (StyleNames != NULL) + { + delete[] StyleNames; + StyleNames = NULL; + } if (UnchangedSpriteNames != NULL) { delete[] UnchangedSpriteNames; @@ -2300,326 +2385,204 @@ static void UnloadDehSupp () static bool LoadDehSupp () { - try + int lump = Wads.CheckNumForName ("DEHSUPP"); + bool gotnames = false; + int i; + BYTE *supp; + + if (lump == -1) { - int lump = Wads.CheckNumForName ("DEHSUPP"); - bool gotnames = false; - int i; + return false; + } - if (lump == -1) + if (++DehUseCount > 1) + { + return true; + } + + if (EnglishStrings == NULL) + { + EnglishStrings = new FStringTable; + EnglishStrings->LoadStrings (true); + } + + if (UnchangedSpriteNames == NULL) + { + UnchangedSpriteNames = new char[sprites.Size()*4]; + NumUnchangedSprites = sprites.Size(); + for (i = 0; i < NumUnchangedSprites; ++i) { - return false; + memcpy (UnchangedSpriteNames+i*4, &sprites[i].name, 4); } + } - if (++DehUseCount > 1) + if (DehSuppLump != NULL) + { + supp = DehSuppLump; + } + else + { + int len = Wads.LumpLength (lump); + supp = new BYTE[len]; + Wads.ReadLump (lump, supp); + DehSuppLump = supp; + } + + for (;;) + { + if (CompareLabel ("NAME", supp)) { - return true; + gotnames = true; + NumNames = GetWord (supp + 6); + NameBase = (char *)(supp + 8 + NumNames * 2); + NameOffs = (WORD *)GetWordSpace (supp + 8, NumNames); + supp += GetWord (supp + 4) + 6; } - - if (EnglishStrings == NULL) + else if (CompareLabel ("HIGH", supp)) { - EnglishStrings = new FStringTable; - EnglishStrings->LoadStrings (true); + NumOrgHeights = GetWord (supp + 4); + OrgHeights = supp + 6; + supp += NumOrgHeights + 6; } - - if (UnchangedSpriteNames == NULL) + else if (CompareLabel ("ACTF", supp)) { - UnchangedSpriteNames = new char[sprites.Size()*4]; - NumUnchangedSprites = sprites.Size(); - for (i = 0; i < NumUnchangedSprites; ++i) + NumCodePtrs = GetWord (supp + 4); + CodePtrNames = (CodePtrMap *)GetWordSpace (supp + 6, NumCodePtrs*2); + CodePtrSymbols = new PSymbol*[NumCodePtrs]; + for(int i=0;iSymbols.FindSymbol(name, true); } + supp += 6 + NumCodePtrs * 4; } - - FScanner sc; - - sc.OpenLumpNum(lump, "DEHSUPP"); - sc.SetCMode(true); - - while (sc.GetString()) + else if (CompareLabel ("ACTM", supp)) { - if (sc.Compare("ActionList")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("NULL")) - { - Actions.Push(NULL); - } - else - { - // all relevant code pointers are either defined in AInventory - // or AActor so this will find all of them. - FString name = "A_"; - name << sc.String; - PSymbol *sym = RUNTIME_CLASS(AInventory)->Symbols.FindSymbol(name, true); - if (sym == NULL || sym->SymbolType != SYM_ActionFunction) - { - sc.ScriptMessage("Unknown code pointer '%s'", sc.String); - } - else - { - FString &args = static_cast(sym)->Arguments; - if (args.Len()!=0 && (args[0]<'a' || args[0]>'z')) - { - sc.ScriptMessage("Incompatible code pointer '%s'", sc.String); - sym = NULL; - } - } - Actions.Push(sym); - } - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("OrgHeights")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetNumber(); - OrgHeights.Push(sc.Number); - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("CodePConv")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetNumber(); - CodePConv.Push(sc.Number); - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("OrgSprNames")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - DEHSprName s; - if (strlen(sc.String) ==4) - { - s.c[0] = sc.String[0]; - s.c[1] = sc.String[1]; - s.c[2] = sc.String[2]; - s.c[3] = sc.String[3]; - s.c[4] = 0; - } - else - { - Printf("Invalid sprite name '%s' (must be 4 characters)", sc.String); - s.c[0] = 0; - } - OrgSprNames.Push(s); - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("StateMap")) - { - bool addit = StateMap.Size() == 0; + NumActions = GetWord (supp + 4); + ActionList = supp + 6; + supp += NumActions + 6; + } + else if (CompareLabel ("CODP", supp)) + { + NumCodeP = GetWord (supp + 4); + CodePConv = GetWordSpace (supp + 6, NumCodeP); + supp += 6 + NumCodeP * 2; + } + else if (CompareLabel ("SPRN", supp)) + { + char *sprites; - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) + NumSprites = GetWord (supp + 4); + OrgSprNames = new char *[NumSprites]; + sprites = new char[NumSprites*5]; + for (i = 0; i < NumSprites; i++) + { + sprites[i*5+0] = supp[6+i*4+0]; + sprites[i*5+1] = supp[6+i*4+1]; + sprites[i*5+2] = supp[6+i*4+2]; + sprites[i*5+3] = supp[6+i*4+3]; + sprites[i*5+4] = 0; + OrgSprNames[i] = sprites + i*5; + } + supp += 6 + NumSprites * 4; + } + else if (CompareLabel ("STAT", supp)) + { + if (!gotnames) + { + Printf ("Names must come before state map\n"); + return false; + } + if (StateMap == NULL) + { + NumStateMaps = GetWord (supp + 4); + StateMap = new StateMapper[NumStateMaps]; + for (i = 0; i < NumStateMaps; i++) { - StateMapper s; - sc.MustGetString(); - - const PClass *type = PClass::FindClass (sc.String); - AActor *def = NULL; + const char *name = GetName (GetWord (supp + 6 + i*4)); + const PClass *type = PClass::FindClass (name); if (type == NULL) { - sc.ScriptMessage ("Can't find type %s", sc.String); + Printf ("Can't find type %s\n", name); return false; } else if (type->ActorInfo == NULL) { - sc.ScriptMessage ("%s has no ActorInfo", sc.String); + Printf ("%s has no ActorInfo\n", name); return false; } else { - def = GetDefaultByType (type); - } + AActor *def = GetDefaultByType (type); - sc.MustGetStringName(","); - sc.MustGetString(); - if (type != NULL) - { - switch (sc.MustMatchString(StateBaseNames)) + switch (supp[6 + i*4 + 2]) { case FirstState: - s.State = type->ActorInfo->OwnedStates; + StateMap[i].State = type->ActorInfo->OwnedStates; break; case SpawnState: - s.State = def->SpawnState; + StateMap[i].State = def->SpawnState; break; case DeathState: - s.State = type->ActorInfo->FindState(NAME_Death); - break; - default: - sc.ScriptMessage("Invalid state base '%s' in '%s'", sc.String, type->TypeName.GetChars()); - s.State = NULL; + StateMap[i].State = type->ActorInfo->FindState(NAME_Death); break; } + StateMap[i].StateSpan = supp[6+i*4+3]; + StateMap[i].Owner = type; + StateMap[i].OwnerIsPickup = (def->flags & MF_SPECIAL) != 0; } - else s.State = NULL; - - sc.MustGetStringName(","); - sc.MustGetNumber(); - if (type != NULL) - { - if (s.State == NULL || s.State + sc.Number > type->ActorInfo->OwnedStates + type->ActorInfo->NumOwnedStates) - { - sc.ScriptMessage("Invalid state range in '%s'", type->TypeName.GetChars()); - s.State = NULL; // cannot be used because it's incomplete. - } - } - - s.StateSpan = sc.Number; - s.Owner = type; - s.OwnerIsPickup = def != NULL && (def->flags & MF_SPECIAL) != 0; - if (addit) StateMap.Push(s); - - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); } } - else if (sc.Compare("SoundMap")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - SoundMap.Push(S_FindSound(sc.String)); - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("InfoNames")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - const PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL) - { - sc.ScriptMessage("Unknown actor type '%s' in DEHSUPP", sc.String); - } - InfoNames.Push(cls); - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("ThingBits")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - BitName bit; - sc.MustGetNumber(); - if (sc.Number < 0 || sc.Number > 31) - { - sc.ScriptMessage("Invalid bit value %d", sc.Number); - sc.Number = 0; - } - bit.Bit = sc.Number; - sc.MustGetStringName(","); - sc.MustGetNumber(); - if (sc.Number < 0 || sc.Number > 2) - { - sc.ScriptMessage("Invalid flag word %d", sc.Number); - sc.Number = 0; - } - bit.WhichFlags = sc.Number; - sc.MustGetStringName(","); - sc.MustGetString(); - strncpy(bit.Name, sc.String, 19); - bit.Name[19]=0; - BitNames.Push(bit); - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("RenderStyles")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - StyleName style; - sc.MustGetNumber(); - style.Num = sc.Number; - sc.MustGetStringName(","); - sc.MustGetString(); - strncpy(style.Name, sc.String, 19); - style.Name[19]=0; - StyleNames.Push(style); - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("AmmoNames")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - if (sc.Compare("NULL")) - { - AmmoNames.Push(NULL); - } - else - { - const PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL || cls->ParentClass != RUNTIME_CLASS(AAmmo)) - { - sc.ScriptMessage("Unknown ammo type '%s' in DEHSUPP", sc.String); - } - AmmoNames.Push(cls); - } - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else if (sc.Compare("WeaponNames")) - { - sc.MustGetStringName("{"); - while (!sc.CheckString("}")) - { - sc.MustGetString(); - const PClass *cls = PClass::FindClass(sc.String); - if (cls == NULL || !cls->IsDescendantOf(RUNTIME_CLASS(AWeapon))) - { - sc.ScriptMessage("Unknown weapon type '%s' in DEHSUPP", sc.String); - } - WeaponNames.Push(cls); - if (sc.CheckString("}")) break; - sc.MustGetStringName(","); - } - } - else - { - sc.ScriptError("Unknown section '%s' in DEHSUPP", sc.String); - } - - sc.MustGetStringName(";"); + supp += 6 + NumStateMaps * 4; + } + else if (CompareLabel ("SND ", supp)) + { + NumSounds = GetWord (supp + 4); + SoundMap = GetWordSpace (supp + 6, NumSounds); + supp += 6 + NumSounds * 2; + } + else if (CompareLabel ("INFN", supp)) + { + NumInfos = GetWord (supp + 4); + InfoNames = GetWordSpace (supp + 6, NumInfos); + supp += 6 + NumInfos * 2; + } + else if (CompareLabel ("TBIT", supp)) + { + NumBitNames = GetWord (supp + 4); + BitNames = new BitName[NumBitNames]; + for (i = 0; i < NumBitNames; i++) + { + BitNames[i].Name = GetWord (supp + 6 + i*3); + BitNames[i].Bit = supp[6+i*3+2] & 0x1f; + BitNames[i].WhichFlags = clamp (supp[6+i*3+2] >> 5, 0, 3); + } + supp += 6 + NumBitNames * 3; + } + else if (CompareLabel ("REND", supp)) + { + NumStyleNames = GetWord (supp + 4); + StyleNames = new StyleName[NumStyleNames]; + for (i = 0; i < NumStyleNames; i++) + { + StyleNames[i].Name = GetWord (supp + 6 + i*3); + StyleNames[i].Num = supp[6+i*3+2]; + } + supp += 6 + NumStyleNames * 3; + } + else if (CompareLabel ("END ", supp)) + { + return true; + } + else + { + Printf ("Unknown block %c%c%c%c in DEHSUPP\n", + supp[0], supp[1], supp[2], supp[3]); + return false; } - return true; - } - catch(CRecoverableError &err) - { - // Don't abort if DEHSUPP loading fails. - // Just print the message and continue. - Printf("%s", err.GetMessage()); - return false; } } @@ -2664,8 +2627,11 @@ void FinishDehPatch () } // Now that all Dehacked patches have been processed, it's okay to free StateMap. - StateMap.Clear(); - StateMap.ShrinkToFit(); + if (StateMap != NULL) + { + delete[] StateMap; + StateMap = NULL; + } } void A_SpawnDehackedPickup (AActor *actor) diff --git a/src/s_sound.cpp b/src/s_sound.cpp index cf1a554f2c..d06613143f 100644 --- a/src/s_sound.cpp +++ b/src/s_sound.cpp @@ -163,7 +163,7 @@ static fixed_t P_AproxDistance2 (AActor *listener, fixed_t x, fixed_t y) void S_NoiseDebug (void) { FSoundChan *chan; - fixed_t ox, oy; + fixed_t ox, oy, oz; int y, color; y = 32 * CleanYfac; @@ -173,9 +173,10 @@ void S_NoiseDebug (void) screen->DrawText (CR_GOLD, 0, y, "name", TAG_DONE); screen->DrawText (CR_GOLD, 70, y, "x", TAG_DONE); screen->DrawText (CR_GOLD, 120, y, "y", TAG_DONE); - screen->DrawText (CR_GOLD, 170, y, "vol", TAG_DONE); - screen->DrawText (CR_GOLD, 200, y, "dist", TAG_DONE); - screen->DrawText (CR_GOLD, 240, y, "chan", TAG_DONE); + screen->DrawText (CR_GOLD, 170, y, "z", TAG_DONE); + screen->DrawText (CR_GOLD, 220, y, "vol", TAG_DONE); + screen->DrawText (CR_GOLD, 250, y, "dist", TAG_DONE); + screen->DrawText (CR_GOLD, 290, y, "chan", TAG_DONE); y += 8; if (Channels == NULL) @@ -195,16 +196,19 @@ void S_NoiseDebug (void) { ox = players[consoleplayer].camera->x; oy = players[consoleplayer].camera->y; + oz = players[consoleplayer].camera->z; } else if (origin) { ox = origin[0]; oy = origin[1]; + oz = origin[2]; } else { ox = chan->X; oy = chan->Y; + oz = chan->Z; } color = chan->Loop ? CR_BROWN : CR_GREY; Wads.GetLumpName (temp, chan->SfxInfo->lumpnum); @@ -214,12 +218,14 @@ void S_NoiseDebug (void) screen->DrawText (color, 70, y, temp, TAG_DONE); sprintf (temp, "%d", oy >> FRACBITS); screen->DrawText (color, 120, y, temp, TAG_DONE); - sprintf (temp, "%g", chan->Volume); + sprintf (temp, "%d", oz >> FRACBITS); screen->DrawText (color, 170, y, temp, TAG_DONE); + sprintf (temp, "%g", chan->Volume); + screen->DrawText (color, 220, y, temp, TAG_DONE); sprintf (temp, "%d", P_AproxDistance2 (players[consoleplayer].camera, ox, oy) / FRACUNIT); - screen->DrawText (color, 200, y, temp, TAG_DONE); + screen->DrawText (color, 250, y, temp, TAG_DONE); sprintf (temp, "%d", chan->EntChannel); - screen->DrawText (color, 240, y, temp, TAG_DONE); + screen->DrawText (color, 290, y, temp, TAG_DONE); y += 8; if (chan->PrevChan == &Channels) { @@ -671,7 +677,7 @@ static void S_StartSound (fixed_t *pt, AActor *mover, int channel, sfx = &S_sfx[sound_id]; // If this is a singular sound, don't play it if it's already playing. - if (pt != NULL && sfx->bSingular && S_CheckSingular(sound_id)) + if (sfx->bSingular && S_CheckSingular(sound_id)) return; // Resolve player sounds, random sounds, and aliases @@ -715,6 +721,8 @@ static void S_StartSound (fixed_t *pt, AActor *mover, int channel, } else { + basepriority = 0; +#if 0 switch (channel) { case CHAN_WEAPON: @@ -731,7 +739,8 @@ static void S_StartSound (fixed_t *pt, AActor *mover, int channel, basepriority = -10; break; } - basepriority = int(basepriority * attenuation); + basepriority = int(basepriority / attenuation); +#endif } if (mover != NULL && channel == CHAN_AUTO) @@ -764,7 +773,7 @@ static void S_StartSound (fixed_t *pt, AActor *mover, int channel, { for (chan = Channels; chan != NULL; chan = chan->NextChan) { - if (chan->Mover == mover && chan->EntChannel == channel) + if (((mover != NULL && chan->Mover == mover) || (chan->Pt == pt)) && chan->EntChannel == channel) { GSnd->StopSound(chan); break; diff --git a/src/sc_man.cpp b/src/sc_man.cpp index afc96ca986..cfaeaf24c8 100644 --- a/src/sc_man.cpp +++ b/src/sc_man.cpp @@ -982,32 +982,6 @@ void STACK_ARGS FScanner::ScriptError (const char *message, ...) AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); } -//========================================================================== -// -// FScanner::ScriptError -// -//========================================================================== - -void STACK_ARGS FScanner::ScriptMessage (const char *message, ...) -{ - FString composed; - - if (message == NULL) - { - composed = "Bad syntax."; - } - else - { - va_list arglist; - va_start (arglist, message); - composed.VFormat (message, arglist); - va_end (arglist); - } - - Printf ("Script error, \"%s\" line %d:\n%s\n", ScriptName.GetChars(), - AlreadyGot? AlreadyGotLine : Line, composed.GetChars()); -} - //========================================================================== // // FScanner :: CheckOpen diff --git a/src/sc_man.h b/src/sc_man.h index b86cd8ec33..245adbff15 100644 --- a/src/sc_man.h +++ b/src/sc_man.h @@ -58,7 +58,6 @@ public: int MustMatchString(const char **strings); void ScriptError(const char *message, ...); - void ScriptMessage(const char *message, ...); // Members ------------------------------------------------------ char *String; diff --git a/src/sound/fmodsound.cpp b/src/sound/fmodsound.cpp index 9aacdbb94e..3e117b89bf 100644 --- a/src/sound/fmodsound.cpp +++ b/src/sound/fmodsound.cpp @@ -164,6 +164,8 @@ static const FEnumList SpeakerModeNames[] = { "1", FMOD_SPEAKERMODE_MONO }, { "2", FMOD_SPEAKERMODE_STEREO }, { "4", FMOD_SPEAKERMODE_QUAD }, + { "Headphones", 9001 }, + { "HRTF", 9001 }, { NULL, 0 } }; @@ -292,6 +294,7 @@ public: return false; } Channel->setChannelGroup(Owner->MusicGroup); + Channel->setSpeakerMix(1, 1, 1, 1, 1, 1, 1, 1); Channel->setVolume(volume); // Ensure reverb is disabled. FMOD_REVERB_CHANNELPROPERTIES reverb; @@ -478,7 +481,7 @@ bool FMODSoundRenderer::Init() { speakermode = FMOD_SPEAKERMODE(eval); } - result = Sys->setSpeakerMode(speakermode); + result = Sys->setSpeakerMode(speakermode < 9000 ? speakermode : FMOD_SPEAKERMODE_STEREO); ERRCHECK(result); // Set software format @@ -548,7 +551,11 @@ bool FMODSoundRenderer::Init() } // Try to init - initflags = FMOD_INIT_NORMAL | FMOD_INIT_SOFTWARE_HRTF; + initflags = FMOD_INIT_NORMAL; + if (speakermode > 9000) + { + initflags |= FMOD_INIT_SOFTWARE_HRTF; + } if (snd_dspnet) { initflags |= FMOD_INIT_ENABLE_DSPNET; diff --git a/src/sound/music_midistream.cpp b/src/sound/music_midistream.cpp index 58117710e5..f2bf7ce66e 100644 --- a/src/sound/music_midistream.cpp +++ b/src/sound/music_midistream.cpp @@ -205,29 +205,9 @@ void MIDIStreamer::Play (bool looping) } else if (res == SONG_DONE) { - if (looping) - { - Restarting = true; - if (SONG_MORE == FillBuffer(BufferNum, MAX_EVENTS, MAX_TIME)) - { - if (0 != MIDI->StreamOut(&Buffer[BufferNum])) - { - Printf ("Initial midiStreamOut failed\n"); - Stop(); - return; - } - BufferNum ^= 1; - } - else - { - Stop(); - return; - } - } - else - { - EndQueued = true; - } + // Do not play super short songs that can't fill the initial two buffers. + Stop(); + return; } else { diff --git a/tools/dehsupp/Makefile b/tools/dehsupp/Makefile new file mode 100644 index 0000000000..2502093ce9 --- /dev/null +++ b/tools/dehsupp/Makefile @@ -0,0 +1,55 @@ +ifeq (Windows_NT,$(OS)) + WIN=1 + WINCMD=1 +endif +ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) + WIN=1 + WINCMD=0 +endif + +ifeq (1,$(WIN)) + EXE = dehsupp.exe + CFLAGS = $(LOC) -Os -Wall -fomit-frame-pointer +else + EXE = dehsupp + CFLAGS = -Dstricmp=strcasecmp -Dstrnicmp=strncasecmp -Os -Wall -fomit-frame-pointer +endif + +CCDV = @../../ccdv +CC = gcc +LDFLAGS = -s + +RE2C = ../re2c/re2c +LEMON = ../lemon/lemon +LEMONFLAGS = +RE2CFLAGS = -s + +OBJS = dehsupp.o parse.o scanner.o + +all: $(EXE) + +$(EXE): $(OBJS) + $(CCDV) $(CC) $(LDFLAGS) -o $(EXE) $(OBJS) + +.PHONY: clean + +clean: +ifeq (1,$(WINCMD)) + -del /q /f $(EXE) 2>nul + -del /q /f *.o 2>nul +else + rm -f $(EXE) + rm -f *.o +endif + +%.o: %.c + $(CCDV) $(CC) $(CFLAGS) -c -o $@ $< + +parse.h parse.c: parse.y + $(CCDV) $(LEMON) $(LEMONFLAGS) $< + +scanner.c: scanner.re + $(CCDV) $(RE2C) $(RE2CFLAGS) -o $@ $< + +parse.tab.c: parse.y + $(CCDV) $(BISON) $(BISONFLAGS) -o $@ $< diff --git a/tools/dehsupp/dehsupp.c b/tools/dehsupp/dehsupp.c new file mode 100644 index 0000000000..8e805510a6 --- /dev/null +++ b/tools/dehsupp/dehsupp.c @@ -0,0 +1,571 @@ +#include +#include +#include +#include +#include +#include +#include "dehsupp.h" + +FILE *Source, *Dest; +int SourceLine; +int ErrorCount; + +struct StringList *NameList, **NameListLast = &NameList; +int NameCount; + +name *ActionsList; +unsigned char *HeightsArray; +unsigned char *ActionMap; +unsigned short *CodePMap; +char *SpriteNames; +struct StateMapE *StateMaps; +name *SoundMaps; +name *InfoNamesArray; +struct ThingBitsE *ThingBitsMap; +struct RenderStylesE *RenderStylesMap; + +int ActionsListSize, MaxActionsListSize; +int HeightsSize, MaxHeightsSize; +int ActionMapSize, MaxActionMapSize; +int CodePMapSize, MaxCodePMapSize; +int SpriteNamesSize, MaxSpriteNamesSize; +int StateMapsSize, MaxStateMapsSize; +int SoundMapsSize, MaxSoundMapsSize; +int InfoNamesSize, MaxInfoNamesSize; +int ThingBitsMapSize, MaxThingBitsMapSize; +int RenderStylesSize, MaxRenderStylesSize; + +int main (int argc, char **argv) +{ + if (argc != 3) + { + printf ("Usage: dehsupp \n"); + return -1; + } + Source = fopen (argv[1], "r"); + if (Source == NULL) + { + printf ("Could not open %s\n", argv[1]); + return -2; + } +#if !defined(NDEBUG) && 0 + ParseTrace(fopen("trace.txt", "w"), ""); +#endif + SourceLine = 1; + yyparse (); + fclose (Source); + if (ErrorCount) + { + printf ("There were %d errors\n", ErrorCount); + return -3; + } + SortNames (); + Dest = fopen (argv[2], "wb"); + if (Dest == NULL) + { + printf ("Could not open %s\n", argv[2]); + return -4; + } + WriteNameTable (); + WriteActions (); + WriteCodePConv (); + WriteSprites (); + WriteSounds (); + WriteInfoNames (); + WriteStates (); + WriteActionMap (); + WriteThingBits (); + WriteRenderStyles (); + WriteHeights (); + WriteLabel ("END "); + fclose (Dest); + return 0; +} + +void fail (int code, char *err) +{ + fclose (Dest); + printf ("%s\n", err); + exit (code); +} + +void *ParseAlloc(void *(*mallocProc)(size_t)); +void Parse(void *yyp, int yymajor, struct Token yyminor); +void ParseFree(void *p, void (*freeProc)(void*)); + +void yyparse (void) +{ + Scanner scanner = { Source }; + void *pParser = ParseAlloc (malloc); + struct Token token; + int tokentype; + + while ((tokentype = lex(&scanner, &token)) != EOI) + { + SourceLine = scanner.line; + Parse (pParser, tokentype, token); + } + memset (&token, 0, sizeof(token)); + Parse (pParser, 0, token); + ParseFree (pParser, free); +} + +name FindName (char *name) +{ + struct StringList *probe = NameList; + int count = 0; + + while (probe != NULL) + { + if (stricmp (probe->String, name) == 0) + { + return count; + } + count++; + probe = probe->Next; + } + return -1; +} + +name AddName (char *name) +{ + struct StringList *newone; + int index = FindName (name); + + if (index != -1) + return index; + + newone = malloc (sizeof(*newone) + strlen(name)); + strcpy (newone->String, name); + newone->Next = NULL; + *NameListLast = newone; + NameListLast = &newone->Next; + return NameCount++; +} + +int FindAction (char *namei) +{ + int name = FindName (namei); + + if (name != -1) + { + int i; + + for (i = 0; i < ActionsListSize; i++) + { + if (ActionsList[i] == name) + return i; + } + } + printf ("Line %d: Unknown action %s\n", SourceLine, namei); + ErrorCount++; + return -1; +} + +void AddAction (char *name) +{ + int newname = AddName (name); + if (ActionsListSize == MaxActionsListSize) + { + MaxActionsListSize = MaxActionsListSize ? MaxActionsListSize * 2 : 256; + ActionsList = realloc (ActionsList, MaxActionsListSize*sizeof(*ActionsList)); + } + ActionsList[ActionsListSize++] = newname; +} + +void AddHeight (int h) +{ + if (MaxHeightsSize == HeightsSize) + { + MaxHeightsSize = MaxHeightsSize ? MaxHeightsSize * 2 : 256; + HeightsArray = realloc (HeightsArray, MaxHeightsSize); + } + HeightsArray[HeightsSize++] = h; +} + +void AddActionMap (char *name) +{ + int index = FindAction (name); + + if (index != -1) + { + if (ActionMapSize == MaxActionMapSize) + { + MaxActionMapSize = MaxActionMapSize ? MaxActionMapSize * 2 : 256; + ActionMap = realloc (ActionMap, MaxActionMapSize*sizeof(*ActionMap)); + } + ActionMap[ActionMapSize++] = index; + } +} + +void AddCodeP (int codep) +{ + if (CodePMapSize == MaxCodePMapSize) + { + MaxCodePMapSize = MaxCodePMapSize ? MaxCodePMapSize * 2 : 256; + CodePMap = realloc (CodePMap, MaxCodePMapSize*sizeof(*CodePMap)); + } + CodePMap[CodePMapSize++] = codep; +} + +void AddSpriteName (char *name) +{ + if (strlen (name) != 4) + { + printf ("Line %d: Sprite name %s must be 4 characters\n", SourceLine, name); + ErrorCount++; + return; + } + if (SpriteNamesSize == MaxSpriteNamesSize) + { + MaxSpriteNamesSize = MaxSpriteNamesSize ? MaxSpriteNamesSize * 2 : 256*4; + SpriteNames = realloc (SpriteNames, MaxSpriteNamesSize*sizeof(*SpriteNames)); + } + SpriteNames[SpriteNamesSize+0] = toupper (name[0]); + SpriteNames[SpriteNamesSize+1] = toupper (name[1]); + SpriteNames[SpriteNamesSize+2] = toupper (name[2]); + SpriteNames[SpriteNamesSize+3] = toupper (name[3]); + SpriteNamesSize += 4; +} + +void AddSoundMap (char *name) +{ + if (SoundMapsSize == MaxSoundMapsSize) + { + MaxSoundMapsSize = MaxSoundMapsSize ? MaxSoundMapsSize * 2 : 256; + SoundMaps = realloc (SoundMaps, MaxSoundMapsSize*sizeof(*SoundMaps)); + } + SoundMaps[SoundMapsSize++] = AddName (name); +} + +void AddInfoName (char *name) +{ + if (InfoNamesSize == MaxInfoNamesSize) + { + MaxInfoNamesSize = MaxInfoNamesSize ? MaxInfoNamesSize * 2 : 256; + InfoNamesArray = realloc (InfoNamesArray, MaxInfoNamesSize*sizeof(*InfoNamesArray)); + } + InfoNamesArray[InfoNamesSize++] = AddName (name); +} + +void AddStateMap (char *name, int state, int count) +{ + if (count == 0) + { + printf ("Line %d: Count is 0. Is this right?\n", SourceLine); + return; + } + if ((unsigned)count > 255) + { + printf ("Line %d: Count must be in the range 1-255\n", SourceLine); + ErrorCount++; + } + if (StateMapsSize == MaxStateMapsSize) + { + MaxStateMapsSize = MaxStateMapsSize ? MaxStateMapsSize*2 : 256; + StateMaps = realloc (StateMaps, MaxStateMapsSize*sizeof(*StateMaps)); + } + StateMaps[StateMapsSize].Name = AddName (name); + StateMaps[StateMapsSize].State = state; + StateMaps[StateMapsSize].Count = count; + StateMapsSize++; +} + +void AddThingBits (char *name, int bitnum, int flagnum) +{ + if ((unsigned)bitnum > 31) + { + printf ("Line %d: Bit %d must be in the range 0-31\n", SourceLine, bitnum); + ErrorCount++; + return; + } + if (MaxThingBitsMapSize == ThingBitsMapSize) + { + MaxThingBitsMapSize = MaxThingBitsMapSize ? MaxThingBitsMapSize*2 : 128; + ThingBitsMap = realloc (ThingBitsMap, MaxThingBitsMapSize*sizeof(*ThingBitsMap)); + } + ThingBitsMap[ThingBitsMapSize].Name = AddName (name); + ThingBitsMap[ThingBitsMapSize].BitNum = bitnum; + ThingBitsMap[ThingBitsMapSize].FlagNum = flagnum; + ThingBitsMapSize++; +} + +void AddRenderStyle (char *name, int stylenum) +{ + if ((unsigned)stylenum > 255) + { + printf ("Line %d: %s must be in the range 0-255\n", SourceLine, name); + ErrorCount++; + return; + } + if (MaxRenderStylesSize == RenderStylesSize) + { + MaxRenderStylesSize = MaxRenderStylesSize ? MaxRenderStylesSize*2 : 16; + RenderStylesMap = realloc (RenderStylesMap, MaxRenderStylesSize*sizeof(*RenderStylesMap)); + } + RenderStylesMap[RenderStylesSize].Name = AddName (name); + RenderStylesMap[RenderStylesSize].StyleNum = stylenum; + RenderStylesSize++; +} + +int sortfunc (const void *a, const void *b) +{ + return stricmp (((struct StringSorter *)a)->Entry->String, + ((struct StringSorter *)b)->Entry->String); +} + +void SortNames () +{ + name *remap = malloc (NameCount * sizeof(*remap)); + struct StringSorter *sorter = malloc (NameCount * sizeof(*sorter)); + struct StringList *probe, **prev; + int i; + + for (i = 0, probe = NameList; probe != NULL; probe = probe->Next, i++) + { + sorter[i].OldName = i; + sorter[i].Entry = probe; + } + + // There are some warnings here, though I have no idea why. + qsort (sorter, NameCount, sizeof(*sorter), sortfunc); + + for (i = 0, prev = &NameList; i < NameCount; i++) + { + *prev = sorter[i].Entry; + prev = &sorter[i].Entry->Next; + } + *prev = NULL; + + for (i = 0; i < NameCount; i++) + { + remap[sorter[i].OldName] = i; + } + + for (i = 0; i < ActionsListSize; i++) + { + ActionsList[i] = remap[ActionsList[i]]; + } + for (i = 0; i < SoundMapsSize; i++) + { + SoundMaps[i] = remap[SoundMaps[i]]; + } + for (i = 0; i < InfoNamesSize; i++) + { + InfoNamesArray[i] = remap[InfoNamesArray[i]]; + } + for (i = 0; i < StateMapsSize; i++) + { + StateMaps[i].Name = remap[StateMaps[i].Name]; + } + for (i = 0; i < ThingBitsMapSize; i++) + { + ThingBitsMap[i].Name = remap[ThingBitsMap[i].Name]; + } + for (i = 0; i < RenderStylesSize; i++) + { + RenderStylesMap[i].Name = remap[RenderStylesMap[i].Name]; + } +} + +int yyerror (char *s) +{ + printf ("Line %d: %s\n", SourceLine, s); + ErrorCount++; + return 0; +} + +void WriteWord (int word) +{ + putc (word >> 8, Dest); + putc (word & 255, Dest); +} + +void WriteLabel (char *label) +{ + fwrite (label, 1, 4, Dest); +} + +void WriteWords (int count, short *array) +{ + int i; + + WriteWord (count); + for (i = 0; i < count; i++) + { + WriteWord (array[i]); + } +} + +void WriteBytes (int count, unsigned char *array) +{ + WriteWord (count); + fwrite (array, 1, count, Dest); +} + +void WriteNameTable () +{ + struct StringList *probe; + int i, size; + + WriteLabel ("NAME"); + // Count the length of each string, including nulls + for (probe = NameList, size = 0; probe != NULL; probe = probe->Next) + { + size += (int)strlen (probe->String) + 1; + } + + if (size == 0) + { + WriteWord (2); // Size of this lump + WriteWord (0); // Number of names + return; + } + size += NameCount*2 + 2; + if (size >= 65536) + { + fail (-5, "Name table is larger than 64K"); + } + WriteWord (size); // Size of this lump + WriteWord (NameCount); // Number of names + + // Write each name's offset from the first name, which is stored + // immediately after this list + for (i = size = 0, probe = NameList; i < NameCount; i++, probe = probe->Next) + { + WriteWord (size); + size += (int)strlen (probe->String) + 1; + } + + // Write each name's string in order now + for (probe = NameList; probe != NULL; probe = probe->Next) + { + fputs (probe->String, Dest); + putc (0, Dest); + } +} + +typedef struct +{ + name Name; + short Num; +} NameNum; + +int sortfunc2 (const void *a, const void *b) +{ + return ((NameNum *)a)->Name - ((NameNum *)b)->Name; +} + +void WriteActions () +{ + NameNum *sorter = malloc (ActionsListSize * sizeof(*sorter)); + int i; + + WriteLabel ("ACTF"); + WriteWord (ActionsListSize); + + for (i = 0; i < ActionsListSize; i++) + { + sorter[i].Name = ActionsList[i]; + sorter[i].Num = i; + } + // warnings here. ignore. + qsort (sorter, ActionsListSize, sizeof(*sorter), sortfunc2); + for (i = 0; i < ActionsListSize; i++) + { + WriteWord (sorter[i].Name); + WriteWord (sorter[i].Num); + } + free (sorter); +} + +void WriteActionMap () +{ + WriteLabel ("ACTM"); + WriteBytes (ActionMapSize, ActionMap); +} + +void WriteHeights () +{ + WriteLabel ("HIGH"); + WriteBytes (HeightsSize, HeightsArray); +} + +void WriteCodePConv () +{ + WriteLabel ("CODP"); + WriteWords (CodePMapSize, (short *)CodePMap); +} + +void WriteSprites () +{ + WriteLabel ("SPRN"); + WriteWord (SpriteNamesSize / 4); + fwrite (SpriteNames, SpriteNamesSize, 1, Dest); +} + +void WriteStates () +{ + int i; + + WriteLabel ("STAT"); + WriteWord (StateMapsSize); + for (i = 0; i < StateMapsSize; i++) + { + WriteWord (StateMaps[i].Name); + putc (StateMaps[i].State, Dest); + putc (StateMaps[i].Count, Dest); + } +} + +void WriteSounds () +{ + WriteLabel ("SND "); + WriteWords (SoundMapsSize, SoundMaps); +} + +void WriteInfoNames () +{ + WriteLabel ("INFN"); + WriteWords (InfoNamesSize, InfoNamesArray); +} + +int sortfunc3 (const void *a, const void *b) +{ + return ((struct ThingBitsE *)a)->Name - ((struct ThingBitsE *)b)->Name; +} + +void WriteThingBits () +{ + int i; + + WriteLabel ("TBIT"); + WriteWord (ThingBitsMapSize); + // warnings here; ignore them + qsort (ThingBitsMap, ThingBitsMapSize, sizeof(*ThingBitsMap), sortfunc3); + for (i = 0; i < ThingBitsMapSize; i++) + { + WriteWord (ThingBitsMap[i].Name); + putc (ThingBitsMap[i].BitNum | (ThingBitsMap[i].FlagNum<<5), Dest); + } +} + +int sortfunc4 (const void *a, const void *b) +{ + return ((struct RenderStylesE *)a)->Name - ((struct RenderStylesE *)b)->Name; +} + +void WriteRenderStyles () +{ + int i; + + WriteLabel ("REND"); + WriteWord (RenderStylesSize); + // More warnings; ignore + qsort (RenderStylesMap, RenderStylesSize, sizeof(*RenderStylesMap), sortfunc4); + for (i = 0; i < RenderStylesSize; i++) + { + WriteWord (RenderStylesMap[i].Name); + putc (RenderStylesMap[i].StyleNum, Dest); + } +} diff --git a/tools/dehsupp/dehsupp.h b/tools/dehsupp/dehsupp.h new file mode 100644 index 0000000000..e40043c4a0 --- /dev/null +++ b/tools/dehsupp/dehsupp.h @@ -0,0 +1,124 @@ +#include +#include "parse.h" + +typedef enum { false, true } bool; +typedef short name; +typedef unsigned char uchar; +typedef unsigned int uint; + +typedef struct Scanner { + FILE *fd; + uchar *bot, *tok, *ptr, *cur, *pos, *lim, *top, *eof; + uint line; +} Scanner; + +struct Token +{ + int val; + char *string; +}; + +int lex(Scanner *s, struct Token *tok); + +int yyerror (char *s); +void yyparse (void); + +extern FILE *Source, *Dest; +extern int SourceLine; +extern int ErrorCount; + + +void WriteWord (int word); +void WriteLabel (char *label); +void WriteWords (int count, short *array); +void WriteBytes (int count, unsigned char *array); + +void WriteNameTable (); + +void WriteActions (); +void WriteActionMap (); +void WriteHeights (); +void WriteCodePConv (); +void WriteSprites (); +void WriteStates (); +void WriteSounds (); +void WriteInfoNames (); +void WriteThingBits (); +void WriteRenderStyles (); + + +struct StringList +{ + struct StringList *Next; + char String[1]; +}; + +struct StringSorter +{ + name OldName; + struct StringList *Entry; +}; + +extern struct StringList *NameList, **NameListLast; +extern int NameCount; + +name AddName (char *name); +name FindName (char *name); + +void SortNames (); + +struct StateMapE +{ + name Name; + unsigned char State; + unsigned char Count; +}; + +struct ThingBitsE +{ + name Name; + unsigned char BitNum; + unsigned char FlagNum; +}; + +struct RenderStylesE +{ + name Name; + unsigned char StyleNum; +}; + +void AddAction (char *name); +int FindAction (char *name); + +extern name *ActionsList; +extern unsigned char *HeightsArray; +extern unsigned char *ActionMap; +extern unsigned short *CodePMap; +extern char *SpriteNames; +extern struct StateMapE *StateMaps; +extern name *SoundMaps; +extern name *InfoNamesArray; +extern struct ThingBitsE *ThingBitsMap; +extern struct RenderStylesE *RenderStylesMap; + +extern int ActionsListSize, MaxActionsListSize; +extern int HeightsSize, MaxHeightsSize; +extern int ActionMapSize, MaxActionMapSize; +extern int CodePMapSize, MaxCodePMapSize; +extern int SpriteNamesSize, MaxSpriteNamesSize; +extern int StateMapsSize, MaxStateMapsSize; +extern int SoundMapsSize, MaxSoundMapsSize; +extern int InfoNamesSize, MaxInfoNamesSize; +extern int ThingBitsMapSize, MaxThingBitsMapSize; +extern int RenderStylesSize, MaxRenderStylesSize; + +void AddHeight (int h); +void AddActionMap (char *name); +void AddCodeP (int codep); +void AddSpriteName (char *name); +void AddStateMap (char *name, int type, int count); +void AddSoundMap (char *sound); +void AddInfoName (char *sound); +void AddThingBits (char *name, int bitnum, int flagnum); +void AddRenderStyle (char *name, int stylenum); + diff --git a/tools/dehsupp/dehsupp.vcproj b/tools/dehsupp/dehsupp.vcproj new file mode 100644 index 0000000000..bdce02aa26 --- /dev/null +++ b/tools/dehsupp/dehsupp.vcproj @@ -0,0 +1,465 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tools/dehsupp/parse.c b/tools/dehsupp/parse.c new file mode 100644 index 0000000000..29fc39603e --- /dev/null +++ b/tools/dehsupp/parse.c @@ -0,0 +1,1471 @@ +/* Driver template for the LEMON parser generator. +** The author disclaims copyright to this source code. +*/ +/* First off, code is included which follows the "include" declaration +** in the input file. */ +#include +#include +#include + +#ifdef _MSC_VER +#define CDECL __cdecl +#else +#define CDECL +#endif + +#line 1 "parse.y" + +#include +#include "dehsupp.h" +#line 21 "parse.c" +/* Next is all token values, in a form suitable for use by makeheaders. +** This section will be null unless lemon is run with the -m switch. +*/ +/* +** These constants (all generated automatically by the parser generator) +** specify the various kinds of tokens (terminals) that the parser +** understands. +** +** Each symbol here is a terminal symbol in the grammar. +*/ +/* Make sure the INTERFACE macro is defined. +*/ +#ifndef INTERFACE +# define INTERFACE 1 +#endif +/* The next thing included is series of defines which control +** various aspects of the generated parser. +** YYCODETYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 terminals +** and nonterminals. "int" is used otherwise. +** YYNOCODE is a number of type YYCODETYPE which corresponds +** to no legal terminal or nonterminal number. This +** number is used to fill in empty slots of the hash +** table. +** YYFALLBACK If defined, this indicates that one or more tokens +** have fall-back values which should be used if the +** original value of the token will not parse. +** YYACTIONTYPE is the data type used for storing terminal +** and nonterminal numbers. "unsigned char" is +** used if there are fewer than 250 rules and +** states combined. "int" is used otherwise. +** ParseTOKENTYPE is the data type used for minor tokens given +** directly to the parser from the tokenizer. +** YYMINORTYPE is the data type used for all minor tokens. +** This is typically a union of many types, one of +** which is ParseTOKENTYPE. The entry in the union +** for base tokens is called "yy0". +** YYSTACKDEPTH is the maximum depth of the parser's stack. If +** zero the stack is dynamically sized using realloc() +** ParseARG_SDECL A static variable declaration for the %extra_argument +** ParseARG_PDECL A parameter declaration for the %extra_argument +** ParseARG_STORE Code to store %extra_argument into yypParser +** ParseARG_FETCH Code to extract %extra_argument from yypParser +** YYNSTATE the combined number of states. +** YYNRULE the number of rules in the grammar +** YYERRORSYMBOL is the code number of the error symbol. If not +** defined, then do no error processing. +*/ +#define YYCODETYPE unsigned char +#define YYNOCODE 67 +#define YYACTIONTYPE unsigned short int +#define ParseTOKENTYPE struct Token +typedef union { + ParseTOKENTYPE yy0; + int yy64; + int yy133; +} YYMINORTYPE; +#ifndef YYSTACKDEPTH +#define YYSTACKDEPTH 100 +#endif +#define ParseARG_SDECL +#define ParseARG_PDECL +#define ParseARG_FETCH +#define ParseARG_STORE +#define YYNSTATE 170 +#define YYNRULE 87 +#define YYERRORSYMBOL 34 +#define YYERRSYMDT yy133 +#define YY_NO_ACTION (YYNSTATE+YYNRULE+2) +#define YY_ACCEPT_ACTION (YYNSTATE+YYNRULE+1) +#define YY_ERROR_ACTION (YYNSTATE+YYNRULE) + +/* Next are that tables used to determine what action to take based on the +** current state and lookahead token. These tables are used to implement +** functions that take a state number and lookahead value and return an +** action integer. +** +** Suppose the action integer is N. Then the action is determined as +** follows +** +** 0 <= N < YYNSTATE Shift N. That is, push the lookahead +** token onto the stack and goto state N. +** +** YYNSTATE <= N < YYNSTATE+YYNRULE Reduce by rule N-YYNSTATE. +** +** N == YYNSTATE+YYNRULE A syntax error has occurred. +** +** N == YYNSTATE+YYNRULE+1 The parser accepts its input. +** +** N == YYNSTATE+YYNRULE+2 No such action. Denotes unused +** slots in the yy_action[] table. +** +** The action table is constructed as a single large table named yy_action[]. +** Given state S and lookahead X, the action is computed as +** +** yy_action[ yy_shift_ofst[S] + X ] +** +** If the index value yy_shift_ofst[S]+X is out of range or if the value +** yy_lookahead[yy_shift_ofst[S]+X] is not equal to X or if yy_shift_ofst[S] +** is equal to YY_SHIFT_USE_DFLT, it means that the action is not in the table +** and that yy_default[S] should be used instead. +** +** The formula above is for computing the action when the lookahead is +** a terminal symbol. If the lookahead is a non-terminal (as occurs after +** a reduce action) then the yy_reduce_ofst[] array is used in place of +** the yy_shift_ofst[] array and YY_REDUCE_USE_DFLT is used in place of +** YY_SHIFT_USE_DFLT. +** +** The following are the tables generated in this section: +** +** yy_action[] A single table containing all actions. +** yy_lookahead[] A table containing the lookahead for each entry in +** yy_action. Used to detect hash collisions. +** yy_shift_ofst[] For each state, the offset into yy_action for +** shifting terminals. +** yy_reduce_ofst[] For each state, the offset into yy_action for +** shifting non-terminals after a reduce. +** yy_default[] Default action for each state. +*/ +static const YYACTIONTYPE yy_action[] = { + /* 0 */ 170, 32, 25, 22, 24, 26, 23, 28, 27, 21, + /* 10 */ 56, 147, 101, 35, 83, 165, 17, 87, 108, 145, + /* 20 */ 137, 144, 57, 66, 77, 88, 99, 58, 101, 35, + /* 30 */ 92, 65, 98, 67, 167, 166, 164, 162, 161, 159, + /* 40 */ 158, 157, 156, 153, 152, 150, 25, 22, 24, 26, + /* 50 */ 23, 28, 27, 24, 26, 23, 28, 27, 29, 16, + /* 60 */ 25, 22, 24, 26, 23, 28, 27, 26, 23, 28, + /* 70 */ 27, 140, 31, 25, 22, 24, 26, 23, 28, 27, + /* 80 */ 33, 97, 80, 100, 151, 104, 72, 25, 22, 24, + /* 90 */ 26, 23, 28, 27, 22, 24, 26, 23, 28, 27, + /* 100 */ 32, 60, 63, 21, 53, 117, 111, 112, 113, 51, + /* 110 */ 17, 85, 46, 48, 169, 144, 9, 79, 31, 39, + /* 120 */ 75, 54, 84, 82, 73, 18, 76, 10, 38, 44, + /* 130 */ 155, 81, 47, 89, 93, 95, 28, 27, 106, 78, + /* 140 */ 91, 71, 30, 69, 52, 62, 19, 107, 102, 143, + /* 150 */ 258, 1, 59, 146, 168, 109, 142, 49, 4, 55, + /* 160 */ 103, 45, 41, 94, 8, 2, 5, 43, 114, 50, + /* 170 */ 42, 141, 96, 115, 116, 40, 37, 12, 34, 131, + /* 180 */ 118, 105, 36, 138, 163, 128, 121, 13, 15, 110, + /* 190 */ 20, 259, 119, 86, 139, 149, 126, 7, 148, 160, + /* 200 */ 136, 120, 90, 134, 130, 6, 135, 61, 124, 154, + /* 210 */ 122, 133, 64, 259, 259, 123, 129, 74, 11, 127, + /* 220 */ 70, 14, 3, 125, 259, 132, 68, +}; +static const YYCODETYPE yy_lookahead[] = { + /* 0 */ 0, 51, 1, 2, 3, 4, 5, 6, 7, 4, + /* 10 */ 10, 49, 50, 51, 13, 65, 11, 17, 58, 14, + /* 20 */ 15, 16, 22, 23, 24, 25, 26, 49, 50, 51, + /* 30 */ 30, 31, 32, 33, 37, 38, 39, 40, 41, 42, + /* 40 */ 43, 44, 45, 46, 47, 48, 1, 2, 3, 4, + /* 50 */ 5, 6, 7, 3, 4, 5, 6, 7, 13, 13, + /* 60 */ 1, 2, 3, 4, 5, 6, 7, 4, 5, 6, + /* 70 */ 7, 12, 51, 1, 2, 3, 4, 5, 6, 7, + /* 80 */ 51, 34, 34, 34, 63, 13, 34, 1, 2, 3, + /* 90 */ 4, 5, 6, 7, 2, 3, 4, 5, 6, 7, + /* 100 */ 51, 34, 34, 4, 57, 58, 27, 28, 29, 61, + /* 110 */ 11, 34, 60, 64, 65, 16, 13, 13, 51, 51, + /* 120 */ 13, 53, 19, 19, 34, 13, 19, 13, 51, 62, + /* 130 */ 63, 19, 55, 19, 13, 34, 6, 7, 21, 13, + /* 140 */ 19, 13, 13, 34, 54, 19, 13, 19, 19, 51, + /* 150 */ 35, 36, 19, 21, 20, 20, 51, 56, 13, 51, + /* 160 */ 19, 52, 51, 19, 18, 18, 11, 51, 20, 51, + /* 170 */ 51, 51, 19, 21, 20, 51, 51, 18, 51, 21, + /* 180 */ 20, 59, 51, 20, 20, 14, 21, 18, 18, 21, + /* 190 */ 13, 66, 20, 19, 21, 20, 20, 18, 12, 21, + /* 200 */ 20, 20, 19, 21, 20, 18, 21, 19, 14, 20, + /* 210 */ 20, 20, 19, 66, 66, 20, 20, 19, 18, 20, + /* 220 */ 19, 18, 18, 21, 66, 20, 19, +}; +#define YY_SHIFT_USE_DFLT (-1) +#define YY_SHIFT_MAX 107 +static const short yy_shift_ofst[] = { + /* 0 */ -1, 0, 99, 99, 5, 5, 99, 99, 117, 99, + /* 10 */ 99, 173, 171, 168, 165, 158, 99, 99, 99, 99, + /* 20 */ 79, 99, 99, 99, 99, 99, 99, 99, 99, 99, + /* 30 */ 117, 45, 1, 72, 59, 86, 86, 86, 86, 86, + /* 40 */ 86, 92, 50, 63, 103, 104, 107, 112, 114, 121, + /* 50 */ 130, 126, 128, 129, 133, 130, 155, 179, 186, 184, + /* 60 */ 188, 189, 191, 193, 196, 200, 203, 204, 205, 207, + /* 70 */ 199, 202, 201, 198, 195, 194, 190, 187, 185, 182, + /* 80 */ 183, 181, 180, 178, 175, 174, 172, 170, 169, 164, + /* 90 */ 163, 160, 159, 152, 154, 153, 148, 144, 147, 146, + /* 100 */ 141, 145, 135, 134, 132, 46, 177, 176, +}; +#define YY_REDUCE_USE_DFLT (-51) +#define YY_REDUCE_MAX 30 +static const short yy_reduce_ofst[] = { + /* 0 */ 115, -3, 67, 49, -38, -22, 77, 68, 47, 21, + /* 10 */ -50, 48, 52, 101, 90, 109, 131, 127, 125, 124, + /* 20 */ 122, 120, 119, 118, 116, 111, 108, 105, 98, 29, + /* 30 */ -40, +}; +static const YYACTIONTYPE yy_default[] = { + /* 0 */ 171, 257, 247, 253, 185, 185, 218, 208, 228, 257, + /* 10 */ 257, 242, 237, 223, 213, 203, 257, 257, 257, 257, + /* 20 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 30 */ 257, 257, 257, 257, 257, 189, 231, 220, 219, 209, + /* 40 */ 210, 196, 198, 197, 257, 257, 257, 257, 257, 257, + /* 50 */ 192, 257, 257, 257, 257, 193, 257, 257, 257, 257, + /* 60 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 70 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 80 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 90 */ 257, 257, 257, 257, 257, 257, 257, 257, 257, 257, + /* 100 */ 257, 186, 257, 257, 257, 257, 257, 257, 230, 226, + /* 110 */ 224, 232, 233, 234, 222, 225, 227, 229, 221, 217, + /* 120 */ 216, 214, 235, 212, 239, 215, 211, 236, 238, 207, + /* 130 */ 206, 204, 202, 240, 205, 244, 201, 190, 241, 243, + /* 140 */ 200, 199, 195, 194, 191, 188, 250, 187, 184, 245, + /* 150 */ 183, 249, 182, 181, 246, 248, 180, 179, 178, 177, + /* 160 */ 256, 176, 175, 251, 174, 255, 173, 172, 252, 254, +}; +#define YY_SZ_ACTTAB (int)(sizeof(yy_action)/sizeof(yy_action[0])) + +/* The next table maps tokens into fallback tokens. If a construct +** like the following: +** +** %fallback ID X Y Z. +** +** appears in the grammer, then ID becomes a fallback token for X, Y, +** and Z. Whenever one of the tokens X, Y, or Z is input to the parser +** but it does not parse, the type of the token is changed to ID and +** the parse is retried before an error is thrown. +*/ +#ifdef YYFALLBACK +static const YYCODETYPE yyFallback[] = { +}; +#endif /* YYFALLBACK */ + +/* The following structure represents a single element of the +** parser's stack. Information stored includes: +** +** + The state number for the parser at this level of the stack. +** +** + The value of the token stored at this level of the stack. +** (In other words, the "major" token.) +** +** + The semantic value stored at this level of the stack. This is +** the information used by the action routines in the grammar. +** It is sometimes called the "minor" token. +*/ +struct yyStackEntry { + int stateno; /* The state-number */ + int major; /* The major token value. This is the code + ** number for the token at this stack level */ + YYMINORTYPE minor; /* The user-supplied minor token value. This + ** is the value of the token */ +}; +typedef struct yyStackEntry yyStackEntry; + +/* The state of the parser is completely contained in an instance of +** the following structure */ +struct yyParser { + int yyidx; /* Index of top element in stack */ + int yyerrcnt; /* Shifts left before out of the error */ + ParseARG_SDECL /* A place to hold %extra_argument */ +#if YYSTACKDEPTH<=0 + int yystksz; /* Current side of the stack */ + yyStackEntry *yystack; /* The parser's stack */ +#else + yyStackEntry yystack[YYSTACKDEPTH]; /* The parser's stack */ +#endif +}; +typedef struct yyParser yyParser; + +#ifndef NDEBUG +#include +static FILE *yyTraceFILE = 0; +static char *yyTracePrompt = 0; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* +** Turn parser tracing on by giving a stream to which to write the trace +** and a prompt to preface each trace message. Tracing is turned off +** by making either argument NULL +** +** Inputs: +**
    +**
  • A FILE* to which trace output should be written. +** If NULL, then tracing is turned off. +**
  • A prefix string written at the beginning of every +** line of trace output. If NULL, then tracing is +** turned off. +**
+** +** Outputs: +** None. +*/ +void ParseTrace(FILE *TraceFILE, char *zTracePrompt){ + yyTraceFILE = TraceFILE; + yyTracePrompt = zTracePrompt; + if( yyTraceFILE==0 ) yyTracePrompt = 0; + else if( yyTracePrompt==0 ) yyTraceFILE = 0; +} +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing shifts, the names of all terminals and nonterminals +** are required. The following table supplies these names */ +static const char *const yyTokenName[] = { + "$", "OR", "XOR", "AND", + "MINUS", "PLUS", "MULTIPLY", "DIVIDE", + "NEG", "EOI", "PRINT", "LPAREN", + "RPAREN", "COMMA", "STRING", "ENDL", + "NUM", "Actions", "LBRACE", "RBRACE", + "SEMICOLON", "SYM", "OrgHeights", "ActionList", + "CodePConv", "OrgSprNames", "StateMap", "FirstState", + "SpawnState", "DeathState", "SoundMap", "InfoNames", + "ThingBits", "RenderStyles", "error", "main", + "translation_unit", "external_declaration", "print_statement", "actions_def", + "org_heights_def", "action_list_def", "codep_conv_def", "org_spr_names_def", + "state_map_def", "sound_map_def", "info_names_def", "thing_bits_def", + "render_styles_def", "print_list", "print_item", "exp", + "actions_list", "org_heights_list", "action_list_list", "codep_conv_list", + "org_spr_names_list", "state_map_list", "state_map_entry", "state_type", + "sound_map_list", "info_names_list", "thing_bits_list", "thing_bits_entry", + "render_styles_list", "render_styles_entry", +}; +#endif /* NDEBUG */ + +#ifndef NDEBUG +/* For tracing reduce actions, the names of all rules are required. +*/ +static const char *const yyRuleName[] = { + /* 0 */ "main ::= translation_unit", + /* 1 */ "translation_unit ::=", + /* 2 */ "translation_unit ::= translation_unit external_declaration", + /* 3 */ "external_declaration ::= print_statement", + /* 4 */ "external_declaration ::= actions_def", + /* 5 */ "external_declaration ::= org_heights_def", + /* 6 */ "external_declaration ::= action_list_def", + /* 7 */ "external_declaration ::= codep_conv_def", + /* 8 */ "external_declaration ::= org_spr_names_def", + /* 9 */ "external_declaration ::= state_map_def", + /* 10 */ "external_declaration ::= sound_map_def", + /* 11 */ "external_declaration ::= info_names_def", + /* 12 */ "external_declaration ::= thing_bits_def", + /* 13 */ "external_declaration ::= render_styles_def", + /* 14 */ "print_statement ::= PRINT LPAREN print_list RPAREN", + /* 15 */ "print_list ::=", + /* 16 */ "print_list ::= print_item", + /* 17 */ "print_list ::= print_item COMMA print_list", + /* 18 */ "print_item ::= STRING", + /* 19 */ "print_item ::= exp", + /* 20 */ "print_item ::= ENDL", + /* 21 */ "exp ::= NUM", + /* 22 */ "exp ::= exp PLUS exp", + /* 23 */ "exp ::= exp MINUS exp", + /* 24 */ "exp ::= exp MULTIPLY exp", + /* 25 */ "exp ::= exp DIVIDE exp", + /* 26 */ "exp ::= exp OR exp", + /* 27 */ "exp ::= exp AND exp", + /* 28 */ "exp ::= exp XOR exp", + /* 29 */ "exp ::= MINUS exp", + /* 30 */ "exp ::= LPAREN exp RPAREN", + /* 31 */ "actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON", + /* 32 */ "actions_def ::= Actions LBRACE error RBRACE SEMICOLON", + /* 33 */ "actions_list ::=", + /* 34 */ "actions_list ::= SYM", + /* 35 */ "actions_list ::= actions_list COMMA SYM", + /* 36 */ "org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON", + /* 37 */ "org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON", + /* 38 */ "org_heights_list ::=", + /* 39 */ "org_heights_list ::= exp", + /* 40 */ "org_heights_list ::= org_heights_list COMMA exp", + /* 41 */ "action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON", + /* 42 */ "action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON", + /* 43 */ "action_list_list ::=", + /* 44 */ "action_list_list ::= SYM", + /* 45 */ "action_list_list ::= action_list_list COMMA SYM", + /* 46 */ "codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON", + /* 47 */ "codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON", + /* 48 */ "codep_conv_list ::=", + /* 49 */ "codep_conv_list ::= exp", + /* 50 */ "codep_conv_list ::= codep_conv_list COMMA exp", + /* 51 */ "org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON", + /* 52 */ "org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON", + /* 53 */ "org_spr_names_list ::=", + /* 54 */ "org_spr_names_list ::= SYM", + /* 55 */ "org_spr_names_list ::= org_spr_names_list COMMA SYM", + /* 56 */ "state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON", + /* 57 */ "state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON", + /* 58 */ "state_map_list ::=", + /* 59 */ "state_map_list ::= state_map_entry", + /* 60 */ "state_map_list ::= state_map_list COMMA state_map_entry", + /* 61 */ "state_map_entry ::= SYM COMMA state_type COMMA exp", + /* 62 */ "state_type ::= FirstState", + /* 63 */ "state_type ::= SpawnState", + /* 64 */ "state_type ::= DeathState", + /* 65 */ "sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON", + /* 66 */ "sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON", + /* 67 */ "sound_map_list ::=", + /* 68 */ "sound_map_list ::= STRING", + /* 69 */ "sound_map_list ::= sound_map_list COMMA STRING", + /* 70 */ "info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON", + /* 71 */ "info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON", + /* 72 */ "info_names_list ::=", + /* 73 */ "info_names_list ::= SYM", + /* 74 */ "info_names_list ::= info_names_list COMMA SYM", + /* 75 */ "thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON", + /* 76 */ "thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON", + /* 77 */ "thing_bits_list ::=", + /* 78 */ "thing_bits_list ::= thing_bits_entry", + /* 79 */ "thing_bits_list ::= thing_bits_list COMMA thing_bits_entry", + /* 80 */ "thing_bits_entry ::= exp COMMA exp COMMA SYM", + /* 81 */ "render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON", + /* 82 */ "render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON", + /* 83 */ "render_styles_list ::=", + /* 84 */ "render_styles_list ::= render_styles_entry", + /* 85 */ "render_styles_list ::= render_styles_list COMMA render_styles_entry", + /* 86 */ "render_styles_entry ::= exp COMMA SYM", +}; +#endif /* NDEBUG */ + +#if YYSTACKDEPTH<=0 +/* +** Try to increase the size of the parser stack. +*/ +static void yyGrowStack(yyParser *p){ + int newSize; + yyStackEntry *pNew; + + newSize = p->yystksz*2 + 100; + pNew = realloc(p->yystack, newSize*sizeof(pNew[0])); + if( pNew ){ + p->yystack = pNew; + p->yystksz = newSize; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack grows to %d entries!\n", + yyTracePrompt, p->yystksz); + } +#endif + } +} +#endif + +/* +** This function allocates a new parser. +** The only argument is a pointer to a function which works like +** malloc. +** +** Inputs: +** A pointer to the function used to allocate memory. +** +** Outputs: +** A pointer to a parser. This pointer is used in subsequent calls +** to Parse and ParseFree. +*/ +void *ParseAlloc(void *(CDECL *mallocProc)(size_t)){ + yyParser *pParser; + pParser = (yyParser*)(*mallocProc)( (size_t)sizeof(yyParser) ); + if( pParser ){ + pParser->yyidx = -1; +#if YYSTACKDEPTH<=0 + yyGrowStack(pParser); +#endif + } + return pParser; +} + +/* The following function deletes the value associated with a +** symbol. The symbol can be either a terminal or nonterminal. +** "yymajor" is the symbol code, and "yypminor" is a pointer to +** the value. +*/ +static void yy_destructor(YYCODETYPE yymajor, YYMINORTYPE *yypminor){ + switch( yymajor ){ + /* Here is inserted the actions which take place when a + ** terminal or non-terminal is destroyed. This can happen + ** when the symbol is popped from the stack during a + ** reduce or during error processing or when a parser is + ** being destroyed before it is finished parsing. + ** + ** Note: during a reduce, the only symbols destroyed are those + ** which appear on the RHS of the rule, but which are not used + ** inside the C code. + */ + case 1: /* OR */ + case 2: /* XOR */ + case 3: /* AND */ + case 4: /* MINUS */ + case 5: /* PLUS */ + case 6: /* MULTIPLY */ + case 7: /* DIVIDE */ + case 8: /* NEG */ + case 9: /* EOI */ + case 10: /* PRINT */ + case 11: /* LPAREN */ + case 12: /* RPAREN */ + case 13: /* COMMA */ + case 14: /* STRING */ + case 15: /* ENDL */ + case 16: /* NUM */ + case 17: /* Actions */ + case 18: /* LBRACE */ + case 19: /* RBRACE */ + case 20: /* SEMICOLON */ + case 21: /* SYM */ + case 22: /* OrgHeights */ + case 23: /* ActionList */ + case 24: /* CodePConv */ + case 25: /* OrgSprNames */ + case 26: /* StateMap */ + case 27: /* FirstState */ + case 28: /* SpawnState */ + case 29: /* DeathState */ + case 30: /* SoundMap */ + case 31: /* InfoNames */ + case 32: /* ThingBits */ + case 33: /* RenderStyles */ +#line 10 "parse.y" +{ if ((yypminor->yy0).string) free((yypminor->yy0).string); } +#line 536 "parse.c" + break; + default: break; /* If no destructor action specified: do nothing */ + } +} + +/* +** Pop the parser's stack once. +** +** If there is a destructor routine associated with the token which +** is popped from the stack, then call it. +** +** Return the major token number for the symbol popped. +*/ +static int yy_pop_parser_stack(yyParser *pParser){ + YYCODETYPE yymajor; + yyStackEntry *yytos = &pParser->yystack[pParser->yyidx]; + + if( pParser->yyidx<0 ) return 0; +#ifndef NDEBUG + if( yyTraceFILE && pParser->yyidx>=0 ){ + fprintf(yyTraceFILE,"%sPopping %s\n", + yyTracePrompt, + yyTokenName[yytos->major]); + } +#endif + yymajor = yytos->major; + yy_destructor( yymajor, &yytos->minor); + pParser->yyidx--; + return yymajor; +} + +/* +** Deallocate and destroy a parser. Destructors are all called for +** all stack elements before shutting the parser down. +** +** Inputs: +**
    +**
  • A pointer to the parser. This should be a pointer +** obtained from ParseAlloc. +**
  • A pointer to a function used to reclaim memory obtained +** from malloc. +**
+*/ +void ParseFree( + void *p, /* The parser to be deleted */ + void (CDECL *freeProc)(void*) /* Function used to reclaim memory */ +){ + yyParser *pParser = (yyParser*)p; + if( pParser==0 ) return; + while( pParser->yyidx>=0 ) yy_pop_parser_stack(pParser); +#if YYSTACKDEPTH<=0 + free(pParser->yystack); +#endif + (*freeProc)((void*)pParser); +} + +/* +** Find the appropriate action for a parser given the terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_shift_action( + yyParser *pParser, /* The parser */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + int stateno = pParser->yystack[pParser->yyidx].stateno; + + if( stateno>YY_SHIFT_MAX || (i = yy_shift_ofst[stateno])==YY_SHIFT_USE_DFLT ){ + return yy_default[stateno]; + } + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + if( iLookAhead>0 ){ +#ifdef YYFALLBACK + int iFallback; /* Fallback token */ + if( iLookAhead %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[iFallback]); + } +#endif + return yy_find_shift_action(pParser, iFallback); + } +#endif +#ifdef YYWILDCARD + { + int j = i - iLookAhead + YYWILDCARD; + if( j>=0 && j %s\n", + yyTracePrompt, yyTokenName[iLookAhead], yyTokenName[YYWILDCARD]); + } +#endif /* NDEBUG */ + return yy_action[j]; + } + } +#endif /* YYWILDCARD */ + } + return yy_default[stateno]; + }else{ + return yy_action[i]; + } +} + +/* +** Find the appropriate action for a parser given the non-terminal +** look-ahead token iLookAhead. +** +** If the look-ahead token is YYNOCODE, then check to see if the action is +** independent of the look-ahead. If it is, return the action, otherwise +** return YY_NO_ACTION. +*/ +static int yy_find_reduce_action( + int stateno, /* Current state number */ + YYCODETYPE iLookAhead /* The look-ahead token */ +){ + int i; + if( stateno>YY_REDUCE_MAX || + (i = yy_reduce_ofst[stateno])==YY_REDUCE_USE_DFLT ){ + return yy_default[stateno]; + } + assert( i!=YY_REDUCE_USE_DFLT ); + assert( iLookAhead!=YYNOCODE ); + i += iLookAhead; + if( i<0 || i>=YY_SZ_ACTTAB || yy_lookahead[i]!=iLookAhead ){ + return yy_default[stateno]; + }else{ + return yy_action[i]; + } + return yy_action[i]; +} + +/* +** The following routine is called if the stack overflows. +*/ +static void yyStackOverflow(yyParser *yypParser, YYMINORTYPE *yypMinor){ + ParseARG_FETCH; + yypParser->yyidx--; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sStack Overflow!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will execute if the parser + ** stack every overflows */ + ParseARG_STORE; /* Suppress warning about unused %extra_argument var */ +} + +/* +** Perform a shift action. +*/ +static void yy_shift( + yyParser *yypParser, /* The parser to be shifted */ + int yyNewState, /* The new state to shift in */ + int yyMajor, /* The major token to shift in */ + YYMINORTYPE *yypMinor /* Pointer ot the minor token to shift in */ +){ + yyStackEntry *yytos; + yypParser->yyidx++; +#if YYSTACKDEPTH>0 + if( yypParser->yyidx>=YYSTACKDEPTH ){ + yyStackOverflow(yypParser, yypMinor); + return; + } +#else + if( yypParser->yyidx>=yypParser->yystksz ){ + yyGrowStack(yypParser); + if( yypParser->yyidx>=yypParser->yystksz ){ + yyStackOverflow(yypParser, yypMinor); + return; + } + } +#endif + yytos = &yypParser->yystack[yypParser->yyidx]; + yytos->stateno = yyNewState; + yytos->major = yyMajor; + yytos->minor = *yypMinor; +#ifndef NDEBUG + if( yyTraceFILE && yypParser->yyidx>0 ){ + int i; + fprintf(yyTraceFILE,"%sShift %d\n",yyTracePrompt,yyNewState); + fprintf(yyTraceFILE,"%sStack:",yyTracePrompt); + for(i=1; i<=yypParser->yyidx; i++) + fprintf(yyTraceFILE," (%d)%s",yypParser->yystack[i].stateno,yyTokenName[yypParser->yystack[i].major]); + fprintf(yyTraceFILE,"\n"); + } +#endif +} + +/* The following table contains information about every rule that +** is used during the reduce. +*/ +static const struct { + YYCODETYPE lhs; /* Symbol on the left-hand side of the rule */ + unsigned char nrhs; /* Number of right-hand side symbols in the rule */ +} yyRuleInfo[] = { + { 35, 1 }, + { 36, 0 }, + { 36, 2 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 37, 1 }, + { 38, 4 }, + { 49, 0 }, + { 49, 1 }, + { 49, 3 }, + { 50, 1 }, + { 50, 1 }, + { 50, 1 }, + { 51, 1 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 3 }, + { 51, 2 }, + { 51, 3 }, + { 39, 5 }, + { 39, 5 }, + { 52, 0 }, + { 52, 1 }, + { 52, 3 }, + { 40, 5 }, + { 40, 5 }, + { 53, 0 }, + { 53, 1 }, + { 53, 3 }, + { 41, 5 }, + { 41, 5 }, + { 54, 0 }, + { 54, 1 }, + { 54, 3 }, + { 42, 5 }, + { 42, 5 }, + { 55, 0 }, + { 55, 1 }, + { 55, 3 }, + { 43, 5 }, + { 43, 5 }, + { 56, 0 }, + { 56, 1 }, + { 56, 3 }, + { 44, 5 }, + { 44, 5 }, + { 57, 0 }, + { 57, 1 }, + { 57, 3 }, + { 58, 5 }, + { 59, 1 }, + { 59, 1 }, + { 59, 1 }, + { 45, 5 }, + { 45, 5 }, + { 60, 0 }, + { 60, 1 }, + { 60, 3 }, + { 46, 5 }, + { 46, 5 }, + { 61, 0 }, + { 61, 1 }, + { 61, 3 }, + { 47, 5 }, + { 47, 5 }, + { 62, 0 }, + { 62, 1 }, + { 62, 3 }, + { 63, 5 }, + { 48, 5 }, + { 48, 5 }, + { 64, 0 }, + { 64, 1 }, + { 64, 3 }, + { 65, 3 }, +}; + +static void yy_accept(yyParser*); /* Forward Declaration */ + +/* +** Perform a reduce action and the shift that must immediately +** follow the reduce. +*/ +static void yy_reduce( + yyParser *yypParser, /* The parser */ + int yyruleno /* Number of the rule by which to reduce */ +){ + int yygoto; /* The next state */ + int yyact; /* The next action */ + YYMINORTYPE yygotominor; /* The LHS of the rule reduced */ + yyStackEntry *yymsp; /* The top of the parser's stack */ + int yysize; /* Amount to pop the stack */ + ParseARG_FETCH; + yymsp = &yypParser->yystack[yypParser->yyidx]; +#ifndef NDEBUG + if( yyTraceFILE && yyruleno>=0 + && yyruleno<(int)(sizeof(yyRuleName)/sizeof(yyRuleName[0])) ){ + fprintf(yyTraceFILE, "%sReduce [%s].\n", yyTracePrompt, + yyRuleName[yyruleno]); + } +#endif /* NDEBUG */ + + /* Silence complaints from purify about yygotominor being uninitialized + ** in some cases when it is copied into the stack after the following + ** switch. yygotominor is uninitialized when a rule reduces that does + ** not set the value of its left-hand side nonterminal. Leaving the + ** value of the nonterminal uninitialized is utterly harmless as long + ** as the value is never used. So really the only thing this code + ** accomplishes is to quieten purify. + ** + ** 2007-01-16: The wireshark project (www.wireshark.org) reports that + ** without this code, their parser segfaults. I'm not sure what there + ** parser is doing to make this happen. This is the second bug report + ** from wireshark this week. Clearly they are stressing Lemon in ways + ** that it has not been previously stressed... (SQLite ticket #2172) + */ + memset(&yygotominor, 0, sizeof(yygotominor)); + + + switch( yyruleno ){ + /* Beginning here are the reduction cases. A typical example + ** follows: + ** case 0: + ** #line + ** { ... } // User supplied code + ** #line + ** break; + */ + case 0: /* main ::= translation_unit */ + case 1: /*translation_unit ::= */ + case 2: /*translation_unit ::= translation_unit external_declaration */ + case 3: /*external_declaration ::= print_statement */ + case 4: /*external_declaration ::= actions_def */ + case 5: /*external_declaration ::= org_heights_def */ + case 6: /*external_declaration ::= action_list_def */ + case 7: /*external_declaration ::= codep_conv_def */ + case 8: /*external_declaration ::= org_spr_names_def */ + case 9: /*external_declaration ::= state_map_def */ + case 10: /*external_declaration ::= sound_map_def */ + case 11: /*external_declaration ::= info_names_def */ + case 12: /*external_declaration ::= thing_bits_def */ + case 13: /*external_declaration ::= render_styles_def */ + case 15: /*print_list ::= */ + case 16: /*print_list ::= print_item */ + case 33: /*actions_list ::= */ + case 38: /*org_heights_list ::= */ + case 43: /*action_list_list ::= */ + case 48: /*codep_conv_list ::= */ + case 53: /*org_spr_names_list ::= */ + case 58: /*state_map_list ::= */ + case 59: /*state_map_list ::= state_map_entry */ + case 67: /*sound_map_list ::= */ + case 72: /*info_names_list ::= */ + case 77: /*thing_bits_list ::= */ + case 78: /*thing_bits_list ::= thing_bits_entry */ + case 83: /*render_styles_list ::= */ + case 84: /*render_styles_list ::= render_styles_entry */ +#line 21 "parse.y" +{ +} +#line 914 "parse.c" + break; + case 14: /* print_statement ::= PRINT LPAREN print_list RPAREN */ +#line 39 "parse.y" +{ + printf ("\n"); + yy_destructor(10,&yymsp[-3].minor); + yy_destructor(11,&yymsp[-2].minor); + yy_destructor(12,&yymsp[0].minor); +} +#line 924 "parse.c" + break; + case 17: /* print_list ::= print_item COMMA print_list */ + case 60: /*state_map_list ::= state_map_list COMMA state_map_entry */ + case 79: /*thing_bits_list ::= thing_bits_list COMMA thing_bits_entry */ + case 85: /*render_styles_list ::= render_styles_list COMMA render_styles_entry */ +#line 45 "parse.y" +{ + yy_destructor(13,&yymsp[-1].minor); +} +#line 934 "parse.c" + break; + case 18: /* print_item ::= STRING */ +#line 47 "parse.y" +{ printf ("%s", yymsp[0].minor.yy0.string); } +#line 939 "parse.c" + break; + case 19: /* print_item ::= exp */ +#line 48 "parse.y" +{ printf ("%d", yymsp[0].minor.yy64); } +#line 944 "parse.c" + break; + case 20: /* print_item ::= ENDL */ +#line 49 "parse.y" +{ printf ("\n"); yy_destructor(15,&yymsp[0].minor); +} +#line 950 "parse.c" + break; + case 21: /* exp ::= NUM */ +#line 52 "parse.y" +{ yygotominor.yy64 = yymsp[0].minor.yy0.val; } +#line 955 "parse.c" + break; + case 22: /* exp ::= exp PLUS exp */ +#line 53 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 + yymsp[0].minor.yy64; yy_destructor(5,&yymsp[-1].minor); +} +#line 961 "parse.c" + break; + case 23: /* exp ::= exp MINUS exp */ +#line 54 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 - yymsp[0].minor.yy64; yy_destructor(4,&yymsp[-1].minor); +} +#line 967 "parse.c" + break; + case 24: /* exp ::= exp MULTIPLY exp */ +#line 55 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 * yymsp[0].minor.yy64; yy_destructor(6,&yymsp[-1].minor); +} +#line 973 "parse.c" + break; + case 25: /* exp ::= exp DIVIDE exp */ +#line 56 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 / yymsp[0].minor.yy64; yy_destructor(7,&yymsp[-1].minor); +} +#line 979 "parse.c" + break; + case 26: /* exp ::= exp OR exp */ +#line 57 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 | yymsp[0].minor.yy64; yy_destructor(1,&yymsp[-1].minor); +} +#line 985 "parse.c" + break; + case 27: /* exp ::= exp AND exp */ +#line 58 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 & yymsp[0].minor.yy64; yy_destructor(3,&yymsp[-1].minor); +} +#line 991 "parse.c" + break; + case 28: /* exp ::= exp XOR exp */ +#line 59 "parse.y" +{ yygotominor.yy64 = yymsp[-2].minor.yy64 ^ yymsp[0].minor.yy64; yy_destructor(2,&yymsp[-1].minor); +} +#line 997 "parse.c" + break; + case 29: /* exp ::= MINUS exp */ +#line 60 "parse.y" +{ yygotominor.yy64 = -yymsp[0].minor.yy64; yy_destructor(4,&yymsp[-1].minor); +} +#line 1003 "parse.c" + break; + case 30: /* exp ::= LPAREN exp RPAREN */ +#line 61 "parse.y" +{ yygotominor.yy64 = yymsp[-1].minor.yy64; yy_destructor(11,&yymsp[-2].minor); + yy_destructor(12,&yymsp[0].minor); +} +#line 1010 "parse.c" + break; + case 31: /* actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON */ + case 32: /*actions_def ::= Actions LBRACE error RBRACE SEMICOLON */ +#line 64 "parse.y" +{ + yy_destructor(17,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1021 "parse.c" + break; + case 34: /* actions_list ::= SYM */ +#line 68 "parse.y" +{ AddAction (yymsp[0].minor.yy0.string); } +#line 1026 "parse.c" + break; + case 35: /* actions_list ::= actions_list COMMA SYM */ +#line 69 "parse.y" +{ AddAction (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1032 "parse.c" + break; + case 36: /* org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON */ + case 37: /*org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON */ +#line 72 "parse.y" +{ + yy_destructor(22,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1043 "parse.c" + break; + case 39: /* org_heights_list ::= exp */ +#line 76 "parse.y" +{ AddHeight (yymsp[0].minor.yy64); } +#line 1048 "parse.c" + break; + case 40: /* org_heights_list ::= org_heights_list COMMA exp */ +#line 77 "parse.y" +{ AddHeight (yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-1].minor); +} +#line 1054 "parse.c" + break; + case 41: /* action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON */ + case 42: /*action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON */ +#line 80 "parse.y" +{ + yy_destructor(23,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1065 "parse.c" + break; + case 44: /* action_list_list ::= SYM */ +#line 84 "parse.y" +{ AddActionMap (yymsp[0].minor.yy0.string); } +#line 1070 "parse.c" + break; + case 45: /* action_list_list ::= action_list_list COMMA SYM */ +#line 85 "parse.y" +{ AddActionMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1076 "parse.c" + break; + case 46: /* codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON */ + case 47: /*codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON */ +#line 88 "parse.y" +{ + yy_destructor(24,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1087 "parse.c" + break; + case 49: /* codep_conv_list ::= exp */ +#line 92 "parse.y" +{ AddCodeP (yymsp[0].minor.yy64); } +#line 1092 "parse.c" + break; + case 50: /* codep_conv_list ::= codep_conv_list COMMA exp */ +#line 93 "parse.y" +{ AddCodeP (yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-1].minor); +} +#line 1098 "parse.c" + break; + case 51: /* org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON */ + case 52: /*org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON */ +#line 96 "parse.y" +{ + yy_destructor(25,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1109 "parse.c" + break; + case 54: /* org_spr_names_list ::= SYM */ +#line 100 "parse.y" +{ AddSpriteName (yymsp[0].minor.yy0.string); } +#line 1114 "parse.c" + break; + case 55: /* org_spr_names_list ::= org_spr_names_list COMMA SYM */ +#line 101 "parse.y" +{ AddSpriteName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1120 "parse.c" + break; + case 56: /* state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON */ + case 57: /*state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON */ +#line 104 "parse.y" +{ + yy_destructor(26,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1131 "parse.c" + break; + case 61: /* state_map_entry ::= SYM COMMA state_type COMMA exp */ +#line 111 "parse.y" +{ AddStateMap (yymsp[-4].minor.yy0.string, yymsp[-2].minor.yy64, yymsp[0].minor.yy64); yy_destructor(13,&yymsp[-3].minor); + yy_destructor(13,&yymsp[-1].minor); +} +#line 1138 "parse.c" + break; + case 62: /* state_type ::= FirstState */ +#line 114 "parse.y" +{ yygotominor.yy64 = 0; yy_destructor(27,&yymsp[0].minor); +} +#line 1144 "parse.c" + break; + case 63: /* state_type ::= SpawnState */ +#line 115 "parse.y" +{ yygotominor.yy64 = 1; yy_destructor(28,&yymsp[0].minor); +} +#line 1150 "parse.c" + break; + case 64: /* state_type ::= DeathState */ +#line 116 "parse.y" +{ yygotominor.yy64 = 2; yy_destructor(29,&yymsp[0].minor); +} +#line 1156 "parse.c" + break; + case 65: /* sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON */ + case 66: /*sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON */ +#line 119 "parse.y" +{ + yy_destructor(30,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1167 "parse.c" + break; + case 68: /* sound_map_list ::= STRING */ +#line 123 "parse.y" +{ AddSoundMap (yymsp[0].minor.yy0.string); } +#line 1172 "parse.c" + break; + case 69: /* sound_map_list ::= sound_map_list COMMA STRING */ +#line 124 "parse.y" +{ AddSoundMap (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1178 "parse.c" + break; + case 70: /* info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON */ + case 71: /*info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON */ +#line 127 "parse.y" +{ + yy_destructor(31,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1189 "parse.c" + break; + case 73: /* info_names_list ::= SYM */ +#line 131 "parse.y" +{ AddInfoName (yymsp[0].minor.yy0.string); } +#line 1194 "parse.c" + break; + case 74: /* info_names_list ::= info_names_list COMMA SYM */ +#line 132 "parse.y" +{ AddInfoName (yymsp[0].minor.yy0.string); yy_destructor(13,&yymsp[-1].minor); +} +#line 1200 "parse.c" + break; + case 75: /* thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON */ + case 76: /*thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON */ +#line 135 "parse.y" +{ + yy_destructor(32,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1211 "parse.c" + break; + case 80: /* thing_bits_entry ::= exp COMMA exp COMMA SYM */ +#line 142 "parse.y" +{ AddThingBits (yymsp[0].minor.yy0.string, yymsp[-4].minor.yy64, yymsp[-2].minor.yy64); yy_destructor(13,&yymsp[-3].minor); + yy_destructor(13,&yymsp[-1].minor); +} +#line 1218 "parse.c" + break; + case 81: /* render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON */ + case 82: /*render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON */ +#line 145 "parse.y" +{ + yy_destructor(33,&yymsp[-4].minor); + yy_destructor(18,&yymsp[-3].minor); + yy_destructor(19,&yymsp[-1].minor); + yy_destructor(20,&yymsp[0].minor); +} +#line 1229 "parse.c" + break; + case 86: /* render_styles_entry ::= exp COMMA SYM */ +#line 152 "parse.y" +{ AddRenderStyle (yymsp[0].minor.yy0.string, yymsp[-2].minor.yy64); yy_destructor(13,&yymsp[-1].minor); +} +#line 1235 "parse.c" + break; + }; + yygoto = yyRuleInfo[yyruleno].lhs; + yysize = yyRuleInfo[yyruleno].nrhs; + yypParser->yyidx -= yysize; + yyact = yy_find_reduce_action(yymsp[-yysize].stateno,yygoto); + if( yyact < YYNSTATE ){ +#ifdef NDEBUG + /* If we are not debugging and the reduce action popped at least + ** one element off the stack, then we can push the new element back + ** onto the stack here, and skip the stack overflow test in yy_shift(). + ** That gives a significant speed improvement. */ + if( yysize ){ + yypParser->yyidx++; + yymsp -= yysize-1; + yymsp->stateno = yyact; + yymsp->major = yygoto; + yymsp->minor = yygotominor; + }else +#endif + { + yy_shift(yypParser,yyact,yygoto,&yygotominor); + } + }else{ + assert( yyact == YYNSTATE + YYNRULE + 1 ); + yy_accept(yypParser); + } +} + +/* +** The following code executes when the parse fails +*/ +static void yy_parse_failed( + yyParser *yypParser /* The parser */ +){ + ParseARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sFail!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser fails */ + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following code executes when a syntax error first occurs. +*/ +static void yy_syntax_error( + yyParser *yypParser, /* The parser */ + int yymajor, /* The major type of the error token */ + YYMINORTYPE yyminor /* The minor type of the error token */ +){ + ParseARG_FETCH; +#define TOKEN (yyminor.yy0) +#line 8 "parse.y" + yyerror("Syntax error"); +#line 1295 "parse.c" + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* +** The following is executed when the parser accepts +*/ +static void yy_accept( + yyParser *yypParser /* The parser */ +){ + ParseARG_FETCH; +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sAccept!\n",yyTracePrompt); + } +#endif + while( yypParser->yyidx>=0 ) yy_pop_parser_stack(yypParser); + /* Here code is inserted which will be executed whenever the + ** parser accepts */ + ParseARG_STORE; /* Suppress warning about unused %extra_argument variable */ +} + +/* The main parser program. +** The first argument is a pointer to a structure obtained from +** "ParseAlloc" which describes the current state of the parser. +** The second argument is the major token number. The third is +** the minor token. The fourth optional argument is whatever the +** user wants (and specified in the grammar) and is available for +** use by the action routines. +** +** Inputs: +**
    +**
  • A pointer to the parser (an opaque structure.) +**
  • The major token number. +**
  • The minor token number. +**
  • An option argument of a grammar-specified type. +**
+** +** Outputs: +** None. +*/ +void Parse( + void *yyp, /* The parser */ + int yymajor, /* The major token code number */ + ParseTOKENTYPE yyminor /* The value for the token */ + ParseARG_PDECL /* Optional %extra_argument parameter */ +){ + YYMINORTYPE yyminorunion; + int yyact; /* The parser action. */ + int yyendofinput; /* True if we are at the end of input */ +#ifdef YYERRORSYMBOL + int yyerrorhit = 0; /* True if yymajor has invoked an error */ +#endif + yyParser *yypParser; /* The parser */ + + /* (re)initialize the parser, if necessary */ + yypParser = (yyParser*)yyp; + if( yypParser->yyidx<0 ){ +#if YYSTACKDEPTH<=0 + if( yypParser->yystksz <=0 ){ + memset(&yyminorunion, 0, sizeof(yyminorunion)); + yyStackOverflow(yypParser, &yyminorunion); + return; + } +#endif + yypParser->yyidx = 0; + yypParser->yyerrcnt = -1; + yypParser->yystack[0].stateno = 0; + yypParser->yystack[0].major = 0; + } + yyminorunion.yy0 = yyminor; + yyendofinput = (yymajor==0); + ParseARG_STORE; + +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sInput %s\n",yyTracePrompt,yyTokenName[yymajor]); + } +#endif + + do{ + yyact = yy_find_shift_action(yypParser,yymajor); + if( yyactyyerrcnt--; + yymajor = YYNOCODE; + }else if( yyact < YYNSTATE + YYNRULE ){ + yy_reduce(yypParser,yyact-YYNSTATE); + }else{ +#ifdef YYERRORSYMBOL + int yymx; +#endif + assert( yyact == YY_ERROR_ACTION ); +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sSyntax Error!\n",yyTracePrompt); + } +#endif +#ifdef YYERRORSYMBOL + /* A syntax error has occurred. + ** The response to an error depends upon whether or not the + ** grammar defines an error token "ERROR". + ** + ** This is what we do if the grammar does define ERROR: + ** + ** * Call the %syntax_error function. + ** + ** * Begin popping the stack until we enter a state where + ** it is legal to shift the error symbol, then shift + ** the error symbol. + ** + ** * Set the error count to three. + ** + ** * Begin accepting and shifting new tokens. No new error + ** processing will occur until three tokens have been + ** shifted successfully. + ** + */ + if( yypParser->yyerrcnt<0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yymx = yypParser->yystack[yypParser->yyidx].major; + if( yymx==YYERRORSYMBOL || yyerrorhit ){ +#ifndef NDEBUG + if( yyTraceFILE ){ + fprintf(yyTraceFILE,"%sDiscard input token %s\n", + yyTracePrompt,yyTokenName[yymajor]); + } +#endif + yy_destructor(yymajor,&yyminorunion); + yymajor = YYNOCODE; + }else{ + while( + yypParser->yyidx >= 0 && + yymx != YYERRORSYMBOL && + (yyact = yy_find_reduce_action( + yypParser->yystack[yypParser->yyidx].stateno, + YYERRORSYMBOL)) >= YYNSTATE + ){ + yy_pop_parser_stack(yypParser); + } + if( yypParser->yyidx < 0 || yymajor==0 ){ + yy_destructor(yymajor,&yyminorunion); + yy_parse_failed(yypParser); + yymajor = YYNOCODE; + }else if( yymx!=YYERRORSYMBOL ){ + YYMINORTYPE u2; + u2.YYERRSYMDT = 0; + yy_shift(yypParser,yyact,YYERRORSYMBOL,&u2); + } + } + yypParser->yyerrcnt = 3; + yyerrorhit = 1; +#else /* YYERRORSYMBOL is not defined */ + /* This is what we do if the grammar does not define ERROR: + ** + ** * Report an error message, and throw away the input token. + ** + ** * If the input token is $, then fail the parse. + ** + ** As before, subsequent error messages are suppressed until + ** three input tokens have been successfully shifted. + */ + if( yypParser->yyerrcnt<=0 ){ + yy_syntax_error(yypParser,yymajor,yyminorunion); + } + yypParser->yyerrcnt = 3; + yy_destructor(yymajor,&yyminorunion); + if( yyendofinput ){ + yy_parse_failed(yypParser); + } + yymajor = YYNOCODE; +#endif + } + }while( yymajor!=YYNOCODE && yypParser->yyidx>=0 ); + return; +} diff --git a/tools/dehsupp/parse.h b/tools/dehsupp/parse.h new file mode 100644 index 0000000000..932f082a5e --- /dev/null +++ b/tools/dehsupp/parse.h @@ -0,0 +1,33 @@ +#define OR 1 +#define XOR 2 +#define AND 3 +#define MINUS 4 +#define PLUS 5 +#define MULTIPLY 6 +#define DIVIDE 7 +#define NEG 8 +#define EOI 9 +#define PRINT 10 +#define LPAREN 11 +#define RPAREN 12 +#define COMMA 13 +#define STRING 14 +#define ENDL 15 +#define NUM 16 +#define Actions 17 +#define LBRACE 18 +#define RBRACE 19 +#define SEMICOLON 20 +#define SYM 21 +#define OrgHeights 22 +#define ActionList 23 +#define CodePConv 24 +#define OrgSprNames 25 +#define StateMap 26 +#define FirstState 27 +#define SpawnState 28 +#define DeathState 29 +#define SoundMap 30 +#define InfoNames 31 +#define ThingBits 32 +#define RenderStyles 33 diff --git a/tools/dehsupp/parse.y b/tools/dehsupp/parse.y new file mode 100644 index 0000000000..4b6d4935c7 --- /dev/null +++ b/tools/dehsupp/parse.y @@ -0,0 +1,152 @@ +%include{ +#include +#include "dehsupp.h" +} + +%token_type {struct Token} + +%syntax_error { yyerror("Syntax error"); } + +%token_destructor { if ($$.string) free($$.string); } + +%left OR. +%left XOR. +%left AND. +%left MINUS PLUS. +%left MULTIPLY DIVIDE. +%left NEG. + +%left EOI. + +main ::= translation_unit. + +translation_unit ::= . /* empty */ +translation_unit ::= translation_unit external_declaration. + +external_declaration ::= print_statement. +external_declaration ::= actions_def. +external_declaration ::= org_heights_def. +external_declaration ::= action_list_def. +external_declaration ::= codep_conv_def. +external_declaration ::= org_spr_names_def. +external_declaration ::= state_map_def. +external_declaration ::= sound_map_def. +external_declaration ::= info_names_def. +external_declaration ::= thing_bits_def. +external_declaration ::= render_styles_def. + +print_statement ::= PRINT LPAREN print_list RPAREN. +{ + printf ("\n"); +} + +print_list ::= . /* EMPTY */ +print_list ::= print_item. +print_list ::= print_item COMMA print_list. + +print_item ::= STRING(A). { printf ("%s", A.string); } +print_item ::= exp(A). { printf ("%d", A); } +print_item ::= ENDL. { printf ("\n"); } + +%type exp {int} +exp(A) ::= NUM(B). { A = B.val; } +exp(A) ::= exp(B) PLUS exp(C). { A = B + C; } +exp(A) ::= exp(B) MINUS exp(C). { A = B - C; } +exp(A) ::= exp(B) MULTIPLY exp(C). { A = B * C; } +exp(A) ::= exp(B) DIVIDE exp(C). { A = B / C; } +exp(A) ::= exp(B) OR exp(C). { A = B | C; } +exp(A) ::= exp(B) AND exp(C). { A = B & C; } +exp(A) ::= exp(B) XOR exp(C). { A = B ^ C; } +exp(A) ::= MINUS exp(B). [NEG] { A = -B; } +exp(A) ::= LPAREN exp(B) RPAREN. { A = B; } + + +actions_def ::= Actions LBRACE actions_list RBRACE SEMICOLON. +actions_def ::= Actions LBRACE error RBRACE SEMICOLON. + +actions_list ::= . /* empty */ +actions_list ::= SYM(A). { AddAction (A.string); } +actions_list ::= actions_list COMMA SYM(A). { AddAction (A.string); } + + +org_heights_def ::= OrgHeights LBRACE org_heights_list RBRACE SEMICOLON. +org_heights_def ::= OrgHeights LBRACE error RBRACE SEMICOLON. + +org_heights_list ::= . /* empty */ +org_heights_list ::= exp(A). { AddHeight (A); } +org_heights_list ::= org_heights_list COMMA exp(A). { AddHeight (A); } + + +action_list_def ::= ActionList LBRACE action_list_list RBRACE SEMICOLON. +action_list_def ::= ActionList LBRACE error RBRACE SEMICOLON. + +action_list_list ::= . /* empty */ +action_list_list ::= SYM(A). { AddActionMap (A.string); } +action_list_list ::= action_list_list COMMA SYM(A). { AddActionMap (A.string); } + + +codep_conv_def ::= CodePConv LBRACE codep_conv_list RBRACE SEMICOLON. +codep_conv_def ::= CodePConv LBRACE error RBRACE SEMICOLON. + +codep_conv_list ::= . /* empty */ +codep_conv_list ::= exp(A). { AddCodeP (A); } +codep_conv_list ::= codep_conv_list COMMA exp(A). { AddCodeP (A); } + + +org_spr_names_def ::= OrgSprNames LBRACE org_spr_names_list RBRACE SEMICOLON. +org_spr_names_def ::= OrgSprNames LBRACE error RBRACE SEMICOLON. + +org_spr_names_list ::= . /* empty */ +org_spr_names_list ::= SYM(A). { AddSpriteName (A.string); } +org_spr_names_list ::= org_spr_names_list COMMA SYM(A). { AddSpriteName (A.string); } + + +state_map_def ::= StateMap LBRACE state_map_list RBRACE SEMICOLON. +state_map_def ::= StateMap LBRACE error RBRACE SEMICOLON. + +state_map_list ::= . /* empty */ +state_map_list ::= state_map_entry. +state_map_list ::= state_map_list COMMA state_map_entry. + +state_map_entry ::= SYM(A) COMMA state_type(B) COMMA exp(C). { AddStateMap (A.string, B, C); } + +%type state_type {int} +state_type(A) ::= FirstState. { A = 0; } +state_type(A) ::= SpawnState. { A = 1; } +state_type(A) ::= DeathState. { A = 2; } + + +sound_map_def ::= SoundMap LBRACE sound_map_list RBRACE SEMICOLON. +sound_map_def ::= SoundMap LBRACE error RBRACE SEMICOLON. + +sound_map_list ::= . /* empty */ +sound_map_list ::= STRING(A). { AddSoundMap (A.string); } +sound_map_list ::= sound_map_list COMMA STRING(A). { AddSoundMap (A.string); } + + +info_names_def ::= InfoNames LBRACE info_names_list RBRACE SEMICOLON. +info_names_def ::= InfoNames LBRACE error RBRACE SEMICOLON. + +info_names_list ::= . /* empty */ +info_names_list ::= SYM(A). { AddInfoName (A.string); } +info_names_list ::= info_names_list COMMA SYM(A). { AddInfoName (A.string); } + + +thing_bits_def ::= ThingBits LBRACE thing_bits_list RBRACE SEMICOLON. +thing_bits_def ::= ThingBits LBRACE error RBRACE SEMICOLON. + +thing_bits_list ::= . /* empty */ +thing_bits_list ::= thing_bits_entry. +thing_bits_list ::= thing_bits_list COMMA thing_bits_entry. + +thing_bits_entry ::= exp(A) COMMA exp(B) COMMA SYM(C). { AddThingBits (C.string, A, B); } + + +render_styles_def ::= RenderStyles LBRACE render_styles_list RBRACE SEMICOLON. +render_styles_def ::= RenderStyles LBRACE error RBRACE SEMICOLON. + +render_styles_list ::= . /* empty */ +render_styles_list ::= render_styles_entry. +render_styles_list ::= render_styles_list COMMA render_styles_entry. + +render_styles_entry ::= exp(A) COMMA SYM(B). { AddRenderStyle (B.string, A); } diff --git a/tools/dehsupp/scanner.c b/tools/dehsupp/scanner.c new file mode 100644 index 0000000000..a12abe34d7 --- /dev/null +++ b/tools/dehsupp/scanner.c @@ -0,0 +1,1091 @@ +/* Generated by re2c 0.12.3 */ +#line 1 "scanner.re" +#include +#include +#include +#include "dehsupp.h" + +#define BSIZE 8192 + +#define YYCTYPE uchar +#define YYCURSOR cursor +#define YYLIMIT s->lim +#define YYMARKER s->ptr +#define YYFILL(n) {cursor = fill(s, cursor);} + +#define RET(i) {s->cur = cursor; return i;} + +uchar *fill(Scanner *s, uchar *cursor) +{ + if(!s->eof) + { + ptrdiff_t cnt = s->tok - s->bot; + if(cnt) + { + memcpy(s->bot, s->tok, s->lim - s->tok); + s->tok = s->bot; + s->ptr -= cnt; + cursor -= cnt; + s->pos -= cnt; + s->lim -= cnt; + } + if((s->top - s->lim) < BSIZE) + { + uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar)); + memcpy(buf, s->tok, s->lim - s->tok); + s->tok = buf; + s->ptr = &buf[s->ptr - s->bot]; + cursor = &buf[cursor - s->bot]; + s->pos = &buf[s->pos - s->bot]; + s->lim = &buf[s->lim - s->bot]; + s->top = &s->lim[BSIZE]; + free(s->bot); + s->bot = buf; + } + if((cnt = fread((char*) s->lim, 1, BSIZE, s->fd)) != BSIZE) + { + s->eof = &s->lim[cnt]; *(s->eof)++ = '\n'; + } + s->lim += cnt; + } + return cursor; +} + +int scan(Scanner *s) +{ + uchar *cursor = s->cur; +std: + s->tok = cursor; +#line 64 "scanner.re" + + + +#line 64 "scanner.c" +{ + YYCTYPE yych; + unsigned int yyaccept = 0; + + if((YYLIMIT - YYCURSOR) < 13) YYFILL(13); + yych = *YYCURSOR; + switch(yych) { + case 0x09: + case 0x0B: + case 0x0C: + case ' ': goto yy22; + case 0x0A: goto yy48; + case '"': goto yy20; + case '&': goto yy28; + case '(': goto yy36; + case ')': goto yy38; + case '*': goto yy34; + case '+': goto yy32; + case ',': goto yy40; + case '-': goto yy30; + case '/': goto yy2; + case '0': goto yy17; + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': goto yy19; + case ';': goto yy46; + case 'A': goto yy7; + case 'B': + case 'E': + case 'G': + case 'H': + case 'J': + case 'K': + case 'L': + case 'M': + case 'N': + case 'P': + case 'Q': + case 'U': + case 'V': + case 'W': + case 'X': + case 'Y': + case 'Z': + case '_': + case 'a': + case 'b': + case 'c': + case 'd': + case 'f': + case 'g': + case 'h': + case 'i': + case 'j': + case 'k': + case 'l': + case 'm': + case 'n': + case 'o': + case 'q': + case 'r': + case 's': + case 't': + case 'u': + case 'v': + case 'w': + case 'x': + case 'y': + case 'z': goto yy16; + case 'C': goto yy9; + case 'D': goto yy13; + case 'F': goto yy14; + case 'I': goto yy11; + case 'O': goto yy8; + case 'R': goto yy15; + case 'S': goto yy10; + case 'T': goto yy12; + case '^': goto yy26; + case 'e': goto yy4; + case 'p': goto yy6; + case '{': goto yy42; + case '|': goto yy24; + case '}': goto yy44; + default: goto yy50; + } +yy2: + yyaccept = 0; + yych = *(YYMARKER = ++YYCURSOR); + if(yych == '*') goto yy200; + if(yych == '/') goto yy198; +yy3: +#line 107 "scanner.re" + { RET(DIVIDE); } +#line 164 "scanner.c" +yy4: + ++YYCURSOR; + if((yych = *YYCURSOR) == 'n') goto yy194; + goto yy72; +yy5: +#line 91 "scanner.re" + { RET(SYM); } +#line 172 "scanner.c" +yy6: + yych = *++YYCURSOR; + if(yych == 'r') goto yy189; + goto yy72; +yy7: + yych = *++YYCURSOR; + if(yych == 'c') goto yy177; + goto yy72; +yy8: + yych = *++YYCURSOR; + if(yych == 'r') goto yy158; + goto yy72; +yy9: + yych = *++YYCURSOR; + if(yych == 'o') goto yy149; + goto yy72; +yy10: + yych = *++YYCURSOR; + if(yych <= 'p') { + if(yych <= 'n') goto yy72; + if(yych <= 'o') goto yy123; + goto yy124; + } else { + if(yych == 't') goto yy125; + goto yy72; + } +yy11: + yych = *++YYCURSOR; + if(yych == 'n') goto yy114; + goto yy72; +yy12: + yych = *++YYCURSOR; + if(yych == 'h') goto yy105; + goto yy72; +yy13: + yych = *++YYCURSOR; + if(yych == 'e') goto yy95; + goto yy72; +yy14: + yych = *++YYCURSOR; + if(yych == 'i') goto yy85; + goto yy72; +yy15: + yych = *++YYCURSOR; + if(yych == 'e') goto yy73; + goto yy72; +yy16: + yych = *++YYCURSOR; + goto yy72; +yy17: + yyaccept = 1; + yych = *(YYMARKER = ++YYCURSOR); + if(yych == 'X') goto yy68; + if(yych == 'x') goto yy68; + goto yy67; +yy18: +#line 94 "scanner.re" + { RET(NUM); } +#line 231 "scanner.c" +yy19: + yych = *++YYCURSOR; + goto yy65; +yy20: + yyaccept = 2; + yych = *(YYMARKER = ++YYCURSOR); + if(yych != 0x0A) goto yy54; +yy21: +#line 124 "scanner.re" + { + printf("unexpected character: %c\n", *s->tok); + goto std; + } +#line 245 "scanner.c" +yy22: + ++YYCURSOR; + yych = *YYCURSOR; + goto yy52; +yy23: +#line 99 "scanner.re" + { goto std; } +#line 253 "scanner.c" +yy24: + ++YYCURSOR; +#line 101 "scanner.re" + { RET(OR); } +#line 258 "scanner.c" +yy26: + ++YYCURSOR; +#line 102 "scanner.re" + { RET(XOR); } +#line 263 "scanner.c" +yy28: + ++YYCURSOR; +#line 103 "scanner.re" + { RET(AND); } +#line 268 "scanner.c" +yy30: + ++YYCURSOR; +#line 104 "scanner.re" + { RET(MINUS); } +#line 273 "scanner.c" +yy32: + ++YYCURSOR; +#line 105 "scanner.re" + { RET(PLUS); } +#line 278 "scanner.c" +yy34: + ++YYCURSOR; +#line 106 "scanner.re" + { RET(MULTIPLY); } +#line 283 "scanner.c" +yy36: + ++YYCURSOR; +#line 108 "scanner.re" + { RET(LPAREN); } +#line 288 "scanner.c" +yy38: + ++YYCURSOR; +#line 109 "scanner.re" + { RET(RPAREN); } +#line 293 "scanner.c" +yy40: + ++YYCURSOR; +#line 110 "scanner.re" + { RET(COMMA); } +#line 298 "scanner.c" +yy42: + ++YYCURSOR; +#line 111 "scanner.re" + { RET(LBRACE); } +#line 303 "scanner.c" +yy44: + ++YYCURSOR; +#line 112 "scanner.re" + { RET(RBRACE); } +#line 308 "scanner.c" +yy46: + ++YYCURSOR; +#line 113 "scanner.re" + { RET(SEMICOLON); } +#line 313 "scanner.c" +yy48: + ++YYCURSOR; +#line 117 "scanner.re" + { + if(cursor == s->eof) RET(EOI); + s->pos = cursor; s->line++; + goto std; + } +#line 322 "scanner.c" +yy50: + yych = *++YYCURSOR; + goto yy21; +yy51: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy52: + if(yych <= 0x0A) { + if(yych == 0x09) goto yy51; + goto yy23; + } else { + if(yych <= 0x0C) goto yy51; + if(yych == ' ') goto yy51; + goto yy23; + } +yy53: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy54: + if(yych <= '!') { + if(yych != 0x0A) goto yy53; + } else { + if(yych <= '"') goto yy57; + if(yych == '\\') goto yy56; + goto yy53; + } +yy55: + YYCURSOR = YYMARKER; + if(yyaccept <= 1) { + if(yyaccept <= 0) { + goto yy3; + } else { + goto yy18; + } + } else { + goto yy21; + } +yy56: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= 'b') { + if(yych <= '7') { + if(yych <= '&') { + if(yych == '"') goto yy53; + goto yy55; + } else { + if(yych <= '\'') goto yy53; + if(yych <= '/') goto yy55; + goto yy60; + } + } else { + if(yych <= '[') { + if(yych == '?') goto yy53; + goto yy55; + } else { + if(yych <= '\\') goto yy53; + if(yych <= '`') goto yy55; + goto yy53; + } + } + } else { + if(yych <= 'r') { + if(yych <= 'm') { + if(yych == 'f') goto yy53; + goto yy55; + } else { + if(yych <= 'n') goto yy53; + if(yych <= 'q') goto yy55; + goto yy53; + } + } else { + if(yych <= 'u') { + if(yych == 't') goto yy53; + goto yy55; + } else { + if(yych <= 'v') goto yy53; + if(yych == 'x') goto yy59; + goto yy55; + } + } + } +yy57: + ++YYCURSOR; +#line 97 "scanner.re" + { RET(STRING); } +#line 411 "scanner.c" +yy59: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= '@') { + if(yych <= '/') goto yy55; + if(yych <= '9') goto yy62; + goto yy55; + } else { + if(yych <= 'F') goto yy62; + if(yych <= '`') goto yy55; + if(yych <= 'f') goto yy62; + goto yy55; + } +yy60: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= '"') { + if(yych == 0x0A) goto yy55; + if(yych <= '!') goto yy53; + goto yy57; + } else { + if(yych <= '7') { + if(yych <= '/') goto yy53; + goto yy60; + } else { + if(yych == '\\') goto yy56; + goto yy53; + } + } +yy62: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= '9') { + if(yych <= '!') { + if(yych == 0x0A) goto yy55; + goto yy53; + } else { + if(yych <= '"') goto yy57; + if(yych <= '/') goto yy53; + goto yy62; + } + } else { + if(yych <= '[') { + if(yych <= '@') goto yy53; + if(yych <= 'F') goto yy62; + goto yy53; + } else { + if(yych <= '\\') goto yy56; + if(yych <= '`') goto yy53; + if(yych <= 'f') goto yy62; + goto yy53; + } + } +yy64: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy65: + if(yych <= '/') goto yy18; + if(yych <= '9') goto yy64; + goto yy18; +yy66: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy67: + if(yych <= '/') goto yy18; + if(yych <= '9') goto yy66; + goto yy18; +yy68: + yych = *++YYCURSOR; + if(yych <= '@') { + if(yych <= '/') goto yy55; + if(yych >= ':') goto yy55; + } else { + if(yych <= 'F') goto yy69; + if(yych <= '`') goto yy55; + if(yych >= 'g') goto yy55; + } +yy69: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych <= '@') { + if(yych <= '/') goto yy18; + if(yych <= '9') goto yy69; + goto yy18; + } else { + if(yych <= 'F') goto yy69; + if(yych <= '`') goto yy18; + if(yych <= 'f') goto yy69; + goto yy18; + } +yy71: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; +yy72: + if(yych <= 'Z') { + if(yych <= '/') goto yy5; + if(yych <= '9') goto yy71; + if(yych <= '@') goto yy5; + goto yy71; + } else { + if(yych <= '_') { + if(yych <= '^') goto yy5; + goto yy71; + } else { + if(yych <= '`') goto yy5; + if(yych <= 'z') goto yy71; + goto yy5; + } + } +yy73: + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'd') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 'r') goto yy72; + yych = *++YYCURSOR; + if(yych != 'S') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'y') goto yy72; + yych = *++YYCURSOR; + if(yych != 'l') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy84; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy84; + if(yych <= 'z') goto yy71; + } + } +yy84: +#line 89 "scanner.re" + { RET(RenderStyles); } +#line 565 "scanner.c" +yy85: + yych = *++YYCURSOR; + if(yych != 'r') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'S') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy94; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy94; + if(yych <= 'z') goto yy71; + } + } +yy94: +#line 88 "scanner.re" + { RET(FirstState); } +#line 599 "scanner.c" +yy95: + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'h') goto yy72; + yych = *++YYCURSOR; + if(yych != 'S') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy104; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy104; + if(yych <= 'z') goto yy71; + } + } +yy104: +#line 86 "scanner.re" + { RET(DeathState); } +#line 633 "scanner.c" +yy105: + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'g') goto yy72; + yych = *++YYCURSOR; + if(yych != 'B') goto yy72; + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy113; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy113; + if(yych <= 'z') goto yy71; + } + } +yy113: +#line 85 "scanner.re" + { RET(ThingBits); } +#line 665 "scanner.c" +yy114: + yych = *++YYCURSOR; + if(yych != 'f') goto yy72; + yych = *++YYCURSOR; + if(yych != 'o') goto yy72; + yych = *++YYCURSOR; + if(yych != 'N') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 'm') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy122; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy122; + if(yych <= 'z') goto yy71; + } + } +yy122: +#line 84 "scanner.re" + { RET(InfoNames); } +#line 697 "scanner.c" +yy123: + yych = *++YYCURSOR; + if(yych == 'u') goto yy142; + goto yy72; +yy124: + yych = *++YYCURSOR; + if(yych == 'a') goto yy133; + goto yy72; +yy125: + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 'M') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 'p') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy132; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy132; + if(yych <= 'z') goto yy71; + } + } +yy132: +#line 82 "scanner.re" + { RET(StateMap); } +#line 735 "scanner.c" +yy133: + yych = *++YYCURSOR; + if(yych != 'w') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'S') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy141; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy141; + if(yych <= 'z') goto yy71; + } + } +yy141: +#line 87 "scanner.re" + { RET(SpawnState); } +#line 767 "scanner.c" +yy142: + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'd') goto yy72; + yych = *++YYCURSOR; + if(yych != 'M') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 'p') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy148; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy148; + if(yych <= 'z') goto yy71; + } + } +yy148: +#line 83 "scanner.re" + { RET(SoundMap); } +#line 795 "scanner.c" +yy149: + yych = *++YYCURSOR; + if(yych != 'd') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 'P') goto yy72; + yych = *++YYCURSOR; + if(yych != 'C') goto yy72; + yych = *++YYCURSOR; + if(yych != 'o') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 'v') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy157; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy157; + if(yych <= 'z') goto yy71; + } + } +yy157: +#line 80 "scanner.re" + { RET(CodePConv); } +#line 827 "scanner.c" +yy158: + yych = *++YYCURSOR; + if(yych != 'g') goto yy72; + yych = *++YYCURSOR; + if(yych == 'H') goto yy160; + if(yych == 'S') goto yy161; + goto yy72; +yy160: + yych = *++YYCURSOR; + if(yych == 'e') goto yy170; + goto yy72; +yy161: + yych = *++YYCURSOR; + if(yych != 'p') goto yy72; + yych = *++YYCURSOR; + if(yych != 'r') goto yy72; + yych = *++YYCURSOR; + if(yych != 'N') goto yy72; + yych = *++YYCURSOR; + if(yych != 'a') goto yy72; + yych = *++YYCURSOR; + if(yych != 'm') goto yy72; + yych = *++YYCURSOR; + if(yych != 'e') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy169; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy169; + if(yych <= 'z') goto yy71; + } + } +yy169: +#line 81 "scanner.re" + { RET(OrgSprNames); } +#line 870 "scanner.c" +yy170: + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 'g') goto yy72; + yych = *++YYCURSOR; + if(yych != 'h') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy176; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy176; + if(yych <= 'z') goto yy71; + } + } +yy176: +#line 78 "scanner.re" + { RET(OrgHeights); } +#line 898 "scanner.c" +yy177: + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 'o') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych == 'L') goto yy184; + if(yych != 's') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy183; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy183; + if(yych <= 'z') goto yy71; + } + } +yy183: +#line 77 "scanner.re" + { RET(Actions); } +#line 927 "scanner.c" +yy184: + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 's') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy188; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy188; + if(yych <= 'z') goto yy71; + } + } +yy188: +#line 79 "scanner.re" + { RET(ActionList); } +#line 951 "scanner.c" +yy189: + yych = *++YYCURSOR; + if(yych != 'i') goto yy72; + yych = *++YYCURSOR; + if(yych != 'n') goto yy72; + yych = *++YYCURSOR; + if(yych != 't') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy193; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy193; + if(yych <= 'z') goto yy71; + } + } +yy193: +#line 76 "scanner.re" + { RET(PRINT); } +#line 975 "scanner.c" +yy194: + yych = *++YYCURSOR; + if(yych != 'd') goto yy72; + yych = *++YYCURSOR; + if(yych != 'l') goto yy72; + ++YYCURSOR; + if((yych = *YYCURSOR) <= 'Z') { + if(yych <= '/') goto yy197; + if(yych <= '9') goto yy71; + if(yych >= 'A') goto yy71; + } else { + if(yych <= '_') { + if(yych >= '_') goto yy71; + } else { + if(yych <= '`') goto yy197; + if(yych <= 'z') goto yy71; + } + } +yy197: +#line 75 "scanner.re" + { RET(ENDL); } +#line 997 "scanner.c" +yy198: + ++YYCURSOR; + if(YYLIMIT == YYCURSOR) YYFILL(1); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy202; + goto yy198; +yy200: + ++YYCURSOR; +#line 67 "scanner.re" + { goto comment; } +#line 1008 "scanner.c" +yy202: + ++YYCURSOR; +#line 69 "scanner.re" + { + if(cursor == s->eof) RET(EOI); + s->tok = s->pos = cursor; s->line++; + goto std; + } +#line 1017 "scanner.c" +} +#line 128 "scanner.re" + + +comment: + +#line 1024 "scanner.c" +{ + YYCTYPE yych; + if((YYLIMIT - YYCURSOR) < 2) YYFILL(2); + yych = *YYCURSOR; + if(yych == 0x0A) goto yy208; + if(yych != '*') goto yy210; + ++YYCURSOR; + if((yych = *YYCURSOR) == '/') goto yy211; +yy207: +#line 139 "scanner.re" + { goto comment; } +#line 1036 "scanner.c" +yy208: + ++YYCURSOR; +#line 134 "scanner.re" + { + if(cursor == s->eof) RET(EOI); + s->tok = s->pos = cursor; s->line++; + goto comment; + } +#line 1045 "scanner.c" +yy210: + yych = *++YYCURSOR; + goto yy207; +yy211: + ++YYCURSOR; +#line 132 "scanner.re" + { goto std; } +#line 1053 "scanner.c" +} +#line 140 "scanner.re" + +} + +int lex(Scanner *s, struct Token *tok) +{ + int tokentype = scan(s); + char *p, *q; + + tok->val = 0; + tok->string = NULL; + + switch (tokentype) + { + case NUM: + tok->val = strtol((char *)s->tok, NULL, 0); + break; + + case STRING: + tok->string = (char *)malloc(s->cur - s->tok - 1); + strncpy(tok->string, (char *)s->tok + 1, s->cur - s->tok - 2); + tok->string[s->cur - s->tok - 2] = '\0'; + for (p = q = tok->string; *p; ++p, ++q) + { + if (p[0] == '\\' && p[1] == '\\') + ++p; + *q = *p; + } + break; + + case SYM: + tok->string = (char *)malloc(s->cur - s->tok + 1); + strncpy(tok->string, (char *)s->tok, s->cur - s->tok); + tok->string[s->cur - s->tok] = '\0'; + break; + } + return tokentype; +} diff --git a/tools/dehsupp/scanner.re b/tools/dehsupp/scanner.re new file mode 100644 index 0000000000..828e2ee58b --- /dev/null +++ b/tools/dehsupp/scanner.re @@ -0,0 +1,176 @@ +#include +#include +#include +#include "dehsupp.h" + +#define BSIZE 8192 + +#define YYCTYPE uchar +#define YYCURSOR cursor +#define YYLIMIT s->lim +#define YYMARKER s->ptr +#define YYFILL(n) {cursor = fill(s, cursor);} + +#define RET(i) {s->cur = cursor; return i;} + +uchar *fill(Scanner *s, uchar *cursor) +{ + if(!s->eof) + { + ptrdiff_t cnt = s->tok - s->bot; + if(cnt) + { + memcpy(s->bot, s->tok, s->lim - s->tok); + s->tok = s->bot; + s->ptr -= cnt; + cursor -= cnt; + s->pos -= cnt; + s->lim -= cnt; + } + if((s->top - s->lim) < BSIZE) + { + uchar *buf = (uchar*) malloc(((s->lim - s->bot) + BSIZE)*sizeof(uchar)); + memcpy(buf, s->tok, s->lim - s->tok); + s->tok = buf; + s->ptr = &buf[s->ptr - s->bot]; + cursor = &buf[cursor - s->bot]; + s->pos = &buf[s->pos - s->bot]; + s->lim = &buf[s->lim - s->bot]; + s->top = &s->lim[BSIZE]; + free(s->bot); + s->bot = buf; + } + if((cnt = fread((char*) s->lim, 1, BSIZE, s->fd)) != BSIZE) + { + s->eof = &s->lim[cnt]; *(s->eof)++ = '\n'; + } + s->lim += cnt; + } + return cursor; +} + +int scan(Scanner *s) +{ + uchar *cursor = s->cur; +std: + s->tok = cursor; +/*!re2c +any = [\000-\377]; +O = [0-7]; +D = [0-9]; +L = [a-zA-Z_]; +H = [a-fA-F0-9]; +ESC = [\\] ([abfnrtv?'"\\] | "x" H+ | O+); +*/ + +/*!re2c + "/*" { goto comment; } /* C comment */ + "//" (any\"\n")* "\n" /* C++ comment */ + { + if(cursor == s->eof) RET(EOI); + s->tok = s->pos = cursor; s->line++; + goto std; + } + + "endl" { RET(ENDL); } + "print" { RET(PRINT); } + "Actions" { RET(Actions); } + "OrgHeights" { RET(OrgHeights); } + "ActionList" { RET(ActionList); } + "CodePConv" { RET(CodePConv); } + "OrgSprNames" { RET(OrgSprNames); } + "StateMap" { RET(StateMap); } + "SoundMap" { RET(SoundMap); } + "InfoNames" { RET(InfoNames); } + "ThingBits" { RET(ThingBits); } + "DeathState" { RET(DeathState); } + "SpawnState" { RET(SpawnState); } + "FirstState" { RET(FirstState); } + "RenderStyles" { RET(RenderStyles); } + + L (L|D)* { RET(SYM); } + + ("0" [xX] H+) | ("0" D+) | (D+) + { RET(NUM); } + + (["] (ESC|any\[\n\\"])* ["]) + { RET(STRING); } + + [ \t\v\f]+ { goto std; } + + "|" { RET(OR); } + "^" { RET(XOR); } + "&" { RET(AND); } + "-" { RET(MINUS); } + "+" { RET(PLUS); } + "*" { RET(MULTIPLY); } + "/" { RET(DIVIDE); } + "(" { RET(LPAREN); } + ")" { RET(RPAREN); } + "," { RET(COMMA); } + "{" { RET(LBRACE); } + "}" { RET(RBRACE); } + ";" { RET(SEMICOLON); } + + + "\n" + { + if(cursor == s->eof) RET(EOI); + s->pos = cursor; s->line++; + goto std; + } + + any + { + printf("unexpected character: %c\n", *s->tok); + goto std; + } +*/ + +comment: +/*!re2c + "*/" { goto std; } + "\n" + { + if(cursor == s->eof) RET(EOI); + s->tok = s->pos = cursor; s->line++; + goto comment; + } + any { goto comment; } +*/ +} + +int lex(Scanner *s, struct Token *tok) +{ + int tokentype = scan(s); + char *p, *q; + + tok->val = 0; + tok->string = NULL; + + switch (tokentype) + { + case NUM: + tok->val = strtol((char *)s->tok, NULL, 0); + break; + + case STRING: + tok->string = (char *)malloc(s->cur - s->tok - 1); + strncpy(tok->string, (char *)s->tok + 1, s->cur - s->tok - 2); + tok->string[s->cur - s->tok - 2] = '\0'; + for (p = q = tok->string; *p; ++p, ++q) + { + if (p[0] == '\\' && p[1] == '\\') + ++p; + *q = *p; + } + break; + + case SYM: + tok->string = (char *)malloc(s->cur - s->tok + 1); + strncpy(tok->string, (char *)s->tok, s->cur - s->tok); + tok->string[s->cur - s->tok] = '\0'; + break; + } + return tokentype; +} diff --git a/wadsrc/Makefile b/wadsrc/Makefile index cb78c22ee0..8c183509e0 100644 --- a/wadsrc/Makefile +++ b/wadsrc/Makefile @@ -10,15 +10,16 @@ RM=rm -f SLASH=/ MAKEWAD=..$(SLASH)tools$(SLASH)makewad$(SLASH)makewad +DEHSUPP=..$(SLASH)tools$(SLASH)dehsupp$(SLASH)dehsupp makethewad: wadmake Makefile2 - $(MAKE) $(NOLOGO) -f Makefile2 + $(MAKE) $(NOLOGO) DEHSUPP=$(DEHSUPP) -f Makefile2 wadmake: zdoom.lst $(MAKEWAD) -make wadmake zdoom.lst clean: - $(RM) wadmake zdoom.pk3 + $(RM) wadmake zdoom.pk3 dehsupp.lmp # This target is for Visual C++'s Rebuild All command nrebuild: clean diff --git a/wadsrc/Makefile.mgw b/wadsrc/Makefile.mgw index f7cb6a71e2..523efbd378 100644 --- a/wadsrc/Makefile.mgw +++ b/wadsrc/Makefile.mgw @@ -1,4 +1,5 @@ MAKEWAD=../tools/makewad/makewad +DEHSUPP=../tools/dehsupp/dehsupp ifneq ($(MAKECMDGOALS),clean) include Makefile2 @@ -7,15 +8,18 @@ ifeq ($(findstring msys,$(shell sh --version 2>nul)),msys) export OSTYPE=msys endif -wadmake: zdoom.lst $(MAKEWAD).exe +wadmake: zdoom.lst $(MAKEWAD).exe $(DEHSUPP).exe $(MAKEWAD) -make wadmake zdoom.lst clean: ifeq ($(OSTYPE),msys) - rm -f wadmake zdoom.pk3 + rm -f wadmake zdoom.pk3 dehsupp.lmp else - del /q /f wadmake zdoom.pk3 2>nul + del /q /f wadmake zdoom.pk3 dehsupp.lmp 2>nul endif ../tools/makewad/makewad.exe: $(MAKE) -C ../tools/makewad -f Makefile + +../tools/dehsupp/dehsupp.exe: + $(MAKE) -C ../tools/dehsupp -f Makefile diff --git a/wadsrc/Makefile2 b/wadsrc/Makefile2 index 82d1cf51be..0202e1bacb 100644 --- a/wadsrc/Makefile2 +++ b/wadsrc/Makefile2 @@ -1,2 +1,5 @@ include wadmake +dehsupp.lmp: dehsupp.txt + $(DEHSUPP) dehsupp.txt dehsupp.lmp + \ No newline at end of file diff --git a/wadsrc/dehsupp.lmp b/wadsrc/dehsupp.lmp new file mode 100644 index 0000000000000000000000000000000000000000..881790dd91d3e91e128e8c77664188e98564f1d6 GIT binary patch literal 9569 zcmbtad0<<`(VtnJwrojG$W0Q*QSQTc5&}7NTd^+mWIG9gAlq^*EK5R?W1IU3N4d&T zS_%zNpj_pK_JfvkAEixON-0n%6v|cF(gRwKuLZu}zV~E1J^uRS%-i4W?%TIJvpX}p zo2WbDpAq5fh{!^XLCI-=e2w|`#H+nxtE8z$S3jHd=Y=0Z{WN5`}{ON$FK4`{2_lPs>F0LU#t*q zVvC4~?V?W%ixb7!;!?3++$ioBKM+repNUt*TjKZPBk>P|!BA(IXJ{}q8P*%zhE7Ab zA!Qggj2ZSBE;d|cxW#a<;bFr8!;6M@41Y0vZZsO}jPs2vjBUoP#*i^$>^2@_JkB^` zJllAQ@mk}Z#)phQG5*r{s_|{(`^LYUOeUvkhN<4P%Cye3#S}C}Ogl{jrsGW~o6azu zXS&REjphs{Ov3FfoR7n}E+ zZ!zCze#HEY`33VE<_|1vv0LU?T$U!wCQGNK$I@rXS;j0UTh6guYT0kO$#S>l`<5py z2Q1H9UbTE^C9Bms!#dx(+}dK@XboDE)}ySw){M1eJHT5q@BYkk1_ zu=PpnPpmIlU$g$s`l0oUDqGd8s)nkjsw1j8s^V3MZOeO2`>)%RCF zUHyFZYt?U6zhC`P_2)K=t=2Zvw!pT`)?{06^Vm9VJ8d~z(Kc?|XS>L@-*&U@Hru_n zM{Pf~y=MDkjk#ue&D@&$niVyzHJ%!!rmv=0b6U;0HJ8;~UvqEGV>LgodA;V(HJ{WP zYaO-oYM0fv)*eyYS$kyduG&m(srHoGb80WC{YLE#wYSwiQ2SKvbG2{Q{;Bp;yU}j9 z&$KVJuduh)7Df;^=g2 zccdK!$BB-!9hW+;cHHWC!0}_pD~^wyW~bdb)49O8)Y;z=K9t?r$= zzt(-WvOk?F57NqkOsPyO_Y_BRNV2J1KdmgJGP&laCR#bB)p2LD!>IzfBc3j$gWSbb z-(W6ZF6MJnaXgzU4X2RPH@G*GO;3P8rYM==e9@E7jg+W2)jQsp>MLjVrZud6L(MK_ z_6(M_+|g8ah&-qpNtaVupuV932!;4=W91!*wU<0H-;>J9sz9-Uj|#1geW|{@t`rq& zee)u>KRt|jGJ#a-dojz>*%U^Hf?R(#T`FhrA+I|cjV0r9jsYs+kk2ncGVFJE`vc)v zED;ZR$t(3LA92|^?;r-UX9Qo+L2zVT!===y1f?{d>As;vI-5`RlQ)|ws1Hwm3~9cU zRtEEBG|)ocd^Vp8W_n8!jSQp7{P3{sX|Xe%28Yip=uoUHnhYiV5e;>Q!eR2p^A%x9 zm`D%EIo~(ln=V#_qT<1Pen8LG1tha|*?J|`q=l)`KOr%aoKKaait_p4&~QP`4d+W` zB|nl?nMkUb$)#1O4@rtbzM`nom1t*vxHprIq;klYYEeH|S&SOfuTD!152v$O2pU!= zo(8qP`_konE>*@CG0l9jXwsK(_mHpBJuOw$E%RU<#?wW$xC>SwjZWd+lA6(zP8DQl z^7&$^vA@{7yAOJq!sZJQf2FkL;L?`eYN;=lh+w9WFA&q@6ZATzg*3{8F30o#%tAvSE29pXvidm+mJPpWaV@g{v8lwqP!>aH! zs0mLsit+)oLo)RSF^5$E>pBGU83-l(K6k_&^sCvCOsOQTs;m-+#m=Lz5^6?QLUb!D z7s3=AP7k1ilVu6jyvhuHhNy)T3m_mp0oIv2sXaY04+XGl%2;8VZBrMa2P?pfUdaXN z4Ts`DI|%EhH{Gw#!KsX9X4PdCET;Bm%HtG-dCh6|Q-zwfR6S5-E^3S>LJg}T)SxCp z2rPin4^l@8W+<9hO`gg`^TCmFNrlO9K0k!+`|_i?gEG1b8aws9q&CP7EEIiBN~l{X zk~o%gYl}%TrKw!DJgB)hloZRl0g*1KGp7o@Bh#Nw4x%U2A&o%DTTyOixKJ6i3biRD zp*DJnv~?&^2~%#2RHQZ=ip1UCB!!}y+CsU3Vyc+#r%-P1NH&))rg}43h+OwVp=ftk zIOf!uh7V<^Coe|Y`X(glD3z3kbgdopIK36KIi*gxKWTZ4$gw>;H%oC1zJ0tG624g;? z>Y|Cpe34+XBLRUECak_RqOqvb5sM{N4MovnKAY*+20xW+#VeC#Z3l7f6PzBcL}QBI zn~Wv!<)km-PI@~e@`wHLSOVYff&+_1BQei5iowuM=qE1Y1gUpj(JEBufr>PR$5F1Y z6$$0+kf}eL9!}?E+!l8$irRKuQzSfiXIGqb6Q-Fj)k$bDkr{xID`a6#8w=&;-NTvw zDICmR;UE@j!FzBldMGpLhvOqTL|`(OP(>+0j~gRRU1~XBqK511}SlO4}4@O z9Et`>k;X)wJ8HIOskO}PxK=74@Q;ArGdyRo7z*(AanyPmbI=W{qAtG137RmGO$*XJHr0m?tZkQ zqQJ-rC!n_~hVj9>IxIpKIuk3Dr&d!2Q~mHoT16=xtdCqt=T)2?>4TXdWu$;5tjz-| zse7z+sWCm4Dff<)bCWr_d~sOKNkaTnC!XXd=UFn{HyBPKMy`Ms6~!~zY^q2TmM^JW zb|1DMsGym7=@DfOB^isvN!sUNM+_!fowMq`P+#Q9gxsRIlc89Yrr_qO48E(@>hiX< zPr&x33AlbT*N@;e371jOr(IWWGGge;9kkR{_MkUQ$>ymi6!q!B zK~FwAkd~nZHtY(Gf-7N{r0&vmMw9SpzL@QA>{a*UW3*j&89QLg^P{Ru)1cyabI8Hqjf6Hk-HBl!u(>5Hf#;BD#sEtC@PGOX6q7CE$w-}{$6u}{E5;nn}0O5p*xUbRT)?DGJgvWTqeC82HEJpr6om z9Q8KP&&f*9QHoxsEjadNdWRD92ilF}U!sp`8ht_w=$|+&{)_@_rG;EYOSqb<*-j>Q zP!%6SHeNu7^FqQwF)if=Qg|`-u#0x^5;}^P($Tzun)xtl;f>V9N6=>WQR`(&UUw2IiF1{_#9fv=aPl5rbXVE zFV2sk-vTl)VtiFpO*Y8J4ms4J|I;DwnUL)QS_sK5!iZh8l$Oy79D}c>M(C{>I%|c* z+ac}s(9B`9kq(FCHqmCt#0}kfp(pI$Ai)mkaT_!ph90BPbR61CkOGZ%Q8y0Mw?n6+ z(A$2xhOVU>=_VYi-${4T-E2=C=l9^-L7fltK6!O46IpUS84>3k-ig=>Th`K$ajz5-k%J6W`2t@SXfUTr@n$Kj4S>VSa=k<;VDOeuAImr}&5bBR;@C=A<^BaRbUT#Dqxs2CIDxEwi2 zoGeZer;5|W>EaA=rr0OW!iC8>;#_f_xIkPeE)tiC>%{fq2JtOiq1+^H7Pp97#ka+6 z;&yR|xKrFE?iTlm`*6APAg)&)5)X?<#G~Rd@wj+GJc;X;r^Pek$Kt2r1@WSIN&HH@ zjO&+Qi&w>K;y2=T@rL-VcoWw#Z;N-ud$^SOllZgv++a3T8El3cgTvs&1|^2$gsk&N{J_;bY3zMizyw+V7x0DjE59S0q~MqydA+H zD1cZz2ns0fo?twTI$F)IVqaIHpin;-JBGL?M@wgMs9{=`u0OzcpShN|` z;_3A7NPu>LJZLll+5u9Mp-9B<3n{U#a2!VoaV3cZ*{Bln2i;0nC>h5tH{Kmm42E~;Qe;6Iz?uolQJ%O%ZB#3h)2rlgIiel^v_8Cbf7;W*!!d*%v z*%FK;n&UCZEf#JEwSiheGH)HqWO*y74b-kgLP@;W43h7+g4!@7pVyOc1FuUa{LP>i zM0Q@Ue}_MS@gToF2_+?ii73i^O2m^?uqRg{iDZY*(+p|>wSw9}?Vxq>mC&Td;CF-lEEMLHv@mH|+ui(qE{x9S&@uhqTf0-}F#o~FelHY?ZGgFa{hg~~{ zkA`*ML)Y`^bQY}NtMnSZ35)**t}W%?_whFfn|%npMkl=65BUr_oBqLv(*W$*ne+g! zhd(pXb?V>!u)t~9_}{`ibn`Z{^C|Q+eadb0P1xstct|IoOoI2ruk^s;oln1}GL`6c zX}4gN8{s?F!Y8k$Gie_z)>ZT*Jpt>vj$7#!94$rRsdKPj&C(a~OrFKF=?pp@{sRa9 z9D-+=2~U0xJRhGhz(`%H}fD97G{=F^ajuzyn+ZxmYNN+;7q%$h!fp zEQkMJ0EwG;7HB5MbUNBN1KJ7#XCc8p#8R6uS7snz#s>F*o`udM_^K6gS{3@R6LmgE zyI0Z@=*EF4#SHxzI6y{d$O>&4pbdf61oUOWhz-z;8M-l}7lP|RvV1YpX`pLC3da5t z+_f8Z9>&;afnS33S7@^q*o?o2@J=Ui81?3X4h8ms{J_gWD}bkgWTE=6#*7(S!OU5ons55)E ze1DFuR=z%W<~&r;n)olzL-qXm|D{~ZMg&=}qD5Ll4GoL+pKA#rz+5WxD}{hlD=hnu z6;NaOl-~;1N|*XuCEu>JDBhQ%H?xP9oI%#1(S~!$%p=%TH)|Y z1+A=MvCDM?vhdQB7f?3!olTW@D&6{zg;T%g+6+$bNkhXH$fH88Wy`kGg335C(uM|d ztE$wVE)S-?US9c}-f}~OSFN~ZvCAj_WcymL*Xy$Z3iPX=g;~>nQ+v9>H7UVG^?C(8 zkuAwzP75#A|ePEyu=g{Al(MPN3i`7gUm~CuZ!8Pl6#ulEloEL58 zWz%@2;LWpnE3?PSzNOqjoLIp94&KwkgKK$cE@$WR@I21BIq%_umyh@G_&h%0P(E=! zpR|C#z9`|3`rr(b7VZ+