log in | register | forums
Show:
Go:
Forums
Username:

Password:

User accounts
Register new account
Forgot password
Forum stats
List of members
Search the forums

Advanced search
Recent discussions
- Elsear brings super-fast Networking to Risc PC/A7000/A7000+ (News:)
- Latest hardware upgrade from RISCOSbits (News:)
- Accessing old floppy disks (Gen:3)
- November developer 'fireside' chat on saturday night (News:)
- RISCOSbits releases a new laptop solution (News:4)
- Announcing the TIB 2024 Advent Calendar (News:2)
- RISC OS London Show Report 2024 (News:1)
- Code GCC produces that makes you cry #12684 (Prog:39)
- Rougol November 2024 meeting on monday (News:)
- Drag'n'Drop 14i1 edition reviewed (News:)
Latest postings RSS Feeds
RSS 2.0 | 1.0 | 0.9
Atom 0.3
Misc RDF | CDF
 
View on Mastodon
@www.iconbar.com@rss-parrot.net
Site Search
 
Article archives
Acorn Arcade forums: Programming: Take two
 
  Take two
  This is a long thread. Click here to view the threaded list.
 
Andrew Message #63188, posted by andrew at 20:04, 10/3/2005
HandbagHandbag Boi
Posts: 3439
Here are some gfx and shots from the cave-demo I was working on:

http://web.ukonline.co.uk/a.weston2/programs/vic1.png


http://web.ukonline.co.uk/a.weston2/programs/vic2.png

Here's the total map (1806x the size of the screen!):
http://web.ukonline.co.uk/a.weston2/programs/mapFS.png









[Edited by andrew at 00:55, 11/3/2005]
  ^[ Log in to reply ]
 
Jeffrey Lee Message #63190, posted by Phlamethrower at 20:30, 10/3/2005, in reply to message #63188
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
<img src="url">

Looks good, but the large map is a bit... simple :|
  ^[ Log in to reply ]
 
Andrew Message #63210, posted by andrew at 13:56, 11/3/2005, in reply to message #63190
HandbagHandbag Boi
Posts: 3439
Well the idea behind the map was to have it generated by an algorithm and technically it can be generated on-the-fly although that would make it extremely slow as it uses sine/cosine.
Therefore it creates a lookup table of bits (~36K).
There was one map when I was playing about with the generator that was incredibly complex and looked like a vast cave network with a vertical shaft going all the way to the bottom and 'tunnels' emerging at the sides but it would have made it impossible to navigate. So I opted for this which although less complex is easier to fly about in ;)
  ^[ Log in to reply ]
 
Tony Haines Message #63211, posted by Loris at 17:19, 11/3/2005, in reply to message #63210
madbanHa ha, me mine, mwahahahaha
Posts: 1025
Moral of the story - don't use sin or cosine in on-the-fly generation.

Seriously, Andrew, if you want help generating a suitable, big, interesting-looking map let me know.

(I'm not disparaging what you've done - keep working on it.)

[Edited by Loris at 17:21, 11/3/2005]
  ^[ Log in to reply ]
 
Lewis Westbury Message #63212, posted by instantiator at 17:33, 11/3/2005, in reply to message #63211
Member
Posts: 365
tables?
  ^[ Log in to reply ]
 
Andrew Message #63220, posted by andrew at 01:14, 12/3/2005, in reply to message #63212
HandbagHandbag Boi
Posts: 3439
Thanks for the offer. I found it v.difficult to get interesting patterns without using polar calculations but I didn't want to nab anybody's formula although there was a random no. generator I was going to try. It's not a problem really having a lookup table in terms of size although finding bits might impose an overhead.
  ^[ Log in to reply ]
 
Jason Tribbeck Message #63256, posted by tribbles at 23:59, 12/3/2005, in reply to message #63220
tribbles
Captain Helix

Posts: 929
Mmmm ... tables...

For ArcCommand (and Equinox), I have sin tables, and an arctan table (cos is derived from sin).

