Jump to content
IGNORED

Playfield procedural drawing, compression


iesposta

Recommended Posts

•This thread is to discuss Playfield data in batari Basic DPC+ to benefit very detailed and lots of playfields in a single game. (The assembly programmers have tools, but I wanted to develop ones for batari Basic.)

•This thread is to discuss playfield compression. Is it really worth it? Does it save space?

•Creation of guides or scripts or apps to compress playfield data.

•Creation of code to decompress data.

 

Beyond the normal defining of playfield, I needed to store playfield screens in the rom banks, apart from the area DPC+ puts playfields.

I have 2 highest resolution playfields in the DPC+ data area by defining the normal "playfield:" command.

I also have 3 other highest resolution playfields as data in the usable DPC+ banks, bank2, bank3, bank4, bank5, or bank6.

• Procedurally drawing a playfield.

Bogax coded a routine to turn pixels on and off using data.

<routine will go here>

 

• Regular Playfield.

Storing 8 pixels in a single byte is already quite a good storage technique.

There are 8 bits in a byte and each bank only has around 4,000 bytes, so to get the most in a program, every byte counts!

For one line of playfield, batari Basic has 32 pixels and this works out to 4 bytes: 00000000, 00111101, 00001111, 00000000

Here is the top 1/4 of my DKbB playfield:

 %00000111,%11111111,%11111111,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%10000000,%00001000,%00000000
 %00001001,%00000000,%00000100,%10000000
 %00000000,%00000000,%00000000,%00000000
 %00000010,%00000000,%00000010,%00000000
 %00001111,%11111111,%11111111,%10000000
 %00001010,%10101010,%10101010,%10000000
 %00001010,%10101010,%10101010,%10000000
 %00001010,%10101010,%10101010,%10000000
 %00001111,%11111111,%11111111,%10000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00001001,%00000000,%00000100,%10000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00000000,%00000000,%00000000,%00000000
 %00001001,%00000000,%00000100,%10000000
 %00000000,%00000000,%00000000,%00000000

That 1/4 takes 176 bytes.

All 4 playfield data chunks takes 704 bytes to make one highest resolution playfield. That's almost three quarters of 1K of the 4K bytes.

There sure are a LOT of 0's, each "0" holding one bit in the ROM.

I have searched for compression in the "Basic" language here and on the web, and I have not found much.

Here's what I have found / developed so far.

Can compression gain space?

 

• RLE Compression.

RLE or Run Length Encoding is a simple compression that takes data and says 5 zeros, 19 ones, 16 zeros, 1 one, 11 zeros, etc.

The above 1/4 playfield would RLE compress to this:

 
; 105 bytes compressed play field
 
%00000101, %10001001, %00010000, %10000001, %00001011, %10000001
%00110011, %10000001, %00001011, %10000001, %00110011, %10000001
%00001011, %10000001, %00001011, %10000001, %00001011, %10000001
%00110011, %10000001, %00001011, %10000001, %00110011, %10000001
%00001011, %10000001, %00001011, %10000001, %00001011, %10000001
%00110011, %10000001, %00001011, %10000001, %00110011, %10000001
%00001011, %10000001, %00001011, %10000001, %00001011, %10000001
%00110011, %10000001, %00001011, %10000001, %00110011, %10000001
%00001011, %10000001, %00001011, %10000001, %00001011, %10000001
%00110011, %10000001, %00001011, %10000001, %00110011, %10000001
%00000010, %10000001, %00001101, %10000001, %00000010, %10000001
%00101101, %10000001, %00001111, %10000001, %00001101, %10010101
%00001011, %11111111, %10101010, %10101010, %10101000, %00000000
%10101010, %10101010, %10101000, %00000000, %10101010, %10101010
%10101000, %00000000, %10000000, %10010101, %01001011, %10000001
%00000010, %10000001, %00001101, %10000001, %00000010, %10000001
%01101011, %10000001, %00000010, %10000001, %00001101, $10000001
%00000010, %10000001, %00100111
That is 105 bytes, a savings of 71 bytes, but routines are still needed to expand the data.
(Note: the bottom of the above data is incorrect, as I have begun to add "flag" bytes.)
I used a python script, and hand typed the above table with the 1st bit in each section showing if the number is ones or zeros. The decimal for the data that starts with "%0" is how many zeros.
The first line says 5 zeros.
The data that starts with "%1" is data for on bits. The byte converted to decimal, minus 128, would be the number of 1's.
The fourth byte, "%10000001" says 1 ones. <- I noticed this is wasteful. A whole byte to say one 1?
Looking at the above data, I began to see more patterns.
Notice it alternates zeros data, ones data, etc.
Also notice it alternates a lot with: data, one 1, data, one 1, data, one 1, etc.
More waste:
%10101010 just doesn't gain anything from this compression, it actually goes from one byte to 16 bytes!
This is the point where I came up with Conditions.
• Compressed Playfield with Conditions.
It makes sense to set a byte to tell the playfield plotting routine to just use every bit as playfield data - it is not compressed.
I came up with three Conditions:
Condition0 128 means normal RLE operation. 128 = %10000000
Condition1 192 means every other operation is 1 on pixel. 192 = %11000000
Condition2 256 means plot every byte. 256 = %11111111
The playfield data with Conditions would be this:
%10000000
; Condition0 
%00000101, %10001001
 
