+Gemintronic Posted July 31, 2012 Share Posted July 31, 2012 (edited) So, RevEng thinks that inline pfread may be broken (for multi-sprite kernel). In that case I'd have to make a collision map of the playfield. Unfortunatly, SDATA statement appear to be broken in the latest bB 1.1. A multi-sprite playfield would have 32x40 elements. The normal DATA statement can only hold 256 values. It would make sense to use an array of binary values to represent either empty space (0) or a playfield pixel (1). How does one use DATA as a binary array? Is there an easy way to access, say, the 107th binary element from a DATA statement? Batari himself uses a binary array in his RallyB example but it's indecipherable to me. http://www.atariage....e/#entry2566587 Edited July 31, 2012 by theloon Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted August 1, 2012 Author Share Posted August 1, 2012 (edited) Normally I'd think that one would make a function that returns a binary value from a DATA statement like so: (assuming the DATA statement is named "leveldata") function levelarray rem The first argument is the x value wanted from the level data rem The second argument is the y value wanted levelx = temp1 levely = temp2 rem Figure out what 8-bit value that has the bit we need whatcell = levelx * levely rem Divide that value by 10 to get the position of the bit we want from that 8-bit value whatbit = whatcell / 10 rem Read the 8-bit cell we want to a variable thecell = leveldata[whatcell] rem Return the bit we want from the 8-bit value return thecell[whatbit] end Is this how it works? Edited August 1, 2012 by theloon Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted August 2, 2012 Share Posted August 2, 2012 (edited) How does one use DATA as a binary array? Is there an easy way to access, say, the 107th binary element from a DATA statement? Loon, yes you could turn your 107th bit offset into a byte offset plus a bit offset: Divide by 8 and grab the remainder - the 107th binary element is the 3rd bit in the 14th byte; you can check to see if the 3rd bit is on by ANDing just the third bit (%00000100). If the result is >0 the bit is set And only keeps the bits turned on that are both turned on; since you're masking every other bit as off you will only get a zero result if the target bit you are checking for is off - if your byte was %10101010 and you AND %000000100 the results would be zero, showing the third bit was off. Edited August 2, 2012 by Mr SQL 1 Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted August 2, 2012 Author Share Posted August 2, 2012 (edited) So, er, umm.. Given that you want the 251th row, 253rd column in a binary array (made out of 8-bit values) you would: You divide the x value in a binary map data array by 8 You divide the y value wanted by 8 You multiply the new x and y values to get the 8-bit cell you want (DATA statements are one dimensional arrays - we're just using them as 2d) Then you extract the bit in that cell by the remainder of y? Help Mr. SQL! I feel like I'm doing an outer join with my math skills and BASIC commands Edited August 2, 2012 by theloon Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted August 3, 2012 Share Posted August 3, 2012 (edited) LOL! I like your SQL humour Loon! Aha you want x and y, not just the nth element of the binary array. You're right about the data being a 1D array but we can change that conceptually by picking a row length. Say we want to turn this 1D array into a table (2D array) of 16x3 (X and Y) elements: .byte 01010101, 01010101, 0001111, 1110111, 0000011,1111101 becomes: byte. 10101010, 01010101 byte. 01101010, 01010101 byte. 00000011, 11111110 Now we can calculate X and Y coordinates with ease from our table construct. Say you want to find the bit at the X and Y coordinates 12,2 (where 0,0 is in the upper left): Multiply your row size (in bytes, not bits) by your Y value: 2x2 bytes=4 This is your offset that turns that 1D array into a 2D table You can see that it brings us down to the start of the 3rd line; now just add the math we talked about previously to walk to the target bit - 8 goes into 12 once with 4 left over so the target bit is the 4th bit of the next byte (2nd byte in the row). Technically it is the 5th bit of that byte but we are using 0,0 offset coordinates and reading all the bits in the row from left to right Now do an AND against that byte with a bit mask like we talked about above, masking all of the bits in the comparison except the target bit you want to check is on or off. Edited August 3, 2012 by Mr SQL Quote Link to comment Share on other sites More sharing options...
+Gemintronic Posted August 3, 2012 Author Share Posted August 3, 2012 (edited) Okay, this is my attempt to integrate the hints Mr SQL gave me. I couldn't get div_mul16.asm to compile so I couldn't use a remainder value. I don't think I'm doing it right yet.. Since SDATA is broke I can only use 256 values per DATA statement. This means 128x128 binary values or 16x16 8-bit values. include div_mul.asm rem Kernel options set smartbranching on set romsize 4k dim mapx = a dim mapy = b dim cell = c dim cellx = d dim celly = e dim bit = f dim result = g player0: %11000011 %10000001 %00000000 %00000000 %00000000 %00000000 %10000001 %11000011 end playfield: XX............................XX X..............................X ................................ ................................ ................................ ................................ ................................ ................................ ................................ X..............................X XX............................XX end init COLUPF=$4E scorecolor = $0E rem We want to get the binary value 5 rows by 5 columns into the map data. mapx = 5 mapy = 5 rem Convert the binary x and y into 8 bit values rem Multiply the y value by 16 as the data array is 16 8-bit values wide celly = (mapy * 16) rem Divide the binary x value by 8 as each binary value is stored in an 8 bit data entry cellx = (mapx / rem Add the two values to get the 8 bit cell with our binary data cell = (mapx + celly) rem Grab the 8 bit value from the map data result = map[cell] rem Grab the binary x value we want from the 8 bit value we extracted from the data rem and show it as the score if result[cellx] then score = 1 else score = 0 goto main main gosub draw_event goto main draw_event drawscreen return data map %11111101, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111 %10000001, %00000011, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000111, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00011000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000001, %00000010, %00000011, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00011100, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111 end binarr.bas Edited August 3, 2012 by theloon Quote Link to comment Share on other sites More sharing options...
Mr SQL Posted August 4, 2012 Share Posted August 4, 2012 Excellent progress Loon! I see you've calculated the row offset to get your Y value and then add in your x byte off set: cellx = (mapx/8) But you need the remainder to check the bit; in this case 5/8 is zero remainder 5, or the 5th bit (reading left to right, 4th bit really) of the 1st byte in the row. One way to get the byte offset and the bit offset is with a subtract loop: xbyteoffset=0 subloop if mapx<= 8 then jumparound mapx = mapx-8 xbyteoffset=xbyteoffset+1 goto subloop jumparound cell = (xbyteoffset + celly) rem mapx now holds the remainder or target bit in the cell (0-7) rem you could use 8 handlers like these to check the status of the target bit: rem if mapx = 0 then result = cell and %1000000 rem this will check the 1st bit reading left to right if mapx = 1 then result = cell and %01000000 ... I'm not sure if that's the correct syntax for using AND but I know it's supported, check RT's command reference on AND'ing if it throws an error Quote Link to comment Share on other sites More sharing options...
bogax Posted August 15, 2012 Share Posted August 15, 2012 (edited) Things will be easiest if you can keep one dimension in powers of 2 Then you can use simple shifts and bitwise logical ops for composing the cell and bit addresses, there by avoiding expensive multiplys/divides Bb will use shifts for multiplying and dividing by low powers of two, much faster than full blown mutiplications and divisions (I think a low power of 2 means 8, 4, or 2) Near as I can tell, Bb wants a constant for bit ops so to use a variable you'll have to do it yourself If you have 256 bytes that's 2048 bits So say you have 128 (x coordinate) x 16 (y coordinate) x will be 16 (bytes) * 8 (bits) You can get the bit address (ie the bit you want in the selected cell) by simply masking for the lower 3 bits of x dim mapx = a dim mapy = b dim cell = c dim cellx = d rem x mod 8 cellx = mapx & 7 rem ORing instead of addition saves a clc so it's slightly rem faster and is possible since mapx / 8 is an integral rem power of 2 bytes per row (ie per y) rem mapy * 16 is done as mapy * 4 * 4 so that Bb will use rem shifts rather than invoking a mutilplication subroutine cell = mapy * 4 * 4 | mapx / 8 if map[cell] & setbits[cellx] then score = 1 else score = 0 rem use an adressable set of masks so you can point rem to them with a variable data setbits %10000000, %01000000, %00100000, %00010000 %00001000, %00000100, %00000010, %00000001 end data clearbits %01111111, %10111111, %11011111, %11101111 %11110111, %11111011, %11111101, %11111110 end data map %11111101, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111 %10000001, %00000011, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000111, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00011000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000001, %00000010, %00000011, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00011100, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000000, %00000001 %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111, %11111111 end If you want your map to be something closer to square, say, 40 x 51 You could use a look up table for the mutiplication or hard code it ie write a dedicated mutiply routine (or just use the built in multiplication routine which would be slower). I think I'd go with a look up table (if there's room), it'd only cost an extra 40 bytes or so and be a lot faster. Here's hard coded for 40 ie rows of 5 bytes of 8 bits Each row is 5 bytes so you need to mutiply y by 5 (still uses the same map data, but I'm sure it doesn't make sense here) dim mapx = a dim mapy = b dim cell = c dim cellx = d rem x mod 8 cellx = mapx & 7 rem have to use addition this time rem 5 = 1 + 4 cell = mapy + mapy * 4 + mapx / 8 if map[cell] & setbits[cellx] then score = 1 else score = 0 rem use an adressable set of masks so you can point rem to them with a variable data setbits %10000000, %01000000, %00100000, %00010000 %00001000, %00000100, %00000010, %00000001 end data clearbits %01111111, %10111111, %11011111, %11101111 %11110111, %11111011, %11111101, %11111110 end data map %11111101, %11111111, %11111111, %11111111, %11111111 %11111111, %11111111, %11111111, %11111111, %11111111 %11111111, %11111111, %11111111, %11111111, %11111111 %11111111, %10000001, %00000011, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000001, %10000000, %00000000, %00000111 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000001, %10000000, %00000000 %00000000, %00011000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000001, %10000000 %00000000, %00000000, %00000001, %00000010, %00000011 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000 %00011100, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000001, %10000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000001, %10000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000001, %10000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000001, %10000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000001 %10000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000001, %10000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000001, %10000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000001, %10000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000001, %10000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000000 %00000000, %00000000, %00000000, %00000000, %00000001 %11111111, %11111111, %11111111, %11111111, %11111111 %11111111, %11111111, %11111111, %11111111, %11111111 %11111111, %11111111, %11111111, %11111111, %11111111 end edit: actually cell = mapy * 4 + mapy + mapx / 8 is faster because Bb doesn't stash mapy on the stack while it computes mapy * 4 edit some more: I suppose you all know this already. It's better to avoid the stack altogether cell = mapx / 8 cell = mapy * 4 + mapy + cell saves 2 bytes and 7 cycles yet more edit: fixed setbits and clearbits which were good for bit variables but not screen stuff Edited October 5, 2012 by bogax Quote Link to comment Share on other sites More sharing options...
Gateway Posted September 6, 2012 Share Posted September 6, 2012 . . edit some more: I suppose you all know this already. It's better to avoid the stack altogether cell = mapx / 8 cell = mapy * 4 + mapy + cell saves 2 bytes and 7 cycles This part doesn't compile, claiming there are duplicate labels. So, do I need to dimension a new "cell"? I tried changing it to cellx, but that causes more problems. Quote Link to comment Share on other sites More sharing options...
bogax Posted September 6, 2012 Share Posted September 6, 2012 . . edit some more: I suppose you all know this already. It's better to avoid the stack altogether cell = mapx / 8 cell = mapy * 4 + mapy + cell saves 2 bytes and 7 cycles This part doesn't compile, claiming there are duplicate labels. So, do I need to dimension a new "cell"? I tried changing it to cellx, but that causes more problems. I can't explain that. All I can say is it worked for me. This was the result: .L08 ; cell = mapx / 8 LDA mapx lsr lsr lsr STA cell .L09 ; cell = mapy * 4 + mapy + cell ; complex statement detected LDA mapy asl asl CLC ADC mapy CLC ADC cell STA cell . ; Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.