So I'm hacking on Mahjongg VGA by Ron Balewski.
Like you do.

This isn't to be confused with Mah Jongg by Nels Anderson.

I'm also hacking that one, but not in THIS thread.

The cool thing about this game is that there's a ton of user-made tilesets for it that have been preserved on old BBS-shovelware CDs.
And it's all this lovely amateur pixelart so naturally I gotta collect it.

so I'm building a tool to convert the tile files to PNGs.

The files are TIS files, which are made of:
1. one metadata string
2. 44 TIL files.
3. PAL.CFG

There's PAKTIL.COM and UNPAKTIL.COM to separate out/rejoin the TIL files. So I gotta figure out how TIL files work.

it turns out they're a 6-byte header and then they're a 48x60 image, but they're vertically planar: The first row is the least significant bit, fourth row is the most significant bit, and so on.

This indexes into the palette, which is stored in PAL.CFG

The TIL files are 48x60, but the tiles are not. They're 44x60. The extra 4 columns of pixels are ignored

PAL.CFG is simple: It's a 16-line text file, each line containing 3 numbers separated by spaces.

As is common for VGA-only software, it's 6-bit VGA, so the RGB is 0-63 instead of 0-255

the DRAFTSMN.DOC file explains some of the special palette entries:

0 is used for the screen background
1 is used for tile backgrounds
7 is used for the tile edges
11 is used for numbers
15 is used for menus

so really you get 11 colors.

some very ugly python code using strings rather than some smart bitshifting code, but it worked first time.

now I just need to wrap this up into a script that unpacks each file one by one, then converts each TIL, then merges them together into a spritesheet

mass-processing, I found a corrupted one! This is supposed to be "People on TV #2", but it crashes VIEWTILE (and my converter). Works in MJVGA31, but it does crash when you exit.
I need to write a simple font engine. TIME ME
done

I made the foolish mistake that all tilesets would define a remotely sensible palette

that was a mistake. several of them do black on black text

I wasted time make it match the correct background/foreground color and it's not even visible half the time!
Reverted back to plain DOS colors

who thought this tileset was a good idea? because they were very wrong.

it's tiled "Carol, Cheryl and Christie" and I have no idea who those women are.

that's Carol Alt, Cheryl Tiegs, and Christie Brinkley.

thanks to @[email protected]

The creator of this one is truly an evil person

I put it on the internet archive but it seems to be unplayably laggy in-browser:

https://archive.org/details/mahjong_soup

Mahjong VGA Soup : Ron Balewski : Free Download, Borrow, and Streaming : Internet Archive

This is Ron Balewski's Mah Jongg VGA (version 3.1) with Ralph Varble's Soup's On! tileset pre-installed.I slightly modified the tileset to use the default...

Internet Archive
it seems playable on chrome, but firefox barely lets you move the mouse where. that's a shame
much more playable (at least on my slow firefox) version here, by using the windows 3.1 version:
https://archive.org/details/MJWINSOUP#
Mah Jongg for Windows - Soup's on! : Ron Balewski : Free Download, Borrow, and Streaming : Internet Archive

This is Ron Balewski's Mah Jongg for Windows (version 1.0) with Ralph Varble's Soup's On! tileset pre-installed.I slightly modified the tileset to use the...

Internet Archive
this project has officially reached ghidra-o-clock

_putpixel? what are you doing with putpixel, game?

oh, no.

address 3000:4c2e in DOSBox maps to 2C03:0E2E in ghidra.

> LOOK
There is a sign on the wall

> LOOK SIGN
The sign reads "It has been zero days since x86's segmented addressing has made foone's day harder"

The sign has no way to increase the number: it's a static unchanging piece of paper.