%11000000
; Condition1 
%00010000, %00001011
%00110011, %00001011, %00110011
%00001011, %00001011, %00001011
%00110011, %00001011, %00110011
%00001011, %00001011, %00001011
%00110011, %00001011, %00110011
%00001011, %00001011, %00001011
%00110011, %00001011, %00110011
%00001011, %00001011, %00001011
%00110011, %00001011, %00110011
%00000010, %00001101, %00000010
%00101101, %00001111
 
%10000000
; Condition0
%00001101, %10010101, %00001011
 
%11111111
; Condition2
%10101010, %10101010, %10101000, %00000000
%10101010, %10101010, %10101000, %00000000, %10101010, %10101010
%10101000, %00000000
 
%10000000
; Condition0
%10010101
 
%11000000
; Condition1
%01001011, %00000010, %00001101, %00000010
%01101011, %00000010, %00001101
%00000010, %00100111

Now the data takes 67 bytes from the original 176. A savings of 109 bytes.

This is as far as I got today.

The above still has patterns, like the 10 "%00001011"'s in the center column.

I can't think of a Condition for that.

 

Times 4 playfield parts that would save around 435 bytes.

Is that enough to make compression/decoding worth it?

Link to comment
Share on other sites

Its worth it, for some designs anyway. When Byte Knight and I made Christmas Adventure, we were desperate for ROM space. The game is 8k, and while Warren Robinett's Adventure is 4k, ours has objects with per-line color and "the grinch" who has more complex behavior than just "guard, wander, or chase".

We allowed some rooms to have all the detail a regular playfield: command and the skills of PAC-MAN-RED can give. The game just needed that graphical oomf in key areas. The rest of the rooms - transition rooms and simple mazes - use a scheme that combines two different compressions.

In our scheme, each row of the playfield is represented by one byte, with each bit representing 4 playfield pixels. This made it easy to design the playfields without building special tools.

We also applied a kind of RLE to that data as well, since big chunks were repeated vertically. In our compressed room data, each playfield data byte is preceded by a count of how many rows the following data byte should repeat. Its a waste in the rare case that you draw only one or two line, but otherwise its a huge savings.

The challenge is to keep your compression routine simple. Otherwise you'll be wasting any potential savings on code. It's also important to keep in mind the technique is only useful for games that can tolerate a blank frame or two between drawing playfields, since the unpacking takes a fair bit of time.

Link to comment
Share on other sites

Compression is fine, but DEcompression will be an issue?

Maybe not so much with external chips like the DPC+ or ARMs.

Id rather use the space differently.

I.e. all PF0 bytes only use the upper nibbles. You can easily store 4 bit values there. I did that i.e. for audio data (AUDV and AUDV are both just 4 bit).

Link to comment
Share on other sites

Compression is fine, but DEcompression will be an issue?

.

With a Donkey Kong type of game, it can pause black during decompression between "screen levels."

For quick movement around a "larger than one screen area" decompression would be an issue.

 

Thanks! Something to keep in mind.

Link to comment
Share on other sites

Id rather use the space differently.

I.e. all PF0 bytes only use the upper nibbles. You can easily store 4 bit values there. I did that i.e. for audio data (AUDV and AUDV are both just 4 bit).

That is a great idea also.

