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.

Brain: “Wah I’m not John Carmack building the next-gen Keen engine after a week of dabbling, I should despair and give up forever”
Come on, brain
Why don’t we strive for something that’s reasonably within reach

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.

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

Show newer

@darius I never had access to it as a kid! The real exciting thing is having TASM though - I would have absolutely murdered someone for a copy, 'cause ALL the graphics tutorials used it

@SpindleyQ you took the words out of my mouth, I almost mentioned that it was second only to TASM

@SpindleyQ BTW this is a prized possession I found at a garage sale in like 2000

@darius it is on my list to track down and interview Denthor of Asphyxia for the fringe.games podcast, because IMO his Turbo Pascal VGA tutorial was an absolutely world-changing document

@darius @SpindleyQ true story, i won a science fair in 6th grade with a qbasic program and used the prize money to buy turbo c++

@aparrish @SpindleyQ this is the most believable Allison story I've ever heard

@aparrish @darius This was incredibly wise.
At one point I had a connected cousin hook me up with a copy of Microsoft QuickC, assuming it would be a natural progression from QBasic, and was crushed when the integrated help system didn't teach me the language or how to do graphics fast.

@SpindleyQ @aparrish @darius I don't think I've ever learned more from any integrated help system than that of QBASIC. A high school friend gave me a copy and I spent hours just reading the help pages and trying each command until I more or less understood how it worked. It wasn't perfect, I never figured out GOSUB or DIM'ing arrays, but I could write a program and understand what it was doing to some degree.

@SpindleyQ @aparrish @darius Of course a few years later I started learning Java in school and had to relearn pretty much all of it, but I at least understood variables, basic flow control, and the text console.

@drewzero1 @SpindleyQ @aparrish I was 10 when I was using qbasic and didn't realize there was a help system until. well, today.

I also didn't know about copy and paste so I used to transcribe code to paper from one file and then type it in manually into another!

@SpindleyQ I feel like the source for Dangerous Dave in Copyright Infringement would be way more useful but alas, no such source I can find

@darius yeah, definitely! Honestly if I could look at the raw video memory while that runs that’d be enough

@darius I should have known someone had just asked John Romero!

@SpindleyQ tbh john LOVES talking about this stuff and would probably happily answer any email you sent him

@darius I have definitely gotten that impression. I might do that!

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

Show newer

@SpindleyQ if yer gonna scroll that shit the trick is getting the framebuffer memory to be one tile-size larger in all directions so you can utilize the EGA's built in hardware scrolling support. that thing also destroyed me as a teenager. i had to write down register maps from the EGA/VGA Programmer's Reference book in the bookstore cuz i couldnt afford the damn book.

@dildog yep, that's what I ultimately did! I spent a while trying to figure out if there was some trick that would mean I didn't have to redraw the whole screen once I hit the edge, like the NES mirroring, but the closest I came was not redrawing tiles that didn't change

@SpindleyQ this is great! I do miss Turbo C :blobowo:

I have to say this machine looks a little odd with a thin TFT instead of a CRT sitting on top :crt_w_blue_screen:

Also, if you can, please consider scanning any of your DOS programming books - especially game oriented ones.

Many of them are not available and
cannot be found online since the internet exploded long after everyone moved to Windows.

They are becoming more and more scarce unless you're willing to dig in landfills.

:msdos: :blobreach:

@polychrome Yeah, it's convenient to have a small, thin monitor with speakers built-in, but it's not exactly period-appropriate. Perhaps someday.

Someday I definitely plan to mail all my weird programming books to the internet archive to be properly scanned. Everything I've been using for this project is reasonably well preserved already, though - very grateful for all of the convenient copies of Michael Abrash's Graphics Programming Black Book floating around.

Sign in to participate in the conversation

The original server operated by the Mastodon gGmbH non-profit