Jump to content
Search In
  • More options...
Find results that contain...
Find results in...

SaladBadger

Members
  • Content count

    1409
  • Joined

  • Last visited

Everything posted by SaladBadger

  1. SaladBadger

    It´s time to give Decino Caco for best Doom player 2021

    The unity port has deathmatch, and explicitly introduced a new mode relatively recently which is like altdeath but makes weapons stay, long considered the one major weakness of altdeath rules. Maybe it doesn't on some platforms... Decino freely admits he isn't the best doom player. With regards to his recent No Chance run, he mentioned that UV play was explicitly reserved for the doom gods and mentioned a number of the players who took the credit for clearing that seemingly impossible challenge, and an 86 run death compilation certainly gives context for where he lies. He's a good and entertaining player, but I don't think we need to ascend him to godhood.
  2. https://github.com/InsanityBringer/Doom05RE I've finally gotten my Doom 0.5 RE project to a point where it's basically feature complete, so I've created a repo for it. The port I've developed is extremely barebones, and mostly exists just to verify that things are functional, but it does the job. I dunno what else to do with this. My main intentions are to write an article similar to Fabien's article on how the BSP based Doom renderer works, and try to delve deep into why the original recursive algorithm was so slow. Additionally, I'd like to also possibly port it on top of Chocolate Doom's gameplay code and see if it would be possible to make it work with features like Build-like moving sectors. In practice, any serious port would be better off adopting Eternity like portals and clever use of portals and polyobjects for complicated moving things, but it might be neat to see what was originally possible. Beyond that, there's not much of interest in an engine derived from alpha-quality game code, beyond being a time capsule of what Doom's code was once like.
  3. SaladBadger

    Doom 0.5 reverse engineering project

    For whatever it's worth, I had some time so I started cleaning up the code. There's a lot of super raw straight-from-the-decompiler-and-then-cleaned-up-to-function-but-not-very-pretty code in the thing, which was bothering me, so I went ahead and used the debugging information present in the executable to add accurate stack variable names where I can and also went ahead and changed while loops back to for loops when they were originally fors and so on. I've done this for the playsim only so far, but I want to do it to all the game's modules, and 0.5 is the only version where we can get such accurate information. One thing I'm a little on the fence about is whether or not I should heavily revise functions to match what they look like in the actual doom source. compare my version of EV_VerticalDoor with the one in the official Doom source release. The flow for things how it handles a door sector already having a thinker is somewhat different, and this can be noticed with a lot of these funcs. I kinda want to try reconstructing the source code as closely as possible, but it's a lot of work for little gain. I'm also still eyeballing getting this working with Open Watcom or a similar DOS compiler because I can't make this the "definitive" source because certain bugs would cause segfaults on modern operating systems if I kept them. Ah well, at least the gameplay logic and rendering seem accurate, accurate enough to run the original demos, for whatever it's worth. At least they desync in the same way as the original.
  4. WRT heretic being forked, while the engine code does mostly resemble 1.2, it's weirdly interesting to note that the texture mapper in heretic more strongly resembles the PRB one, using a large unrolled loop with a table of branches into it to draw less pixels, rather than the self modifying code that Doom itself uses. PRB's debug symbols explicitly mention linear.asm so it's probably the same source, just pruned of low detail drawers. I suspect id kept around a lot of the mode 13h stuff used in the PRB and the heretic source ended up making use of it.
  5. SaladBadger

    EXE hacking

    Have you gotten any of the pre-PRB versions in leloader working before? I worry some they might be tricky since the timer interrupt does a lot of work in them, such as collecting user input and advancing playercmdframe. I suspect that's all emulatable with some work, but it makes things trickier
  6. SaladBadger

    EXE hacking

    That was my assumption for a while, but I eventually realized I wouldn't get sane values at all unless I always masked out the highest bit. Like I had my program set to ignore any values where it was set and then nothing loaded at all... At the moment I'm just throwing out the first table because I can't make heads or tails of why the values are the way they are. Everything else seems to work so far, I'm analyzing a relocated flat binary right now in ghidra and there's no obvious issues.. I'll compare the output against your DosBox capture and see if I can determine where anomalies are rising. edit jesus i'm a fucking idiot the anomalous values were coming from the FPU emulator executable, which I process for... some reason? (actually I started processing it just to ensure my assumptions are correct) everything is fine please proceed as normal. Don't do this when you're running on no sleep, I guess is my moral of tonight. and yeah, with these changes, I mostly match the dump. There's some exceptions, since the C CRT and the like have started up at the time of your dump, some values in memory have changed, but my relocated values in the code data all seem to match. Here's my version of MTLoad for the night. It will generate a simple address map when there is sufficient information, and you can now specify a base address with the -b command line parameter. MTLoad.zip
  7. SaladBadger

    EXE hacking

    Ah heh, I had missed that since I've been buried in my output. I resolved the issue of the missing texture mappers, I was just being dense. The texture mapper fixups are present in the table with the offset value of 1, but they appear before the function fixups, creating a discontinuity. For now, I'm trying to apply values while ignoring the flagged entries because I don't get them. They're there so they probably have a meaning, but I can't comprehend what it is yet.
  8. SaladBadger

    EXE hacking

    thank you so much for the research xttl. The lowest fixup records are giving me confusing results, usually not directly aligning with a memory access, but later ones seem to start being more sensible. Against my 0-based flat executable, I'll see a record against 000079A7 and then I poke at 000079A5 in ghidra and there's a cmp ebx, dword ptr [#0003a1d0] (3b 1d d0 a1 03 00) which corresponds directly. I'll get fixup support implemented tonight, and hopefully I can dump my new sources with the MAP generator and fixup support added tomorrow. One minor issue I'm still yet to track down is that the texture mapping function tables (the alpha texture mappers in all builds I've studied is much like the heretic one, essentially using a huge unrolled loop with jumps into it depending on how many pixels need to be drawn. I think it evolved directly into the heretic one actually, from my work with 0.5) don't appear to show up in the information, but I may just be being dense parsing my own output. The ASM texture mappers seem slightly enigmatic to me since they don't register in the symbol tables at all, but I'm sure I'm just missing something obvious. edit: I think the second value is just an offset applied to the values, kinda. The first int16 is the amount of records, the second is added to the read values * 32768. This has had successful effects for me. I'm now really curious what the highest bit of the records indicate. edit (god here we go again) 2: Something definitely is fishy with the values that have the high bit set, masking out the highest bit doesn't seem to create coherent values. All without the high bit set correspond directly to memory addresses in the code. I'll spend a little more time analyzing it.
  9. SaladBadger

    EXE hacking

    Oh, the debug information being offset to the beginning of the MT would explain why all the values were so confusing, now it suddenly makes a lot more sense. I was exploring some of the sub-tables. The first just seems to be basic information, the second seems to be type information, with structure dumps, and the third seems to be the delicious symbol data, containing information on all functions, their stack variables, and heap values and their offsets. I've been working on figuring out this format, and I can extract stack values from it at the moment, but I need to validate that I understood things properly still. Each entry has a header defining the offset in memory where the heap variables will be loaded, as well as it's name. There's some other bits in there I'm still figuring out. Heap symbols always seem to start with a 0x05, followed by a 4-byte value which defines the offset from the offset specified in the header. Following that is two unknown bytes. My guess is that the first or possibly both define type information, as they seem equal across things with the same type (ie: it's 0x14 for all the s_ variables that define monster states, but different for something that isn't a s_ variable.). Following the two bytes, there's one byte that contains the length of the symbol string, followed of course by the symbol chars. I'll explore this more today and work on getting extracting this information working in my MT load program. Edit: Having some good success here. A couple of my assumptions were wrong, but I've been able to correct them and get something that works. Here's the first 100 symbol table entries as reported by my MTLoad: https://pastebin.com/04BTSKu1 Edit 2: Okay, yeah, some tweaks later, it loads the entire thing just fine (loading from pointer 2 in the table to pointer 3). The symbol information is basically a table of "commands", here's what I determined: Command identifiers are specified by a single byte, followed by the payload. Here's the payloads: All strings are an array of char, with the length specified by a preceding byte. "String" will be encoded as 06 53 74 72 69 6E 67 cmd 0: Defines module int32_t codesize; //Size of code in bytes int32_t codestart; //Offset of the code str name; cmd 1: Defines function int32_t offset; //Absolute offset from the base address int16_t typeid; //Type id of return type, I think int8_t b1: //unknown int32_t stacksize; //assumption int32_t dw1; //unknwon str name; cmd 2: Ends block. No payload. After a function or module. cmd 3: Specifies that following variables are relative to the specified offset. int32_t offset; cmd 4: Specifies that following variables are relative to the stack, or something like that. Used for parameters. cmd 5: Variable. Can be relative to the stack or a heap pointer from the previous two commands int32_t offset; int16_t typeid; str name; cmd 15: Unknown. Usually before heap variables int8_t b1; //always 0 in Doom 0.2, I think cmd 23: Unknown. Usually before heap variables int8_t b1; //always 0 in Doom 0.2, I think cmd 64: Register variable. Can be used for args, but args are always passed by stack. Args specified this way appear to be MOVed into a register at the start. int8_t b1; //Probably identifies the register int16_t typeid; str name; I'm not 100% sure I can create a coherent .MAP file, mostly due to the weird sectioning scheme compared to other executable formats like PE. Creating IDC should work, if there's some documentation on how it works. But creating some sort of table to get absolute addresses in memory should absolutely be possible. edit 3: Actually looking at the heretic/hexen .MAPs it shouldn't be impossible, but lacking any further information about how things go I'm kinda forced to just give everything the same selector. It's not really a big deal, I think? But it looks strange. So far as I can tell, the memory bits in the executable have absolutely no way of distinguishing between TEXT and DATA sections, everything's.. just.. memory... There's nothing that even resembles a BSS section, beyond the bit in the header that specifies how large the program's address space is. ah, let's just try this for now. I just gave all heap vars a selector of 0001 for now. Why not... It should be functional though, and it's been helpful for my own use.
  10. SaladBadger

    EXE hacking

    Segmented would be a little weird for a 32-bit program (32-bit x86 programs are segmented via a much different scheme), but I'm really not sure. The only thing I see in the fixup table is a pile of increasing 16-bit numbers that eventually wrap over at some point. It doesn't correspond to fixup records I've seen in other executables, but at the same time I've never pursued it too closely. I need to study things closer.
  11. SaladBadger

    EXE hacking

    Well I mean, if you actually read the large post you quoted and extracted context, you'll realize I'm not working with the final version of doom, or on savegame buffers, but eh. Anyways, it turns out my assumptions were right, all MT executables do have a number of blocks that are basically the same format, and they seem to be stored all the way up to the end of the executable. I attached a simple program that can read Doom 0.2 and Doom 0.3 and map out a flat executable version of it. It's not perfect, since I don't understand the fixup entries yet (doesn't 16 bits per entry seem a little.. small for programs with 32-bit address spaces? I must be missing something), so they're all mapped at 0 which causes conflicts (IE writing to VGA at 0xA0000), but I've been able to map flat executables of 0.2 and 0.3 in Ghidra and they should work in IDA just fine. All the initialized variables appear to be in the right place and everything. This is real nice, because I've been wanting to see how Alpha 0.3 varies from the tech demo, and the later 0.4 release. ed: reupload because of a mistake MTLoad.zip
  12. SaladBadger

    EXE hacking

    so I've been trying to complete xttl's work on the Alpha 0.2 and 0.3 format since I'd like to complete RE of them, but my crude way of mapping them wasn't working out well. I feel like I'm close, so freaking close, but it's not 100% falling in place. Here's my estimate of the header right now: 002 dwcodestart.: 0x000012cc (4812) //this value is dwrelocsize + wheadersize 006 dwrelocsize.: 0x00001292 (4754) 00a dwdatasize..: 0x0003e573 (255347) //in memory 00e dwstackptr..: 0x0003fdac (261548) //this value is dwdatasize + dwstacksize + 1. Extremely wild guess atm. Doesn't 100% make sense 012 unknown5....: 0x00000000 (0) 016 word16......: 0x0000 (0) 018 wheadersize.: 0x003a (58) //3a in both Doom 0.2 and Doom 0.3 01a dwstacksize.: 0x00001838 (6200) //131072 in Doom 0.3 01e unknown9....: 0x00000000 (0) 022 dword22.....: 0x00000000 (0) 026 dwcodesize..: 0x0000e4a7 (58535) 02a unknown12...: 0x00000000 (0) 02e unknown13...: 0x00000000 (0) 032 dwmtsize....: 0x0000f773 (63347) 036 dwdbgsize...: 0x0001abf5 (109557) 03a unknown16...: 0x000004ad (1197) From the bits of data I've extracted so far, I can throw my program at the Doom 0.2 or Doom 0.3 executables and correctly locate the code section and work through that. The code section starts with a small sub-header of 3 dwords. The second is always 1, and the third is always 0, and then there's the db goto =main jump. The most convincing value is the first one, which is nearly 3 times larger in 0.3, because Doom 0.3 has significantly more code than 0.2, but it's not quite enough to get to the data section, and the amount it's not enough varies across the two executables. This is frustrating because I poked at the data section, and I can see how it's assigning default values of memory to the program's address space, but I can't get that final piece of the puzzle, what actually locates it to work, and that's frustrating. I can hardcode it and get the 0-based flat executables I want, but I want to understand damnit. Would also like to be able to understand the relocation data. I have to assume the relocation data is sandwiched between the header and the code section. EDIT: AGH, why's this always happen right after I make the post explaining how I can't figure it out? I figured it out. I think. There is no separation between "code sections" and "data sections", so far as I can tell so far. Instead, there's one big unified block that puts bytes into memory. From the start of the code section up to the end of the MT file, a number of blocks are stored. The blocks have a simple format: int blocksize; //size of the block int unknown; //always 1 to the best of my knowledge, unknown purpose int address; //where in the 0-based address space the bytes will be placed uint8_t data[blocksize]; //the data to read into memory This should resolve every lingering problem I've had so far. Fingers crossed...
  13. SaladBadger

    Raze 1.0.0 Has Been Released!

    a couple of people, me included, have had success working around the visual corruption bug by enabling 4x MSAA. No idea why that works..
  14. image.png.bdfdb4fe95e843607551668f4c35c3fe.png

    I've been a little inspired by the "weirdest doom source port" thread so I'm trying to port the simplest known version of Doom to a platform that is absolutely, positively not suited for running such a game, but is technically capable of doing so.

     

    A platform where the only scalar type is a 64-bit double, there's only extremely limited string support, no heap allocations, file IO only works one byte at a time from a specific file, and so on... I'm surprised I've gotten this far, and I know the entire game, hell, all of the final version of Doom could be run in this platform.

  15. I mean, I hate to be that guy, especially since the author has tragically passed away (RIP), but that doesn't really count either because it's nowhere near complete. If it was, then I'd gladly accept it as one of the weirder languages used for a Doom port. I think in general there's just not a lot of ports to non-C like languages because it's a lot of work for little gain. As a bored side project I've been considering doing a port to C#, but it's just following in the footsteps of Mocha Doom, with some additional conveniences that Java doesn't have. I think there's also been some attempts at porting it to Rust, which does implicate some architectural changes due to Rust's heavy focus on memory safety.
  16. I experienced the same bug in Chocolate Descent, when I debugged it with RenderDoc what I noticed is that Discord was overwriting the texture bound at GL_TEXTURE0 with its new framebuffer texture, so I added code to rebind it before drawing the framebuffer and it fixed the problem for everyone who's ever reported it to me. I don't know why discord rebinds GL_TEXTURE0 and then fails to restore it, but it works? Not like it's a huge perf penalty or anything either, many games would already be doing at the very least one bind per frame...
  17. SaladBadger

    To everyone who has played on only UV play Nightmare

    I think the biggest barrier to changing monster spawns based on difficulty is that it opens a gigantic can of worms with regards to on-the-fly difficulty changing, a feature in 2016 and Eternal, and for that record almost all modern games... The only Doom game to have changed spawns based on difficulty and the ability to change on the fly was Doom 3, and it wasn't particularly well done. Damage traits would change normally, but spawns wouldn't. It's also more design work to set up, compared to adjusting AI traits and the like
  18. SaladBadger

    PsyDoom 0.7.4 - PSX Doom port (reverse engineered) for PC

    Great success! It seems to work perfectly now. I checked with MSAA on and off and both seem to work just fine.
  19. SaladBadger

    PsyDoom 0.7.4 - PSX Doom port (reverse engineered) for PC

    link since large screenshot I did a couple of tests. At the usual resolutions I run windowed old games at (1280x960 and 1920x1080), when turning off 4x MSAA, the game would simply become a seizurefest, sometimes rendering black, sometimes rendering a perfectly normal frame, so I tried some other resolutions, like fullscreen 2560x1440, which produced the exciting new artifacting that was seen in the screenshot above. This is definitely more what I would think of with a sync bug.
  20. SaladBadger

    PsyDoom 0.7.4 - PSX Doom port (reverse engineered) for PC

    Regrettably not quite out of the woods on my machine, with a Radeon RX 580. I think you're on the right track though, occasionally a perfectly normal view flashes through the corruption. To be completely honest, I can't 100% rule out a problem on my end, but all other Vulkan programs I can try ATM, such as Doom 2016 or GZDoom all seem to work fine, so I'm not 100% sure. Hopefully the test hardware can reveal something...
  21. SaladBadger

    PsyDoom 0.7.4 - PSX Doom port (reverse engineered) for PC

    It works out of the box now, still framebuffer corruption, though. Though apparently it works on other AMD hardware, from fenderc's post? that's interesting.
  22. SaladBadger

    PsyDoom 0.7.4 - PSX Doom port (reverse engineered) for PC

    TBH there's two traits to the corruption that make me wonder if it's a side effect of me expanding the block size in the allocator to make it work in the first place. The two things I've noticed are that if you expand the canvas, like 1920x1080 here, there are some blocks of the screen that are perfectly fine, and there's also other odd traits like brown colors "winning" over the corruption
  23. SaladBadger

    PsyDoom 0.7.4 - PSX Doom port (reverse engineered) for PC

    Sorry for the double post, but I'll stick this in a different post because it's a different bug: the idcloak cheat doesn't appear to work properly for AMBUSH monsters, they'll still see you if they hear you shoot.
  24. SaladBadger

    PsyDoom 0.7.4 - PSX Doom port (reverse engineered) for PC

    I built it on my AMD machine, and got this Assert failure raised from here when I tried running it: The minimum alignment reported from getMinAlignment() on my machine is 4096, but the desired alignment is 65536. Confusing, since that comes out of the vkGetImageMemoryRequirements call. ed: looking at the code further, the 4096 is a constant on your end. I'm guessing AMD's alignment traits are too much for that. also weird. From further experimentation, they can vary wildly. 65536 is only what the dummy texture created at the start gets, I'm also getting 131072 and the like after bumping up the constant. (yet another edit: I think the alignment traits are to put it on a boundary that's the size of the required image data, rounded to the next power of 2 if it doesn't exactly fall on one, so it can get arbitrarily large... Definitely not a good idea to rely on a fixed alignment here...) ed2: the results of bumping that constant up to 131072 are certainly exciting and interesting: But it's fine when the menu is fading in and out? Still confusing. Switching to the classic renderer works fine.
  25. SaladBadger

    Duke Nukem 3D's Build Engine trickery

    Duke 3D is weird like that. It's designed to look like a real place, but it still remains very abstract and strange when you apply logic to it. Some of it is engine limits, with things like why the freeway level is just a small span of road, and some of it's weird design decisions like this carpeted bathroom with a sofa, but somehow it still remains memorable to me, so I guess they did something right.
×