My game uses 28 pf pixels out of the 32. I originally was planning on using those leftover 4 bytes for music data ( I am drawing each playfield as opposed to defining one so the extra 4 bits wouldn't be drawn on the playfield. )

Link to comment
Share on other sites

Id rather use the space differently.

I.e. all PF0 bytes only use the upper nibbles. You can easily store 4 bit values there. I did that i.e. for audio data (AUDV and AUDV are both just 4 bit).

That is a great idea also.

My game uses 28 pf pixels out of the 32. I originally was planning on using those leftover 4 bytes for music data ( I am drawing each playfield as opposed to defining one so the extra 4 bits wouldn't be drawn on the playfield. )

Link to comment
Share on other sites

There's compression, and then there's compression. ;) That is to say, there are different ways of "compressing" something, and all methods of compression are not equal-- not to mention (as enthusi brought up) the issue of decompression. I think you should analyze what's being compressed and how it needs to be used when determining whether to use compression and, if so, what method to use.

 

In this case, I think counting the number of repeated 0s and 1s is not the best way to do it. It would be better to count the number of repeated rows, or better yet the number of repeated row patterns. For example, this particular row pattern is repeated several times:

 

 

 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000

 

But looking at all of the row data, I see an even better option. If you load the rows (4 bytes per row) into a programmer's text editor and sort the rows, removing all duplicates, you see that there are only 7 unique row patterns. So that means you could store the unique rows in a table (or set of four tables), assigning each row an index (pattern number), and then for your actual playfield data table you just need to store the index or pattern number for each row. That would also speed up the "decompression" process, because if you read the PF table in your scan line loop, you see that a particular row should be draw using pattern number 4, then you can just read the PF1L, PF2L, PF2R, and PF1R bytes for pattern 4 from the pattern tables. It does add extra cycles to the scan line logic, but that way there's no need to "decompress" anything during the VBLANK.

 

And in this case, since there are only 7 unique rows, you could squeeze 2 pattern numbers into a single byte: %0aaa0bbb. On the other hand, if you've got several screens it will probably be most efficient to sort the rows for all screens together, since there might be row patterns common to two or more screens (as long as you don't have more than 256 unique rows).

 

PS -- Combining different types of bit- or nibble-oriented data into a single byte is really another kind of compression, as is overlapping data tables that happen to have identical rows of data at their beginnings and ends. And you could even use the overlapping data tables in addition to what I've described above-- if you can find a way to shuffle around your unique rows of data such that there are some overlaps between the PF1L, PF2L, PF2R, and PF1R data tables).

  • Like 1
Link to comment
Share on other sites

There's compression, and then there's compression. ;) That is to say, there are different ways of "compressing" something, and all methods of compression are not equal-- not to mention (as enthusi brought up) the issue of decompression. I think you should analyze what's being compressed and how it needs to be used when determining whether to use compression and, if so, what method to use.

 

In this case, I think counting the number of repeated 0s and 1s is not the best way to do it. It would be better to count the number of repeated rows, or better yet the number of repeated row patterns. For example, this particular row pattern is repeated several times:

 %00000000,%10000000,%00001000,%00000000
 %00000000,%00000000,%00000000,%00000000

But looking at all of the row data, I see an even better option. If you load the rows (4 bytes per row) into a programmer's text editor and sort the rows, removing all duplicates, you see that there are only 7 unique row patterns. So that means you could store the unique rows in a table (or set of four tables), assigning each row an index (pattern number), and then for your actual playfield data table you just need to store the index or pattern number for each row. That would also speed up the "decompression" process, because if you read the PF table in your scan line loop, you see that a particular row should be draw using pattern number 4, then you can just read the PF1L, PF2L, PF2R, and PF1R bytes for pattern 4 from the pattern tables. It does add extra cycles to the scan line logic, but that way there's no need to "decompress" anything during the VBLANK.

 

On the other hand, if you've got several screens it will probably be most efficient to sort the rows for all screens together, since there might be row patterns common to two or more screens (as long as you don't have more than 256 unique rows).

 

PS -- Combining different types of bit- or nibble-oriented data into a single byte is really another kind of compression, as is overlapping data tables that happen to have identical rows of data at their beginnings and ends. And you could even use the overlapping data tables in addition to what I've described above-- if you can find a way to shuffle around your unique rows of data such that there are some overlaps between the PF1L, PF2L, PF2R, and PF1R data tables).

Thanks for showing another way to look at it!

