Started by Coolcrab, Sep 24 2017 10:26 AM

33 replies to this topic

Posted Sat Sep 30, 2017 10:21 AM

Do you have the readpaddle kernel option set?

Posted Sat Sep 30, 2017 10:25 AM

And, yes, you can definitely make an 8K game or larger with bB. Check out the romsize option on RT's page. If all you did is set romsize to 8K,and put a " . bank 2" line at the end of your source, it would automatically put the display kernel and graphics in bank 2, freeing up lots of space in bank 1 without even having to do any manual bankswitching.

Posted Sat Sep 30, 2017 10:35 AM

Do you have the readpaddle kernel option set?

Yes, I have this at the top. And I'm following this example: http://www.randomterrain.com/atari-2600-memories-batari-basic-commands.html#pfpixel

I must be doing something wrong but I can't seem to find it.

set kernel_options no_blank_lines readpaddle currentpaddle = 0 drawscreen

Posted Sat Sep 30, 2017 12:48 PM

Ok I'm getting there as it now responds to the paddle and can move around. However as soon as I limit the value of paddle tot 29 (Or whatever other number) it gets stuck at one value and does not respond anymore. Am I missing something with how the paddle works? As far as I can see it should have a value between 0 and 77 so it should be easily capped if I say 'if x > 29 then x = 29' right?

Posted Mon Oct 2, 2017 8:12 PM

Here I've rearranged your code some.

I added some code to test if any of the joy0 RLDU are pressed and

skip the line drawing if not

joy0 is bits 7..4 of SWCHA and a bit reads 0 if it's active

so it inverts SWCHA, masks for bits 7..4 and loops back if none are 1

I used variables p and q and let p range from 0..75 and q 0..20

p is then scaled by 13/32 to get 0..31 for x

and q is divided by 2 to get 0..10 for y

that's just to to show one way of dealing with a range of 0..77

and I added a test to see if x, y have changed no need to draw the (same) line again if not

I added a test to end the line when we've reached the right point in the major direction

not sure you'll always be at the right spot in the minor direction

initializes ea to 1/2 the delta for better accuracy and symmetry

added a custom point plotting bit to improve the speed

added a custom routine to clear the playfield

I rewrote the line drawing for better speed but it still goes over time on long lines

if you're also doing the score so I split the line drawing, putting x,y in the score

and reading joy0 among different frames

