Jump to content
IGNORED

Abstract Memory References?


Cybearg

Recommended Posts

Is there any way that I could have abstract references to memory locations, either in bB alone or with a combination of bB and Assembly? For instance, let's say that I have a number of sprites on screen:

 

player0

player1

player2

player3

player4

player5

 

... Now in order to do anything with those, I'd have to perform the same checks on each of them, bogging down the code and slowing things down:

 

if i then goto player0 player1 player2 player3 player4 player5

player0
if missile0x <= player0x + 4 && missile0x >= player0x && missile0y <= player0y + 8 && missile0y >= player0y then goto confirmed_hit else i = i + 1: goto denied_hit

player1
if missile0x <= player1x + 4 && missile0x >= player1x && missile0y <= player1y + 8 && missile0y >= player1y then goto confirmed_hit else i = i + 1: goto denied_hit

 

... etc.

 

Is there some way that I could, for instance, set up an array to point to the memory locations (the below locations are based on this)?

 

data spritex
$87, $88, $89, $8a, $8b, $8c
end

data spritey
$8d, $8e, $8f, $90, $91, $92
end

if missile0x <= spritex[i] + 4 && missile0x >= spritex[i] && missile0y <= spritey[i] + 8 && missile0y >= spritey[i] then goto confirmed_hit else i = i + 1: goto denied_hit

 

... Or, since memory locations are often defined in a row, something like:

 

dim sprite0x = $87
dim sprite0y = $8d

if missile0x <= spritex[i] + 4 && missile0x >= spritex[i] && missile0y <= spritey[i] + 8 && missile0y >= spritey[i] then goto confirmed_hit else i = i + 1: goto denied_hit

 

(which would work kind of like a[0] = a, a[1] = b, a[2] = c, etc.)

 

... Or maybe through the use of inline assembly? (I like the use of arrays best because, while it takes more space to define the arrays, it gives you control over what is being indexed)

 

 

data spritex
87, 88, 89, 8a, 8b, 8c
end

data spritey
8d, 8e, 8f, 90, 91, 92
end

temp1 = spritex[i]
temp2 = spritey[i]

asm
LDA $temp1
STA temp3
LDA $temp2
STA temp4
end

if missile0x <= temp3 + 4 && missile0x >= temp3 && missile0y <= temp4 + 8 && missile0y >= temp4 then goto confirmed_hit else i = i + 1: goto denied_hit

 

If none of these, is there some other way?

Link to comment
Share on other sites

Alright, I've been doing some experiments. So far, I can confirm that the second method works:

 


dim pt0x = $80
dim pt0y = $85


player0:
%11111111
%11111111
%11111111
%11100111
%11100111
%11111111
%11111111
%11111111
end

player1:
%11111111
%11111111
%11111111
%11100111
%11100111
%11111111
%11111111
%11111111
end


data spritex
40, 60
end

data spritey
40, 60
end


main_loop
rem player0 is red, player1 is green
COLUP0 = $40
COLUP1 = $C0


for i = 0 to 1
pt0x[i] = spritex[i]
pt0y[i] = spritey[i]
next

drawscreen
goto main_loop

 

I'll be testing the other methods to see what I find.

Link to comment
Share on other sites

So far, I haven't found a way to abstractly reference memory locations from an array. I've tried methods one and three above, but neither works, though it's possible that my syntax is wrong and that there's another way to do it. Anyone know?

 

I did find a less elegant but still effective way that works effectively about like how an array would:

 

player0:
%11111111
%11111111
%11111111
%11100111
%11100111
%11111111
%11111111
%11111111
end

player1:
%11111111
%11111111
%11111111
%11100111
%11100111
%11111111
%11111111
%11111111
end

data spritex
40, 60
end

data spritey
40, 60
end

main_loop
rem player0 is red, player1 is green
COLUP0 = $40
COLUP1 = $C0

for i = 0 to 1
temp1 = spritex[i]
temp2 = spritey[i]

gosub storei
next

drawscreen
goto main_loop

storei
on i goto pl0 pl1

pl0
asm
LDA temp1
STA $80
LDX temp2
STX $85
end

return

pl1
asm
LDA temp1
STA $81
LDX temp2
STX $86
end

return

 

The part I don't like is that, unless you want to repeat the on-goto statement or just inline add enough assembly to account for the different values of i, it requires an on-goto on top of a gosub, which is a bit pricey, cycle-wise. And then, you'd another entire subroutine for reading those memory locations, which means another on-goto and another gosub. It's more space-efficient than just writing everything out, but I don't know if the loss of cycles are worth it.

 