As I said, when I looked into compression, the first and easiest to understand is RLE. You've given me more to think about.

I also don't understand this: "And in this case, since there are only 7 unique rows, you could squeeze 2 pattern numbers into a single byte: %0aaa0bbb." As I am used to 1's & 0's, but I can probably figure it out.

I want to find ways of doing this in Basic.

Using a text editor, removing duplicates and sorting is the kind of "steps" I'm looking for. (As well as any scripts or batari Basic code.)

Again, thank you.

Link to comment
Share on other sites

I also don't understand this: "And in this case, since there are only 7 unique rows, you could squeeze 2 pattern numbers into a single byte: %0aaa0bbb." As I am used to 1's & 0's, but I can probably figure it out.

 

I just meant you can put two "pattern IDs" in one byte-- one in the high nibble, the other in the low nibble. The "0aaa" just meant that it takes 3 bits to store pattern number A, and "0bbb" means 3 bits to store pattern number B. So you'd actually have two free bits left over (bit 4 and bit 7), although you might not have any use for them. And this assumes there are no more than 8 unique patterns. Looking back, I see that the data you posted as an example was just for the top 1/4 of a screen, so presumably there might be more than 7 unique patterns for just that (whole) screen. And if you're putting the data for several screens together, I'm guessing there will possibly be more than 16 unique patterns, so squeezing two pattern numbers into a single byte might not be feasible. Also, having two IDs in one byte would mean the logic for the scan line loop would have to be based around a two-line kernel, since for one row you'd want to use the high nibble, and for the other row you'd want to use the low nibble.

 

But as far as doing this in batari Basic-- I guess that rules out doing the decompression during the scan lines, anyway.

 

In any case, this method would require only 28 bytes of PF data (7 rows of 4 bytes) for the first 1/4 of the screen, which could be reduced a little bit more by overlapping the four tables. But then you'd still need to store the sequence of pattern numbers for each screen-- 44 more bytes (or 22 if you put two values in each byte). So for the first 1/4 of the screen this method would require 72 bytes at most (28+44). But squeezing two values into a byte (and without using table overlapping), it could be as little as 50 bytes (28+22). And from looking at the 7 patterns for the first 1/4 of that screen, I can definitely say that at least 4 more bytes could be saved by overlapping the tables, so that's 46 bytes.

 

Plus, I think this method should "decompress" faster than the other method.

Link to comment
Share on other sites

I try to find novel ways of generating playfield backdrops rather than generalized compression. My strategy is usually to use a master seed coupled with the screens x/y coordinates in the game world. With each screen having its own unique value I can use "room construction" routines that generate unique corridors, items and exits.

Link to comment
Share on other sites

Compression usually works best when it uses dependencies. E.g. in our case the chances of a 0 following a 0 are usually higher than a 1 following a 0. And a 1 following a 1 is more likely than a 0 following a 1. If you use XOR this means a 0 (= no change) will become much more likely than a 1 (= bit has changed).

 

I case of a playfield there are two dimensions to look add. If you look at your example above, I am pretty sure if you compress by column, the result would become better. Columns are more related here. And if we reuse the previous data and only calculate the difference by using XOR, this would allow very nice RLE compression for the two middle columns.

 

Last not least, the pattern size can vary. In this case (like shown above) you just have 7 unique row patterns.

Link to comment
Share on other sites

For something like this that I am doing, although not symmetrical, there are LOTS of repeated rows, repeated row sections. As you can see:

med_gallery_29575_885_23922.jpg

Just seeing that playfield: data with all those 0's and repeated patterns seems so wasteful when I can imagine using a computer to find a lest wasteful way of storing all that.

And as I said, the eight pixels per byte literal storage method starts off quite good.

Link to comment
Share on other sites

I see alot of repeated patterns in that screen. I'm not sure if compression is the right mindset here. The floors can be drawn the same with some increment in the starting and ending points. Likewise the ladders closest to the edge could be drawn just a few playfield pixels closer in each iteration.

 

Stupid question: Does DPC+ allow pfpixel commands?

Link to comment
Share on other sites

I see alot of repeated patterns in that screen. I'm not sure if compression is the right mindset here. The floors can be drawn the same with some increment in the starting and ending points. Likewise the ladders closest to the edge could be drawn just a few playfield pixels closer in each iteration.

 

Stupid question: Does DPC+ allow pfpixel commands?

