PoP1 supports 256-color images?

About PR usage and development, and about the POP format.
Post Reply
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

PoP1 supports 256-color images?

Post by David »

Recently I was browsing the disassembly of Prince.exe, when I found this:

Code: Select all

seg009:99F1		    and	    ax,	7000h
seg009:99F4		    cmp	    ax,	3000h
and later...
seg009:9AEC		    and	    ax,	7000h
seg009:9AEF		    cmp	    ax,	7000h
(This is in the graphics code, look for "graphics_mode" and "decompr_img" nearby.)
Both of these check the bitdepth of the current image, from the ImageMask field. (See the specifications.)
The first comparison matches when the top 4 bits of the ImageMask are x011, that is, when the image is 4 bpp. (16 colors)
The second comparison matches when the top 4 bits are x111. In PoP2 this means that the image is 8 bpp. (256 colors)
(See the additions.)

I didn't know that PoP1 supported 256-color images, so I tested it:

Open title.dat in a hex editor, and change these:
0x2e98: 0xD4 -> 0x94 (checksum)
0x2e9e: 0xB3 -> 0xF3 (upper byte of ImageMask)
Now we changed the main title image from 4bpp to 8bpp.
This is what happens if you start the game:
pop1_256.png
pop1_256.png (19.04 KiB) Viewed 2932 times
So what happened? The image data is the same, but it is interpreted differently. One byte means one pixel (8bpp) instead of two (4bpp).
So each row is now pressed into a half row, and the image data ends at the half of the screen.

Of course, to use this for modding, certain problems have to be solved, like the palettes, adding PR support, etc.
David
The Prince of Persia
The Prince of Persia
Posts: 2848
Joined: December 11th, 2008, 9:48 pm
Location: Hungary

Re: PoP1 supports 256-color images?

Post by David »

Okay, I added support to PR (not yet released). Now it can properly import and export 256-color images in PoP1 DAT files, but PR supports only 16 color palettes (currently).
It is possible to add another 16 colors (overwriting the CGA/EGA palettes) and set the byte at offset 3 to 0x20 with a hex editor.
However, this is not enough, because prince.exe has some hard-coded data about how should palettes be loaded, and currently only the first 16 colors are loaded of any palette.
More precisely, each palette loading has a 16-bit parameter, whose bits tell which palette slots can receive this palette.
Bit 0 means slots 0x00..0x0F, bit 1 is slots 0x10..0x1F, ..., bit 15 is slots 0xF0..0xFF.
Currently each of these has only one bit set.

For example: the kid's palette is loaded into slots 0x70..0x7F, because palette_bits has only bit 7 set. (1 shl 7 = 1<<7 = 0x80)

Code: Select all

seg000:1D2C ; int __cdecl far load_kid_sprite()
seg000:1D2C load_kid_sprite proc far                ; CODE XREF: init_game+10P
seg000:1D2C                 mov     ax, id_chtab_2_kid
seg000:1D2F                 push    ax              ; chtab_id
seg000:1D30                 mov     ax, 400
seg000:1D33                 push    ax              ; resource
seg000:1D34                 mov     ax, offset kid_dat ; "kid.dat"
seg000:1D37                 push    ax              ; filename
seg000:1D38                 mov     ax, 1 shl 7
seg000:1D3B                 push    ax              ; palette_bits
seg000:1D3C                 mov     ax, offset kid_is_unpack_tbl
seg000:1D3F                 push    ax              ; is_pack
seg000:1D40                 push    cs
seg000:1D41                 call    near ptr load_chtab_from_file
seg000:1D44                 retf
seg000:1D44 load_kid_sprite endp
Post Reply