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

port_out(0x3c4,0xf02);

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

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
OH GOODY I found a mistake in OSDEV
their docs on the PC gameport are incorrect
and I can't rename some local variables either!?
what the fuck, ghidra?

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.

Game port - OSDev Wiki

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.
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.

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.

LEARN TO WRITE REUSABLE FUNCTIONS
@foone They also have dialog_box_custom. Does that not let you pass a string, solving the rest of the problem?

@goofpunk not exactly. it passes some kind of number that's an index to a list of strings.

so... almost

@foone @goofpunk When I have seen this style of functions named the same way, it was in old old C code, and involved creating a map/array from a string to a function pointer. This was apparently a way to use static+const strings before const was a thing or to achieve interned strings like in e.g. C#. Maybe that was what was going on there.