Need help understanding VGA Planar

Discuss game modding
Post Reply
User avatar
driedfruit
Less than a nibble
Posts: 3
Joined: December 4th, 2014, 5:10 am

Need help understanding VGA Planar

Post by driedfruit »

Hi there!

First post here, so please be gentle.

I wanted to spend some time on a compressed format for a game, and to have samples of both compressed and uncompressed data, however I'm having trouble interepting the "raw" data.

Thus, I decided to grab whole VGA memory block and work backwards from there. And still, I can't interept the data :/ I'm positive, that once I can "view" the VGA dump, I would relatively easily work out everything else.

Here's what I know. Game uses Mode X, as it's 256-color 320x240. This leads to conclusion, data in VGA memory must be planar VGA. And this is where I'm at loss.

From what I read, there are 4 planes. So, I simple-mindedly attempted something like this:

Code: Select all

int x = 0, y = 0;
int plane_offset = n / 4;
for (i = 0; i < n; i += 4) {
  int off = i / 4;
  for (j = 0; j < 4; j++) {
    char c = src[j * plane_offset + off];
    put_pixel(x, y, c);
    x++; if (x > width) { x = 0; y++; }
  }
}
Which didn't work.

But then, I read there is also WRITE PLANE register (0x03C4), which adjust which plane is going to be written to. But here's where I'm mostly at loss, why would one need a special register? If you have offset into VGA memory anyway? And more importantly, can I just dump the VGA memory block, i.e. is it "complete", with all 4 planes, or should I iterate over each plane, set register, dump, repeat? (In other words, does A000:0000 always point to the same location, or does this location change, when you set register?)

And just if it helps, here is a blitting function (one of a several) from the game.

Code: Select all

mov  dx,03C4 ; Write Plane Reg
mov  ax,0F02 ; 0x02 ?? 0010
out  dx,ax

mov  ax,A000 ;
mov  es,ax ; es= VGA mem
mov  cx,8000 ; 0x8000 times
mov  ax,0000 ;
mov  di,0000 ; dst_offset = 0
repe stosw ; (from ds:si to es:di, cx times)
Oh, and when I say "didn't work", I mean I can somewhat see the image, but all the planes are wrong and the numbers (offset, tile_width, total_width, bpp, etc) that allow me to do so, don't make any sense to me (for example, setting maximum width to 344px (or 344/2 or 344/4), gives me at least the shape of the image).

Thanks in advance!
Malvineous
8-bit mega nerd
Posts: 293
Joined: March 17th, 2007, 6:40 pm
Location: Brisbane, Australia
Contact:

Re: Need help understanding VGA Planar

Post by Malvineous »

Does the ModdingWiki Planar VGA article help? Maybe you can post the 64000 byte VGA dump so we can have a look and confirm what format it's in.

I'm not sure how the VGA registers work as I have never programmed them, but if your image is planar VGA, then loading it as a normal linear VGA image will make it look like four smaller images stacked vertically (or perhaps even in a 2x2 grid depending on the mode.)

It looks like your code might work, but you do it quite differently to the way I'm used to. Here is how I do it, by reading each byte in order and drawing it as appropriate:
  • for p = plane 0 to 3
    • for y = 0 to 240
      • for x = 0 to 320, x += 4
        • read next byte
        • draw as pixel (x + p, y)
User avatar
driedfruit
Less than a nibble
Posts: 3
Joined: December 4th, 2014, 5:10 am

Re: Need help understanding VGA Planar

Post by driedfruit »

Here are some things I've managed to figure.

1. VGA block DOES point to a different location when the registers are changed.
2. The 344 number is not a glitch, I've found a blitting function that explicitly deals with 86-pixel offsets. 86 * 4 = 344.
3. For now, I assume that the game uses 344 x 240 "virtual" resolution, which gives it 12 pixels on both left and right side of the screen, for smooth scrolling (tiles are apparently 16x16).
4. From what I understood, reading some more VGA-related docs, such a thing is indeed possible, if you change the OFFSET register (80 by default) to 86.

