foone,
@foone@digipres.club avatar

the best thing about ghidra is that no matter which version you're using, setting equates sometimes just doesn't work, but if you google it, you only find several bug reports which basically say "equates don't work" and then it's "closed, fixed in X.Y.Z" and that's a version you're upgraded way past

foone,
@foone@digipres.club avatar

port_out(0x3c4,0xf02);

I SO WANT TO EQUATE 0x3C4 TO THE VGA SEQUENCER INDEX REGISTER BUT I CAN'T

foone,
@foone@digipres.club avatar

the weird thing is the equates table says it's been set, says there's a reference to it at that address, but if I go to that address, there's nothing. just 0x3c4

foone,
@foone@digipres.club avatar

OH GOODY I found a mistake in OSDEV
their docs on the PC gameport are incorrect

foone,
@foone@digipres.club avatar

and I can't rename some local variables either!?

foone,
@foone@digipres.club avatar

what the fuck, ghidra?

dougall,
@dougall@mastodon.social avatar

@foone FWIW, I believe in IDA this kind of thing mostly happens because they want to attach the new name to something in the assembly code, so when the decompiler has introduced the variable, it's often not clear what it should be attached to, and things get weird and broken.

foone,
@foone@digipres.club avatar

@dougall yeah I've had that happen. Not here, though. The variable it can't rename is just a standard register

foone,
@foone@digipres.club avatar

okay I've fixed OSDEV:
https://wiki.osdev.org/Game_port

They had the introduction of the gameport listed as "the PCjr" (it's from 1981, the PCjr came out in 1984... and didn't even have this gameport connector!) but more importantly, they had the order of the joystick axises wrong.

MishaVanMollusq,
@MishaVanMollusq@sfba.social avatar

@foone just has a vision of you cloning an original IBM PC .
Only one of the cloning methods used a 3D printer

foone,
@foone@digipres.club avatar

and the IBM Game Control Adapter is mentioned in the August 1981 IBM PC Technical Reference, so IBM clearly had the gameport ready at day one of the IBM PC, even if it was an optional add-in.

foone,
@foone@digipres.club avatar

mind you, on the IBM PC, just about everything is an optional add-in. You get a keyboard and a cassette port for free: you want graphics/text, floppies, hard drives, serial/parallel ports? that's extra.

sundhaug92,
@sundhaug92@mastodon.social avatar

@foone Wasn't graphics/text something you had to get but you could choose which one?

Infoseepage,
@Infoseepage@mastodon.social avatar

@foone And ram. Only 16 or 64K on the motherboard from the factory. You want 640K? That is more add-on cards too.

foone,
@foone@digipres.club avatar

@Infoseepage yup! my own 5150 has the max 640, thanks to a AST SixPakPlus

Infoseepage,
@Infoseepage@mastodon.social avatar

@foone Now THAT is a combo card!

My first in the house computer was a 386, but I remember the days of not having enough slots/resources and having to fiddle with way too many jumpers/dip switches to get it to all play nice.

wuffish,
@wuffish@mastodon.social avatar

@foone The best option, IMHO. Integrating the drive controllers... eh, okay, but other things, it's nice to have them separate. The sound chip on my current board started making Dalek mating calls one day, so I had to disable it, plugged in an Audigy 5/Rx. Been having issues with the two 8TB USB 3.0 drives connected, and might need a new card for that, but I'm out of PCIe slots.

flobo,

@foone Wait, the default was cassette and not floppy ?

foone,
@foone@digipres.club avatar

@flobo yup!

foone,
@foone@digipres.club avatar

god. Duke Nukem 1 has so much copy-pasted code.
Like, there's a ton of hint dialog boxes like "You need the key to open this door!" or "you get more points if you catch the balloon"

you'd think they'd just have ShowMessage() and pass it a different string, but nope. it's a different function.

beeoproblem,
@beeoproblem@mastodon.gamedev.place avatar

@foone when I see stuff like that in really old code I always wonder if it's the bad kind of laziness or if there's some really fucked up restriction they had to work around that drove them to write code that way.

Like writing it the sane way would cause some exceptionally slow memory access or long jump or whatever. Or a crappy compiler or linker would put the string in the wrong place or something...

qkslvrwolf,
@qkslvrwolf@mastodon.social avatar

@foone want Duke em largely built by one kid?

Wouldn't be surprised if it was a " good at math but not software" situation

foone,
@foone@digipres.club avatar

@qkslvrwolf Mainly by Todd Replogle (who was 22) with some hints from John Carmack.

sparrows,
@sparrows@calamity.world avatar

@foone I was bracing for it to be something like "They call it with a copy-pasted string instead of a variable for all the identical messages."

I was not prepared for the truth.

alys,

@foone going to bookmark this for the next time i'm feeling bad about my game jam code.

dalias,
@dalias@hachyderm.io avatar

@foone At least it's their own artisnal c&p'd code rather than c&p'd from SO or c&p'd and disguised by Copylot...

foone,
@foone@digipres.club avatar

@dalias yeah, they only stole the graphics, not the code!

evilspoons,
@evilspoons@mastodon.social avatar

@foone I can't help but wonder if this is some extremely primitive and/or attempt at optimization.

foone,
@foone@digipres.club avatar

LEARN TO WRITE REUSABLE FUNCTIONS

alanbrookland,

@foone I do, in fact, need_robohand

Miaourt,
@Miaourt@raru.re avatar

@foone NEVER

darkling,
@darkling@mstdn.social avatar

@foone I bet you it's a compiler macro in the original source.

foone,
@foone@digipres.club avatar

@darkling I really hope so

darkling,
@darkling@mstdn.social avatar

@foone Assuming C, it's a bit weird. You'd have to do something like:

DEF_DBOX(restore_which_game, "Restore which game?")

void some_func(...) {

int value = USE_DBOX(restore_which_game);
}

Not sure how that's any better than just writing a sane dbox function.

hdfssk,

@foone dialog_box_eat_turkey, some of my finest work

foone,
@foone@digipres.club avatar

interesting. there's 12 hint-variables which are used to make sure you don't get hinted for something you've used before.

One of them is still maintained, but not used. So there must have been another hintable thing that got dropped

foone,
@foone@digipres.club avatar

although I'm looking at DN1, episode 1. Maybe it does do something in DN1E2 or DN1E3?

foone,
@foone@digipres.club avatar

because yeah this was also the era where you'd have 3 separate executables for 3 separate episodes of the same game

foone,
@foone@digipres.club avatar

like, it has a function that loops through all 16 color indices and sets them to black. it takes one parameters, which tells it how long to wait between each color is set, so it'll fade slowly to black, instead of being instant.

there's also an identical function that does the same, but sets it to white, instead.

foone,
@foone@digipres.club avatar

so instead of fade_screen(COLOR_BLACK) and fade_screen(COLOR_WHITE), it's two separate functions!

darkling,
@darkling@mstdn.social avatar

@foone If it was fading each index (slowly changing to the target, rather than just switching one palette entry at a time), then I could understand making it two functions, as it probably makes the code a bit simpler.

Of course, if it's just:

for(int i=0; i<16; i++) { palette[i] = 0; }

then separate functions are less attractive.

Who said old code was more efficient? :blobcatwink:

sundhaug92,
@sundhaug92@mastodon.social avatar

@foone Extreme inlining?

foone,
@foone@digipres.club avatar

@sundhaug92 they're not inlined!

kawa,
@kawa@mas.to avatar

@foone If you think DN1 is badly written, don't look at DN3D's menu screen code.

foone,
@foone@digipres.club avatar

naturally instead of a function like "adjust_duke_health(n)" there's a "give_duke_one_health_point" function

foone,
@foone@digipres.club avatar

todd replogle: look, I know programmers who use function parameters and data-driven design, and they're all cowards

darkling,
@darkling@mstdn.social avatar

@foone If you're not explicitly setting the registers and then using JMP, you're just wasting your time, and mine.

foone,
@foone@digipres.club avatar

The game starts with these two screens.
There's a function to draw Dr Proton, a different function to draw Duke Nukem, a function to draw Proton's text, and another function to draw Duke's

image/png

foone,
@foone@digipres.club avatar

