Friday, October 15, 2021

Maps & Masks in One

Hmm. The weather forecast in the morning suggested rain at 0200hrs tomorrow, but a quick glance at it just now suggested rain between 0700hrs to 0800hrs instead.

Okay... meanwhile, it is still as hot as can be.

And that lubricant trick for the fan? Well... I don't think it worked. I probably need to really take it apart completely to get it right. Or wear enough parts down to trigger the service contract.

I'm carefully making my way through Mathematics for Engineers (2nd Edition) by Raymond W. Dull. The early fifth of the book is very algebraic in nature, reminding me of material from upper secondary/early junior college from Back In The Day. There's a sizeable chunk of information on how to use much fewer [significant] digits to get approximate calculations that fall within some specified tolerance; that's interesting when one realises that this book was written in a time where the most potent and ubiquitous calculatory tool is a slide rule.

In retro-programming news, I messed a bit more of my DOSBox installation. The main concern was the general slowness it felt. I know I said I'd like to do retro-programming, but 3000 cycles emulated just felt more sluggish than I remembered. I pulled up the associated Wiki, and according to this table, the approximate system emulated was closer to an 80286. Sadly, I cut my teeth in systems that were faster than that---it was at least an 80486. No wonder I found it super sluggish, and it also explained how the old LED(II) was acting slower than I remembered too.

I think I settled upon the following configuration for my own edification:
[cpu]
core=dynamic
cputype=auto
cycles=max
cycleup=10
cycledown=20
The setting of core=dynamic allows a ``dynamically recompiling core'', which aided in speed. Setting the cycles=max means that we run at whatever the maximum clock rate of a single core is. I also set output=ddraw under the [sdl] section, hopefully for more speed.

And oh boy. A jump to about 96× to 119× compared to before. And this was with VLC running at 2× replay speed and with Minecraft running in the background as I AFK-ed at my mob farm.

Configuration issues aside, I worked a little on LED2-20 today using the concept of ``hybrid bitmaps''. The problem that needed ``hybrid bitmaps'' was the management of arrays from within the QuickBASIC environment. For each bitmap with an associated mask, one would normally need to have two array names defined. Multiply this by the number of sprites and what-not, and the management of these array names are a downright pain in the ass.

Thankfully, the GET and PUT graphics statements allow the passing of an array name with an associated index to start the bitmap from. With that in mind, I decided to solve my ``too damn many arrays'' problem by combining bitmap and mask arrays into a single integer array using an offset to separate them. The first thing to note is that with a bitmap of 320×200 in this screen mode (screen 7's full screen), it requires 32004 bytes. Double that (one for bitmap, one for the mask) yields 64008 bytes. Using the 16-bit integer primitive data type for the array, the index goes up to 32004. Adding an additional 16-bit integer to record the offset yields an array with only 32005 entries. This is less than 65536 bytes (limit of a non-huge array), and more importantly, has an index range of less than 32767. These two limits are not busted by the largest image with mask that I can come up with (the whole screen), so it is not a problem for the much smaller sprites that I have in mind.

And thus, the ``hybrid bitmap'' is created. I updated the various sub-routines to handle this, and also tweaked the sample sprite-generator code to save the generated sprites according to the new ``hybrid bitmap''. The sub-routine updates were quite painless since QuickBASIC allows one to define array indexes using any range of signed 16-bit integers---all I did was to ensure my ``hybrid bitmap'' array was defined like DIM a(0 TO ...) AS INTEGER while the regular bitmaps were defined as DIM a(1 TO ...) AS INTEGER.

Now I'm wondering how best to do pixel-perfect collision checking. I envision basic bounding box collision checking before we apply the pixel-perfect collision.

That's about it for now. Till the next update.

No comments: