Jump to content
IGNORED

Drawing playfields from data statements


Grebnedlog

Recommended Posts

I've been trying to write an elegant loop statement that can rewrite chunks of longer playfields from data statements, but I've been failing a lot more than I planned to. 8)

 

Basically, the attached program writes 256 consecutive bytes of the playfield using the pfpixel command and a data statement (the idea here was to conserve some romspace in the graphics bank of DPC+ programs by defining some playfield data in other banks, and I'm assuming - maybe wrongly - this is the best way to do it.) The write-routine works, but it's too expensive in ROM to be useful right now (705 bytes):

 

data objectdata
0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0
end


WritePFChunk
for temp1 = 0 to 31
if objectdata[temp1] = 1 then pfpixel temp1 current_row on
temp2 = temp1 + 32 : temp3 = current_row + 1
if objectdata[temp2] = 1 then pfpixel temp1 temp3 on
temp2 = temp1 + 64 : temp3 = current_row + 2
if objectdata[temp2] = 1 then pfpixel temp1 temp3 on
temp2 = temp1 + 96 : temp3 = current_row + 3
if objectdata[temp2] = 1 then pfpixel temp1 temp3 on
temp2 = temp1 + 128 : temp3 = current_row + 4
if objectdata[temp2] = 1 then pfpixel temp1 temp3 on
temp2 = temp1 + 160 : temp3 = current_row + 5
if objectdata[temp2] = 1 then pfpixel temp1 temp3 on
temp2 = temp1 + 192 : temp3 = current_row + 6
if objectdata[temp2] = 1 then pfpixel temp1 temp3 on
temp2 = temp1 + 224 : temp3 = current_row + 7
if objectdata[temp2] = 1 then pfpixel temp1 temp3 on
next

 

I might have some sort of basic brain problem here... this doesn't seem like such a complex task. I've tried to do it with nested for-loops and pointers, but these approaches either don't work as expected or cause a fatal ARM exception. Essentially, I need to advance the data pointer by 32 elements eight times using the fewest bytes possible, and I know the above method is pretty dumb. Can anyone help out?

draw_pf_from_array.bas.bin

draw_pf_from_array.bas

Edited by Grebnedlog
Link to comment
Share on other sites

As I understand it Batari's stated plan is to only allow graphic data like playfields access the extra storage space. He said maybe on allowing use for SDATA and was even less enthusiastic about normal DATA statements (which is what I'd want it for most).

 

So, if I got my info right, just using normal playfield statements sounds like the way forward. That being said, why not just use consecutive pfpixel statements and call it a day?

 

Also, what RevEng said. My opinion is that temp vars are too unpredictable for normal use. i actually "waste" one or two normal vars for temp usage.

 

Also, once more, are you using each 8-bit data statement element as one playfield pixel? I didn't have time to figure out if you were. If so, I'd suggest using each of the 8 bits in an element as playfield pixels.

Edited by theloon
Link to comment
Share on other sites

pfpixel and similar functions obliterate temp1, temp2, and temp3, which is probably why you're having trouble with the looping and getting ARM exceptions.

 

Aha! Thanks so much, that indeed seems to be the trouble. :)

 

With that in mind, this version already looking a lot more streamlined, and saving some precious bytes:

 

dim current_row = a
dim current_col = b
dim lo_pointer = c
dim current_pixel = d
dim print_row = e
dim chunk_start = f

chunk_start = 20


PROGRAMLOOP
DF0FRACINC=128
DF1FRACINC=128
DF2FRACINC=128
DF3FRACINC=128
DF4FRACINC=255
DF6FRACINC=24
if joy0fire then z{0} = 1
if !joy0fire && z{0} then gosub WritePFChunk
drawscreen
goto PROGRAMLOOP



data hellodata
0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,1,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,1,1,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,0,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,0,0,0,
0,0,0,0,0,0,1,0,0,1,0,1,1,1,0,1,1,1,0,1,1,1,0,1,1,1,0,0,0,0,0,0
end


WritePFChunk
for current_row = 0 to 8
for current_col = 0 to 31
current_pixel = lo_pointer + current_col
print_row = chunk_start + current_row
if hellodata[current_pixel] = 1 then pfpixel current_col print_row on
next
lo_pointer = current_row * 32
next

z{0} = 0

return thisbank

 

 

That said, I'm wondering if there's a way to slim it down even more?

 

Also, now I'm starting to wonder in general if there's a way to reuse the same routine with variable data statements in bB, but without hard coding the name of the set each time. In other words, could the line:

 if hellodata[current_pixel] = 1 then pfpixel current_col print_row on

be expressed such that "hellodata" is replaced with a variable that points to one of 256-byte several tables in ROM (i.e. "goodbyedata", "endofdata", etc.)? Or would that line have to be repeated for each table name?

 

EDIT: Ugh, the site screwed up my code formatting a bit, so I attached the new BAS and BIN

draw_pf_from_array_v2.bas

draw_pf_from_array_v2.bas.bin

Edited by Grebnedlog
Link to comment
Share on other sites

Aha! Thanks so much, that indeed seems to be the trouble. :)

 

Not a problem. I only nudged you in the right direction. :)

 

 

...

That said, I'm wondering if there's a way to slim it down even more?

 

Also, now I'm starting to wonder in general if there's a way to reuse the same routine with variable data statements in bB, but without hard coding the name of the set each time.

 

The best way to slim it down (as theloon suggested) is to convert your data to use binary representation instead of setting bytes to 0's and 1's. (eg. %11001101 would replace 1,1,0,0,1,1,0,1,...) Each screen will go from using 256 bytes to using 32 bytes.

 

There isn't a way in pure bB to pass on a reference to an array. (or any variable)

 

How many screens worth of data are we talking about? If you convert to binary representation and it's 8 or less you could fit them all into a single data statement, and just offset which row you begin with to access them individually. If it's more, then you need to convert to using sdata.

Link to comment
Share on other sites

possibly I misunderstand your intent.

 

On your first pass through the inner for loop

current_col will be 0 and lo_pointer will be whatever

you haven't set lo_pointer yet

At the end of the first pass through the loop

you'll set lo_pointer to current_col * 0

and lo_pointer will be 0 while current_col is 1

(second pass). etc

also you'll make 9 passes through the loop

(0-8 inclusive)

 

If you multiply by a power of two that's 8 or less

Bb will use shifts so * 8 * 4 compiles as shifts

* 32 calls the mutiplication routine

Link to comment
Share on other sites

As I understand it Batari's stated plan is to only allow graphic data like playfields access the extra storage space. He said maybe on allowing use for SDATA and was even less enthusiastic about normal DATA statements (which is what I'd want it for most).

 

So, if I got my info right, just using normal playfield statements sounds like the way forward. That being said, why not just use consecutive pfpixel statements and call it a day?

 

Well, I guess the point of the experiment is to maximize the graphic storage space for something other than playfield data (for instance, the project I'm working on requires the use of a lot of sprite data, and uses 88 rows of playfield pixels. So dynamically drawing certain portions of the playfield without storing that data in the graphics bank is actually pretty helpful to me. Not sure what you mean by "consecutive pfpixel statements" (from what I can tell, that's what I'm doing with my for-loop in the post above).

 

Also, what RevEng said. My opinion is that temp vars are too unpredictable for normal use. i actually "waste" one or two normal vars for temp usage.

 

Again, I'm not really sure what you mean by "normal use" here. They can't be used to store persistent data, but I wasn't trying to use them that way in my example. They do seem to have a few quirks that weren't readily apparent. For instance, I'm still not sure why the temp vars are obliterated after a pfpixel, but I know that I haven't had any problem using them to draw pixels in an un-nested for-next loop... well, not so far, at least. ;) The problem only seemed to arise when I included them in a nested loop. Perhaps RevEng could explain why that is.

 

Also, once more, are you using each 8-bit data statement element as one playfield pixel? I didn't have time to figure out if you were. If so, I'd suggest using each of the 8 bits in an element as playfield pixels.

 

The best way to slim it down (as theloon suggested) is to convert your data to use binary representation instead of setting bytes to 0's and 1's. (eg. %11001101 would replace 1,1,0,0,1,1,0,1,...) Each screen will go from using 256 bytes to using 32 bytes.

 

You know, I tried following the example in this post, but I confess I got a bit lost (Get it? A bit lost? :D). I guess part of the reason is that I'm not sure what the binary posted there is supposed to be doing. Maybe one of you can edit my v2 BAS to demonstrate how it would be converted to a binary array and drawn from my routine? I took the liberty of comma-separating the "hellodata" statement, to remove some of the grunt work for you:

 

 %00000010,%01011101,%00010001,%11000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01011101,%11011101,%11000000

 

There isn't a way in pure bB to pass on a reference to an array. (or any variable)

 

Oh, OK. Is that because the assembled code auto-labels the jump tables during compilation?

 

How many screens worth of data are we talking about? If you convert to binary representation and it's 8 or less you could fit them all into a single data statement, and just offset which row you begin with to access them individually. If it's more, then you need to convert to using sdata.

 

Well, I suppose I was only thinking of about twelve (partial) screens for the particular project I was working on, but obviously more (and smaller) is always better, and drawing the pf using a bit array with offsets would be useful for all sorts of projects, I would think.

 

Thanks to both of you for your help.

Link to comment
Share on other sites

possibly I misunderstand your intent.

 

On your first pass through the inner for loop

current_col will be 0 and lo_pointer will be whatever

you haven't set lo_pointer yet

At the end of the first pass through the loop

you'll set lo_pointer to current_col * 0

and lo_pointer will be 0 while current_col is 1

(second pass). etc

also you'll make 9 passes through the loop

(0-8 inclusive)

 

If you multiply by a power of two that's 8 or less

Bb will use shifts so * 8 * 4 compiles as shifts

* 32 calls the mutiplication routine

 

When lo_pointer is zero, the routine is searching the array values representing the first row in the "playfield chunk" (i.e. the segment of the playfield being drawn). The lo_pointer advances by 32 on each iteration to draw the next playfield row, starting with playfield position 0 and advancing to position 31. The routine checks the value, then draws a pixel if it reads a "1".

 

As RevEng and theloon pointed out above, this routine would obviously be a lot better (and more useful) if the array data could be read as a binary array, since only on/off states are needed. I'm fighting my way through the binary array examples you provided on that other thread, but I'm not sure how to adapt it to this purpose. Any help would be much appreciated.

Edited by Grebnedlog
Link to comment
Share on other sites

I phrased that poorly

 

Suppose you set lo_pointer = 15 (some arbitrary value)

then call WritePFChunk

 

then the first time you run the current_col

loop current_row = 0 and lo_pointer = 15

at the end of the first pass through the

current_row loop lo_pointer will get set to 0

ie 0 * 32 so your passes would go like this

 

current row = 0, lo_pointer = 15

current row = 1, lo_pointer = 0

current row = 2, lo_pointer = 32

current row = 3, lo_pointer = 64

current row = 4, lo_pointer = 96

current row = 5, lo_pointer = 128

current row = 6, lo_pointer = 160

current row = 7, lo_pointer = 192

current row = 8, lo_pointer = 224

 

9 iterations of the current row loop

the first one with what ever lo_pointer is

when you call WritePFChunk

Link to comment
Share on other sites

I phrased that poorly

 

Suppose you set lo_pointer = 15 (some arbitrary value)

then call WritePFChunk

 

then the first time you run the current_col

loop current_row = 0 and lo_pointer = 15

at the end of the first pass through the

current_row loop lo_pointer will get set to 0

ie 0 * 32 so your passes would go like this

 

current row = 0, lo_pointer = 15

current row = 1, lo_pointer = 0

current row = 2, lo_pointer = 32

current row = 3, lo_pointer = 64

current row = 4, lo_pointer = 96

current row = 5, lo_pointer = 128

current row = 6, lo_pointer = 160

current row = 7, lo_pointer = 192

current row = 8, lo_pointer = 224

 

9 iterations of the current row loop

the first one with what ever lo_pointer is

when you call WritePFChunk

 

Okay, I think I see what you mean. If so, then yes you are right that it is the wrong number of iterations. I changed it to "for current_row 1 to 8." Thanks!

 

Is there any chance you can help with converting this to a binary bitmap routine?

Edited by Grebnedlog
Link to comment
Share on other sites

You could straight up use code to avoid DATA statements and complicated for next loops.