set kernel_options no_blank_lines readpaddle drawscreen dim ea = a dim dy = b dim dx = c dim state = w dim x1 = temp1 dim x0 = temp2 dim y1 = temp3 dim y0 = temp4 dim ep = temp3 dim xinc = temp4 dim yinc = temp5 dim delay = h dim rand16 = z dim xpos = k dim ypos = l dim sc1 = score dim sc2 = score + 1 dim sc3 = score + 2 x = 0 y = 0 t = 0 player0: %11000000 %11000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 end player1: %11110000 %11110000 %11110000 %11110000 %00000000 %00000000 %00000000 %00000000 end COLUPF = $62 scorecolor = $2A state = 1 mainloop COLUP0 = $1C COLUP1 = $B4 drawscreen on state goto readjoy drawline doscore ; drawing the line just about takes all of one frames worth of program time goto mainloop readjoy temp1 = (SWCHA ^ $FF) & $F0 ; tests for joy0 RLDU active if !temp1 then mainloop ; predicate true iff temp1 = 0 goto not needed if we're within 128 bytes (and it's the only statement) if joy0up && q > 0 then q = q - 1 if joy0down && q < 20 then q = q + 1 if joy0left && p > 2 then p = p - 3 ; p is meant to emulate a paddle (sort of) increments by 3 for speed of movement if joy0right && p < 75 then p = p + 3 ; which with the scaling makes the movement a little jerky x1 = (((p/4 + p)/4 + p)/2 + p)/4 ; scales p by 13/32 to get 0..31 y1 = q/2 ; and has the effect of slowing the movement ie 2 frames/q's to change y by one if x1 = x && y1 = y then goto mainloop ; no need to draw the line if x and y haven't changed x = x1 : y = y1 state = 1 : goto mainloop doscore temp6 = x : gosub leftsc ; puts x in the left three digits of score temp6 = y : gosub rightsc ; puts y in the right three digits of score state = 0 goto mainloop drawline x0 = 14 : y0 = 9 : x1 = x : y1 = y gosub clpf setup_line if x0 < x1 then f{2} = 1 : dx = x1 - x0 else f{2} = 0 : dx = x0 - x1 if y0 < y1 then f{1} = 1 : dy = y1 - y0 else f{1} = 0 : dy = y0 - y1 xpos = x0 : ypos = y0 if dx > dy then xmajor ; initializes ea to 1/2 for better accuracy, symmetry f{0} = 0 : xinc = xinc_tbl[f] : yinc = yinc_tbl[f] : ea = dy/2 : ep = y1 goto yentry yloop ypos = ypos + yinc temp1 = ea ea = ea - dx if temp1 < ea then ea = ea + dy : xpos = xpos + xinc yentry ; plots a pf pixel temp1 = xpos/8 temp1 = ypos * 4 | temp1 temp2 = xpos & $0F var0[temp1] = var0[temp1] | setbyte[temp2] ; setbyte is the kernel table for setting playfield bits if ypos <> ep then yloop ; loops if not at end in major direction in this case y but not sure it wont miss its x state = 2 : goto mainloop xmajor f{0} = 1 : xinc = xinc_tbl[f] : yinc = yinc_tbl[f] : ea = dx/2 : ep = x1 goto xentry xloop xpos = xpos + xinc temp1 = ea ea = ea - dy if temp1 < ea then ea = ea + dx : ypos = ypos + yinc xentry ; plots a pf pixel temp1 = xpos/8 temp1 = ypos * 4 | temp1 temp2 = xpos & $0F var0[temp1] = var0[temp1] | setbyte[temp2] if xpos <> ep then xloop state = 2 : goto mainloop data yinc_tbl $FF, $FF, $01, $01, $FF, $FF,$01, $01 end data xinc_tbl $FF, $FF, $FF, $FF, $01, $01, $01, $01 end pf playfield: ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ end return ; fastest way to clear playfield clpf var0=0:var1=0:var2=0:var3=0:var4=0:var5=0:var6=0:var7=0:var8=0:var9=0:var10=0:var11=0:var12=0:var13=0:var14=0:var15=0:var16=0:var17=0:var18=0:var19=0:var20=0:var21=0:var22=0 var23=0:var24=0:var25=0:var26=0:var27=0:var28=0:var29=0:var30=0:var31=0:var32=0:var33=0:var34=0:var35=0:var36=0:var37=0:var38=0:var39=0:var40=0:var41=0:var42=0:var43=0 return leftsc sc1 = 0 : sc2 = sc2 & 15 if temp6 >= 100 then sc1 = sc1 + 16 : temp6 = temp6 - 100 if temp6 >= 100 then sc1 = sc1 + 16 : temp6 = temp6 - 100 if temp6 >= 50 then sc1 = sc1 + 5 : temp6 = temp6 - 50 if temp6 >= 30 then sc1 = sc1 + 3 : temp6 = temp6 - 30 if temp6 >= 20 then sc1 = sc1 + 2 : temp6 = temp6 - 20 if temp6 >= 10 then sc1 = sc1 + 1 : temp6 = temp6 - 10 sc2 = (temp6 * 4 * 4) | sc2 return rightsc sc2 = sc2 & 240 : sc3 = 0 if temp6 >= 100 then sc2 = sc2 + 1 : temp6 = temp6 - 100 if temp6 >= 100 then sc2 = sc2 + 1 : temp6 = temp6 - 100 if temp6 >= 50 then sc3 = sc3 + 80 : temp6 = temp6 - 50 if temp6 >= 30 then sc3 = sc3 + 48 : temp6 = temp6 - 30 if temp6 >= 20 then sc3 = sc3 + 32 : temp6 = temp6 - 20 if temp6 >= 10 then sc3 = sc3 + 16 : temp6 = temp6 - 10 sc3 = sc3 | temp6 return busy COLUP0 = $1C COLUP1 = $B4 drawscreen goto busy

**Edited by bogax, Mon Oct 2, 2017 8:48 PM.**

- Random Terrain likes this

Posted Tue Oct 3, 2017 1:36 AM