the only difference between the "draw proton"/"draw duke" functions is what base address they draw from.

YOU CAN PASS ADDRESSES TO FUNCTIONS, TODD

foone,
@foone@digipres.club avatar

there are 5 of these functions in total.
Exactly identical, except they point to different buffers for different fullscreen images

roughnight,
@roughnight@mastodon.gamedev.place avatar

@foone pls show me the code of a modern AAA where is no tape or glue to be found :D

foone,
@foone@digipres.club avatar

oh god please don't tell me there's a hidden cheat code that's been missed for... 32 years?

labria,
@labria@social.yeschenko.com avatar

@foone that would be worth all the rage :)

foone,
@foone@digipres.club avatar

Nope! it's known, it's just slightly mis-documented and tricky to pull off.

If you press the fire button (not alt!) and release F6 on the main menu, after launching the game with "dn1 asp", you can play the demo level

foone,
@foone@digipres.club avatar

there is some extra code for checking the command line for another code, which I think would be "dn1 asp g" but I'm not sure what it does. something in the keyboard handler, it seems?

foone,
@foone@digipres.club avatar

okay so the unused hint is supposedly for the teleporter, according to the modding wiki and cross-referencing with the load_game function:
https://moddingwiki.shikadi.net/wiki/Duke_1_Savegame_Format

foone,
@foone@digipres.club avatar

getting closer to my goal. I figured out where it sets the variable for duke's backflipping, at 3000:2499.
0 = not backflipping
1 = left
2 = right

joephillips,
@joephillips@mastodon.social avatar

@foone I never know what you’re tootin about but I always like it

whilefun,

@foone i didn't realize how much i wanted to know all of this goofy behind the scenes DN1 lore until right now

foone,
@foone@digipres.club avatar

Wait wait wait. Either I'm completely misremembering a key part of how one of my favorite dos games works, or this save system makes no sense

foone,
@foone@digipres.club avatar

nope, not misremembering. See this message? You can only save games in the between-level hallways.

foone,
@foone@digipres.club avatar

so why in the fuck does the game save your position in the level and the camera position?

You'll always be in the hallway! you can't be anywhere else!

foone,
@foone@digipres.club avatar

and apparently the game ignores the camera position, but not the player position, which is relative to the player position that it didn't load.

foone,
@foone@digipres.club avatar

so... if you set up a savegame so it puts you in an actual level instead of a hallway, does it load properly?

foone,
@foone@digipres.club avatar

yep. you can have it load you right into a level. you can't save a game there, but you can restore one.

weird.

foone,
@foone@digipres.club avatar

I was gonna say that it would make sense if they originally had a save system that let you save anywhere, but not exactly: some stuff is missing that'd let you have a real mid-level save.
it doesn't save your keys or if you have the access card, which means you could be trapped after reloading a mid-level save

foone,
@foone@digipres.club avatar

but yeah: despite it technically being visible for 32 years, I never noticed that the game doesn't just save which hallway you're in.
It saves where the duke is relative to the hallway, even if not his actual position.
I just loaded two different saves of Duke in the first hallway. Didn't press any other buttons... but he appears in different places!

image/png

foone,
@foone@digipres.club avatar

guess I'll have to find out where it shows the "you can only save in hallways, dummkopf!" dialog and see if there's an if(!in_hallway && !debug_mode)" before it

foone,
@foone@digipres.club avatar

I found the part where it shows that dialogbox, it was tricky because it was in Dark Code, but I can't find what calls it for presumably exactly the same reason

nebojsac,
@nebojsac@phpc.social avatar

@foone sorry, what is Dark Code? Google and DuckDuckGo were not helpful.

foone,
@foone@digipres.club avatar

@nebojsac I mean bytes that ghidra didn't know are code yet, they haven't been disassembled

nebojsac,
@nebojsac@phpc.social avatar

@foone ah ok, thanks!

foone,
@foone@digipres.club avatar

it also means there's yet another dialog_box function that's identical to all the others except for a couple things that could be easily parameterized

foone,
@foone@digipres.club avatar

segmented real mode DOS is so silly.
I know this function is a far call (not a "fall car", as my fingers somehow typed it) so I just need to look for JMP 208e:1bb0, right?