(I'll make a real version once I have a chance to install print studio onto my PC with a dot matrix printer)

oh good, I just missed how putimage/getimage was being compiled.

It's at least using BGI's slow blitter, rather than manually plotting every pixel through BGI's slow pixelplotter.

this set of FIDBs helps with that, btw. Real handy if you regularly reverse engineer 16-bit dos applications.

https://github.com/moralrecordings/ghidra-fidb-dos-win16

GitHub - moralrecordings/ghidra-fidb-dos-win16: Scripts for scraping vintage x86 C/C++ libraries in Ghidra, in order to generate FunctionId databases.

Scripts for scraping vintage x86 C/C++ libraries in Ghidra, in order to generate FunctionId databases. - moralrecordings/ghidra-fidb-dos-win16

GitHub
ugh, with a 640x480x16 fucking-planar mode, I can't just easily do a memdumpbin a000:0 10000 to get a copy of the current screen's VRAM
(I only get one of the planes)
I think this one is blue.
this game seems to be spending most of its time drawing to an offscreen buffer
So, the way it handles you removing a tile: it draws a subset of the current puzzle on an offscreen buffer, tile by tile, then it blits that over the screen.

Fun fact: This game from 1991 supports dual monitors.

The PC didn't usually support this until way later, but you COULD install a monochrome card alongside a regular VGA display, and use the monochrome card simultaneously. It was mainly used by programmers, running their debugger/IDE on the secondary monitor, but a few games supported it for things like this.

I'd tried to use this earlier and couldn't get it to work, but reading the changelog I discovered an infuriating change:
It used to be that you had to use the D command line argument to disable monochrome support (it can corrupt memory, for deeply stupid DOS reasons), but then the author inverted the meaning of the argument: it now ENABLES monochrome support!

The dumb reason is that DOS was so starved for memory that one trick that was actually used was to get an extra 8k (I think? My math may be off, it's 2am) for TSRs by using storing them in the upper memory block reserved for the monochrome video card framebuffer.

Which works fine as long as you don't try to use that memory as a framebuffer, which usually doesn't happen if you have a VGA card.

A game blindly drawing to it will draw into the ram of a device driver and stuff will break, hard.

uint __cdecl16far FUN_26f4_0672(int param_1)

{
uint uVar1;

do {
uVar1 = _rand();
} while (param_1 < (int)(uVar1 & 0xff));
return uVar1 & 0xff;
}

I KNOW PROGRAMMERS WHO USE MODULO AND THEY'RE ALL COWARDS

I found another place in the code where it does this.

I'm scared.

for (int i = 0; i < 10; i++) {
local_8 = _rand();
}

ahh, make sure your random numbers are properly seasoned, a good plan.

I haven't fully reversed this function but I think it is bubble sorting the tilesets.

no wonder it was so slow when I had 372 of them in the directory

A password? you ask me for a password?

ARE YOU CHALLENGING ME?

I found where it calls strcmp() before throwing an invalid password error, paused in the debugger. The password is PASSWORD.

and looking in the (hidden!) MJVGA3.HOF file, the first 8 bytes are the following:

AF BE AC AC A8 B0 AD BB

which is "PASSWORD" XOR'd with FF

the manual:

When you first start EDITHOF, you'll be asked for a password. When
MJVGA creates MJVGA.HOF, the default password is PASSWORD (in upper
case). You can, of course, change this password to your own. More on
that shortly.

@foone or in other words, bitwise NOT'd
@foone So... not a challenge at all.

@foone files that store the password simply are <3

Shout out to PDF where you can remove the password easily.

@foone is that better or worse than the appliance I had to configure for a customer recently that shipped with SSH and root password login enabled by default and password "P@ssw0rd"?
@foone To be fair, it does not ask the user to enter _the_ password, it only tells you to enter password.
@halfur that won't work though! the password isn't "password", it's "PASSWORD"
@foone That makes it kind of like the gates of Moria. ​
@foone speak "friend" and enter...
@foone i heard this in the invader zim voice

@foone They even used 8 dashes for a password hint. The XOR-ing was what somebody did after a couple of hits of the company bong.

"Dude! This is going to totally work!"

@foone when I was doing programming the one thing we really wanted was more random random numbers.

"5 occurred 3 times in a row!?"

eventually we started building lists of all the values we wanted and using the random numbers to select which one would be used and REMOVED from the list.

@RueNahcMohr @foone I mean, that's not how random works. but I can see why you would want that.
@fishidwardrobe @RueNahcMohr @foone it's what a lot of Tetris implementations do to select the next piece!
@barometz @RueNahcMohr @foone right, I was thinking it would be good for a game!
@foone that’s one way to deal with output correlation
@foone scary code that goes bump in the night to scare the midnight reverse engineer

@foone Oh yes indeed.

DEVICE=C:\DOS\EMM386.EXE RAM I=B000-B7FF

Committed to memory decades ago, it's so useful.

One `mode mono` command and "goodnight Vienna."

@foone "640k should be enough for everybody" was the biggest lie ever told.
@sqhistorian @foone Attributed to Bill Gates, but he only ever said those words in that order to say it's a stupid claim.
@kawa @sqhistorian @foone It wasn't even Microsoft who set that limit (and DOS did not have it – I remember reading about Microsoft using some non-PC 8086 machine that was stuffed with as much RAM as was possible, because it was the only computer that was able to link their linker – it needed more than 640 kB available on PC-compatibles).

@foone

The thing that vexes me most about reserved driver memory blocks is that even today, Windows still has one.

On 64bit systems this aint so bad, but on 32 bit it was slap in the middle of the address space. Even if you had a load of RAM and could page out, the maximum _contiguous_ address space you could get was about 1.2GB

Guess what wants to allocate a single block of contiguous address space for it's heap? Java.

No Java programs with over 1.2GB of heap for you, person with 4GB RAM.

@foone I used a Hercules mono card, and since I was always in text mode (WordStar!) I used a TSR print spooler that used the graphics ram as its buffer. Of course I had to disable it and reboot before launching a game with graphics.
@foone i was just ruminating on using framebuffer memory for extra ram the other day, nice·
@foone now that's some good trivia, one of those things i'd never quite thought of but it makes sense that it works given what i know about dos era x86 platforms
@foone er, I've done that with my amber monochrome back in the day. I feel old(er) now. didn't know this game supported it though...
@foone Didn't Lotus 1–2–3 support displaying graphs on a CGA card while displaying the spreadsheet on an MDA card too?
@foone Microsoft's "Ma Jong" was a ripoff of Activision's Shanghai. (I have a screen credit on its sequel.)
@foone Oh, that's nice! I wonder how many people were set up like that in the VGA era... And how many of those were developers, for that matter!
@foone Oh yeah, I got a lot of stuff second and third hand (that means: late), but this means I had a Hercules card in addition to the VGA card in my 386 in the mid-90s and could run a DOS command line *simultaneously* on the Hercules with my Win 3.11 on the VGA. I felt like the king of the world!
@foone not only did I not know about the dual monitor thing on DOS, but I didn't know DOSBox-X supports emulating 2 displays. Neato!
@foone this is how I found out dosbox-x supports a second display

@eniko @foone And now part of me wants to see if it supports a third, or a fourth screen.

And/or if any DOS software could take advantage of that, or if one could write DOS software *to* take advantage of the extra monitors.

@AT1ST @eniko I know a way to get up to 3 (add a 3DFX card) but 4 would be tricky. There's no way to do that in a standardized way, you'd have to build a system with multiple PCI cards and program them directly.

Doable, but not easily, and support would basically be zero: it'd need that specific card.

@foone @AT1ST i really wanna see the poor desk that has to hold up 4 CRT monitors
Doom The Way it Was Meant to Be Played - v1.1 Multi-monitor

YouTube
@foone Oh, such a blast from the past. The ipxodi countrip is something I haven't heard for years. And it brings back some long forgotten memories. Thank you for sharing it.
@eniko @AT1ST