The idea here is this routine goes from your current angle-5 to current angle +5, in increments of 1. The result is an 11-entry stack, with either $FF for nothing found, or the type ID and distance of the object found. The renderer will then parse that stack to update the screen.

Feel free to correct/optimize, but let me know what, if anything, I did wrong so I learn. Thanks!


Code:

#define distance tempSwapArea ; 1 byte
#define rayCurrent distance+1 ; 2 bytes
#define angleCurrent rayEnd+2 ; 1 byte
#define angleStart angleCurrent+1 ; 1 byte
#define angleStop angleStart+1 ; 1 byte
#define iterVector angleStop+1  ; 2 bytes
#define rcStack iterVector+2 ; 2 bytes, a pointer to the start of the raycaster object stack
#define renderDistance 10 ; adjust this to change the render distance
#define priorAngle rcStack+2 ; 1 byte

 
engine_raycaster_Init:
 ld hl,smallEditCol
 ld (rcStack),hl ; reset pointer to start of raycaster stack
 ld a,(playerDirection)
 ld hl,priorAngle
 cp (hl)
 jr z,{1@}
 ld a,b
 ld b,5
 add a,b
 ld (angleStop),a
 ld b,-10
 add a,b
 ld (angleStart),a
@:  ld a,(angleStart)  ; sorry about this bit, but needs to be here for the jump to work
 ld (angleCurrent),a  ; shouldnt be too time-consuming to do that
rc_loop_angle:
 call _getTempVector
 ld a,(playerPosX)
 ld h,a
 ld a,(playerPosY)
 ld l,a
 ld bc,(iterVector)
rc_loop_ray:
 add hl,bc
 call rc_getDistance
 ld (distance),a
 ld a,l
 multAbyWidth
 ld c,h
 ld b,0
 add hl,bc
 call rc_getMap
 ld a,(hl)
 or a
 jr z,rc_tiletest_skip
; rc_tilepush:  if tile is something, push this object onto rcStack, renderer will handle it
 ld de,(rcStack)
 ld (de),a ; object type Id
 inc de
 ld a,(distance)
 ld (de),a
 inc de
 ld (rcStack),de
 jr rc_skip_writeempty
rc_tiletest_skip:
 ld a,(distance)
 cp renderDistance
 jr z,rc_loop_angle_next
 jr c,rc_loop_angle_next
 jr rc_loop_ray
rc_loop_angle_next:
 ld de,(rcStack)
 ld a,$ff
 ld (de),a
 inc de
 ld (rcStack),de
rc_skip_writeempty:
 ld a,(angleCurrent)
 inc a
 ld (angleCurrent),a
 jr rc_loop_angle
 
 
 
 




rc_getTempVector:
; using current angle, gets vectors. each vector is in 8.8 FP format, so we only save the .8 part
; input: a = angle
; output: new vectors loaded into (iterVector) word
 push af
  call calcSin ; a = angle
  ld (iterVector),l ; hl = 8.8 FP
 pop af
 call calcCos
 ld (iterVector+1),l
 ret

rc_getMap:
; input: hl = offset in map
; output: hl points to tile
 ld bc,(SlendMapPtr)
 add hl,bc
 ret

rc_getDistance:
; input: hl = current testing location
; output: a = distance from origin

; this should do distance formula. pretend it does
 ret
bump
bump again.

At least one glitch i've spotted already, but not sure how to resolve.

in getTempVectors, each time the trig routine returns hl, an 8.8 Fixed Point, I save 'l', the .8 part, into iterVector. So iterVector is .8 for the X and .8 for the Y. Yet, the player position we use is the integer parts. Right after rc_loop_ray, I have hl, which is player position, and bc, which is (iterVector) and I add hl and bc. This is wrong. I may have to do two additions, one for X and one for Y, but I was hoping to avoid that.
Are you worried about under- and over-flowing in the individual parts? If so, you definitely can't do it as a single addition. I see plenty of things that could be optimized in the code in the first post, but before optimization, you should worry about functionality. Does this code work? I'm a firm believer in incremental development: you should never, ever write big chunks of untested code. Instead, you should write one small core piece, test it and make sure it works, add another piece, test, and so on. Is it safe to say you haven't run this code yet?
It compiles and runs without crashing. However, without a set of graphics to render, I can't actually see if its working as it should, or looping, or somehow getting stuck.
ACagliano wrote:
It compiles and runs without crashing. However, without a set of graphics to render, I can't actually see if its working as it should, or looping, or somehow getting stuck.
Ah, that makes sense. Well, it sounds like you have a very clear next step in your project, then. Smile
You can tell if it's looping/getting stuck easily enough just by checking if the routine finishes. However i agree with Kerm that you should work on your program in pieces. If you have no way to test if the output is correct, perhaps you should work on something else. Otherwise you'll just have more trouble debugging it later as you aren't as familiar with the code anymore. Write some of the graphic routines so that you can actually check if the code works.

You can also enter default values and check to see if the results from the routine are correct. For example, check if the bytes at (rcStack) (ie smallEditBufer) = $FF. Then add some objects in and check if they are detected.

But if you really have no way of testing if a routine works, in my opinion it's much too early to be writing that routine. I can't remember the last time a piece of code i wrote worked the first time. Actually, that's not exactly true, a couple days ago working with add a piece of code worked perfectly on the first assemble, but that's definitely the exception, not the rule. Writing blind assembly is just asking for trouble later.
Ok, I made some changes and revisions work, however I'm having an issue where the same "object" is returned twice because two adjacent rays happen over the same box. Would an adequate way to resolve this be to simply strike out duplicates from the stack?
  
Register to Join the Conversation
Have your own thoughts to add to this or any other topic? Want to ask a question, offer a suggestion, share your own programs and projects, upload a file to the file archives, get help with calculator and computer programming, or simply chat with like-minded coders and tech and calculator enthusiasts via the site-wide AJAX SAX widget? Registration for a free Cemetech account only takes a minute.

» Go to Registration page
Page 1 of 1
» All times are UTC - 5 Hours
 
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum

 

Advertisement