ComradeGibbon,

@foone The hell of the 1980's. 8086 with it's segmented memory. 68000 with it's big endian. And no MMU's

foone,
@foone@digipres.club avatar

what if instead they JMP to 208F:1BA0? that's the same linear address!

foone,
@foone@digipres.club avatar

or any of the 256 other possible addresses for the same fucking function?

foone, (edited )
@foone@digipres.club avatar

> Exception while decompiling 208e:4094: Decompiler process died

this would be easier if Ghidra would STOP FUCKING CRASHING

foone,
@foone@digipres.club avatar

oh god this code better not be jumping into the middle of an instruction

foone,
@foone@digipres.club avatar

it's always fun to find things like that while looking at disassembly. it's a telltale sign that the compiled code ends here. a human wrote this

foone,
@foone@digipres.club avatar

here there be dragons

foone,
@foone@digipres.club avatar

NOPE! it just checks if you're on an even level, and then tells you to fuck off if so.

foone,
@foone@digipres.club avatar

idea: what happen if I sabotage this check and make it always let you save?

foone,
@foone@digipres.club avatar

it's time... for hax

foone,
@foone@digipres.club avatar

75 09 ; JNZ +9
turns into
EB 09 ; JMP +9

foone,
@foone@digipres.club avatar

There we go! I'm saving mid-level.

foone,
@foone@digipres.club avatar

and it loads properly. Nothing about the level state is saved (other than your player position relative to the default camera position), mind you, so there's not really any reason to do this.
Although it does... okay I think I may have figured out why they did this. One moment while I test.

foone,
@foone@digipres.club avatar

okay I think I know why they disabled mid-level saving:
so, they don't save your position or level state when saving a game, but there IS an exploit: the gun powerup

foone,
@foone@digipres.club avatar

the gun powerup is unique in that it can be collected multiple times. The game is smart enough to not let you collect permanent powerups again: if you enter the level where you get the jump boots already wearing them, they simply won't spawn

foone,
@foone@digipres.club avatar

but that's not the case with the gun powerup because you collect up to three of them over the course of the game. The game doesn't know if it should make them appear or not, since you may have gotten a previous one

foone,
@foone@digipres.club avatar

and if you can save mid-level, your gun powerup state is saved.
So you enter level 4, collect the gun powerup, and save. quit and restore your game. You now have the gun powerup, and you can collect it again, getting you to gun level 3. Save and restore again, and now you're max gun level (4).

foone,
@foone@digipres.club avatar

and making you save only in hallways avoids this. And the game stores the state of duke in the last hallway: so when you use f10 to restart, it takes you back to the last hallway, but you lose all your upgrades

foone,
@foone@digipres.club avatar

so you can't use this trick.

now I think they could have solved this in another way: make the save function save the state of duke as he entered the level. They already save that for restoring the player when you die

foone,
@foone@digipres.club avatar

but maybe they didn't figure out this exploit into late in development and just sticking a "you can only save in hallways" patch on it was easier

foone,
@foone@digipres.club avatar

you can also use this trick to get infinite health, but that's a much less impactful exploit than maxing out your gun much earlier

foone,
@foone@digipres.club avatar

oh interesting.
the game does reuse a dialog box!

just one of them: The main-hallway hints and Dr. Proton's security-camera taunts? They're literally the same system, with the two sets of text intertwined.

foone,
@foone@digipres.club avatar

the game selects what message to play based on your current level. on odd-numbered levels, it ends up being a hint message (because those are the hallway levels), and on even-numbered levels, it's dr. proton taunting you

foone,
@foone@digipres.club avatar

my ghidra is full of a lot of comments like "this actually points to keyboard_interrupt_handler" because ghidra is mis-compiling this so badly

foone,
@foone@digipres.club avatar

ghidra really doesn't do a great job of handling 32bit pointers in a 16bit real mode program.
The problem is that they're handled as two 16bit integers, not a single 32bit integer.

foone,
@foone@digipres.club avatar

So sometimes a function fill be like void foobar(int a, int b, char far * string)

and ghidra will be like "oh it takes 4 parameters!"

foone,
@foone@digipres.club avatar