Good idea. This rivet level and the cement/pie factory are the easiest. The 1st slanted girders level and elevator level would benefit from some kind of compression I hope.

I already have all 6 screens in my 28K DPC+ ROM. It is getting the game logic into the space left that I am looking into new ways to get back space.

And to help future DPC+ programmers fit more high res backgrounds into their games.

(I'd like to flicker level 1 background like I do for the elevator level (for the blue ladders), but have some testing to do about that.)

 

 

Does DPC+ allow pfpixel commands?

Yes.

Link to comment
Share on other sites

I cant write a routine for this.

The below table values could be stored in nibbles. 0 1, 2 1, etc. for savings, but I cant get this simple routine working

Here is a data table for each PF line, 0 to 175.

It says the first PF line is the 4 bytes in 0 of L4_0n, then draw the 4 bytes in line 1 of L4_0n, then 2, then draw using line 1 again...

 

[data]

data L4p

0, 1, 2, 1, 2, 1, 2, 1

2, 1, 2, 1, 2, 1, 2, 1

2, 1, 2, 1, 2, 1, 2, 1

2, 1, 2, 1, 3, 2, 4, 5, 6, 6, 6, 5, 2, 2, 3, 2

2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 2, 2, 2, 3, 2

7, 2, 3, 2, 4, 4, 8, 6, 6, 6, 8, 2, 2, 7, 2, 2, 2, 7, 2, 2

2, 7, 2, 2, 2, 7, 2, 2, 2, 7, 2, 2, 2, 6, 2, 9, 2, 7, 2, 2

4, 10, 11, 11, 11, 10, 2, 2, 9, 2, 2, 2, 9, 2, 2, 2, 9, 2

2, 2, 9, 2, 2, 2, 9, 2, 2, 2, 9, 2, 12, 2, 9, 2, 4, 4, 13

11, 11, 11, 13, 2, 2, 12, 2, 2, 2, 12, 2, 2, 2, 12, 2, 2, 2, 12

2, 2, 2, 12, 2, 2, 2, 12, 2, 2, 2, 12, 2, 2, 2, 14, 15, 15, 15, 14

end

[/data]

 

And here are the unique PF rows, 0 to 15:

[data]

data L4_0n

%00000111,%11111111,%11111111,%00000000

%00000000,%10000000,%00001000,%00000000

%00000000,%00000000,%00000000,%00000000

%00001001,%00000000,%00000100,%10000000

%00000010,%00000000,%00000010,%00000000

%00001111,%11111111,%11111111,%10000000

%00001010,%10101010,%10101010,%10000000

%00010000,%00000010,%00000000,%01000000

%00011111,%11111111,%11111111,%11000000

%00100000,%01000000,%00010000,%00100000

%00111111,%11111111,%11111111,%11100000

%00101010,%10101010,%10101010,%10100000

%01000000,%00000010,%00000000,%00010000

%01111111,%11111111,%11111111,%11110000

%11111111,%11111111,%11111111,%11111000

%10101010,%10101010,%10101010,%10101000

end

[/data]

 

print_row = 0: current_col = 0

for current_row = 0 to 175

current_col = L4p[current_row]

for print_row = 0 to 3

temp2 = current_row + print_row

current_byte = L4_0n[temp2]

for current_bit = 0 to 7

byte_ptr = current_byte[current_bit]

if byte_ptr then pfpixel current_row byte_ptr on

if !byte_ptr then pfpixel current_row byte_ptr off

next

next

next

Link to comment
Share on other sites

Probably not lucky enough to be able to directly access the playfield variables. I could see a short loop on long lines of pixels just inserting the value 255 over and over again.

In my Satan's Hollow mock-up I am pushing a byte to the playfield data stream RAM in the white "building bridge" part at the lower right.

When you grab the white "Ball" from the left and it gets to the right, I DF7PUSH %10000000, then %11000000 and so on (except it is upside down (draws bottom up) and backwards (the first 2 bridge pixels are %00000011 I think))

Above the bridge i am pushing a few lines of random.

http://atariage.com/forums/topic/210959-satans-hollow-demo/?p=2762691

So there are not "playfield variables" like bB 1, but I am dreaming up wild possibilities.

  • Like 1
Link to comment
Share on other sites

I cant write a routine for this.

The below table values could be stored in nibbles. 0 1, 2 1, etc. for savings, but I cant get this simple routine working

 

If I understand correctly, L4_0n is the data for the 16 unique rows, and L4p is the data for the row indices. Here's how I would store and retrieve the data:

 

   data L4p
   $01
   $21
   $21
   $21
   $21
   $21
   $21
   $21
   $21
   $21
   $21
   $21
   $21
   $21
   $32
   $45
   $66
   $65
   $22
   $32
   $22
   $32
   $22
   $32
   $22
   $32
   $22
   $32
   $22
   $32
   $72
   $32
   $44
   $86
   $66
   $82
   $27
   $22
   $27
   $22
   $27
   $22
   $27
   $22
   $27
   $22
   $26
   $29
   $27
   $22
   $4A
   $BB
   $BA
   $22
   $92
   $22
   $92
   $22
   $92
   $22
   $92
   $22
   $92
   $22
   $92
   $C2
   $92
   $44
   $DB
   $BB
   $D2
   $2C
   $22
   $2C
   $22
   $2C
   $22
   $2C
   $22
   $2C
   $22
   $2C
   $22
   $2C
   $22
   $2E
   $FF
   $FE
end
   data PF1L_L4_0n
   %00000111
   %00000000
   %00000000
   %00001001
   %00000010
   %00001111
   %00001010
   %00010000
   %00011111
   %00100000
   %00111111
   %00101010
   %01000000
   %01111111
   %11111111
   %10101010
end
   data PF2L_L4_0n
   %11111111
   %10000000
   %00000000
   %00000000
   %00000000
   %11111111
   %10101010
   %00000010
   %11111111
   %01000000
   %11111111
   %10101010
   %00000010
   %11111111
   %11111111
   %10101010
end
   data PF2R_L4_0n
   %11111111
   %00001000
   %00000000
   %00000100
   %00000010
   %11111111
   %10101010
   %00000000
   %11111111
   %00010000
   %11111111
   %10101010
   %00000000
   %11111111
   %11111111
   %10101010
end
   data PF1R_L4_0n
   %00000000
   %00000000
   %00000000
   %10000000
   %00000000
   %10000000
   %10000000
   %01000000
   %11000000
   %00100000
   %11100000
   %10100000
   %00010000
   %11110000
   %11111000
   %10101000
end
   current_row = 0
decompress_L4_loop
   print_row = L4p[current_row]
   current_byte = print_row / 16
   PF1L[2 * current_row] = PF1L_L4_0n[current_byte]
   PF2L[2 * current_row] = PF2L_L4_0n[current_byte]
   PF2R[2 * current_row] = PF2R_L4_0n[current_byte]
   PF1R[2 * current_row] = PF1R_L4_0n[current_byte]
   current_byte = print_row & 15
   PF1L[2 * current_row + 1] = PF1L_L4_0n[current_byte]
   PF2L[2 * current_row + 1] = PF2L_L4_0n[current_byte]
   PF2R[2 * current_row + 1] = PF2R_L4_0n[current_byte]
   PF1R[2 * current_row + 1] = PF1R_L4_0n[current_byte]
   current_row = current_row + 1
   if current_row <> 88 then goto decompress_L4_loop

Now, if you need to keep the cycles predictable then you'd want to make sure each data table doesn't cross a page boundary, as that would add extra cycles. And that decompression loop isn't exact and isn't intended to be "legal bB"-- in particular, the eight PFxx[] statements are meant to represent whatever you have to do to push or store the retrieved PF data into the RAM locations from which the DPC+ kernel will read it, which I don't know how to do yet (as I've

yet to learn about the DPC+ kernel). But I'm hoping you can get the basi idea and either figure that part out yourself or get help from someone else.