pfpixel 1 1 on : pfpixel 2 1 on : pfpixel 3 1 on : pfpixel 4 1 on : pfpixel 5 1 on : pfpixel 3 2 on : pfpixel 3 3 on : pfpixel 8 3 on : pfpixel 9 3 on : pfpixel 10 3 on : pfpixel 11 3 on : pfpixel 3 4 on
pfpixel 8 4 on : pfpixel 27 4 on : pfpixel 28 4 on : pfpixel 3 5 on : pfpixel 8 5 on : pfpixel 9 5 on : pfpixel 15 5 on : pfpixel 16 5 on : pfpixel 17 5 on : pfpixel 27 5 on : pfpixel 28 5 on : pfpixel 8 6 on
pfpixel 14 6 on : pfpixel 20 6 on : pfpixel 21 6 on : pfpixel 22 6 on : pfpixel 23 6 on : pfpixel 24 6 on : pfpixel 27 6 on : pfpixel 28 6 on : pfpixel 8 7 on : pfpixel 9 7 on : pfpixel 10 7 on : pfpixel 11 7 on
pfpixel 15 7 on : pfpixel 16 7 on : pfpixel 22 7 on : pfpixel 27 7 on : pfpixel 28 7 on : pfpixel 17 8 on : pfpixel 22 8 on : pfpixel 14 9 on : pfpixel 15 9 on : pfpixel 16 9 on : pfpixel 22 9 on : pfpixel 27 9 on
pfpixel 28 9 on : pfpixel 22 10 on

 

If that code is run the playfield should look like this:

................................
.XXXXX..........................
...X............................
...X....XXXX....................
...X....X..................XX...
...X....XX.....XXX.........XX...
........X.....X.....XXXXX..XX...
........XXXX...XX.....X....XX...
.................X....X.........
..............XXX.....X....XX...
......................X.........

 

The only thing to watch out for is going over your CPU cycles so the screen starts to roll. The easy way out is to break up your pfpixel commands with an appropriate DRAWSCREEN somewhere.

 

Also, normal use means expecting temp vars to look, feel and taste like normal vars. You can't expect the values to hold. You can't expect the calculations to actually happen. Just don't use them. Trust me.

Edited by theloon
Link to comment
Share on other sites

Okay, I think I see what you mean. If so, then yes you are right that it is the wrong number of iterations. I changed it to "for current_row 1 to 8." Thanks!

 

That might do it but then you need to intialize

lo_pointer

 

Your rows are going to be addressed as 0-7

 

Is there any chance you can help with converting this to a binary bitmap routine?

 

I can try but you probably want someone who knows what they're doing ;P

 

I'd imagine it something like this:

 

dim current_row = a
dim current_col = b
dim current_byte = c
dim current_bit = d
dim print_row = e
dim chunk_start = f

chunk_start = 20


PROGRAMLOOP
DF0FRACINC=128
DF1FRACINC=128
DF2FRACINC=128
DF3FRACINC=128
DF4FRACINC=255
DF6FRACINC=24
if joy0fire then z{0} = 1
if !joy0fire && z{0} then gosub WritePFChunk
drawscreen
goto PROGRAMLOOP


WritePFChunk
for current_row = 0 to 7
for current_col = 0 to 31
current_byte = current_col / 8 + lo_pointer[current_row]
current_bit = current_col & 7
print_row = chunk_start + current_row
if hellodata[current_byte] & setbits[current_bit] then pfpixel current_col print_row on
next
next

z{0} = 0

return thisbank


bank 3

bank 4

bank 5

bank 6

data lo_pointer
0, 4, 8, 12, 16, 20, 24, 28
end

data hellodata
%00000010,%01011101,%00010001,%11000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01011101,%11011101,%11000000
end

data setbits
%10000000, %01000000, %00100000, %00010000,
%00001000, %00000100, %00000010, %00000001
end

 

I used a look up table for lo_pointer because it

only costs a couple bytes, doesn't use a variable

and is faster

 

edit: ack! wrong! it's significantly slower

(forgot that moves it into the inner loop)

 

so using a variable:

dim current_row = a
dim current_col = b
dim current_byte = c
dim current_bit = d
dim lo_pointer = e
dim print_row = f
dim chunk_start = g

chunk_start = 20


PROGRAMLOOP
DF0FRACINC=128
DF1FRACINC=128
DF2FRACINC=128
DF3FRACINC=128
DF4FRACINC=255
DF6FRACINC=24
if joy0fire then z{0} = 1
if !joy0fire && z{0} then gosub WritePFChunk
drawscreen
goto PROGRAMLOOP