nope! far pointers are passed as two 16-bit integers but actually represent one 20/24-bit pointer.

foone,
@foone@digipres.club avatar

honestly real mode x86 is such an abomination of nonsense that we should pretend it doesn't exist.

if only for the minor problem that nearly all PC software and games were written in it for like 12 years

foone,
@foone@digipres.club avatar

ugh. I don't know what this function even does but I can already tell that the only difference between two adjacent functions is which pointers they use.

TODD, PARAMETERS. PARAMETERS TODD

foone,
@foone@digipres.club avatar

I'm really doubting the function duplications has anything to do with aggressive compiler optimizations because there's one very small function to determine if something is onscreen or not. It's a couple additions and 4 compares. prime inlining material!

it's not inlined. it's far-called from 148 locations

foone,
@foone@digipres.club avatar

optimization level: this is a consumer-grade compiler for DOS from 1988, you're lucky we even know what optimization is

tursilion,
@tursilion@furries.club avatar

@foone I do recall when optimizers were a paid feature.

poundquerydotinfo,
@poundquerydotinfo@virctuary.com avatar

@foone My recollection (I'm old) was that C compilers tended to go overboard with optimization back then, which is why ANSI has so much UB - the compiler makers didn't want to let go, and saw optimization as a way to distinguish themselves from their rivals.

That said, the 'far call to something inlineable' thing was likely to be because optimization happened within the scope of the file the compiler was compiling. If the function you were calling was in different .c file, then it wouldn't get optimized away. The fact it's a far call to that function strongly suggests, to me, that it was. TBH I don't know how current compilers do it, I'd have thought the same applies, as otherwise linking would break but the world's changed a lot in 40 years.

(Please correct me if I'm wrong, I know you do this kind of thing for breakfast, it's just I recall optimization being very, very, controversial during the 1980s, and it affecting the ANSI C standard in very negative ways.)

foone,
@foone@digipres.club avatar

I hope this is just me misunderstanding the purpose of this function and this game doesn't just have a function named process_sodas

foone,
@foone@digipres.club avatar

oh fuck me I think it does

foone,
@foone@digipres.club avatar

instead of having a big array called like GameObjects and a big update function that loops through them all, I think there's separate arrays for sodas and turkeys and atomic molecules and flags and footballs and floppy disks and and and

foone,
@foone@digipres.club avatar

and a separate copy-pasted function to update each one

foone,
@foone@digipres.club avatar

I'm going to set this game on fire

foone,
@foone@digipres.club avatar

oh god it even does it for static things like doors

apparently every frame it loops through the doors array and checks if the player is standing in front of them and then checks if the player is pushing the up key

foone,
@foone@digipres.club avatar

instead of, you know, waiting until the user pushes the up key, then figuring out what they're in front of, and triggering the appropriate action

foone,
@foone@digipres.club avatar

also apparently beating the game gives you 34,464 points.
random-ass number.

foone,
@foone@digipres.club avatar

at least it doesn't loop over a shoes array, since there can only be one per level

foone,
@foone@digipres.club avatar

I'm now doing some hybrid static/dynamic debugging. I set a breakpoint on the add_score function, then I'm doing stuff to get points, and seeing what function called add_score

foone,
@foone@digipres.club avatar

there's a separate function and array that's looped over for EVERY SINGLE ENEMY TYPE

Timberwolf,
@Timberwolf@topspicy.social avatar

@foone As someone who is normally trying to dissect genius-level code where it's like, "oh yes, we developed this unique system to cram 32KB of data into just 1.9KB and by the way we put it in the display memory using this palette trick" I am living vicariously through this documentary of the same kind of stupid shit I used to do when I'd only been programming a few years.

foone,
@foone@digipres.club avatar

my current theory:
todd replogle didn't really understand C programming but unfortunately did a lot of it when he made duke nukem 1

foone,
@foone@digipres.club avatar

I think that instead of iterating over all the destructable blocks, it instead calls handle_block_hit from every update function when a bullet doesn't hit an enemy, and that function checks if it was a destructable block and gives you points if it was

foone,
@foone@digipres.club avatar

but I could be wrong
I hope I'm wrong

foone,
@foone@digipres.club avatar

for some reason, unlike every other enemy, the rabbitoids are handled in the "main loop" function that also handles the menus

foone,
@foone@digipres.club avatar

okay so beating the game doesn't give you 34464, it gives you 100,000 points. It's just not clear because WHOOPS a 32bit integer in a 16bit mode?
does add_score take two 16bit integers or one 32bit integer? who can say?

foone,
@foone@digipres.club avatar

anyway I think I've found them all and there's 29 mostly-copy-pasted functions for updating all the various objects in the game.
29 arrays.
29 number-of-items-in-array variables

WHY TODD

foone,
@foone@digipres.club avatar

okay I'm too fried to keep working on this anymore today.

but at least I found out the function 1097:7b68: process_floppies

cutefloor,
@cutefloor@mastodon.social avatar

@foone Now I have read all of your comments on this, and I'm glad I couldn't see the mess behind this game while playing it back then. As a programmer, I could only guess that he was inexperienced, and this was his first project.

lethal_guitar,
@lethal_guitar@mastodon.social avatar

@foone having recently reverse engineered the entire game logic of Duke 1 myself, this thread was an absolute treat to follow along. Happy to see you're just as baffled by Todd's strange decisions & coding style. 😄

foone,
@foone@digipres.club avatar

@lethal_guitar oh neat! Is that info online anywhere?

lethal_guitar,
@lethal_guitar@mastodon.social avatar

@foone unfortunately not at the moment, as I did this in the context of an upcoming commercial remaster project. But I hope I'll be able to share some things publicly at some point in the future 🙂

foone,
@foone@digipres.club avatar

@lethal_guitar ahh, cool! Carry on, then, and good luck!

lethal_guitar,
@lethal_guitar@mastodon.social avatar

@foone no, the rabbitoids are handled like other enemies. But there's code in the main loop to count them, for the end of level bonus.

foone,
@foone@digipres.club avatar

@lethal_guitar ahh, good to know. I was following the addscore calls, so I must have missed the bunny update function

BluJBird,

@foone I can't help but wonder if any of this helps explain Duke Nukem Forever. Or maybe the entire series is just cursed with bad programming.

foone,
@foone@digipres.club avatar

@BluJBird nah, he only got "special thanks" credit on that one

suetanvil,
@suetanvil@freeradical.zone avatar

@foone

I get the sense that late-80s-era gamedevs tended toward high INT, low WIS.

lethal_guitar,
@lethal_guitar@mastodon.social avatar

@foone he made quite a leap with Cosmo and Duke 2. But still often preferred global variables over function parameters, for some reason.

lizakowski,

@foone 34,464 = 100,000 - 65,536

foone,
@foone@digipres.club avatar
annmygdala,

@foone This is the exact thing that the previous developer did in the project I'm assigned to at my job right now 🫠

foone,
@foone@digipres.club avatar

@annmygdala are you able to kill them?

annmygdala,

@foone For diplomatic reasons, I have refrained for now

foone,
@foone@digipres.club avatar

@annmygdala I admire your restraint

NULLderef,

@foone aaaaaaaaaaaaaaaaaaaaaaaa real mode x86 scares meeeeee i wanna go back to my safe protected modeeee :blobcatflop:

rxpz,

@foone excellent haxorring skills!

DrHyde,
@DrHyde@fosstodon.org avatar

@foone that's a perfectly cromulent technique for saving memory!

foone,
@foone@digipres.club avatar

@DrHyde and making reverse engineers (like me) cry!

f4grx,
@f4grx@chaos.social avatar

@foone whats the difference then? Access rights to specific segments?

foone,
@foone@digipres.club avatar

@f4grx no access rights yet! there are no protections at this point.

the difference is that they're different numbers that point to the same place. There is no technical difference, both are valid

stilescrisis,
@stilescrisis@mastodon.gamedev.place avatar

@foone I bet they found bugs with save-anywhere at some point and got rid of it. Anything not in the save files might have been added after the save-in-hallway decision occurred.

thewispsoftime,

@foone My guess is that saving outside of the hallway was once planned and then scrapped partway through? Or maybe the loading part was used for playtesting/bugtests?

foone,
@foone@digipres.club avatar
eichin,
@eichin@mastodon.mit.edu avatar

@foone
Or maybe the devs learned about save scumming mid development :)
@thewispsoftime