Link to comment
Share on other sites

Thanks Sea.

But i just need a loop for lines 0 to 176

Using the "line" number from L4p which corresponds to the data in L4_0n as:

 

data L4_0n

0 line, 4 bytes

1 line, 4 bytes , etc.

2

3

4

5

6

7

8

9

10

11

12

13

14

15

end

 

and then turn on or off each pixel in the 4 bytes by:

If "bit is a one" then pfpixel current_row(1 to 176) byte_ptr(1 to 32 PF bits) on

If "bit is a zero" then pfpixel row pixel off

if byte_ptr then pfpixel current_row byte_ptr on

if !byte_ptr then pfpixel current_row byte_ptr off

Edit: theloon has confused the issue by asking about accessing the PF directly which can be done, but nobody has figured a way yet, so we have to use batari Basic pfpixel command to turn each pixel on or off.

Link to comment
Share on other sites

SeaGtGruff,

Your code sure works!

Because with this:

 
  DF6LOW = 184
  DF6HI = %00001001
  DF7LOW = 184
  DF7HI = %00001000
 
   current_row = 0
decompress_L4_loop
   print_row = L4p[current_row]
   current_byte = print_row / 16
  DF6PUSH = PF1L_L4_0n[current_byte]
  DF7PUSH = PF2L_L4_0n[current_byte]
 rem   DF6PUSH = PF1R_L4_0n[current_byte]
 rem   DF7PUSH = PF2R_L4_0n[current_byte]
 rem 
 rem   DF7PUSH = PF2R_L4_0n[current_byte]
 rem   DF6PUSH = PF1R_L4_0n[current_byte]
 rem 
 rem    PF1L[2 * current_row] = PF1L_L4_0n[current_byte]
 rem    PF2L[2 * current_row] = PF2L_L4_0n[current_byte]
 rem    PF2R[2 * current_row] = PF2R_L4_0n[current_byte]
 rem    PF1R[2 * current_row] = PF1R_L4_0n[current_byte]
   current_byte = print_row & 15
  DF6PUSH = PF1L_L4_0n[current_byte]
  DF7PUSH = PF2L_L4_0n[current_byte]
 rem   DF7PUSH = PF2R_L4_0n[current_byte]
 rem   DF6PUSH = PF1R_L4_0n[current_byte]
 rem 
 rem    PF2L[2 * current_row + 1] = PF2L_L4_0n[current_byte]
 rem    PF2R[2 * current_row + 1] = PF2R_L4_0n[current_byte]
 rem    PF1R[2 * current_row + 1] = PF1R_L4_0n[current_byte]
   current_row = current_row + 1
   if current_row <> 88 then goto decompress_L4_loop
