I wonder when I became the kind of person for whom Michael Abrash's Graphics Programming Black Book became exciting and fun to read, instead of being daunting and terrifying

I have successfully loaded tiles from a TIF file that I drew in NeoPaint, converted them internally into EGA planar format, and drawn them to the screen. mastodon.social/media/Yg3wSvnV

Just implemented page flipping, as a prelude to maybe implementing smooth scrolling.
It’s pretty amazing how little code this is? Like once you have a grasp on how EGA memory is laid out and you’ve got Michael Abrash telling you which registers you can poke to do neat stuff, it’s not complicated? This shit DESTROYED me as a teenager though, I never got ANY of it working outside the basic mode 13h linear framebuffer

Like I was convinced Mode X was black undocumented voodoo magic, instead of just, like, bankswitching? I had no concept that mode 13h was just throwing away 192kb of video memory because I had no concept of how RAM worked at all, really

I assumed interfacing with hardware was hard, when what was actually going on was that debugging was hard, and programs I wrote on my own without copying directly from tutorials were buggy

It’s really astonishing to me how different the experience of programming a 286 is compared to what I do at my job, how starkly the priorities are different
At my job, I make sure the code I write is flexible and correct. I build safeguards to ensure bad things will not happen when someone makes a change or grows the system
For this project, I put together a pile of purpose-built subroutines and macros, kept simple enough that I could delete and rewrite any of them a dozen different ways

Mouse support is trickier than I expected! It would be easy if I just polled the state every frame but I decided to try to install a callback. I think I need to set the DS register at the start of the callback in order to access my data - I’m scribbling over something important and the computer hangs. But how do I know the value I should set it to? Is it even possible to do this in the small memory model? Argh

Got it! I looked at the generated ASM and figured out that DS was being ASSUMEd to a symbol called “DGROUP”; so I just explicitly set DS to that at the start of the callback and no more crashy!
I am definitely doing something to confuse CuteMouse’s cursor-drawing routine though... probably it assumes I have writing to all four planes enabled mastodon.social/media/uax66anG

Well, definitely that, but it also plays _very_ badly with my page flipping implementation - you can see it writing into video memory when I’m flipped to the second page! sooo I guess I’ll be drawing my own damn mouse cursor mastodon.social/media/QGLwPAja

I’ve been pondering scrolling for a few days, and whether I could figure out how to write a huge smooth-scrolling playfield or whether I’d just flip from one screen to the next. This evening it occurred to me that surely at some point the Commander Keen source code must’ve been released and I could just see how they handled scrolling. And indeed Keen Dreams is GPLed! github.com/keendreams/keen

Hmmmm this is... a little overwhelming. Lots of extra stuff that makes me wonder if I’m missing something important. Gotta keep in mind that it’s an entire game, after many rounds of optimization, instead of a week’s worth of occasional hacking, and my slower, dumber code can still lead to an outcome I’m happy with.

Ok, here’s what I definitely do understand:
Keen has two “pages” of video memory that it flips between. Each page represents an image slightly larger than the screen that it can smoothly pan around in. We’re talking, like, 16 pixels wider.

Follow

Keen keeps track of which 16x16 tiles are dirty via a dirt-simple byte array where they mark each tile position 1 or 0 - because only 21x15 tiles are onscreen, this only costs a few hundred bytes and is a huge optimization. I’ll probably steal this idea. (Extremely common retroprogramming pattern that has basically disappeared from modern computing: knowing there are, at most, N of something, where N is small.)

The tiles are redrawn by copying from what the code refers to as the “master screen”, which is an area of video memory after the two pages.
I don’t know how this memory is structured, but I don’t really need to - because of the page sizes, I know that a full redraw into a page MUST happen regularly without slowing everything down. So as long as the tiles live in video memory and I have a reasonably efficient copy loop I should be fine.

This morning an old Michael Abrash article taught me exactly how to trivially speed up my current tile drawing routine 4x by caching tiles in video memory so this makes sense to me.

Also thanks to @darius reminding me of its existence I now have Dangerous Dave in Copyright Infringement running on my 286, along with John Romero’s tilemap editor, and I’m kinda thinking it’d be fucking rad to use it to build my maps instead of slogging through writing my own

Implemented my tile-blitting speedup
Pro: it is indeed much faster
Con: don't quite have all the bugs worked out yet mastodon.social/media/LEqZ5yj7

I really wanted to play with the split screen register, so now there's a static footer and I can scroll around the map with the arrow keys. Scrolling is a bit slower 'cause I have an actual map in RAM now. Name is absolutely not final.