Maybe someone else has a better idea for how it can be done more efficiently.

 

EDIT: I suppose that, technically, there's no reason to use anything besides the method in the post above this one, since, if memory values don't align properly to use the a method, one can always re-map the kernel's memory locations by simplify modifying the 2600basic.h, multisprite.h, or DPCplus.h files so that they do line up.

Edited by Cybearg
Link to comment
Share on other sites

What kernel/kernel options are you using ?

 

edit

I'm having trouble following your code.

 

I think what you want for that last bit would be

data spritex
40, 60
end

data spritey
40, 60
end

main_loop
rem player0 is red, player1 is green
COLUP0 = $40
COLUP1 = $C0

for i = 0 to 1
player0x[i] = spritex[i]
player0y[i] = spritey[i]

next

drawscreen
goto main_loop

 

let me rephrase that I'm not sure that's what

you want I think that's what you're doing.

Edited by bogax
Link to comment
Share on other sites

What kernel/kernel options are you using ?

 

edit

I'm having trouble following your code.

 

I think what you want for that last bit would be

data spritex
40, 60
end

data spritey
40, 60
end

main_loop
rem player0 is red, player1 is green
COLUP0 = $40
COLUP1 = $C0

for i = 0 to 1
player0x[i] = spritex[i]
player0y[i] = spritey[i]

next

drawscreen
goto main_loop

 

let me rephrase that I'm not sure that's what

you want I think that's what you're doing.

Yeah, that's basically what I'm doing. The reason for the weird way I did it, redefining the player variables, is because I wanted to find a way to reference any memory location, not just ones that were necessarily defined in a row.

 

For instance, let's say I'm using missile0, missile1, and the ball along with sprites. I was hoping for a way to map them, using an array or otherwise, so that they could be listed as:

 

player0

player1

player2

player3

player4

player5

missile0

missile1

ball

 

... or in any other order I prefer:

 

player4

ball

player2

player3

missile1

player0

missile0

player1

 

... etc.

 

That was my overall goal--to be able to list memory locations in any order I desire and still reference them with an index. If you can think of any way to do that, please do let me know.

 

The above example with real memory locations used the standard kernel, but ideally there would be a method that would fit for any kernel.

Edited by Cybearg
Link to comment
Share on other sites

You could put your mapping into table

and do something like this.

 

const mem = 0
const player0 = 0
const player1 = 1
const player2 = 2
const player3 = 3
const player2 = 4
const player3 = 5
const missle0 = 6
const missle1 = 7
const ball = 8

dim xptr = temp1
dim yptr = temp2

data x_ptrs
player0x, player1x, player2x, player3x, player2x, player3x, missle0x, missle1x, ballx
end

data y_ptrs
player0y, player1y, player2y, player3y, player2y, player3y, missle0y, missle1y, bally
end


for i = 0 to 1

xptr = x_ptrs[i]
yptr = y_ptrs[i]

mem[xptr] = spritex[i]
mem[yptr] = spritey[i]

next

Link to comment
Share on other sites

I don't follow what you're doing there. How would that be able to set values to and from player x/y positions? Is one able to make an array consisting of variables? I was under the impression only actual values were allowed.

 

Since your code is incomplete (you reference spritex and spritey without defining them anywhere), I assume it's supposed to integrate with some of the stuff I wrote above?

Edited by Cybearg
Link to comment
Share on other sites

Any on-the-fly reordering of memory locations is going to have a cycle and rom space penalty, so its best to avoid that.

 

bB already orders all similar variables together - player0x, player1x, etc. - so you can operate in a loop.

 

Which variables do you need to operate on in sequence?

Link to comment
Share on other sites

I don't follow what you're doing there. How would that be able to set values to and from player x/y positions? Is one able to make an array consisting of variables? I was under the impression only actual values were allowed.

 

Since your code is incomplete (you reference spritex and spritey without defining them anywhere), I assume it's supposed to integrate with some of the stuff I wrote above?

 

I'm still not sure what you're trying to do

so that may not be helpful.

 

The variable names are constants, I just

put them in a table so they could be indexed.

 

To get your indirection you have to look them

up and put them in a variable to use as a pointer

since bB doesn't allow for indirection to go any

deeper than that. I used temp variables

renamed to xptr, yptr

 

And yes I was just applying it to the previous

little bit of code as an example.

 

The only reason I could see for doing it that way

is for indexing as in the for next loop but you could

in principle do it with named constant (hence the

constant definitions of table indexes)

 