I got this!!!! :
post-29575-0-55442200-1378688045_thumb.png
So there it is. Upside down. And only the right half of the screen.
Thanks Sea & RevEng, now this is some progress.
Link to comment
Share on other sites

 

So there it is. Upside down. And only the right half of the screen.
Thanks Sea & RevEng, now this is some progress.

 

 

To get it rightside-up, change the decompress loop as follows:

 

 

   current_row = 87
decompress_L4_loop
   print_row = L4p[current_row]
   current_byte = print_row / 16
  DF6PUSH = PF1L_L4_0n[current_byte]
  DF7PUSH = PF2L_L4_0n[current_byte]
 rem   DF6PUSH = PF1R_L4_0n[current_byte]
 rem   DF7PUSH = PF2R_L4_0n[current_byte]
 rem 
 rem   DF7PUSH = PF2R_L4_0n[current_byte]
 rem   DF6PUSH = PF1R_L4_0n[current_byte]
 rem 
 rem    PF1L[2 * current_row] = PF1L_L4_0n[current_byte]
 rem    PF2L[2 * current_row] = PF2L_L4_0n[current_byte]
 rem    PF2R[2 * current_row] = PF2R_L4_0n[current_byte]
 rem    PF1R[2 * current_row] = PF1R_L4_0n[current_byte]
   current_byte = print_row & 15
  DF6PUSH = PF1L_L4_0n[current_byte]
  DF7PUSH = PF2L_L4_0n[current_byte]
 rem   DF7PUSH = PF2R_L4_0n[current_byte]
 rem   DF6PUSH = PF1R_L4_0n[current_byte]
 rem 
 rem    PF2L[2 * current_row + 1] = PF2L_L4_0n[current_byte]
 rem    PF2R[2 * current_row + 1] = PF2R_L4_0n[current_byte]
 rem    PF1R[2 * current_row + 1] = PF1R_L4_0n[current_byte]
   current_row = current_row - 1
   if current_row <> 255 then goto decompress_L4_loop
Link to comment
Share on other sites

Well, something falls apart:

Plus that is the wrong center section.

Edit: Also to fill the DPC+ data streams, I believe the PF1 and PF2 data would have to be together. Like PF1L & PF1R as one dataset.

And I don't know if bB is drawing PF1 PF2 PF2 PF1 or PF1 PF2 PF1 PF2 ??

post-29575-0-11351900-1378693652_thumb.png

Edited by iesposta
Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...