bogax
-
Content Count
902 -
Joined
-
Last visited
Posts posted by bogax
-
-
I don't think you need seperate variables for the sprite positions
I don't think any of the variables used by the line drawing needs to be persistent
If the astronomer doesn't move then those coordinates could be constants
they currently get set from constants, the constants could be moved into the code
and the temp variables used for something else
I expect all that junk using p to fake paddles could be cleaned up or removed
Only three bits of f are used by the line drawing you could use the rest for
state (it would need some code to seperate them when needed)
You could maybe save something by taking your star/object velocities
from a table indexed by some master clock you could also solve your
stars going off screen that way (but it would need a variable so you could
do fractional y velocities)
It would be simpler and more straight forward, and arbitrary
(you could add retrograde motion planets, or comets or something)
but it might need more ROM (but maybe not much, you'd be replacing some
code) -
other - put the missing signals out through the cartridge port. That would allow for adding RAM without having to repurpose an address line as the read/write line, and make implementing things like DPC+, CDF, and BUS much easier as you could look for the correct signals instead of trying to recreate them by monitoring changes in the address lines.
I wonder how hard it would be to infer/reconstruct R/W from what you see on the busses (ie with something far short of a full processor)
I mean (disregarding branches and page crossings for a moment) if you know the instruction you know what R/W should be for each cycle.
I don't think it would be too hard to sync to instructions, a read or two from a specific address maybe.
So the question in my mind is can you reasonably accomodate branches (still only two possibilities) with what you can see on the
data and address busses. (I think I could live with out page crossings but if you could accomodate them too it would be nice of course, but I think
being able to deal with branches would be a neccessity)
Even if you could only count on your inferred R/W for a short stretch of code before you had to resync it would be very useful.
-
There's a goto missing on line 180
-
Here I've moved the scroll routines (including the f_ind routine that the fwbyte macro uses)
to bank 2 and fixed the returns.
I did the pfread in bB so there wouldn't be a lot of bank switching going on.
Seems to work.
It could undoubtedly be cleaned up or streamlined some.
-
I didn't have too much trouble getting the scrolling code to run in a different bank
you have to make sure all the routines are present and not use a bank switching return
(both the bank switching and the scroll routines use the x register, I expect there's
interference there but I didn't try to figure out what/where)
in principle at least, you could fill all the banks with world data and scroll around
a 512 x 380 (pf)pixel world (or something, I'd keep x an integral factor of 256 bytes)
the coding might get a little hairy but it wouldn't be THAT bad
-
Hmm
I got a chance to try it in Chrome today and it seemed to work just fine
except I couldn't scroll the page and the end of the text box was hanging off the screen
where I couldn't get at it, but the data was ok.
here's it's fixed for Firefox
-
Here's an augmented version of the 32 x 32 world editor
You can paste data into the text box and put it in the editor
it looks for the first 1024 numbers in the form $xx where the xx are hex digits
and it pads with 0 if there aren't 1024
The clear button works.
There's a rudimentary undo. It saves the undo data when you click on the
canvas or input data but not if you're moving the cursor or the world with
the arrow buttons.
You can load a picture into the world canvas. So you can do your editing
in your favorite graphics editor and convert it to data statements.
It takes the upper left pixel as the background color, any other color
is a playfield pixel.
It seems to work in Opera, the picture loading doesn't work too well in
(an older version of) Firefox and it doesn't work at all in IE.
I haven't tryed it in Chrome yet.
-
2
-
-
Here's code for 32 byte x 32 byte world
Not sure it's really useful it, doesn't leave much room for code or time to run it
There's also a crude world editor
It runs in Opera and Firefox
I'd be curious if any one else can get it to run (and what browser you tried it with)
The clear button doesn't do anything
The flip button cycles through flip, on and off
The left arrow buttons move the cursor (there's no other indication where it is though)
The right arrows scroll the world data around
You can also click on the world canvas
The colors just set the colors and display a corresponding hex value (lifted from RT's page)
The little text box is the name for the data statements if you change it you'll have to change
lines 44, 45 in the code to match
There's no way to save the world data (I should probably fix it so you can put the data statements back in)
You should be able to just copy the data statements into the code and adjust lines 44, 45 if necessary
-
1
-
-
Bogox,
How would you handle 3 moving objects?
Player moves a cursor,
first object moves to that cursor when activated.
Second object follows and tries to catch the first object.
I'm not sure I know what you're askingSimplest would be to have variables andmovement code for each object that needed it and reset upan object whenever a its target changed positionHowever you might end up doing more setup than you neededdepending on how they're moving relative to one anotherYou could parameterize and reuse the same code for different objectsnot sure it would be worth it unless you had a lot of objects -
Seems like I don't have to? I have no idea how it works without setting the error accumulator and all the other stuff?
I'm not sure what you're askingYou're setting all the important stuffYou don't neccesarily need to set the error accumulatorit just makes nicer lines (I think)You count through the delta in the error accumulator until it rolls overat which point you've accumulated a pixel worth of error so you move onepixel in the minor directionIf you set the error accumulator to 1/2 the delta you're half a pixelfrom where you want to be on the line and you can only be at whole pixelsIf you set the error accumulator to 0 you'd be at one pixel from whereyou want to be and the first thing you'd do is take a step in the minordirectionThe line is formed from horizontal or vertical line segments in the majordirectionSay the segment is going to be 8 pixels ie you'll move 8 pixels in the majordirection to accumulate one pixel of error in the minor direction(the error accumulator counts down through the major delta in minor directiondeltas until it goes through zero) if you set the error accumulator to0 you're one pixel away and you'll immediately take a step in the minor directionIf you set the error accumulator to 1/2 the major delta you'll take four steps(half of 8 ) before you take a step in the minor directionand if you set EA to the major delta you'll take 8 steps before you'veaccumulated enough error for a step in the minor directionsomething like this for a 9 pixel line_ ________ ____ _____ ________ _as far as multiplying by 2 if you're working with numbers below 128that just gives you a little more room for accuracy if you're goingto do something else with the error accumulator (since you're continuouslybending the line perhaps you'd want to take into account where you areon the previous line) but it's really not neccesary (or even useful ifyou're just setting the error accumulator to eg 1/2 the delta) -
I made an example of what I want to do, I have robots in my game that shoots missiles at you, but they can only shoot in six directions now and I would like if they shot in the exact direction you where when they fired the shot, I can do that but the problem is that the robots slowly speed up with 0.05 every one hundred points, and the missile automaticly speeds up to,
the missilespeed is the robotspeed + 0.10
So it would just be for speed flexibility, and the smoothness ofcourse, subpixel bresenham movement seems impossible in my brain but I thought I should ask,
what do you think?
The movement code always moves one pixelThe first thing I'd try is set up an accumulator for the fractional change ofposition and when it's accumulated a pixel's worth do the movementsomething liketemp = accumulator accumulator = accumulator + speed if accumulator < temp then skip_move movement code skip_move
-
Does this and other line algorithms require the data tables? I would really like to shoot in a straight line like i can do with this, but with smoother 8.8 type X & Y variables, is it possible?
how will you aim?
no, you don't need tables
I doubt 8.8 variable will get you anything
8 bits should be enough for the maximum
screen resolution
it will depend on how you aim (I think)
-
I'm not sure what you mean by that exactly.
I'm not sure exactly what I mean either (and, again, I haven't had a chance to look at your code)
And I'm just sorta thinking out loud.
from your description:
When new data needed to show up, it would look at the new data I had in the level data table, using a pointer, to pick up the 2 new bytes, and then it would compare bit by bit with what the var screen variables had on the edge of the screen.
What I'm thinking is rather than doing a comparison just have the level data table indicate if a bit needs flipping (build the results of the comparison into the table)
I wouldn't bet that that would save you anything I'm just wondering if it could.
-
If you want to see how I did horizontal scrolling in Princess Rescue, just go to Random Terrain's Batari site, and he has my source code for it there, along with added documentation. You can find how I did my scrolling in there with the ScrollLeft and ScrollRight routines. I did use pfhscroll, but with some added code. When new data needed to show up, it would look at the new data I had in the level data table, using a pointer, to pick up the 2 new bytes, and then it would compare bit by bit with what the var screen variables had on the edge of the screen. If it didn't match up, it would flip the bit, saving time so it didn't redraw every bit on the edge of the screen.
(I haven't looked at your code) (yet)
hmm.
I wonder if it would be useful to store the data as sort of a table of difs or deltas (or whatever you'ld call them)
then just flip a bit if necessary, depending on what's in the table
-
speaking for my code
while you could undoubtedly speed it up in asm I don't think it would be that dramatic
the first thing I'd do is unroll the vertical scrolling and you could do that in bB
as to a 32 x 32 byte world you'ld need to change some constants.
simplest would probably be to break out the world rows in to individual
data statements you could then look up the data statement in a table
and use a few bytes of asm to do the actual look up (because 32 x 32 is too big for a data statement)
you might be able to jimmy it into sdata but I think that would bring some cruft and it really only needs
a few bytes of asm
some thing like
data wrow0 some, stuff, other, stuff, more, stuff, etc end data wrow1 some, stuff, other, stuff, more, stuff, etc end data wrow2 some, stuff, other, stuff, more, stuff, etc end etc data wrow_addresslo <wrow0, <wrow1, <wrow2, <wrow3 end data wrowaddresshi >wrow0, >wrow1, >wrow2, >wrow3 end temp2 = wrow_addresslo[wrow_number] temp3 = wrow_addresshi[wrow_number] temp1 = index ; fetches your world data to temp1 asm ldy temp1 lda (temp2),y sta temp1 end
-
1
-
-
if you include div_mul.asm is compiles (and runs)
-
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
-
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
-
1
-
-
This would be great. If you do not have time, could you tell me how you would tackle such a problem. I don't know how to atomize the process and keep the lines symmetrical.
You could adapt this to draw lines (Bresenhams algorithm is for drawing lines)
I don't know if it would be fast enough
I'd do the pixel setting and clearing in bB for speed
-
score is not a 24 bit binary number, its 6 BCD digits
(this is a complete guess) 175 as two hex digits is 10 and 15 in hex, $AF the A is 160 in decimal and the F is 15 so the number gets adjusted to 65 with a couple of carries thrown in for the tens
assuming you're using sprybugs naming, try setting sc2 = $01: sc3 = $75
somewhere on RTs page are routines (or links to routines) for putting bytes into the score
-
Is there a doc somewhere that explains how bb's special variables are laid out in memory?
(Are player0x and player1x consecutive so I can access them as an array?)
it depends on the kernel
they're defined in the header files
see eg 2600basic.h
-
1
-
-
X ^ X = 0
Y ^ 0 = Y
so
(X ^ Y) ^ Y = X
(X ^ Y) ^ X = Y
or
FLIP = X ^ Y
X ^ FLIP = Y
Y ^ FLIP = X
CFLIP = COR_PLAYER ^ COR_FUNDO
bit INPT4
BMI ButtonNotPressed ;skip if button not pressed
LDA COLUP0
EOR #CFLIP
STA COLUP0
LDA COLUBK
EOR #CFLIP
STA COLUBK
ButtonNotPressed
-
I agree with RT use constants for your color instead of those constant expressions
division takes a lot of time unless it's division by a power of 2
having said that, it compiles fine for me if I include the div mul routines
-
that's a bug not a feature
if you omit the base reference so does bB and DASM (apparently) defaults to 0
I assume it clears a parameter and it stays cleared if you don't change it
however, you can include a constant (in this context a variable name is a constant)
the variables are in order so eg a[3] is the same location as d
-
1
-

[Done] Astronomer development thread
in batari Basic
Posted
I can see why you might want so use something other than "state" but I don't think "jump pointer" is any improvement
call it "whats next" or "next action" or just "next"
then assign constants with meaningful names
so instead of
it would be, like