You'd still have to do the look ups

 

rem this writes x to player0x
xptr = x_ptrs[player0]
mem[xptr] = x

rem this reads x from player0x
xptr = x_ptrs[player0]
x = mem[xptr]

 

You could put stuff like that into macros and/or

subroutines I suppose but I'm not sure you need

anything that general?

 

As RevEng points out they're all ready mostly

in order if you're counting through indexes.

 

If you want something more random access or

arbitrary it's going to cost you, but it

could probably be done.

 

The question is what will it save you?

 

What are you trying to do specifically?

Edited by bogax
Link to comment
Share on other sites

Well, I ended up remapping the memory locations and then using the second method described in the first post.

 

I just want to be able to reference different sprites (whether they're players, missiles, or the ball) based on an index. I couldn't normally do it because the memory map doesn't quite allow it, but adjusting values made it possible:

 

; multisprite stuff below - 5 bytes each starting with spritex

SpriteIndex = $80

player0x = $81
NewSpriteX = $82 ; X position
player1x = $82
player2x = $83
player3x = $84
player4x = $85
player5x = $86
missile1x = $87
ballx = $88
missile0x = $89

player0y = $8A
objecty = $8A
NewSpriteY = $8B ; Y position
player1y = $8B
player2y = $8C
player3y = $8D
player4y = $8E
player5y = $8F
missile1y = $90
bally = $91
missile0y = $92

 

This allowed me to turn this:

 


leap

on closepixel goto leapzero leapone leaptwo leapthree leapfour leapfive leapsix leapseven

leapzero
if player0x = player1x - 4 && player0y = player1y + 10 then return
if player0x > player1x - 4 then player0x = player0x - 1
if player0x < player1x - 4 then player0x = player0x + 1
if player0y > player1y + 10 then player0y = player0y - 1
if player0y < player1y + 10 then player0y = player0y + 1
return

leapone
if player0x = player2x - 4 && player0y = player2y + 10 then return
if player0x > player2x - 4 then player0x = player0x - 1
if player0x < player2x - 4 then player0x = player0x + 1
if player0y > player2y + 10 then player0y = player0y - 1
if player0y < player2y + 10 then player0y = player0y + 1
return

leaptwo
if player0x = player3x - 4 && player0y = player3y + 10 then return
if player0x > player3x - 4 then player0x = player0x - 1
if player0x < player3x - 4 then player0x = player0x + 1
if player0y > player3y + 10 then player0y = player0y - 1
if player0y < player3y + 10 then player0y = player0y + 1
return

leapthree
if player0x = player4x - 4 && player0y = player4y + 10 then return
if player0x > player4x - 4 then player0x = player0x - 1
if player0x < player4x - 4 then player0x = player0x + 1
if player0y > player4y + 10 then player0y = player0y - 1
if player0y < player4y + 10 then player0y = player0y + 1
return

leapfour
if player0x = player5x - 4 && player0y = player5y + 10 then return
if player0x > player5x - 4 then player0x = player0x - 1
if player0x < player5x - 4 then player0x = player0x + 1
if player0y > player5y + 10 then player0y = player0y - 1
if player0y < player5y + 10 then player0y = player0y + 1
return

leapfive
if player0x = missile1x - 4 && player0y = missile1y + 10 then return
if player0x > missile1x - 4 then player0x = player0x - 1
if player0x < missile1x - 4 then player0x = player0x + 1
if player0y > missile1y + 10 then player0y = player0y - 1
if player0y < missile1y + 10 then player0y = player0y + 1
return

leapsix
if player0x = ballx - 4 && player0y = bally + 10 then return
if player0x > ballx - 4 then player0x = player0x - 1
if player0x < ballx - 4 then player0x = player0x + 1
if player0y > bally + 10 then player0y = player0y - 1
if player0y < bally + 10 then player0y = player0y + 1
return

leapseven
if player0x = missile0x - 4 && player0y = missile0y + 10 then return
if player0x > missile0x - 4 then player0x = player0x - 1
if player0x < missile0x - 4 then player0x = player0x + 1
if player0y > missile0y + 10 then player0y = player0y - 1
if player0y < missile0y + 10 then player0y = player0y + 1
return

 

into this:

 


leap

temp1 = pixelx[closepixel] - 4
temp2 = pixely[closepixel] + 10

if player0x > temp1 then player0x = player0x - 2
if player0x < temp1 then player0x = player0x + 2
if player0y > temp2 then player0y = player0y - 2
if player0y < temp2 then player0y = player0y + 2

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