The sin table contains 256 fixed-point values, although everything is actually 32-bit (only uses top 24-bits for sin). This means you don't need to worry about overflow when you're rotating anything, and you get enough accuracy in the value so it doesn't look jerky.

Arctan is used to calculate the angle something needs to be at in order for it to point at something else. My implementation of that algorithm is actually very quick (if you aren't interested in being 100% accurate). The table size is also surprisingly small.

This is ultimately used by the seeking missiles, and enemies that need to track where you are.

Equinox uses random polar coordinates for enemy generation, with 4 different values:

- start angle
- delta angle
- start distance
- delta distance

With these variables, you can create objects at individual points, rings around the player, or randomly.
  ^[ Log in to reply ]
 
Andrew Message #63273, posted by andrew at 15:55, 13/3/2005, in reply to message #63256
HandbagHandbag Boi
Posts: 3439
Why 256 values?
  ^[ Log in to reply ]
 
Adrian Lees Message #63275, posted by adrianl at 16:55, 13/3/2005, in reply to message #63273
Member
Posts: 1637
Why 256 values?

Most probably because if your angles are then in units of 1/256th of a cycle (full circle) then you can look up a value by using modulo arithmetic (sine functions are periodic) which is very cheap for powers of two.

int sin_table[256];

draw(sin_table[(theta + 64) & 0xff], sin_table[theta & 0xff]);

The +64 gives a phase shift, ie. a cosine function rather than have two separate tables of values.

Clear as mud? ;)

[Edited by adrianl at 16:57, 13/3/2005]
  ^[ Log in to reply ]
 
Andrew Message #63286, posted by andrew at 20:13, 13/3/2005, in reply to message #63275
HandbagHandbag Boi
Posts: 3439
What is 1/256th in degrees/radians though?
  ^[ Log in to reply ]
 
Jeffrey Lee Message #63288, posted by Phlamethrower at 20:22, 13/3/2005, in reply to message #63286
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
1/256th would be 360/256 in degrees, or 2*PI/256 in radians. Not that hard to work out, eh? ;)
  ^[ Log in to reply ]
 
Andrew Message #63299, posted by andrew at 23:10, 13/3/2005, in reply to message #63288
HandbagHandbag Boi
Posts: 3439
what I mean is why would your angles be in units of 1/256th of a circle?
  ^[ Log in to reply ]
 
Jeffrey Lee Message #63302, posted by Phlamethrower at 23:22, 13/3/2005, in reply to message #63299
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
The main reason as I see it is that you won't have to worry about rounding large angles down so that they lie in a 0-360 degree range. All you'll have to do is AND the angle with 255 and look up the result in the table.
  ^[ Log in to reply ]
 
Adrian Lees Message #63303, posted by adrianl at 23:31, 13/3/2005, in reply to message #63302
Member
Posts: 1637
The main reason as I see it is that you won't have to worry about rounding large angles down so that they lie in a 0-360 degree range. All you'll have to do is AND the angle with 255 and look up the result in the table.

Indeed. If you already know that your angle lies between 0 and 360 degrees then there's no merit to choosing a power of two.

If, however, your angle can be any number, then it's more efficient to use a power of two because that 'rounding down' process involves a division which is expensive, but division by any power of two is cheap - it becomes a right-shift, and remainder becomes a bitwise AND.
  ^[ Log in to reply ]
 
Tony Haines Message #63332, posted by Loris at 17:51, 14/3/2005, in reply to message #63299
madbanHa ha, me mine, mwahahahaha
Posts: 1025
Jeffry and Adrian are correct - powers of 2 have binary advantages, but to add to that : perhaps you should be asking yourself "why 360?"
256 also has the property of fitting in a byte, which is often useful, and there is of course the ARM constant issue. But if you need more accuracy, use more bits!

Why did you start using trig. functions in the first place - could you give us some idea of what sort of map you really want?
I think you want large caverns, but are there any other desires?
  ^[ Log in to reply ]
 