WritePFChunk
for current_row = 0 to 7
lo_pointer = current_row * 4
for current_col = 0 to 31
current_byte = current_col / 8 + lo_pointer
current_bit = current_col & 7
print_row = chunk_start + current_row
if hellodata[current_byte] & setbits[current_bit] then pfpixel current_col print_row on
next
next

z{0} = 0

return thisbank


bank 3

bank 4

bank 5

bank 6


data hellodata
%00000010,%01011101,%00010001,%11000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01011101,%11011101,%11000000
end

data setbits
%10000000, %01000000, %00100000, %00010000,
%00001000, %00000100, %00000010, %00000001
end

 

damn! more edits:

should be

current_byte = current_col / 8 + lo_pointer

 

even more editing: fixed the setbits (see below)

Edited by bogax
Link to comment
Share on other sites

You could straight up use code to avoid DATA statements and complicated for next loops.

pfpixel 1 1 on : pfpixel 2 1 on : pfpixel 3 1 on : pfpixel 4 1 on : pfpixel 5 1 on : pfpixel 3 2 on : pfpixel 3 3 on : pfpixel 8 3 on : pfpixel 9 3 on : pfpixel 10 3 on : pfpixel 11 3 on : pfpixel 3 4 on
pfpixel 8 4 on : pfpixel 27 4 on : pfpixel 28 4 on : pfpixel 3 5 on : pfpixel 8 5 on : pfpixel 9 5 on : pfpixel 15 5 on : pfpixel 16 5 on : pfpixel 17 5 on : pfpixel 27 5 on : pfpixel 28 5 on : pfpixel 8 6 on
pfpixel 14 6 on : pfpixel 20 6 on : pfpixel 21 6 on : pfpixel 22 6 on : pfpixel 23 6 on : pfpixel 24 6 on : pfpixel 27 6 on : pfpixel 28 6 on : pfpixel 8 7 on : pfpixel 9 7 on : pfpixel 10 7 on : pfpixel 11 7 on
pfpixel 15 7 on : pfpixel 16 7 on : pfpixel 22 7 on : pfpixel 27 7 on : pfpixel 28 7 on : pfpixel 17 8 on : pfpixel 22 8 on : pfpixel 14 9 on : pfpixel 15 9 on : pfpixel 16 9 on : pfpixel 22 9 on : pfpixel 27 9 on
pfpixel 28 9 on : pfpixel 22 10 on

 

No offense intended, but I'm not sure why would that be better than my nested loop statement. I mean, both our versions work, but your version seems like it would be a nightmare for drawing lots of pictures with. Design workflow for my version would just involve drawing a playfield in the ordinary way (either by using tools or typing it out ASCII style), using find-replace to comma separate, copying it into a data array (in the bank of my choosing), and having the program run the routine whenever I need to draw or redraw a section of the playfield.

 

Also, my version allows the programmer to vary the position (vertical only, right now, but probably easily adaptable for horizontal) of the playfield graphic being drawn. For instance, with my V2 version, you can change the message from "HELLO WORLD" to "WORLD HELLO" simply by changing "chunk_start = 20" to "chunk_start=70", whereas your static version would require recoding all the pfpixel statements to achieve the same effect (essentially doubling the ROM space used, too).

 

The only thing to watch out for is going over your CPU cycles so the screen starts to roll. The easy way out is to break up your pfpixel commands with an appropriate DRAWSCREEN somewhere.

 

Actually, for the particular project I had in mind this wouldn't be a problem, since the drawing routine doesn't happen during gameplay, but rather before a new game level starts (i.e. setting up the game map, obstacles, etc). I essentially shut off the display while this is going on by reducing the screen resolution to 1 until the process is finishes, meaning the screen won't appear to roll even if the improper number of scanlines are drawn (which, they most definitely will be). I've tested this on real hardware and it works pretty much as expected. The screen goes black for a second while the drawing is done, and then I increase the screen res just before the level starts.

 

Also, normal use means expecting temp vars to look, feel and taste like normal vars. You can't expect the values to hold. You can't expect the calculations to actually happen. Just don't use them. Trust me.

 