shift_reset,
@shift_reset@mastodon.scot avatar

@foone talk about a maze of twisty passages all alike

fishidwardrobe,
@fishidwardrobe@mastodon.me.uk avatar

@foone wild guess: saving in that one place was a fudge to get around a bug in saving.

bytex64,
@bytex64@awesome.garden avatar

@foone Maybe the hallway restriction was added after the save system. Or the developers have a backdoor to let them save anywhere. Would be pretty useful for testing.

boozook,
@boozook@mastodon.gamedev.place avatar

@foone
Try to determine where in memory stored loaded rooms when they are more then one. I suppose there’s dummy save logic when we’re dumping mem as POD just to file. I've seen this more than once.

Just guessing.

adamrofer,
@adamrofer@mastodon.social avatar

@foone wait what??? I've been wanting to play that level since 1992!

adamrofer,
@adamrofer@mastodon.social avatar

@foone ahh satisfying. Mildly interesting that beating the level doesn't put you in a hallway but keeps you in the level, but with all moving stuff, spikes, etc removed or stopped

foone,
@foone@digipres.club avatar

@adamrofer oh, does it? interesting. I didn't try beating a level in that state.

foone,
@foone@digipres.club avatar

@adamrofer Also you can just play it as map 1 of episode 2.

although interestingly, it's not exactly the same: apparently they made some changes after recording the demo for the shareware version!