Here I've rearranged your code some.I added some code to test if any of the joy0 RLDU are pressed andskip the line drawing if notjoy0 is bits 7..4 of SWCHA and a bit reads 0 if it's activeso it inverts SWCHA, masks for bits 7..4 and loops back if none are 1I used variables p and q and let p range from 0..75 and q 0..20p is then scaled by 13/32 to get 0..31 for xand q is divided by 2 to get 0..10 for ythat's just to to show one way of dealing with a range of 0..77and I added a test to see if x, y have changed no need to draw the (same) line again if notI added a test to end the line when we've reached the right point in the major directionnot sure you'll always be at the right spot in the minor directioninitializes ea to 1/2 the delta for better accuracy and symmetryadded a custom point plotting bit to improve the speedadded a custom routine to clear the playfieldI rewrote the line drawing for better speed but it still goes over time on long linesif you're also doing the score so I split the line drawing, putting x,y in the scoreand reading joy0 among different framesset kernel_options no_blank_lines readpaddle drawscreen dim ea = a dim dy = b dim dx = c dim state = w dim x1 = temp1 dim x0 = temp2 dim y1 = temp3 dim y0 = temp4 dim ep = temp3 dim xinc = temp4 dim yinc = temp5 dim delay = h dim rand16 = z dim xpos = k dim ypos = l dim sc1 = score dim sc2 = score + 1 dim sc3 = score + 2 x = 0 y = 0 t = 0 player0: %11000000 %11000000 %00000000 %00000000 %00000000 %00000000 %00000000 %00000000 end player1: %11110000 %11110000 %11110000 %11110000 %00000000 %00000000 %00000000 %00000000 end COLUPF = $62 scorecolor = $2A state = 1 mainloop COLUP0 = $1C COLUP1 = $B4 drawscreen on state goto readjoy drawline doscore ; drawing the line just about takes all of one frames worth of program time goto mainloop readjoy temp1 = (SWCHA ^ $FF) & $F0 ; tests for joy0 RLDU active if !temp1 then mainloop ; predicate true iff temp1 = 0 goto not needed if we're within 128 bytes (and it's the only statement) if joy0up && q > 0 then q = q - 1 if joy0down && q < 20 then q = q + 1 if joy0left && p > 2 then p = p - 3 ; p is meant to emulate a paddle (sort of) increments by 3 for speed of movement if joy0right && p < 75 then p = p + 3 ; which with the scaling makes the movement a little jerky x1 = (((p/4 + p)/4 + p)/2 + p)/4 ; scales p by 13/32 to get 0..31 y1 = q/2 ; and has the effect of slowing the movement ie 2 frames/q's to change y by one if x1 = x && y1 = y then goto mainloop ; no need to draw the line if x and y haven't changed x = x1 : y = y1 state = 1 : goto mainloop doscore temp6 = x : gosub leftsc ; puts x in the left three digits of score temp6 = y : gosub rightsc ; puts y in the right three digits of score state = 0 goto mainloop drawline x0 = 14 : y0 = 9 : x1 = x : y1 = y gosub clpf setup_line if x0 < x1 then f{2} = 1 : dx = x1 - x0 else f{2} = 0 : dx = x0 - x1 if y0 < y1 then f{1} = 1 : dy = y1 - y0 else f{1} = 0 : dy = y0 - y1 xpos = x0 : ypos = y0 if dx > dy then xmajor ; initializes ea to 1/2 for better accuracy, symmetry f{0} = 0 : xinc = xinc_tbl[f] : yinc = yinc_tbl[f] : ea = dy/2 : ep = y1 goto yentry yloop ypos = ypos + yinc temp1 = ea ea = ea - dx if temp1 < ea then ea = ea + dy : xpos = xpos + xinc yentry ; plots a pf pixel temp1 = xpos/8 temp1 = ypos * 4 | temp1 temp2 = xpos & $0F var0[temp1] = var0[temp1] | setbyte[temp2] ; setbyte is the kernel table for setting playfield bits if ypos <> ep then yloop ; loops if not at end in major direction in this case y but not sure it wont miss its x state = 2 : goto mainloop xmajor f{0} = 1 : xinc = xinc_tbl[f] : yinc = yinc_tbl[f] : ea = dx/2 : ep = x1 goto xentry xloop xpos = xpos + xinc temp1 = ea ea = ea - dy if temp1 < ea then ea = ea + dx : ypos = ypos + yinc xentry ; plots a pf pixel temp1 = xpos/8 temp1 = ypos * 4 | temp1 temp2 = xpos & $0F var0[temp1] = var0[temp1] | setbyte[temp2] if xpos <> ep then xloop state = 2 : goto mainloop data yinc_tbl $FF, $FF, $01, $01, $FF, $FF,$01, $01 end data xinc_tbl $FF, $FF, $FF, $FF, $01, $01, $01, $01 end pf playfield: ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ end return ; fastest way to clear playfield clpf var0=0:var1=0:var2=0:var3=0:var4=0:var5=0:var6=0:var7=0:var8=0:var9=0:var10=0:var11=0:var12=0:var13=0:var14=0:var15=0:var16=0:var17=0:var18=0:var19=0:var20=0:var21=0:var22=0 var23=0:var24=0:var25=0:var26=0:var27=0:var28=0:var29=0:var30=0:var31=0:var32=0:var33=0:var34=0:var35=0:var36=0:var37=0:var38=0:var39=0:var40=0:var41=0:var42=0:var43=0 return leftsc sc1 = 0 : sc2 = sc2 & 15 if temp6 >= 100 then sc1 = sc1 + 16 : temp6 = temp6 - 100 if temp6 >= 100 then sc1 = sc1 + 16 : temp6 = temp6 - 100 if temp6 >= 50 then sc1 = sc1 + 5 : temp6 = temp6 - 50 if temp6 >= 30 then sc1 = sc1 + 3 : temp6 = temp6 - 30 if temp6 >= 20 then sc1 = sc1 + 2 : temp6 = temp6 - 20 if temp6 >= 10 then sc1 = sc1 + 1 : temp6 = temp6 - 10 sc2 = (temp6 * 4 * 4) | sc2 return rightsc sc2 = sc2 & 240 : sc3 = 0 if temp6 >= 100 then sc2 = sc2 + 1 : temp6 = temp6 - 100 if temp6 >= 100 then sc2 = sc2 + 1 : temp6 = temp6 - 100 if temp6 >= 50 then sc3 = sc3 + 80 : temp6 = temp6 - 50 if temp6 >= 30 then sc3 = sc3 + 48 : temp6 = temp6 - 30 if temp6 >= 20 then sc3 = sc3 + 32 : temp6 = temp6 - 20 if temp6 >= 10 then sc3 = sc3 + 16 : temp6 = temp6 - 10 sc3 = sc3 | temp6 return busy COLUP0 = $1C COLUP1 = $B4 drawscreen goto busy