Well, I guess we'll have to agree to disagree on that one. I personally am finding the temp vars indispensable for certain in-game routines (particularly for things like soft collisions, where a temp can act as a second "edge" for a sprite coordinate during an overlap test). It's true they aren't useful as general purpose variables (seing as they are temporary), but not using them at all seems a little extreme.

Link to comment
Share on other sites

No offence taken. But, I'm still not sure how the extra cycles needed for loops and taking the more indirect approach of DATA statements help.

 

Well, I guess the idea is a based on a tradeoff. In this case, the tradeoff is between hi-res playfield definitions and hi-res sprite definitions. Both share the same bank in the DPC+ framework, so if you want more of one, you'll necessarily have less of the other. If I wanted to have 88-row multicolored playfields (which I do) and had to rely solely on using the static playfield definitions, I wouldn't be able to include very many of them, and won't be able to include lots of sprite data either. Live playfield drawing seems far more useful in general for hi-res screens, but particularly if you want to have lots of varying kinds of sprites.

 

From what I can see, the loop statement I used isn't really using that many more cycles than a string of successive static pfpixel commands would (and the screen would roll for either version, if you don't take precautions). Also, your version uses 1650 bytes of ROM, and to draw only 11 rows in one static position. My version draws 8 rows wherever I want them, and only uses 373 bytes (256 of which is the data array itself, and the other 117 of which can be reused to draw multiple screens) and it will use far less still if we can get binary arrays working.

 

Actually, that would be really exciting... if that was the case, a single data statement could draw a full, fairly high resolution screen without sacrificing any space for sprite data.

Edited by Grebnedlog
Link to comment
Share on other sites

That might do it but then you need to intialize

lo_pointer

 

Your rows are going to be addressed as 0-7

 

Oh, okay. Got it now.

 

I can try but you probably want someone who knows what they're doing ;P

 

Ha! Based on that other thread, I'm fairly sure you know what you're doing. Now I just want to be sure that I know what you're doing. :)

 

I'd imagine it something like this:

 

dim current_row = a
dim current_col = b
dim current_byte = c
dim current_bit = d
dim print_row = e
dim chunk_start = f

chunk_start = 20


PROGRAMLOOP
DF0FRACINC=128
DF1FRACINC=128
DF2FRACINC=128
DF3FRACINC=128
DF4FRACINC=255
DF6FRACINC=24
if joy0fire then z{0} = 1
if !joy0fire && z{0} then gosub WritePFChunk
drawscreen
goto PROGRAMLOOP


WritePFChunk
for current_row = 0 to 7
for current_col = 0 to 31
current_byte = current_col / 8 + lo_pointer[current_row]
current_bit = current_col & 7
print_row = chunk_start + current_row
if hellodata[current_byte] & setbits[current_bit] then pfpixel current_col print_row on
next
next

z{0} = 0

return thisbank


bank 3

bank 4

bank 5

bank 6

data lo_pointer
0, 4, 8, 12, 16, 20, 24, 28
end

data hellodata
%00000010,%01011101,%00010001,%11000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01011101,%11011101,%11000000
end

data setbits
%00000001, %00000010, %00000100, %00001000
%00010000, %00100000, %01000000, %10000000
end

 

I used a look up table for lo_pointer because it

only costs a couple bytes, doesn't use a variable

and is faster

 

edit: ack! wrong! it's significantly slower

(forgot that moves it into the inner loop)

 

so using a variable:

 dim current_row = a
dim current_col = b
dim current_byte = c
dim current_bit = d
dim lo_pointer = e
dim print_row = f
dim chunk_start = g

chunk_start = 20


PROGRAMLOOP
DF0FRACINC=128
DF1FRACINC=128
DF2FRACINC=128
DF3FRACINC=128
DF4FRACINC=255
DF6FRACINC=24
if joy0fire then z{0} = 1
if !joy0fire && z{0} then gosub WritePFChunk
drawscreen
goto PROGRAMLOOP


WritePFChunk
for current_row = 0 to 7
lo_pointer = current_row * 4
for current_col = 0 to 31
current_byte = current_col / 8 + lo_pointer
current_bit = current_col & 7
print_row = chunk_start + current_row
if hellodata[current_byte] & setbits[current_bit] then pfpixel current_col print_row on
next
next

z{0} = 0

return thisbank