So, it seems, that, the planes are 86 x 240, not 80 x 240.
Does the ModdingWiki Planar VGA article help?
That's mostly where I started from, so yeah, it does :)
if your image is planar VGA, then loading it as a normal linear VGA image will make it look like four smaller images stacked vertically (or perhaps even in a 2x2 grid depending on the mode.)
Yes, pretty much, but they don't align properly, so when I change my view mode to planar, I get a mess. I'll try again with the 86/12 numbers.
Maybe you can post the 64000 byte VGA dump so we can have a look and confirm what format it's in.
If it's legal, and if you guys have time, sure, I'll be glad to do it. However, I'm now not quite sure 64k block is enough, as the registers do control which plane the block is pointing to. File attached. View it as 344-width.

Thanks for your reply, and yeah, your algorithm does look much cleaner. I'm doing it "backwards" because "number of bytes" is always constant in my viewing utility, while all other values are adjusted interactively. If I'm ever finished with this, the final code will be more like yours, I promise :)
You do not have the required permissions to view the files attached to this post.
Malvineous
8-bit mega nerd
Posts: 293
Joined: March 17th, 2007, 6:40 pm
Location: Brisbane, Australia
Contact:

Re: Need help understanding VGA Planar

Post by Malvineous »

I imagine changing the VGA registers controls how the video memory is read out, but doesn't control how it's written. So the VGA register settings are kind of irrelevant, *unless* you can look up the values in a VGA reference manual to work out the memory layout that way.

Notice when you display the VGA dump as 344x200 (actually it's easier as 86x800) there is an offset about half the width of the image. The first row of non-black pixels starts in the middle of the row - probably 43 pixels/bytes in. This causes the image to run off the right-side of the frame and wrap around to the left. This suggests to me that the source image is manipulated slightly when it is being loaded into video memory. So I am not sure whether deciphering the video memory layout will glean any information on the underlying image format.

I can however only see three images (with a width of 86 pixels), so either the dump is truncated, or there are only three planes.

Also just for the record, posting a VGA dump is much the same as posting a screenshot so there should be no problem there :-) I'd be happy to take a look at the original (decompressed) image if that would help, just in case I recognise the format, although in that case it might be better to send it to me directly - I'm sure you can find my e-mail easily enough.
User avatar
driedfruit
Less than a nibble
Posts: 3
Joined: December 4th, 2014, 5:10 am

Re: Need help understanding VGA Planar

Post by driedfruit »

I imagine changing the VGA registers controls how the video memory is read out, but doesn't control how it's written.
It's something like

Code: Select all

set reg to 1
write to A000:0000 -- writes to plane 0
set reg to 2
write to A000:0000 -- writes to plane 1
etc
(this also allows for "set reg to 0F -- writes to all 4 planes" kind of usage)
This suggests to me that the source image is manipulated slightly when it is being loaded into video memory. So I am not sure whether deciphering the video memory layout will glean any information on the underlying image format.
You're exactly right. The blitting function for this particular image (!) is absolutely crazy, and is nothing like "copy this block of pixels", but more like "for each 32 pixels -- copy these and those bytes, apply mask, copy stuff around inside VGA memory (twice!), add some weird offset, etc". As far as I understand, it's all done to allow BOTH double-buffering AND smooth scrolling in both directions (which would require exactly this type of acrobatics), so, yeah, the layout is extremely unhelpful.

Thus, I've came to same conclusion, that inspecting VGA memory is no longer helpful.

Altho you came to it much faster :) Thank you for your time, I think I probably will send you an e-mail at some point.
Malvineous
8-bit mega nerd
Posts: 293
Joined: March 17th, 2007, 6:40 pm
Location: Brisbane, Australia
Contact:

Re: Need help understanding VGA Planar

Post by Malvineous »

Ah right - that's interesting you can control which bits get written into video memory by changing the registers. I was thinking it wasn't possible to move the actual memory sitting at address A000:0, but now I'm not so sure what actually happens if you, for example, set the registers to write to planes 0 and 2. Are there blocks of data that effectively behave like they are read only in this case? Or does changing this bit allow you to write linear-VGA data at A000:0 and the card moves it into the planar arrangement you see in the dumps?

Interesting either way!
Post Reply