adamrofer,
@adamrofer@mastodon.social avatar

@foone i actually was wondering that exact situation, I wonder what changed? Be careful to avoid the rockets, below them is no exit (the rest of the level is safe though). There's some weird area above the visible area on the top left too that you can grapple up into...

adamrofer,
@adamrofer@mastodon.social avatar

@foone it also scrolled the achievement bonuses right there in the level, amusingly

aburka,
@aburka@hachyderm.io avatar

@foone Is it possible they are generated code somehow? Like a computer instantiating a template function? I'm guessing they weren't using a language with features like that though...

darkling,
@darkling@mstdn.social avatar

@foone There are languages/formalisms where you can only pass one parameter to a function.

Maybe they were working in a language where you can't pass any parameters to a function?

I'm sure there's some mathematician that's managed it. Somewhere.

foone,
@foone@digipres.club avatar

@darkling you'd think, but nope! this was compiled with Borland Turbo C.

darkling,
@darkling@mstdn.social avatar

@foone ... I've got nothing. :blobshrug:

poeschel,

@foone @darkling
Is it possible this is some segmented memory/near/far pointer thing?
Maybe not even the coder did this, but Borland decided to duplicate the function for some reason.

darkling,
@darkling@mstdn.social avatar

@poeschel @foone At this point, I'm talking out of my arse (I'm not really an x86 person), but it's duplicating a significant amount of code to avoid passing a single (possibly-)far pointer where it could avoid the duplication at the cost of passing one far pointer? Seems like a significant mis-optimisation on the part of the compiler.

Maybe a segment change is massively more expensive than I think it is, but I hope it isn't that bad.

foone,
@foone@digipres.club avatar

@darkling @poeschel yeah, I don't think that's the case. all 5 are in the same code segment, addressing the same data segment.

mjfgates,

@foone Real functions don't take parameters, they go reference a couple of globals and run off those.

bytex64,
@bytex64@awesome.garden avatar

@foone Sounds like they may have made heavy use of macros. Maybe they thought passing arguments was too slow?

foone,
@foone@digipres.club avatar

@bytex64 that's the weird thing: it's being used for all these static screens. passing arguments wouldn't have been timing-critical

bytex64,
@bytex64@awesome.garden avatar

@foone Maybe they invented it for timing critical things and the brain damage spread to everything else.

geofisch,

@foone damn it, todd

noam,
@noam@beige.party avatar

@foone Could this be the result of compiler inlining?

foone,
@foone@digipres.club avatar

@noam nope! it's not inlined.