bank 3

bank 4

bank 5

bank 6


data hellodata
%00000010,%01011101,%00010001,%11000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000011,%11011101,%00010001,%01000000
%00000010,%01010001,%00010001,%01000000
%00000010,%01011101,%00010001,%01000000
%00000010,%01011101,%11011101,%11000000
end

data setbits
%00000001, %00000010, %00000100, %00001000
%00010000, %00100000, %01000000, %10000000
end

 

damn! more edits:

should be

current_byte = current_col / 8 + lo_pointer

 

Thanks! The resulting binary looks close to correct. However, instead of saying "HELLO", my screen looks like this:

 

post-33796-0-86920700-1349390051_thumb.jpg

 

I believe that's Klingon for "Destroy all humans" ;)

 

Seriously, though, I guess it looks like it's reading some of the data in backwards, and starting to write it in the middle of the screen. Any ideas?

 

EDIT:

Oh, I also forgot to mention that bB cannot see data in different banks from the one that is reading them, so I cut and pasted the arrays back into bank 2 with the WritePFChunk routine (though, I suppose, you could alternately stick the routine in bank 6, and then bankswitch to it from the main loop.)

Edited by Grebnedlog
Link to comment
Share on other sites

@bogax

 

Okay, I see the problem. The elements in your setbits array were just in reverse order. Changed it to this and it works fine now:

 

 data setbits
%10000000, %01000000, %00100000, %00010000,
%00001000, %00000100, %00000010, %00000001
end

 

Thanks again! I think this could be very useful for hi-def playfield drawing.

 

EDIT:

Attached a BAS file combining all edits and corrections.

draw_pf_from_binary_array.bas

Edited by Grebnedlog
Link to comment
Share on other sites

Another thought.

 

Looks like you could pull the print_row

assignment out of the inner loop

 

for current_row = 0 to 7
lo_pointer = current_row * 4
print_row = chunk_start + current_row
for current_col = 0 to 31
current_byte = current_col / 8 + lo_pointer
current_bit = current_col & 7
if hellodata[current_byte] & setbits[current_bit] then pfpixel current_col print_row on
next
next

Link to comment
Share on other sites

@bogax

 

Okay, I see the problem. The elements in your setbits array were just in reverse order. Changed it to this and it works fine now:

 

 data setbits
%10000000, %01000000, %00100000, %00010000,
%00001000, %00000100, %00000010, %00000001
end

 

Heck! Darn! Other obscenities as required!

 

And since the binary array thread is talking about

screen stuff and not bit variables they're backwards

there too.

 

Ha! Based on that other thread, I'm fairly sure you know what you're doing.

 

How sure are you now ;)

.

Edited by bogax
Link to comment
Share on other sites

What release number of the DPC+ kernel are you using? I am using the version from January 2011.

 

set kernel DPC+
set kernel_options collision(playfield,player1)
set optimization inlinerand
set smartbranching on
set tv ntsc

 

 

Above is what the first few lines of your code say in both BAS files. Is that a typo? I am still new to using DPC+ ,so I don't know.

 

I tried both of the BAS files posted but the compilation fails. I changed around the kernel options but then it was looking for pfcolors, then bkcolors..

 

Any help to get it to compile is welcome. :)

Link to comment
Share on other sites

What release number of the DPC+ kernel are you using? I am using the version from January 2011.

 

set kernel DPC+
set kernel_options collision(playfield,player1)
set optimization inlinerand
set smartbranching on
set tv ntsc

 

 

Above is what the first few lines of your code say in both BAS files. Is that a typo? I am still new to using DPC+ ,so I don't know.

 

I tried both of the BAS files posted but the compilation fails. I changed around the kernel options but then it was looking for pfcolors, then bkcolors..

 

Any help to get it to compile is welcome. :)

 

 

Is what a typo? Not sure I understand your question, but I'm using bB version 1.1d.

Link to comment
Share on other sites

Is what a typo? Not sure I understand your question, but I'm using bB version 1.1d.

 

I didn't recognize this kernel option:

 

set kernel_options collision(playfield,player1)

 

But then, it looks like I need to update my DPC+ files. I have been focused on using the multisprite kernel, so I probably missed a few updates to DPC+.

 

K, thanks, I will try it out again and post if I have any further issues. :)

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