Wow this is great! I'll play around with it when I'm home tonight. Amazing how smooth it runs

Posted Tue Oct 3, 2017 12:12 PM

Here I've rearranged your code some.

Ok I understand most of your code, but I was wondering how you came up with the equation for limiting p between 0-31. Is there a reason that its all div 2 and div4 instead of 53p/128? I assume there is some limit to the math the atari can do?

The code you gave is perfect, apart from the fact that the y position is changed with up and down. I want to add 3 if statements that make it go down in y when it reaches 0,0 and the player still presses left and the same for (31,0). Sothat you can swoop the entire border with just 2 directions. (soon to be paddles hopefully.) But since the range for x1 needs to be extended from 0-31 to 0-47 he equation you gave is not correct. 5p/8 should do the trick but it doesn't. Should I write this as something with only two's?

I've tried to recreate your process in my code and it works reasonably but I get catastrophic failure if I split the movement like this.

enter xpos=14 : ypos=9 pfpixel xpos ypos on x0 = xpos : y0 = ypos if x < 8 then x1 = 0 : y1 = 8-x if x> 7 && x < 37 then x1 = x-8 : y1 = 0 if x > 36 && x < 44 then x1=29 : y1=36-x if x> 45 then x1 = 29 : y1 = 8 gosub setup_move goto pf

However it just jumps all over the place and even makes sound if i got off screen far enough. I'll keep puzzling, but if anyone sees anything stupid please tell me.

**Edited by Coolcrab, Tue Oct 3, 2017 12:34 PM.**

Posted Tue Oct 3, 2017 1:21 PM

I assume there is some limit to the math the atari can do?

While the 6502 can add and subtract, it does not have multiply or divide instructions. It does have bit shifting instructions, which are the equivalent to times two (shift left) or divide by two (shift right).

Those instructions are ASL and ROL for shift left, LSR and ROR for shift right.

In my tutorial I cover how you would multiple by five by converting

X * 5

to:

X * 2 * 2 + X

Posted Tue Oct 3, 2017 7:19 PM

Ok I understand most of your code, but I was wondering how you came up with the equation for limiting p between 0-31. Is there a reason that its all div 2 and div4 instead of 53p/128? I assume there is some limit to the math the atari can do?

The code you gave is perfect, apart from the fact that the y position is changed with up and down. I want to add 3 if statements that make it go down in y when it reaches 0,0 and the player still presses left and the same for (31,0). Sothat you can swoop the entire border with just 2 directions. (soon to be paddles hopefully.) But since the range for x1 needs to be extended from 0-31 to 0-47 he equation you gave is not correct. 5p/8 should do the trick but it doesn't. Should I write this as something with only two's?

oops, yup I started with 13/32 but decided on more accuracy and forgot to change the comments when I went to 53/128

You're working with 8 bit bytes which limits you to integers 0..255. Any fractional part gets truncated.

so the idea is to keep the partial products as large as possible and not throw anything away before you need to

(with out having them too large, the first partial product is 5/4 before the second division by 4 so would overflow

for anything larger than 4/5 * 255 ie 205/4 + 205 = 256, too big)

You could do what you want with if statements but I'd just have a variable that ranged 0.. 50 (or what ever) and look up

x, y in a table it wouldn't take much more space and it would be a lot faster and it would be much more flexible.

Not sure what you're doing but in the changed code the set up and line drawing are no longer subroutines

although they could be if that was useful but I figured it would be faster if they weren't

0 members, 0 guests, 0 anonymous users