MB_is_me Posted October 30, 2014 Hello there, Doomworld citizens. I was hoping to get some help with a dilemma I've encountered when thinking about what I want my custom Heretic WAD to be tech wise. I'm pretty new to this scene, and I thought that you guys could help me out with the technical questions that arise with wanting to create a WAD. Hey, maybe other newbies will find the thread useful? And if there already is a thread like this out there, that would answer the questions I have, feel free to link me there. Anyway, first things first - I'd like to read a short rundown of the available source ports and their technical capabilities, and which one of those would be the most fitting for what I want to do. I'm leaning towards purism in this area - I like the game to remain as close to the original version as possible (again, tech wise). I'm open to the idea of composing MIDI music (I'm a bit of a musician), and am not nauseous of looking at a pixelated Chocolate Heretic screen. But, in all honesty, I would like to compose music with more modern tools and sounds, so the newer source ports are drawing my attention more in that area, since they don't limit themselves with MIDI files. Also, whatever system you'd be playing on, you'd hear the music the way I intended, and not depending on what synthesizer you're emulating. That's important for me. When I realized that in regards to music in a WAD, I also thought about going more modern with the engine, as well. The music is modern, so why not make the graphics that way? But I'm pretty picky in my own right in this area - I like the old slight pixelated feel. I like the sprite-based classic monsters. The new 3D modeled items and enemies look bad for me, I don't like them one bit. Yet I would love to incorporate more interesting lighting in my levels, something that OpenGL ports are able to do. So ZDoom, my current favorite, kind of drops off. And I don't know if it's worth to create a WAD so tailored to one specific port. I'd like to players experience the maps as intended by the maker (graphics and sounds wise, that is), but seeing how many different options are there for launching Doom/Heretic and customizing it to your tastes, I started thinking about what would be the best compromise in this situation? So, in short: I want to compose custom, non-MIDI music for the WAD. I would love to have more advanced shadowing and lighting. I'd like to keep the gameplay as originally intended - no jumping, no free mouse look, no crouching, etc. And I want for the final product to be as "samey" as possible on different source ports. What are the most compatible, friendly source ports out there that would fit my needs? How does the community itself react to tailor made maps for specific ports? Is it the best best to go absolutely pure vanilla and let the players decide how they want to experience it? I'd be grateful for advice you've got, veterans and young-uns alike. 0 Share this post Link to post
Gez Posted October 30, 2014 Why no free look when vanilla Heretic has looking up and down possible? 0 Share this post Link to post
MB_is_me Posted October 30, 2014 Gez said:Why no free look when vanilla Heretic has looking up and down possible? You had to use the keyboard to look up and down. I wouldn't call it "free look", but that's not the point. The point is, I want the gameplay to remain close to vanilla. 0 Share this post Link to post
Vermil Posted October 30, 2014 In terms of Heretic, you've basically got Chocolate Heretic, Doomsday and ZDoom (and derivatives). Chocolate Heretic being the most faithful. Doomsday offers additional modding features, lot's of optional visual enhancements and is almost faithful. ZDoom offers the most modding features, but is less faithful than the other two. GZDoom offer's the same support as ZDoom with some optional visual enhancements. Eternity and 3DGE are both working on supporting Heretic. But the game isn't fully playable in either yet. http://doomwiki.org/wiki/Comparison_Source_Ports 0 Share this post Link to post
MB_is_me Posted October 30, 2014 Vermil said:In terms of Heretic, you've basically got Chocolate Heretic, Doomsday and ZDoom (and derivatives). Chocolate Heretic being the most faithful. Doomsday offers additional modding features, lot's of optional visual enhancements and is almost faithful. ZDoom offers the most modding features, but is less faithful than the other two. GZDoom offer's the same support as ZDoom with some optional visual enhancements. Eternity and 3DGE are both working on supporting Heretic. But the game isn't fully playable in either yet. http://doomwiki.org/wiki/Comparison_Source_Ports I'm thinking of choosing between Chocolate Heretic and ZDoom. I like the vanilla environment, but man does the ability to create music in anything else but MIDI attract me... 0 Share this post Link to post
Blastfrog Posted October 30, 2014 You can actually run streamed music formats in the Chocolate family of ports. 0 Share this post Link to post
wesleyjohnson Posted October 31, 2014 Your plan is self-defeating. You want to make a level map with some new music (in a non-MIDI format) and in a format that is near vanilla. You want the player to experience it as you design it, without free-look and without jumping, (etc.). What you are asking for is a Doom version of DRM. If you reject jumping and free-look capable ports, then you cannot use their extended wad formats either. But if you make a limited wad, that does not restrict what port the player uses to play your level map. I can still use DoomLegacy to play any Boom wad, and I can turn the mouse free-look on or off while playing your level map. I won't hear your new non-Midi music, but will not notice because the default music will load instead. The best you can do is choose some port with the music format you want to use. Make all walls high enough that they cannot be jumped. There is nothing you can do about people using free-look. You can turn it off on just about any port for your own playing. Don't use any 3d floors, or sloped floors, or other enhancements. It does not matter if the port supports them, just don't use them in your level map. 0 Share this post Link to post
MB_is_me Posted October 31, 2014 wesleyjohnson said:Your plan is self-defeating. You want to make a level map with some new music (in a non-MIDI format) and in a format that is near vanilla. You want the player to experience it as you design it, without free-look and without jumping, (etc.). What you are asking for is a Doom version of DRM. If you reject jumping and free-look capable ports, then you cannot use their extended wad formats either. But if you make a limited wad, that does not restrict what port the player uses to play your level map. I can still use DoomLegacy to play any Boom wad, and I can turn the mouse free-look on or off while playing your level map. I won't hear your new non-Midi music, but will not notice because the default music will load instead. The best you can do is choose some port with the music format you want to use. Make all walls high enough that they cannot be jumped. There is nothing you can do about people using free-look. You can turn it off on just about any port for your own playing. Don't use any 3d floors, or sloped floors, or other enhancements. It does not matter if the port supports them, just don't use them in your level map. I suppose you're right. I think I'll simply stick with ZDoom at this point. 0 Share this post Link to post
Koko Ricky Posted November 1, 2014 I'm having a similar issue, because I want to use non-MIDI music for my maps, but they're all Vanilla-ish. I've made it so jumping won't wreck them and freelook doesn't affect gameplay, but I'm stuck because I don't know what to go with in terms of adding MP3 music. 0 Share this post Link to post
Jaxxoon R Posted November 3, 2014 I can say for me, it's either DECORATE, ACS and UDMF or geddefuckout. The one exception might be Eternity with those portals and all, they look pretty fun. It's a pity Zdoom doesn't have them to the same level because of it's renderer's limitations. 0 Share this post Link to post
40oz Posted November 3, 2014 I've heard prboom (a port that's very strict about compatibility concerns) supports ogg format music, and I'm sure there are online web-based converters that will convert an mp3 to ogg. Not sure if prboom has anything to do with heretic though. Best solution I can think of is to design your heretic wad while testing both with zdoom and whatever executable is closest to vanilla. Rule out the things you can and cant do with both and try to find a middle ground. It could be possible for some ZDoom features like OpenGL light sourcing and other things can be added into the map so that they appear in ZDoom, and still function in vanilla with that sort of eye candy just invisible without crashing the game. If music is the only main concern, just make the wad in vanilla and test in vanilla until completion, then add the music as the final thing and tell people they have to play it in a ZDoom-based port (which most people play heretic in anyway) if they want to hear the music. 0 Share this post Link to post
rabidrage Posted November 4, 2014 Last I checked, Doomsday is about looks before tricks. It makes everything look amazing, but as far as I know it doesn't do room-over-room, slopes, etc. 0 Share this post Link to post
Vermil Posted November 4, 2014 Doomsday doesn't support slopes or room over room (though you can do something similar to HeXen's star bridges, even better with models). Doomsday's XG is probably more capable than many Doomer's think. Boom's generalized linetypes are, under the hood, a ton of hardcoded linetypes. Despite what Doom Builder's GUI implies when you place a Boom linetype, you are actually just selecting a hardcoded linetype. With Doomsday's XG, you make your own line and sector types from scratch that can perform multiple actions (complete with time delays for each action) across multiple sectors and can interact with each other (I.e XG line A can alter or activate/deactivate XG line B). XG lies half way between Boom and ACS really. But there is no known GUI for it, like there is with Boom. Below is a simple XG def; upon the player using a line with a trigger type of 7000 (7001-7003 do not need to be placed on the map because 7000 calls them it'self), it changes the upper, middle and lower textures on the tagged line (in this instance itself, though you can reference any line on the map), plays a sound in the tagged sector (in this instance, the tag is the same as the linedef) and spawns two mobjs in certain areas of the map. Line Type { ID= 7000 Comment= "Intruder alert map 1" Class = "ltc_chain_sequence" Count = 1 Type = "lat_timed_off"; Flags = "ltf_player_use_a"; Flags2 = "ltf2_when_act ltf2_any"; Time = 10 Ip0="chsf_done_d"; Ip1 = 7001 Ip2 = 7002 Ip3 = 7003 } Line Type { ID = 7001; Comment = "Badguy spawn"; Flags2 = "ltf2_when_act ltf2_any"; Class = "ltc_command"; Count = 1 Sp0 = "spawnmobj TROOP 3104 -672 0 270; spawnmobj BRUISER 3104 -544 0 90"; } Line Type { ID= 7002; Comment = "Play the sound in tagged sector"; Class = "ltc_sound"; Count = 1 Flags2 = "ltf2_when_act ltf2_any"; Ip0 = "lsref_line_tagged"; Ip2 = "intrudr1"; } Line Type { ID = 7003; Comment = "Change texture on tagged line"; Flags2 = "ltf2_when_act ltf2_any"; Class = "ltc_wall_texture"; Count = 1 Ip0 = "lref_line_tagged"; Ip3 = "1TERM6"; Ip4 = "1TERM6"; Ip5 = "1TERM6"; } 0 Share this post Link to post
Gez Posted November 4, 2014 Vermil said:Boom's generalized linetypes are, under the hood, a ton of hardcoded linetypes. Despite what Doom Builder's GUI implies when you place a Boom linetype, you are actually just selecting a hardcoded linetype. I don't think it's fair and accurate to say that. There are thousands of combinations and not thousands of declarations. I'm gonna post the Boom's P_UseSpecialLine here. It's a long function so it's in a spoiler box. Spoiler // // P_UseSpecialLine // // // Called when a thing uses (pushes) a special line. // Only the front sides of lines are usable. // Dispatches to the appropriate linedef function handler. // // Passed the thing using the line, the line being used, and the side used // Returns true if a thinker was created // boolean P_UseSpecialLine ( mobj_t* thing, line_t* line, int side ) { if (side) //jff 6/1/98 fix inadvertent deletion of side test return false; //jff 02/04/98 add check here for generalized floor/ceil mover if (!demo_compatibility) { // pointer to line function is NULL by default, set non-null if // line special is push or switch generalized linedef type int (*linefunc)(line_t *line)=NULL; // check each range of generalized linedefs if ((unsigned)line->special >= GenFloorBase) { if (!thing->player) if ((line->special & FloorChange) || !(line->special & FloorModel)) return false; // FloorModel is "Allow Monsters" if FloorChange is 0 if (!line->tag && ((line->special&6)!=6)) //jff 2/27/98 all non-manual return false; // generalized types require tag linefunc = EV_DoGenFloor; } else if ((unsigned)line->special >= GenCeilingBase) { if (!thing->player) if ((line->special & CeilingChange) || !(line->special & CeilingModel)) return false; // CeilingModel is "Allow Monsters" if CeilingChange is 0 if (!line->tag && ((line->special&6)!=6)) //jff 2/27/98 all non-manual return false; // generalized types require tag linefunc = EV_DoGenCeiling; } else if ((unsigned)line->special >= GenDoorBase) { if (!thing->player) { if (!(line->special & DoorMonster)) return false; // monsters disallowed from this door if (line->flags & ML_SECRET) // they can't open secret doors either return false; } if (!line->tag && ((line->special&6)!=6)) //jff 3/2/98 all non-manual return false; // generalized types require tag linefunc = EV_DoGenDoor; } else if ((unsigned)line->special >= GenLockedBase) { if (!thing->player) return false; // monsters disallowed from unlocking doors if (!P_CanUnlockGenDoor(line,thing->player)) return false; if (!line->tag && ((line->special&6)!=6)) //jff 2/27/98 all non-manual return false; // generalized types require tag linefunc = EV_DoGenLockedDoor; } else if ((unsigned)line->special >= GenLiftBase) { if (!thing->player) if (!(line->special & LiftMonster)) return false; // monsters disallowed if (!line->tag && ((line->special&6)!=6)) //jff 2/27/98 all non-manual return false; // generalized types require tag linefunc = EV_DoGenLift; } else if ((unsigned)line->special >= GenStairsBase) { if (!thing->player) if (!(line->special & StairMonster)) return false; // monsters disallowed if (!line->tag && ((line->special&6)!=6)) //jff 2/27/98 all non-manual return false; // generalized types require tag linefunc = EV_DoGenStairs; } else if ((unsigned)line->special >= GenCrusherBase) { if (!thing->player) if (!(line->special & CrusherMonster)) return false; // monsters disallowed if (!line->tag && ((line->special&6)!=6)) //jff 2/27/98 all non-manual return false; // generalized types require tag linefunc = EV_DoGenCrusher; } if (linefunc) switch((line->special & TriggerType) >> TriggerTypeShift) { case PushOnce: if (!side) if (linefunc(line)) line->special = 0; return true; case PushMany: if (!side) linefunc(line); return true; case SwitchOnce: if (linefunc(line)) P_ChangeSwitchTexture(line,0); return true; case SwitchMany: if (linefunc(line)) P_ChangeSwitchTexture(line,1); return true; default: // if not a switch/push type, do nothing here return false; } } // Switches that other things can activate. if (!thing->player) { // never open secret doors if (line->flags & ML_SECRET) return false; switch(line->special) { case 1: // MANUAL DOOR RAISE case 32: // MANUAL BLUE case 33: // MANUAL RED case 34: // MANUAL YELLOW //jff 3/5/98 add ability to use teleporters for monsters case 195: // switch teleporters case 174: case 210: // silent switch teleporters case 209: break; default: return false; break; } } if (!P_CheckTag(line)) //jff 2/27/98 disallow zero tag on some types return false; // Dispatch to handler according to linedef type switch (line->special) { // Manual doors, push type with no tag case 1: // Vertical Door case 26: // Blue Door/Locked case 27: // Yellow Door /Locked case 28: // Red Door /Locked case 31: // Manual door open case 32: // Blue locked door open case 33: // Red locked door open case 34: // Yellow locked door open case 117: // Blazing door raise case 118: // Blazing door open EV_VerticalDoor (line, thing); break; // Switches (non-retriggerable) case 7: // Build Stairs if (EV_BuildStairs(line,build8)) P_ChangeSwitchTexture(line,0); break; case 9: // Change Donut if (EV_DoDonut(line)) P_ChangeSwitchTexture(line,0); break; case 11: // Exit level P_ChangeSwitchTexture(line,0); G_ExitLevel (); break; case 14: // Raise Floor 32 and change texture if (EV_DoPlat(line,raiseAndChange,32)) P_ChangeSwitchTexture(line,0); break; case 15: // Raise Floor 24 and change texture if (EV_DoPlat(line,raiseAndChange,24)) P_ChangeSwitchTexture(line,0); break; case 18: // Raise Floor to next highest floor if (EV_DoFloor(line, raiseFloorToNearest)) P_ChangeSwitchTexture(line,0); break; case 20: // Raise Plat next highest floor and change texture if (EV_DoPlat(line,raiseToNearestAndChange,0)) P_ChangeSwitchTexture(line,0); break; case 21: // PlatDownWaitUpStay if (EV_DoPlat(line,downWaitUpStay,0)) P_ChangeSwitchTexture(line,0); break; case 23: // Lower Floor to Lowest if (EV_DoFloor(line,lowerFloorToLowest)) P_ChangeSwitchTexture(line,0); break; case 29: // Raise Door if (EV_DoDoor(line,normal)) P_ChangeSwitchTexture(line,0); break; case 41: // Lower Ceiling to Floor if (EV_DoCeiling(line,lowerToFloor)) P_ChangeSwitchTexture(line,0); break; case 71: // Turbo Lower Floor if (EV_DoFloor(line,turboLower)) P_ChangeSwitchTexture(line,0); break; case 49: // Ceiling Crush And Raise if (EV_DoCeiling(line,crushAndRaise)) P_ChangeSwitchTexture(line,0); break; case 50: // Close Door if (EV_DoDoor(line,close)) P_ChangeSwitchTexture(line,0); break; case 51: // Secret EXIT P_ChangeSwitchTexture(line,0); G_SecretExitLevel (); break; case 55: // Raise Floor Crush if (EV_DoFloor(line,raiseFloorCrush)) P_ChangeSwitchTexture(line,0); break; case 101: // Raise Floor if (EV_DoFloor(line,raiseFloor)) P_ChangeSwitchTexture(line,0); break; case 102: // Lower Floor to Surrounding floor height if (EV_DoFloor(line,lowerFloor)) P_ChangeSwitchTexture(line,0); break; case 103: // Open Door if (EV_DoDoor(line,open)) P_ChangeSwitchTexture(line,0); break; case 111: // Blazing Door Raise (faster than TURBO!) if (EV_DoDoor (line,blazeRaise)) P_ChangeSwitchTexture(line,0); break; case 112: // Blazing Door Open (faster than TURBO!) if (EV_DoDoor (line,blazeOpen)) P_ChangeSwitchTexture(line,0); break; case 113: // Blazing Door Close (faster than TURBO!) if (EV_DoDoor (line,blazeClose)) P_ChangeSwitchTexture(line,0); break; case 122: // Blazing PlatDownWaitUpStay if (EV_DoPlat(line,blazeDWUS,0)) P_ChangeSwitchTexture(line,0); break; case 127: // Build Stairs Turbo 16 if (EV_BuildStairs(line,turbo16)) P_ChangeSwitchTexture(line,0); break; case 131: // Raise Floor Turbo if (EV_DoFloor(line,raiseFloorTurbo)) P_ChangeSwitchTexture(line,0); break; case 133: // BlzOpenDoor BLUE case 135: // BlzOpenDoor RED case 137: // BlzOpenDoor YELLOW if (EV_DoLockedDoor (line,blazeOpen,thing)) P_ChangeSwitchTexture(line,0); break; case 140: // Raise Floor 512 if (EV_DoFloor(line,raiseFloor512)) P_ChangeSwitchTexture(line,0); break; // killough 1/31/98: factored out compatibility check; // added inner switch, relaxed check to demo_compatibility default: if (!demo_compatibility) switch (line->special) { //jff 1/29/98 added linedef types to fill all functions out so that // all possess SR, S1, WR, W1 types case 158: // Raise Floor to shortest lower texture // 158 S1 EV_DoFloor(raiseToTexture), CSW(0) if (EV_DoFloor(line,raiseToTexture)) P_ChangeSwitchTexture(line,0); break; case 159: // Raise Floor to shortest lower texture // 159 S1 EV_DoFloor(lowerAndChange) if (EV_DoFloor(line,lowerAndChange)) P_ChangeSwitchTexture(line,0); break; case 160: // Raise Floor 24 and change // 160 S1 EV_DoFloor(raiseFloor24AndChange) if (EV_DoFloor(line,raiseFloor24AndChange)) P_ChangeSwitchTexture(line,0); break; case 161: // Raise Floor 24 // 161 S1 EV_DoFloor(raiseFloor24) if (EV_DoFloor(line,raiseFloor24)) P_ChangeSwitchTexture(line,0); break; case 162: // Moving floor min n to max n // 162 S1 EV_DoPlat(perpetualRaise,0) if (EV_DoPlat(line,perpetualRaise,0)) P_ChangeSwitchTexture(line,0); break; case 163: // Stop Moving floor // 163 S1 EV_DoPlat(perpetualRaise,0) EV_StopPlat(line); P_ChangeSwitchTexture(line,0); break; case 164: // Start fast crusher // 164 S1 EV_DoCeiling(fastCrushAndRaise) if (EV_DoCeiling(line,fastCrushAndRaise)) P_ChangeSwitchTexture(line,0); break; case 165: // Start slow silent crusher // 165 S1 EV_DoCeiling(silentCrushAndRaise) if (EV_DoCeiling(line,silentCrushAndRaise)) P_ChangeSwitchTexture(line,0); break; case 166: // Raise ceiling, Lower floor // 166 S1 EV_DoCeiling(raiseToHighest), EV_DoFloor(lowerFloortoLowest) if (EV_DoCeiling(line, raiseToHighest) || EV_DoFloor(line, lowerFloorToLowest)) P_ChangeSwitchTexture(line,0); break; case 167: // Lower floor and Crush // 167 S1 EV_DoCeiling(lowerAndCrush) if (EV_DoCeiling(line, lowerAndCrush)) P_ChangeSwitchTexture(line,0); break; case 168: // Stop crusher // 168 S1 EV_CeilingCrushStop() if (EV_CeilingCrushStop(line)) P_ChangeSwitchTexture(line,0); break; case 169: // Lights to brightest neighbor sector // 169 S1 EV_LightTurnOn(0) EV_LightTurnOn(line,0); P_ChangeSwitchTexture(line,0); break; case 170: // Lights to near dark // 170 S1 EV_LightTurnOn(35) EV_LightTurnOn(line,35); P_ChangeSwitchTexture(line,0); break; case 171: // Lights on full // 171 S1 EV_LightTurnOn(255) EV_LightTurnOn(line,255); P_ChangeSwitchTexture(line,0); break; case 172: // Start Lights Strobing // 172 S1 EV_StartLightStrobing() EV_StartLightStrobing(line); P_ChangeSwitchTexture(line,0); break; case 173: // Lights to Dimmest Near // 173 S1 EV_TurnTagLightsOff() EV_TurnTagLightsOff(line); P_ChangeSwitchTexture(line,0); break; case 174: // Teleport // 174 S1 EV_Teleport(side,thing) if (EV_Teleport(line,side,thing)) P_ChangeSwitchTexture(line,0); break; case 175: // Close Door, Open in 30 secs // 175 S1 EV_DoDoor(close30ThenOpen) if (EV_DoDoor(line,close30ThenOpen)) P_ChangeSwitchTexture(line,0); break; case 189: //jff 3/15/98 create texture change no motion type // Texture Change Only (Trigger) // 189 S1 Change Texture/Type Only if (EV_DoChange(line,trigChangeOnly)) P_ChangeSwitchTexture(line,0); break; case 203: // Lower ceiling to lowest surrounding ceiling // 203 S1 EV_DoCeiling(lowerToLowest) if (EV_DoCeiling(line,lowerToLowest)) P_ChangeSwitchTexture(line,0); break; case 204: // Lower ceiling to highest surrounding floor // 204 S1 EV_DoCeiling(lowerToMaxFloor) if (EV_DoCeiling(line,lowerToMaxFloor)) P_ChangeSwitchTexture(line,0); break; case 209: // killough 1/31/98: silent teleporter //jff 209 S1 SilentTeleport if (EV_SilentTeleport(line, side, thing)) P_ChangeSwitchTexture(line,0); break; case 241: //jff 3/15/98 create texture change no motion type // Texture Change Only (Numeric) // 241 S1 Change Texture/Type Only if (EV_DoChange(line,numChangeOnly)) P_ChangeSwitchTexture(line,0); break; case 221: // Lower floor to next lowest floor // 221 S1 Lower Floor To Nearest Floor if (EV_DoFloor(line,lowerFloorToNearest)) P_ChangeSwitchTexture(line,0); break; case 229: // Raise elevator next floor // 229 S1 Raise Elevator next floor if (EV_DoElevator(line,elevateUp)) P_ChangeSwitchTexture(line,0); break; case 233: // Lower elevator next floor // 233 S1 Lower Elevator next floor if (EV_DoElevator(line,elevateDown)) P_ChangeSwitchTexture(line,0); break; case 237: // Elevator to current floor // 237 S1 Elevator to current floor if (EV_DoElevator(line,elevateCurrent)) P_ChangeSwitchTexture(line,0); break; // jff 1/29/98 end of added S1 linedef types //jff 1/29/98 added linedef types to fill all functions out so that // all possess SR, S1, WR, W1 types case 78: //jff 3/15/98 create texture change no motion type // Texture Change Only (Numeric) // 78 SR Change Texture/Type Only if (EV_DoChange(line,numChangeOnly)) P_ChangeSwitchTexture(line,1); break; case 176: // Raise Floor to shortest lower texture // 176 SR EV_DoFloor(raiseToTexture), CSW(1) if (EV_DoFloor(line,raiseToTexture)) P_ChangeSwitchTexture(line,1); break; case 177: // Raise Floor to shortest lower texture // 177 SR EV_DoFloor(lowerAndChange) if (EV_DoFloor(line,lowerAndChange)) P_ChangeSwitchTexture(line,1); break; case 178: // Raise Floor 512 // 178 SR EV_DoFloor(raiseFloor512) if (EV_DoFloor(line,raiseFloor512)) P_ChangeSwitchTexture(line,1); break; case 179: // Raise Floor 24 and change // 179 SR EV_DoFloor(raiseFloor24AndChange) if (EV_DoFloor(line,raiseFloor24AndChange)) P_ChangeSwitchTexture(line,1); break; case 180: // Raise Floor 24 // 180 SR EV_DoFloor(raiseFloor24) if (EV_DoFloor(line,raiseFloor24)) P_ChangeSwitchTexture(line,1); break; case 181: // Moving floor min n to max n // 181 SR EV_DoPlat(perpetualRaise,0) EV_DoPlat(line,perpetualRaise,0); P_ChangeSwitchTexture(line,1); break; case 182: // Stop Moving floor // 182 SR EV_DoPlat(perpetualRaise,0) EV_StopPlat(line); P_ChangeSwitchTexture(line,1); break; case 183: // Start fast crusher // 183 SR EV_DoCeiling(fastCrushAndRaise) if (EV_DoCeiling(line,fastCrushAndRaise)) P_ChangeSwitchTexture(line,1); break; case 184: // Start slow crusher // 184 SR EV_DoCeiling(crushAndRaise) if (EV_DoCeiling(line,crushAndRaise)) P_ChangeSwitchTexture(line,1); break; case 185: // Start slow silent crusher // 185 SR EV_DoCeiling(silentCrushAndRaise) if (EV_DoCeiling(line,silentCrushAndRaise)) P_ChangeSwitchTexture(line,1); break; case 186: // Raise ceiling, Lower floor // 186 SR EV_DoCeiling(raiseToHighest), EV_DoFloor(lowerFloortoLowest) if (EV_DoCeiling(line, raiseToHighest) || EV_DoFloor(line, lowerFloorToLowest)) P_ChangeSwitchTexture(line,1); break; case 187: // Lower floor and Crush // 187 SR EV_DoCeiling(lowerAndCrush) if (EV_DoCeiling(line, lowerAndCrush)) P_ChangeSwitchTexture(line,1); break; case 188: // Stop crusher // 188 SR EV_CeilingCrushStop() if (EV_CeilingCrushStop(line)) P_ChangeSwitchTexture(line,1); break; case 190: //jff 3/15/98 create texture change no motion type // Texture Change Only (Trigger) // 190 SR Change Texture/Type Only if (EV_DoChange(line,trigChangeOnly)) P_ChangeSwitchTexture(line,1); break; case 191: // Lower Pillar, Raise Donut // 191 SR EV_DoDonut() if (EV_DoDonut(line)) P_ChangeSwitchTexture(line,1); break; case 192: // Lights to brightest neighbor sector // 192 SR EV_LightTurnOn(0) EV_LightTurnOn(line,0); P_ChangeSwitchTexture(line,1); break; case 193: // Start Lights Strobing // 193 SR EV_StartLightStrobing() EV_StartLightStrobing(line); P_ChangeSwitchTexture(line,1); break; case 194: // Lights to Dimmest Near // 194 SR EV_TurnTagLightsOff() EV_TurnTagLightsOff(line); P_ChangeSwitchTexture(line,1); break; case 195: // Teleport // 195 SR EV_Teleport(side,thing) if (EV_Teleport(line,side,thing)) P_ChangeSwitchTexture(line,1); break; case 196: // Close Door, Open in 30 secs // 196 SR EV_DoDoor(close30ThenOpen) if (EV_DoDoor(line,close30ThenOpen)) P_ChangeSwitchTexture(line,1); break; case 205: // Lower ceiling to lowest surrounding ceiling // 205 SR EV_DoCeiling(lowerToLowest) if (EV_DoCeiling(line,lowerToLowest)) P_ChangeSwitchTexture(line,1); break; case 206: // Lower ceiling to highest surrounding floor // 206 SR EV_DoCeiling(lowerToMaxFloor) if (EV_DoCeiling(line,lowerToMaxFloor)) P_ChangeSwitchTexture(line,1); break; case 210: // killough 1/31/98: silent teleporter //jff 210 SR SilentTeleport if (EV_SilentTeleport(line, side, thing)) P_ChangeSwitchTexture(line,1); break; case 211: //jff 3/14/98 create instant toggle floor type // Toggle Floor Between C and F Instantly // 211 SR Toggle Floor Instant if (EV_DoPlat(line,toggleUpDn,0)) P_ChangeSwitchTexture(line,1); break; case 222: // Lower floor to next lowest floor // 222 SR Lower Floor To Nearest Floor if (EV_DoFloor(line,lowerFloorToNearest)) P_ChangeSwitchTexture(line,1); break; case 230: // Raise elevator next floor // 230 SR Raise Elevator next floor if (EV_DoElevator(line,elevateUp)) P_ChangeSwitchTexture(line,1); break; case 234: // Lower elevator next floor // 234 SR Lower Elevator next floor if (EV_DoElevator(line,elevateDown)) P_ChangeSwitchTexture(line,1); break; case 238: // Elevator to current floor // 238 SR Elevator to current floor if (EV_DoElevator(line,elevateCurrent)) P_ChangeSwitchTexture(line,1); break; case 258: // Build stairs, step 8 // 258 SR EV_BuildStairs(build8) if (EV_BuildStairs(line,build8)) P_ChangeSwitchTexture(line,1); break; case 259: // Build stairs, step 16 // 259 SR EV_BuildStairs(turbo16) if (EV_BuildStairs(line,turbo16)) P_ChangeSwitchTexture(line,1); break; // 1/29/98 jff end of added SR linedef types } break; // Buttons (retriggerable switches) case 42: // Close Door if (EV_DoDoor(line,close)) P_ChangeSwitchTexture(line,1); break; case 43: // Lower Ceiling to Floor if (EV_DoCeiling(line,lowerToFloor)) P_ChangeSwitchTexture(line,1); break; case 45: // Lower Floor to Surrounding floor height if (EV_DoFloor(line,lowerFloor)) P_ChangeSwitchTexture(line,1); break; case 60: // Lower Floor to Lowest if (EV_DoFloor(line,lowerFloorToLowest)) P_ChangeSwitchTexture(line,1); break; case 61: // Open Door if (EV_DoDoor(line,open)) P_ChangeSwitchTexture(line,1); break; case 62: // PlatDownWaitUpStay if (EV_DoPlat(line,downWaitUpStay,1)) P_ChangeSwitchTexture(line,1); break; case 63: // Raise Door if (EV_DoDoor(line,normal)) P_ChangeSwitchTexture(line,1); break; case 64: // Raise Floor to ceiling if (EV_DoFloor(line,raiseFloor)) P_ChangeSwitchTexture(line,1); break; case 66: // Raise Floor 24 and change texture if (EV_DoPlat(line,raiseAndChange,24)) P_ChangeSwitchTexture(line,1); break; case 67: // Raise Floor 32 and change texture if (EV_DoPlat(line,raiseAndChange,32)) P_ChangeSwitchTexture(line,1); break; case 65: // Raise Floor Crush if (EV_DoFloor(line,raiseFloorCrush)) P_ChangeSwitchTexture(line,1); break; case 68: // Raise Plat to next highest floor and change texture if (EV_DoPlat(line,raiseToNearestAndChange,0)) P_ChangeSwitchTexture(line,1); break; case 69: // Raise Floor to next highest floor if (EV_DoFloor(line, raiseFloorToNearest)) P_ChangeSwitchTexture(line,1); break; case 70: // Turbo Lower Floor if (EV_DoFloor(line,turboLower)) P_ChangeSwitchTexture(line,1); break; case 114: // Blazing Door Raise (faster than TURBO!) if (EV_DoDoor (line,blazeRaise)) P_ChangeSwitchTexture(line,1); break; case 115: // Blazing Door Open (faster than TURBO!) if (EV_DoDoor (line,blazeOpen)) P_ChangeSwitchTexture(line,1); break; case 116: // Blazing Door Close (faster than TURBO!) if (EV_DoDoor (line,blazeClose)) P_ChangeSwitchTexture(line,1); break; case 123: // Blazing PlatDownWaitUpStay if (EV_DoPlat(line,blazeDWUS,0)) P_ChangeSwitchTexture(line,1); break; case 132: // Raise Floor Turbo if (EV_DoFloor(line,raiseFloorTurbo)) P_ChangeSwitchTexture(line,1); break; case 99: // BlzOpenDoor BLUE case 134: // BlzOpenDoor RED case 136: // BlzOpenDoor YELLOW if (EV_DoLockedDoor (line,blazeOpen,thing)) P_ChangeSwitchTexture(line,1); break; case 138: // Light Turn On EV_LightTurnOn(line,255); P_ChangeSwitchTexture(line,1); break; case 139: // Light Turn Off EV_LightTurnOn(line,35); P_ChangeSwitchTexture(line,1); break; } return true; } Notice how the regular linedef types are within a switch/case construction, while generalized types are identified by range ("if line_special >= GenTypeBase" kinda deal). Then notice how it handles linefunc, using values extracted from the special used as a bitfield. Let's now look at one of these genlines, for example the generic floor: Spoiler // // EV_DoGenFloor() // // Handle generalized floor types // // Passed the line activating the generalized floor function // Returns true if a thinker is created // // jff 02/04/98 Added this routine (and file) to handle generalized // floor movers using bit fields in the line special type. // int EV_DoGenFloor ( line_t* line ) { int secnum; int rtn; boolean manual; sector_t* sec; floormove_t* floor; unsigned value = (unsigned)line->special - GenFloorBase; // parse the bit fields in the line's special type int Crsh = (value & FloorCrush) >> FloorCrushShift; int ChgT = (value & FloorChange) >> FloorChangeShift; int Targ = (value & FloorTarget) >> FloorTargetShift; int Dirn = (value & FloorDirection) >> FloorDirectionShift; int ChgM = (value & FloorModel) >> FloorModelShift; int Sped = (value & FloorSpeed) >> FloorSpeedShift; int Trig = (value & TriggerType) >> TriggerTypeShift; rtn = 0; // check if a manual trigger, if so do just the sector on the backside manual = false; if (Trig==PushOnce || Trig==PushMany) { if (!(sec = line->backsector)) return rtn; secnum = sec-sectors; manual = true; goto manual_floor; } secnum = -1; // if not manual do all sectors tagged the same as the line while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; manual_floor: // Do not start another function if floor already moving if (P_SectorActive(floor_special,sec)) { if (!manual) continue; else return rtn; } // new floor thinker rtn = 1; floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker); sec->floordata = floor; floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->crush = Crsh; floor->direction = Dirn? 1 : -1; floor->sector = sec; floor->texture = sec->floorpic; floor->newspecial = sec->special; //jff 3/14/98 transfer old special field too floor->oldspecial = sec->oldspecial; floor->type = genFloor; // set the speed of motion switch (Sped) { case SpeedSlow: floor->speed = FLOORSPEED; break; case SpeedNormal: floor->speed = FLOORSPEED*2; break; case SpeedFast: floor->speed = FLOORSPEED*4; break; case SpeedTurbo: floor->speed = FLOORSPEED*8; break; default: break; } // set the destination height switch(Targ) { case FtoHnF: floor->floordestheight = P_FindHighestFloorSurrounding(sec); break; case FtoLnF: floor->floordestheight = P_FindLowestFloorSurrounding(sec); break; case FtoNnF: floor->floordestheight = Dirn? P_FindNextHighestFloor(sec,sec->floorheight) : P_FindNextLowestFloor(sec,sec->floorheight); break; case FtoLnC: floor->floordestheight = P_FindLowestCeilingSurrounding(sec); break; case FtoC: floor->floordestheight = sec->ceilingheight; break; case FbyST: floor->floordestheight = (floor->sector->floorheight>>FRACBITS) + floor->direction * (P_FindShortestTextureAround(secnum)>>FRACBITS); if (floor->floordestheight>32000) //jff 3/13/98 prevent overflow floor->floordestheight=32000; // wraparound in floor height if (floor->floordestheight<-32000) floor->floordestheight=-32000; floor->floordestheight<<=FRACBITS; break; case Fby24: floor->floordestheight = floor->sector->floorheight + floor->direction * 24*FRACUNIT; break; case Fby32: floor->floordestheight = floor->sector->floorheight + floor->direction * 32*FRACUNIT; break; default: break; } // set texture/type change properties if (ChgT) // if a texture change is indicated { if (ChgM) // if a numeric model change { sector_t *sec; //jff 5/23/98 find model with ceiling at target height if target //is a ceiling type sec = (Targ==FtoLnC || Targ==FtoC)? P_FindModelCeilingSector(floor->floordestheight,secnum) : P_FindModelFloorSector(floor->floordestheight,secnum); if (sec) { floor->texture = sec->floorpic; switch(ChgT) { case FChgZero: // zero type floor->newspecial = 0; //jff 3/14/98 change old field too floor->oldspecial = 0; floor->type = genFloorChg0; break; case FChgTyp: // copy type floor->newspecial = sec->special; //jff 3/14/98 change old field too floor->oldspecial = sec->oldspecial; floor->type = genFloorChgT; break; case FChgTxt: // leave type be floor->type = genFloorChg; break; default: break; } } } else // else if a trigger model change { floor->texture = line->frontsector->floorpic; switch (ChgT) { case FChgZero: // zero type floor->newspecial = 0; //jff 3/14/98 change old field too floor->oldspecial = 0; floor->type = genFloorChg0; break; case FChgTyp: // copy type floor->newspecial = line->frontsector->special; //jff 3/14/98 change old field too floor->oldspecial = line->frontsector->oldspecial; floor->type = genFloorChgT; break; case FChgTxt: // leave type be floor->type = genFloorChg; default: break; } } } if (manual) return rtn; } return rtn;} Again, it uses the line special as a bit field and extracts parameters from it. Note how the subsequents ifs and switches use the extracted parameters rather than the line special value. Compare with the regular floor function: Spoiler // // EV_DoFloor() // // Handle regular and extended floor types // // Passed the line that activated the floor and the type of floor motion // Returns true if a thinker was created. // int EV_DoFloor ( line_t* line, floor_e floortype ) { int secnum; int rtn; int i; sector_t* sec; floormove_t* floor; secnum = -1; rtn = 0; // move all floors with the same tag as the linedef while ((secnum = P_FindSectorFromLineTag(line,secnum)) >= 0) { sec = §ors[secnum]; // Don't start a second thinker on the same floor if (P_SectorActive(floor_special,sec)) //jff 2/23/98 continue; // new floor thinker rtn = 1; floor = Z_Malloc (sizeof(*floor), PU_LEVSPEC, 0); P_AddThinker (&floor->thinker); sec->floordata = floor; //jff 2/22/98 floor->thinker.function.acp1 = (actionf_p1) T_MoveFloor; floor->type = floortype; floor->crush = false; // setup the thinker according to the linedef type switch(floortype) { case lowerFloor: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindHighestFloorSurrounding(sec); break; //jff 02/03/30 support lowering floor by 24 absolute case lowerFloor24: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; break; //jff 02/03/30 support lowering floor by 32 absolute (fast) case lowerFloor32Turbo: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED*4; floor->floordestheight = floor->sector->floorheight + 32 * FRACUNIT; break; case lowerFloorToLowest: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestFloorSurrounding(sec); break; //jff 02/03/30 support lowering floor to next lowest floor case lowerFloorToNearest: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindNextLowestFloor(sec,floor->sector->floorheight); break; case turboLower: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED * 4; floor->floordestheight = P_FindHighestFloorSurrounding(sec); if (floor->floordestheight != sec->floorheight) floor->floordestheight += 8*FRACUNIT; break; case raiseFloorCrush: floor->crush = true; case raiseFloor: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestCeilingSurrounding(sec); if (floor->floordestheight > sec->ceilingheight) floor->floordestheight = sec->ceilingheight; floor->floordestheight -= (8*FRACUNIT)*(floortype == raiseFloorCrush); break; case raiseFloorTurbo: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED*4; floor->floordestheight = P_FindNextHighestFloor(sec,sec->floorheight); break; case raiseFloorToNearest: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindNextHighestFloor(sec,sec->floorheight); break; case raiseFloor24: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; break; // jff 2/03/30 support straight raise by 32 (fast) case raiseFloor32Turbo: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED*4; floor->floordestheight = floor->sector->floorheight + 32 * FRACUNIT; break; case raiseFloor512: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 512 * FRACUNIT; break; case raiseFloor24AndChange: floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = floor->sector->floorheight + 24 * FRACUNIT; sec->floorpic = line->frontsector->floorpic; sec->special = line->frontsector->special; //jff 3/14/98 transfer both old and new special sec->oldspecial = line->frontsector->oldspecial; break; case raiseToTexture: { int minsize = MAXINT; side_t* side; if (!compatibility) minsize = 32000<<FRACBITS; //jff 3/13/98 no ovf floor->direction = 1; floor->sector = sec; floor->speed = FLOORSPEED; for (i = 0; i < sec->linecount; i++) { if (twoSided (secnum, i) ) { side = getSide(secnum,i,0); // jff 8/14/98 don't scan texture 0, its not real if (side->bottomtexture > 0 || (compatibility && !side->bottomtexture)) if (textureheight[side->bottomtexture] < minsize) minsize = textureheight[side->bottomtexture]; side = getSide(secnum,i,1); // jff 8/14/98 don't scan texture 0, its not real if (side->bottomtexture > 0 || (compatibility && !side->bottomtexture)) if (textureheight[side->bottomtexture] < minsize) minsize = textureheight[side->bottomtexture]; } } if (compatibility) floor->floordestheight = floor->sector->floorheight + minsize; else { floor->floordestheight = (floor->sector->floorheight>>FRACBITS) + (minsize>>FRACBITS); if (floor->floordestheight>32000) floor->floordestheight = 32000; //jff 3/13/98 do not floor->floordestheight<<=FRACBITS; // allow height overflow } } break; case lowerAndChange: floor->direction = -1; floor->sector = sec; floor->speed = FLOORSPEED; floor->floordestheight = P_FindLowestFloorSurrounding(sec); floor->texture = sec->floorpic; // jff 1/24/98 make sure floor->newspecial gets initialized // in case no surrounding sector is at floordestheight // --> should not affect compatibility <-- floor->newspecial = sec->special; //jff 3/14/98 transfer both old and new special floor->oldspecial = sec->oldspecial; //jff 5/23/98 use model subroutine to unify fixes and handling sec = P_FindModelFloorSector(floor->floordestheight,sec-sectors); if (sec) { floor->texture = sec->floorpic; floor->newspecial = sec->special; //jff 3/14/98 transfer both old and new special floor->oldspecial = sec->oldspecial; } break; default: break; } } return rtn; } Note the comment ("setup the thinker according to the linedef type") and all the redundancy in the switch/case block. 0 Share this post Link to post
purist Posted November 4, 2014 Couldn't you put your music in a seperate optional WAD? 0 Share this post Link to post
MB_is_me Posted November 4, 2014 purist said:Couldn't you put your music in a seperate optional WAD? I hadn't thought about it, but music isn't the main focus anyway. I think I'll just stick to ZDoom for the time being. 0 Share this post Link to post