Brutkey

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

the matching disassembly:

MOV AH, byte ptr [DI]
MOV byte ptr ES:[DI], AH

DO YOU KNOW WHAT SEGMENT PREFIXES MEAN, GHIDRA?


Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

found the cheat code (it's well known (it's in the MANUAL), but I hadn't seen the (machine/decompiled) code until now.

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

found a copy-paste bug!

the code that draws these three red dots miscolors the center of the rightmost one

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

the code looks like:

MOV AL, 0x34
MOV byte ptr ES:[button_offset + 0xa07 ],AL
MOV byte ptr ES:[button_offset + 0xb46 ],AL
MOV byte ptr ES:[button_offset + 0xb48 ],AL
MOV byte ptr ES:[button_offset + 0xc87 ],AL
MOV AL, 0x32
MOV byte ptr ES:[button_offset + 0xb47 ],AL

but for the 3rd one, that second MOV AL,0x32 is instead MOV AL, 0x34.

that's a copy-paste mistake, that is.

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

so if your gun is on 1-laser mode, it fires every 13-somethings (frames?)
with it on 2-laser mode, it's every 19 somethings
on 3-laser mode, it's every 30 sometimes.

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

yeah it's frames. at least logic frames, I don't think this game unhooks logic from framerate

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

huh! this game doesn't implement highlighted text by the usual way of just drawing the text in a different color.

it instead iterates over the pixels in framebuffer and increases (or decreases, in the case of de-highlighting) the palette index

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

POP AH
PUSH AH
POP AH

IN OR OUT, MAKE UP YOUR MIND!

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

so I went and beat the game while having a breakpoint on a function that tells me conversation IDs:

1: Emer Kane
2: Titus scientist
3. Gimlak
4: Titus (planet)
5: Jelina (planet)
6: Death robots
7: Government
8: Modian
9: Devon Manta
10: Kima
11: Rigelian Supply Depot
12: Titus robot
13: Titus hyperdrive ship
14: Zookeeper alien
15: Rigelian with stolen face
16: Galaen (planet)

So... something is missing!

EDIT: Found 'em

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

why write

bool is_joystick_button_down(int button)

when you can instead write two nigh identical functions:

bool is_joystick_button_1_down()
bool is_joystick_button_2_down()

?

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

I know programmers who don't use copy paste and they're all cowards

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

the only difference between the code is if it ANDs the result against 0x10 (button 1) or 0x20 (button 2).

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

years ago I asked for the source for this game in the hopes of building a modernized version. I think I'm starting to see why I never got the source: it's slightly crap

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

this code does the following:
sets joy_left to false
sets joy_right to false
reads the state of the joystick
if this fails, it sets joy_left to false, joy_right to false, then returns.

YOU DID THAT TWICE. IT'S ALWAYS FALSE

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

this is in the function read_joystick_analog_x, which is the same as read_joystick_analog_y with one byte changed

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

it keeps track of how many enemies/planets are on screen by adding 2 to a global variable in the render_enemies_and_missiles function.

but why two? suspicious.

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

on 16-bit system, 2 is a very suspicious number

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

yep there's an array of pointers!

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

this file loading code is broken. it tries to load the file in 64kb chunks but it only saves the size as a 16bit variable, so a 64kb file will be recorded as 0, and any bigger file will break.

but fortunately the file is only 11kb so it works, as the read-second-chunk behavior never triggers

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

at least this is a compression algorithm that isn't too complicated: it's simple RLE.

0xFF is a marker, and is followed by a byte of repeat count(-1) and a byte of value.

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

although technically this is the second time I hacked this compression, I did figure this out already back in, like, 2013?

Foone🏳️‍⚧️🏳️‍⚧️
@foone@digipres.club

this game uses a ton of hardcoded offsets into data files. I wonder if this was done with linker nonsense or if they had to be manually hardcoded in.

the latter is frighteningly possible

Kevin Karhan :verified:
@kkarhan@infosec.space

@foone@digipres.club that's good, I guess...