Specialist_Being_677,
@Specialist_Being_677@hachyderm.io avatar

@foone if you have no parameters, you don't have to bike shed or even care about calling conventions... Galaxy brain stuff right there.

eniko,
@eniko@peoplemaking.games avatar

@foone I love it. Parameter passing is slow and this circumvents it entirely! :D

foone,
@foone@digipres.club avatar

@eniko it's not THAT slow!
especially when none of these are inner-loop things. They're all "draw some text and then wait for the user to push a key" things

eniko,
@eniko@peoplemaking.games avatar

@foone yeah this is the kind of thing you do when using C on the 6502, not on an x86 machine >_> but I thought it was a funny comment

ids1024,
@ids1024@fosstodon.org avatar

@foone Peano number health points

Ryuu,

@foone "Patched the game. No, nothing added or removed, just cleaned duplicated code because it was driving me mad"

geordie,
@geordie@aus.social avatar

@foone refactor the game.

foone,
@foone@digipres.club avatar

@geordie I don't have the source!

otheorange_tag,
@otheorange_tag@mstdn.social avatar

@foone It's okay someone will write a for loop and a comparator, then someone will write a incrementer on top, then ...

chadaustin,
@chadaustin@mastodon.gamedev.place avatar

@foone This all sounds like the first games I wrote. I rationalize it as kata - repetitive practice writing code was maybe worth something.

lulolwen,
@lulolwen@mastodon.social avatar

@foone Devil's advocate: It might have been macros generating new functions?

curtmack,

@foone They really didn't want to code automatic word-wrapping.

dascandy42,
@dascandy42@mastodon.social avatar

@foone Smells like a linker bug workaround to me.

vfig,
@vfig@mastodon.gamedev.place avatar

@foone hypothesis: one of turbo c’s optimize-for-speed-not-size flags makes it emit a unique function for every call with a different combination of literal arguments?

like, would be weird, but less weird to me than either the copypaste-everything or only-macros-not-functions interpretations.

since godbolt doesnt do turbo c, im gonna have to dig up a copy later and investigate its compile flags.

kaelef,
@kaelef@mastodon.social avatar

@foone the best thing about this sort of copy/paste coding is that it means when you have to fix an issue in one function, you have fix it in 37 different places

patricksdata,

@foone looks like a typical list of react components in storybook. The real question is what's going on underneath all those.

Zotmeister,
@Zotmeister@mastodon.online avatar

@foone GAAAAAAAH

Tramboi,

@foone macro-assembler frenzy ?

Infoseepage,
@Infoseepage@mastodon.social avatar

@foone What? You were going to navigate those 101 monochrome mazes with a keyboard like some pleb?

SHODAN,
@SHODAN@mas.to avatar

@foone Makes me wonder, the commonly assumed narrative is that the IBM PC wasn't designed with games in mind, but did they potentially think with its expandability they thought it could be turned into one with the right cards?

dascandy42,
@dascandy42@mastodon.social avatar

@foone Awesome, thanks!

dascandy42,
@dascandy42@mastodon.social avatar

@foone Did you know the OSDev wiki is a wiki, and relies on knowledgeable people to be corrected?

Would love to help though. What is wrong in it?

foone,
@foone@digipres.club avatar

@dascandy42 I do know! But I don't have an account yet.

luk3,

@foone "fixed in X.Y.Z and exclusively in X.Y.Z"

kawa,
@kawa@mas.to avatar

@foone equates is to Ghidra as the ice cream machine is to McDonald's?

foone,
@foone@digipres.club avatar

@kawa exactly

  • All
  • Subscribed
  • Moderated
  • Favorites
  • random
  • tacticalgear
  • DreamBathrooms
  • ethstaker
  • InstantRegret
  • Youngstown
  • magazineikmin
  • osvaldo12
  • slotface
  • khanakhh
  • rosin
  • kavyap
  • everett
  • thenastyranch
  • ngwrru68w68
  • JUstTest
  • GTA5RPClips
  • cisconetworking
  • mdbf
  • cubers
  • Durango
  • anitta
  • modclub
  • normalnudes
  • tester
  • Leos
  • megavids
  • provamag3
  • lostlight
  • All magazines