Jason Tribbeck Message #63337, posted by tribbles at 21:47, 14/3/2005, in reply to message #63302
tribbles
Captain Helix

Posts: 929
The main reason as I see it is that you won't have to worry about rounding large angles down so that they lie in a 0-360 degree range. All you'll have to do is AND the angle with 255 and look up the result in the table.
Actually, I store it as a full 32-bit value, which means if you want to rotate by, say, 43 bradians (binary radians :) ), then you just do:

ADD r0, r0, #43<<24

You don't need to worry if you've gone over 255, or under 0. It also gives you a heck of a lot of accuracy (should you need it).

Reading from the SIN table is fairly easy:

MOV r0, r0, LSR#24
LDR r0, [r1, r0, LSL#2]

Reading the COS value from the SIN table is also fairly easy:

ADD r0, r0, #64 << 24
MOV r0, r0, LSR#24
LDR r0, [r1, r0, LSL#2]

Any more, and this should be in programming :)


[Edited by tribbles at 21:50, 14/3/2005]
  ^[ Log in to reply ]
 
Richard Goodwin Message #63345, posted by rich at 00:25, 15/3/2005, in reply to message #63337
Rich
Dictator for life
Posts: 6828
I can move it if you wish...
________
RichGCheers,
Rich.
  ^[ Log in to reply ]
 
Adrian Lees Message #63348, posted by adrianl at 10:30, 15/3/2005, in reply to message #63337
Member
Posts: 1637
Reading the COS value from the SIN table is also fairly easy:

ADD r0, r0, #64 << 24
MOV r0, r0, LSR#24
LDR r0, [r1, r0, LSL#2]
For the benefit of anybody else using this technique, you can avoid the ADD instruction by replicating the first 90 degrees worth of table at the table end, so you have 450 degrees of data, and then adjusting the value of r1.

This is more efficient if you do a lot of COS lookups in a row, or can spare a register to have one COS table base and one SIN table base.
  ^[ Log in to reply ]
 
Tony Haines Message #63352, posted by Loris at 12:09, 15/3/2005, in reply to message #63348
madbanHa ha, me mine, mwahahahaha
Posts: 1025
ADD r0, r0, #64 << 24
MOV r0, r0, LSR#24
LDR r0, [r1, r0, LSL#2]
For the benefit of anybody else using this technique, you can avoid the ADD instruction by replicating the first 90 degrees worth of table at the table end, so you have 450 degrees of data, and then adjusting the value of r1.

Ppht. too slow.
One should insert other useful instructions between the MOV and LDR if possible, since memory accesses are slower if the regs are adjusted in preceeding ops. ;)
  ^[ Log in to reply ]
 
Jeffrey Lee Message #63357, posted by Phlamethrower at 12:58, 15/3/2005, in reply to message #63352
PhlamethrowerHot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot Hot stuff

Posts: 15100
Just for completeness, here's the code from WOUM for the 16.16 fixed-point sin/cos functions. They accept angles in degrees as input, and return results within +/- 1/65536th of the correct value (Possibly +/- 2/65536th on one or two values, I can't remember). f1616_costabptr points to a 1441 entry table containing the values of cos 0 to cos 90 in 16.16 format, each entry being one 16th of a degree.

f1616_sin ; r0=in,r0=out
; since sin x=cos (x-90)...
SUB R0,R0,#90*65536
f1616_cos ; R0=angle, returns value
CMP R0,#0
RSBLT R0,R0,#0 ; Make positive
f1616_cos_loop
CMP R0,#360*65536
SUBGE R0,R0,#360*65536
BGT f1616_cos_loop
MOV R1,R0,LSR #12 ; Get location in table
SUB R0,R0,R1,LSL #12 ; Get interpolation factor
ADD R2,R1,#1 ; Location of 2nd value
; Work out quadrant
CMP R1,#180*16
RSBGE R1,R1,#360*16 ; Reflect if >180
RSBGE R2,R2,#360*16
CMP R1,#90*16
CMPGE R2,#90*16
RSBGE R1,R1,#180*16 ; Reflect again
RSBGE R2,R2,#180*16
LDR R3,f1616_costabptr
LDR R1,[R3,R1,LSL #2]
LDR R2,[R3,R2,LSL #2]
MUL R2,R0,R2
RSB R0,R0,#4096
MLA R1,R0,R1,R2
RSBGE R1,R1,#0 ; Negate answer if needed
MOV R0,R1,ASR #12 ; Back to 16.16
MOV PC,R14

And for the benefit of Adrian, no this hasn't been heavily optimised yet ;) (Although I did just spot a couple of inefficiencies and update the code ;))

I did have some code knocking around for representing angles as fractions from 0-1, but it translates them into another format before looking up the result :|

[Edited by Phlamethrower at 13:38, 15/3/2005]
  ^[ Log in to reply ]
 
Adrian Lees Message #63360, posted by adrianl at 13:24, 15/3/2005, in reply to message #63352
Member
Posts: 1637
One should insert other useful instructions between the MOV and LDR if possible, since memory accesses are slower if the regs are adjusted in preceeding ops. ;)
Do you mean that there's an extra cycle of result latency because r0 is shifted by an immediate constant in the LDR instruction? True. LDRs aren't delayed by any old write to their source registers in the preceding instruction, it's just for shifted operands (and just on XScale).

You don't want to go using the result of the LDR within the next 2 cycles, however. (XScale, 1 cycle on SA)... leave it as late as possible, in fact; the data may not be cached!
  ^[ Log in to reply ]
 
Jason Tribbeck Message #63361, posted by tribbles at 13:51, 15/3/2005, in reply to message #63352
tribbles
Captain Helix

Posts: 929
ADD r0, r0, #64 << 24
MOV r0, r0, LSR#24
LDR r0, [r1, r0, LSL#2]
Ppht. too slow.
One should insert other useful instructions between the MOV and LDR if possible, since memory accesses are slower if the regs are adjusted in preceeding ops. ;)
<sarcastic>Aha, so the whole reason why my game is too slow is because I'm wasting cycles.

Wow! I was thinking it's that silly "C" stuff, with all its bloat-code around entry and exit procedures. Thanks for the tip!</sarcastic>

:E
  ^[ Log in to reply ]
 
Tony Haines Message #63365, posted by Loris at 15:05, 15/3/2005, in reply to message #63360
madbanHa ha, me mine, mwahahahaha
Posts: 1025
One should insert other useful instructions between the MOV and LDR if possible, since memory accesses are slower if the regs are adjusted in preceeding ops. ;)
Do you mean that there's an extra cycle of result latency because r0 is shifted by an immediate constant in the LDR instruction? True. LDRs aren't delayed by any old write to their source registers in the preceding instruction, it's just for shifted operands (and just on XScale).

There is result delay too, of course. I was remembering some trials that - I think it was Icebird - did. He found that LDRs were affected by their addressing operands changing. This is different to what Acorn stated. Can't seem to access the website now, so I can't check.
Didn't do my own trials on this, and it was a long time ago, so more recent processors may exhibit different behaviour. Although given that the more recent ARMs seem to have more dependencies, they may not.

You don't want to go using the result of the LDR within the next 2 cycles, however. (XScale, 1 cycle on SA)... leave it as late as possible, in fact; the data may not be cached!
Does moving it beyond 2 instructions change anything? I understood that if it wasn't cached the processor would pause anyway.


<sarcastic>Aha, so the whole reason why my game is too slow is because I'm wasting cycles.

Wow! I was thinking it's that silly "C" stuff, with all its bloat-code around entry and exit procedures. Thanks for the tip!</sarcastic>
Yeah, slowcoach!

You're right of course, and it really doesn't matter that much unless its in the inner loop anyway.

[Edited by Loris at 15:06, 15/3/2005]
  ^[ Log in to reply ]
 
Andrew Message #63385, posted by andrew at 20:05, 15/3/2005, in reply to message #63345
HandbagHandbag Boi
Posts: 3439
I can move it if you wish...
Did you mean to post this in the '2's complement' thread?
  ^[ Log in to reply ]
 
Andrew Message #63386, posted by andrew at 20:16, 15/3/2005, in reply to message #63332
HandbagHandbag Boi
Posts: 3439
Jeffry and Adrian are correct - powers of 2 have binary advantages, but to add to that : perhaps you should be asking yourself "why 360?"
256 also has the property of fitting in a byte, which is often useful, and there is of course the ARM constant issue. But if you need more accuracy, use more bits!
Why did you start using trig. functions in the first place - could you give us some idea of what sort of map you really want?
I think you want large caverns, but are there any other desires?
The problem isn't the looking up it's just the storage of negative values which I refer to in a previous thread. It's a useful tip though should I need more angles calculated as it is important to remember the phase-shift AL refers to. It's easy to forget the relationships between angles, pythagoras, nomenclature etc.

As I said above I used trig. functions as I found it difficult to create the kind of map I was after, otherwise.
The sin and cos lookups (other post) that I am talking about are for something else in the program. The map generator I have ended up storing the result of as a 36K table as I said above. The intention was to create the map on-the-fly but the trig. functions I feared would slow it down too much (although yes I could have a lookup).

The kind of map I was aiming for was shafts and tunnels with caverns but I'm fairly happy with the map personally. However I was going to ask you today about how in Exile bits of scenery might have been generated by the algorithm. Surely they weren't all stored in terms of positions?
  ^[ Log in to reply ]
 
Adrian Lees Message #63390, posted by adrianl at 23:33, 15/3/2005, in reply to message #63365
Member
Posts: 1637
He found that LDRs were affected by their addressing operands changing. This is different to what Acorn stated. Can't seem to access the website now, so I can't check.

OK, I'm only going on the documented performance in the datasheets. As an aside, the XScale makes it a lot easier to actually measure the performance of instruction sequences because of its lovely cycle counter :)

Does moving it beyond 2 instructions change anything? I understood that if it wasn't cached the processor would pause anyway.

TBH I'm not entirely certain. Logically there's no reason for the LDR to stall subsequent instructions unless they require the result, the updated base or the pipeline stage that the LDR occupies (ie. another LDR/STR op), though it could complicate exception handling.

I may have a look at this when I've got something better to do ;)

[Edited by adrianl at 23:34, 15/3/2005]
  ^[ Log in to reply ]
 
Richard Goodwin Message #63404, posted by rich at 09:30, 16/3/2005, in reply to message #63385
Rich
Dictator for life
Posts: 6828
I can move it if you wish...
Did you mean to post this in the '2's complement' thread?
No, the Programming section that you mentioned in your previous post.
________
RichGCheers,
Rich.
  ^[ Log in to reply ]
 
Jason Togneri Message #63406, posted by filecore at 10:22, 16/3/2005, in reply to message #63404

Posts: 3868
Yeah, programming would be better. It's also of use perhaps to other programmers who wouldn't otherwise come into the Playpen... ;-) and it's boring to those of us (just me?) who aren't really that interested in programming - or not this specific thing at least. Do it without telling anybody, confuse the buggers :-o
  ^[ Log in to reply ]
 
 
15:45, 16/3/2005 - At this point the thread was moved from The Playpen to Programming by rich
 
 
Andrew Message #63422, posted by andrew at 01:10, 17/3/2005, in reply to message #63404
HandbagHandbag Boi
Posts: 3439
I can move it if you wish...
Did you mean to post this in the '2's complement' thread?
No, the Programming section that you mentioned in your previous post.
Yes but that post was in the 2's complement thread was it not? :o
  ^[ Log in to reply ]
 
Pages (2): 1 > >|

Acorn Arcade forums: Programming: Take two