Calvin Allett | 18 Sep 12:31

Speed issue's with POINT (x,y)

Hey there, been a while... hope everybody's doing good :)

Some of you may remember me starting work on a new game engine last year, "Slip 'n Slide", well it only got to the stage of a couple of weeks work, but picked it up again 3 months ago and have been working on it daily since then.

It's progressed a lot, with relation to how 'nice' the engine is, and I'm rather pleased with it so far, however since the levels are drawn and there is no map data everything is done using the POINT command (collisions with scenery, enemies and power pills(well there's an array for pills, but fiding them is handled with point initially)), and whilst this allows for rather sweet level designs and movement (You can get squashed vertically or horizontally now :) ) the engine has slowed about 50 % even in the last 4 weeks :(

Is there nothing to be done, is the Point command as fast as it could be or is
there another way forward? I'm always shy/awkward over asking for help, but could anybody see themselves helping with a little machine code prog that would do the following:-

take the x and y values from the Basic variable list, check about 9 pixel colour values around it the main 9*9 sprite (L,R,B,B2,B3,T,C,BR,B0) and put the values into those variables, could this in theory be done easily, or would there be no speed benefit... POINT does seem to be really slow, it's the complexity of the game engine too slowing it down (a lot of code for uncompiled 8 bit basic at least, every iteration) and I've used every trick I learned from Tomato Antics, so no more I can do :(

I'm really sad over this, this is for the 20 Mhz SAM and I know I should
be using MC but I just haven't got the head for learning it at the moment still, and
honestly don't think I would enjoy programming in anything else than Basic... I
really like this engine too, but have took the enemies out, so I'm only drawing 1 (yes ONE) masked sprite... I'm stupid for attempting this in Basic, but it would just be another flat level mapped platformer without the POINT command...

anyways, I've had my moan ;)

Hope all your own projects are coming along, and I'm not really expecting anyone to be able to find the time, but I'd be a fool not to mention it :)

Cal...

Thomas Harte | 18 Sep 14:26

Re: Speed issue's with POINT (x,y)

Maybe something like the following to get the colour of the pixel at (x, y):

10 LET A=IN 252 BAND 31
20 LET BASE=(A+1)*16384
30 LET ADDR = BASE + (x/2) + y*128
40 LET BYTE = PEEK(ADDR)
50 IF x BAND 1 THEN LET COL = BYTE/16 ELSE LET COL = BYTE BAND 15

(psuedo code, because I'm not sure offhand what SAM BASIC does with
respect to floating point numbers versus integer numbers and I don't
recall the syntax for bit shifting - for the purposes of that code
just imagine that all variables are integers and adapt as necessary)

Once you've calculated ADDR for one point, it's probably easier just
to add and subtract fixed amounts to get the address for your other
pixels.

On Thu, Sep 18, 2008 at 11:35 AM, Calvin Allett
<calvin_allett@...> wrote:
> Hey there, been a while... hope everybody's doing good :)
>
> Some of you may remember me starting work on a new game engine last year,
> "Slip 'n Slide", well it only got to the stage of a couple of weeks work,
> but picked it up again 3 months ago and have been working on it daily since
> then.
>
> It's progressed a lot, with relation to how 'nice' the engine is, and I'm
> rather pleased with it so far, however since the levels are drawn and there
> is no map data everything is done using the POINT command (collisions with
> scenery, enemies and power pills(well there's an array for pills, but fiding
> them is handled with point initially)), and whilst this allows for rather
> sweet level designs and movement (You can get squashed vertically or
> horizontally now :) ) the engine has slowed about 50 % even in the last 4
> weeks :(
>
> Is there nothing to be done, is the Point command as fast as it could be or
> is
> there another way forward? I'm always shy/awkward over asking for help, but
> could anybody see themselves helping with a little machine code prog that
> would do the following:-
>
> take the x and y values from the Basic variable list, check about 9 pixel
> colour values around it the main 9*9 sprite (L,R,B,B2,B3,T,C,BR,B0) and put
> the values into those variables, could this in theory be done easily, or
> would there be no speed benefit... POINT does seem to be really slow, it's
> the complexity of the game engine too slowing it down (a lot of code for
> uncompiled 8 bit basic at least, every iteration) and I've used every trick
> I learned from Tomato Antics, so no more I can do :(
>
> I'm really sad over this, this is for the 20 Mhz SAM and I know I should
> be using MC but I just haven't got the head for learning it at the moment
> still, and
> honestly don't think I would enjoy programming in anything else than
> Basic... I
> really like this engine too, but have took the enemies out, so I'm only
> drawing 1 (yes ONE) masked sprite... I'm stupid for attempting this in
> Basic, but it would just be another flat level mapped platformer without the
> POINT command...
>
> anyways, I've had my moan ;)
>
> Hope all your own projects are coming along, and I'm not really expecting
> anyone to be able to find the time, but I'd be a fool not to mention it :)
>
> Cal...
>
>

Geoff Winkless | 18 Sep 16:37

Re: Speed issue's with POINT (x,y)

On Thu, 18 Sep 2008 13:26:15 +0100, "Thomas Harte"
<tomh.retrospec@...> wrote:
> Maybe something like the following to get the colour of the pixel at (x,
> y):
> 
> 10 LET A=IN 252 BAND 31
> 20 LET BASE=(A+1)*16384
> 30 LET ADDR = BASE + (x/2) + y*128
> 40 LET BYTE = PEEK(ADDR)
> 50 IF x BAND 1 THEN LET COL = BYTE/16 ELSE LET COL = BYTE BAND 15

I can't believe that would be any quicker (in fact I'd be amazed if it's
not slower) than POINT(). 

The way to improve the speed in a generic way is to write machine code that
checks the edges of a bitmap you pass it and tests the appropriate points
on the screen.

The _fastest_ way is to write a specific set of checks based on the sprite
and the direction of movement.

Basically, let's say you figure out that if you're moving upwards you need
to test pixels 2 to 6 on line 0 and pixels 1 and 7 on line 1. Your code for
"test-up" would therefore be

LD A, (IX+1) # pixels 2+3
OR A, (IX+2) # pixels 4+5
RET NZ
OR A, (IX+3) # pixels 6+7
INC I:IX (or whatever your assembler uses for that non-instruction)
OR A, (IX)   # pixels 0+1 line 1
AND &0F      # isolate rightmost pixels
RET NZ
OR A, (IX+3) # pixels 7+8 line 1
AND &f0      # isolate leftmost pixel
RET

IIRC if you call this with USR you get the value in A as the result (or is
it BC? Can't remember), so you can just 

IF USR(upcode)<>0 THEN GOTO HIT

There are ways of passing parameters to USR functions, I can't remember how
though :( I'm also not sure if using IX is better than INCing H and L
(probably not)

The problem with POINT (or similar) is that it has to completely
recalculate the positions in memory for every check. That's slowed down
even further because each time it has to access the values from BASIC's
variable stack which (since it's all floating-point and they're stored in a
non-optimal way) is ridiculously slow (it's a shame Andy Wright didn't see
fit to add integer variables like you get in BBC Basic, for example)

Geoff

Geoff Winkless | 18 Sep 17:41

Re: Speed issue's with POINT (x,y)

On Thu, 18 Sep 2008 15:37:51 +0100, Geoff Winkless <sam-users@...>
wrote:
> "test-up" would therefore be
[snip]

D'oh; of course this is wrong (one line in mode 4 is 128 bytes, not 256) so
you'd have to add 128 to IX (or HL) rather than increasing I (or H) but you
get the idea.

G

Thomas Harte | 18 Sep 23:53

Re: Speed issue's with POINT (x,y)

You're quite right — some hasty testing in Sim Coupe reveals that it  
is much slower. I was imagining that POINT might go through some  
arcane paths with all the xos/yos/xrg/yrg stuff.

If you have the memory to spare, could you maybe skip over the problem  
by allocating a new screen that is never shown to the player, then in  
advance (maybe just after the level has been loaded?) plotting a  
colour at each position that represents what should happen when the  
ball is there? It'd mean you could cut yourself down to using a single  
POINT.

On 18 Sep 2008, at 15:37, Geoff Winkless wrote:

> On Thu, 18 Sep 2008 13:26:15 +0100, "Thomas Harte"
> <tomh.retrospec@...> wrote:
>> Maybe something like the following to get the colour of the pixel  
>> at (x,
>> y):
>>
>> 10 LET A=IN 252 BAND 31
>> 20 LET BASE=(A+1)*16384
>> 30 LET ADDR = BASE + (x/2) + y*128
>> 40 LET BYTE = PEEK(ADDR)
>> 50 IF x BAND 1 THEN LET COL = BYTE/16 ELSE LET COL = BYTE BAND 15
>
> I can't believe that would be any quicker (in fact I'd be amazed if  
> it's
> not slower) than POINT().
>
> The way to improve the speed in a generic way is to write machine  
> code that
> checks the edges of a bitmap you pass it and tests the appropriate  
> points
> on the screen.
>
> The _fastest_ way is to write a specific set of checks based on the  
> sprite
> and the direction of movement.
>
> Basically, let's say you figure out that if you're moving upwards  
> you need
> to test pixels 2 to 6 on line 0 and pixels 1 and 7 on line 1. Your  
> code for
> "test-up" would therefore be
>
> LD A, (IX+1) # pixels 2+3
> OR A, (IX+2) # pixels 4+5
> RET NZ
> OR A, (IX+3) # pixels 6+7
> INC I:IX (or whatever your assembler uses for that non-instruction)
> OR A, (IX)   # pixels 0+1 line 1
> AND &0F      # isolate rightmost pixels
> RET NZ
> OR A, (IX+3) # pixels 7+8 line 1
> AND &f0      # isolate leftmost pixel
> RET
>
> IIRC if you call this with USR you get the value in A as the result  
> (or is
> it BC? Can't remember), so you can just
>
> IF USR(upcode)<>0 THEN GOTO HIT
>
> There are ways of passing parameters to USR functions, I can't  
> remember how
> though :( I'm also not sure if using IX is better than INCing H and L
> (probably not)
>
> The problem with POINT (or similar) is that it has to completely
> recalculate the positions in memory for every check. That's slowed  
> down
> even further because each time it has to access the values from  
> BASIC's
> variable stack which (since it's all floating-point and they're  
> stored in a
> non-optimal way) is ridiculously slow (it's a shame Andy Wright  
> didn't see
> fit to add integer variables like you get in BBC Basic, for example)
>
> Geoff
>


Gmane