Trying to figure out how to efficiently draw semitransparent sprites in EGA. It is... not as simple as I thought. Reading the Graphics Programming Black Book chapters about fast animation and some of the methods he's describing are absurd - chapter 43 is like "if you don't mind having every sprite be 1 colour and only using 5 colours total, here's a neat trick" and no actually I do mind those constraints, that's not helpful advice

I'll probably have a quick look at the Keen Dreams source again and then just build something slow and naive

Came up with my own strategy for sprite drawing; so far it seems to be going pretty swell

Very important to document these glitches before I fix them IMO. I've almost got the sprites drawing in the right place, though they're not even close to the right data. I replaced the background tiles with the car sprites I drew just to make sure my TIF loader was reading them OK.

Hey, I can see a mangled version of my car sprite! And it moves around smoothly!

I have unmangled my car sprite! Now to figure out why only the grass tile is being used as a background, and also wtf is going on with my pixel mask, jeez

Coding in C for the 286 is kind of like coding in a dynamic scripting language except the only data types are "array of bytes" and "little-endian words"

Like these bytes have structure but it's probably more trouble than it's worth to try to explain to the type system what it looks like

It's fun when figuring out a problem with something then uncovers exciting new problems with that thing

Implemented smooth horizontal scrolling, which in EGA makes the footer jitter. There’s a VGA-only fix but I think I’ll switch course a little and scroll the footer onscreen at times where the player can’t move. Of course getting rid of the footer ended up exposing a new delightful glitch

Starting to factor out the game loop; added the ability to pop-up the footer by tapping the space bar, which pauses normal game logic.

Nothing visually new today, just a bunch of overdue code cleanup. Everything used to be in one giant C file but now there's proper modules and header files. Fun Turbo C++ tip: to create a new multifile project, select "Open Project" and type in the name of a file that doesn't exist

Show more

@SpindleyQ @darius I spent basically all of the 90s trying to get the most performance possible out of DOS PCs. In retrospect it might be a relaxing time make a retro game that just does what the system is good at and not make it about performing, uh, performance.

@SpindleyQ @darius (Not trying to tell you how to have fun. Just, it's a valid option.)

@mogwai_poet @darius oh definitely! Most of what’s actually driving me is that I spent like 20 years thinking of VGA as a dumb slow framebuffer and the discovery that it’s dumb and slow but actually has some neat bells and whistles makes me wanna try them out. I don’t actually want to become 1991 John Carmack and will be very content with being 1991 Steve Moraff.

@darius @mogwai_poet I wonder if anyone has a copy of the demo tape for his band The Moraffians, because I desperately need that in my life obscuritory.com/puzzle/moraffs

@SpindleyQ @mogwai_poet @aparrish oh fuck I guess I'm adding "edit an anthology of essays about Steve Moraff and his work" to my list of things to do before I die

@SpindleyQ @mogwai_poet @aparrish or: a Boss Fight Books spinoff series where each book is about a Moraff game. worst selling book series of all time

@darius @SpindleyQ @mogwai_poet let's apply for a grant and i promise i'll write the best essay about moraff's boundary-pushing typography you've ever read

@RobF I’m glad it’s interesting to others! It sort of feels self-indulgent sometimes but I’m having too much fun not to share.

@SpindleyQ I'm also enjoying these updates from 286 Land. I hope Jorts can Quest all the Quests

@rabbitboots Yay! I’m gonna make Jorts drive around in a little car next I think

@SpindleyQ How much processing power does the 286 have for special effects like sprite rotation? I'm guessing not a whole lot, but I'm curious, mostly because I discovered Doom and Quake during the era of gigahertz processors.

I had a 286/386 when I was very little. It mostly just had Reader Rabbit 2 and 3 VGA and a couple other, simpler edutainment games

@HihiDanni It’s possible, with well-optimized code & carefully chosen constraints. For example, Wing Commander will run on a 286, but the frame rate is low and huge parts of the screen are a static cockpit image. EGA/VGA doesn’t really have an efficient way of moving CPU-calculated bitmap data into video memory - it’s much faster to copy stuff around that’s already there, and there are various masking & shifting modes to support static sprites.

@HihiDanni Wolf3D runs reasonably well on a 286 IIRC, though probably not at full screen. I should try it. Doom is not gonna happen.

Sign in to participate in the conversation
Mastodon

Server run by the main developers of the project 🐘 It is not focused on any particular niche interest - everyone is welcome as long as you follow our code of conduct!