I have some untested code that prepares objects for drawing (find eligible candidates, sort by distance). If it works correctly, then all you need is to implement the rendering code which should be straight-forward.

Also, I am assuming you already have a sine table of the first 64 elements

**Code:**```
```

ld hl,obj_array

call seive_sort

call render

;<<code>>

ret

seive:

;save our obj_array pointer

;start index at -1

ld (obj_array_ptr),hl

ld a,-1

ld (obj_index),a

push af

pop af

;now we loop through the array

seive_loop:

;our obj_array (array of objects) needs to be scanned and sorted

;the first thing is to update our index

ld hl,obj_index

inc (hl)

ld hl,(obj_array_ptr)

;Get the first byte of the object's code

;If it is 0xFF, then the object array is finished and we move on to sorting

ld a,(hl)

inc a

jp z,sort

inc hl

;Now we get the coordinates of the object relative to the map

ld e,(hl)

inc hl

ld d,(hl)

inc hl

ld (obj_array_ptr),hl

;Now we need to get the coordinates relative to the player

ld hl,(player_coords) ;y,x

ld a,e

sub l

ld e,a

ld a,d

sub h

ld d,a

;Now we rotate based on the player's view angle

call rotate_de

;If the adjusted y-coordinate is negative, this is behind the player

ld a,e

or a

jp m,seive_loop

;Now we check the the x-coordinates. This is a bit complicated:

; If the x-coordinate is 0, it is directly ahead of the player, so draw it

; --Side Note--

; The player view angle can be drawn using the graphs of y=4x, y=-4x.

; This is almost exactly 10 binary degrees, but much easier to compute

; To check if an object is in view, if x is negative, we draw a line of slope

; -4x from the point to locate the x intercept. If this is greater than zero, it fits

; For positive x, we find the x intercept of the line of slope 4x passing through the point

; If this is negative, we are good to go!

; Doing the math, we need 4x+y<=0 for negative x, 4x-y<=0 for positive x

ld a,d ;x-coord, we need it multiplied by 4, so mul by 2 gives us the sign, too!

add a,a

jr nz,$+7

ld d,48

jp accept

push af ;save this for later

jr nc,$+4

neg

add a,a

jr c,seive_loop-1

sub e

neg

jp m,seive_loop-1

;so now we know object is in range

;What we want to do know is figure out the x-coordinate to display the object

;Basically, if we take a horizontal slice of the view range that intercepts the object

;we need how far the object is from the edge divided by total width of the view range

;then we multiply by the screen width (96)

;

;We did the "push af" before to capture whether or not it was in the left of the view range

;or not. this just means we need to do 1-dist_from_edge/total_dist

;Total distance is 2*y/4 = y/2, so we need to perform 96*x/(y/2) = 96*(2x/y)

;This algorithm is hackadasical (<--- made up word), but it relies on the fact that

;2x<y<128 which is always true

;a=4x, e=y

ld d,o \ sub e \ jr nc,$+3 \ add a,e \ rl d

add a,a \ sub e \ jr nc,$+3 \ add a,e \ rl d

add a,a \ sub e \ jr nc,$+3 \ add a,e \ rl d

add a,a \ sub e \ jr nc,$+3 \ add a,e \ rl d

add a,a \ sub e \ jr nc,$+3 \ add a,e \ rl d

add a,a \ sub e

ld a,d

cpl

ld d,a

ccf

rla

add a,d

ld d,a

pop af

jr nc,$+6

ld a,96

sub d

ld d,a

;now we need to write our un-adjusted y, adjusted x, and obj_index to the sort buffer

accept:

ld hl,sort_buf

inc (hl)

ld hl,(sort_buf_write)

ld (hl),e

inc hl

ld (hl),d

inc hl

ld a,(obj_index)

ld (hl),a

jp seive_loop

sort:

;;Use merge-sort

;;data is .db y,x,index

;;sort descending by y

;;Up to 56 objects

;;

;;Outputs: A as the number of objects to draw

;; HL points to the first object

ld bc,$0101

sort_loop:

ld hl,sort_buf

ld a,(hl)

inc hl

cp b

ret nc

sort_loop1:

push bc

sub b

jr nc,$+8

add a,b

ld b,a

xor a

jr c,$+7

sub c

jr nc,$+5

add a,c

ld c,a

xor a

push af

ld a,b

add a,l

ld e,a

ld a,h

adc a,0

ld d,a

call merge_sorted

pop af

pop bc

or a

jr nz,sort_loop1

sla b

ld c,b

jp sort_loop

merge_sorted:

;;Inputs:

;; HL points to one sorted list

;; DE points to another sorted list

;; B is the size of the first list, non zero

;; C is the size of the second list

;;Outputs:

;; The list is merged and sorted, and written back

;; HL points to the next set of sublists

ld a,c

or a

ret z

ld ix,sort_buf+1+3*56

push bc

push hl

merge_and_sort_loop:

ld a,(de)

cp (hl)

jr c,copy_list2

ld a,(hl)

ld (ix),a

inc hl

inc ix

ld a,(hl)

ld (ix),a

inc hl

inc ix

ld a,(hl)

ld (ix),a

inc hl

inc ix

djnz merge_and_sort_loop

;copy the rest of the second list

;actually we will just cheat and write back our current data

;No use in copying the second list just to copy back

push ix

pop hl

ld de,sort_buf+1+3*56

ld a,c

or a

sbc hl,de

ld b,h

ld c,l

pop hl

ex de,hl

ldir

ld c,a

ex de,hl

add hl,bc

pop bc

ret

copy_list2:

ld a,(de)

ld (ix),a

inc de

inc ix

ld a,(de)

ld (ix),a

inc de

inc ix

ld a,(de)

ld (ix),a

inc de

inc ix

dec c

jr nz,merge_and_sort_loop

;now we copy the rest of the first list

push ix

pop de

ld a,b

add a,a

add a,b

ld c,a

ld b,0

ldir

pop de

pop bc

ld a,b

add a,c

ld c,a

ld b,0

add a,a

add a,c

ld c,a

ld hl,sort_buf+1+3*56

ldir

ex de,hl

ret

render:

;;Inputs: A is the number of objects to draw, HL points to the first object

;;Destroys: Assume all

;;Notes:

;; Objects are stored as (y,x,index)

;; Y needs to be adjusted for drawing

;; X is already adjusted

;; "index" refers to the object's index into the list of objects

;; This needs to be used to retrieve the rest of the object information

ret

rotate_de:

;d = x

;e = y

;-(player_angle) is the amount by which to rotate

;

ld a,(player_angle)

neg

; x = x*cos - y*sin

; y = x*sin + y*cos

;get cos(a), sin(a)

;note cos(a) = sin(a-64)

ld c,a

add a,a

xor c

ld a,c

jp p,$+5

neg

and %00111111

ld hl,sine_table

add a,l

ld l,a

jr nc,$+3

inc h

ld a,(hl)

bit 7,c

jr z,$+4

neg

ld b,a

ld a,c

add a,64

ld c,a

add a,a

xor c

ld a,c

jp p,$+5

neg

and %00111111

ld hl,sine_table

add a,l

ld l,a

jr nc,$+3

inc h

ld a,(hl)

bit 7,c

jr z,$+4

neg

ld b,a

;c is sine

;b is cosine

;d = x

;e = y

push de

;x*cos - y*sin

;d*b - e*c

;x*sin + y*cos

;d*c + e*b

ld a,b

ld e,d

call A_Times_E_signed

pop de

push de

push hl

ld a,c

call A_Times_E_signed

pop de

or a

sbc hl,de

ex (sp),hl

push hl

ld a,h

ld e,c

call A_Times_E_signed

pop de

ld a,b

ld b,h

ld c,l

call A_Times_E_signed

add hl,bc

pop de

ld a,e

add a,a

ld a,d

adc a,0

ld d,a

ld a,l

add a,a

ld a,h

adc a,0

ld e,a

ret

A_Times_E_signed:

;;Inputs: A,E

;;Outputs: HL

;;250+6b+34a

;;worst: 332cc

ld a,e

add a,a

sbc a,a

ld d,a

ld a,l

ld hl,0

rlca \ jr nc,$+5 \ ld l,e \ ld h,d

add hl,hl \ rlca \ jr nc,$+3 \ add hl,de

add hl,hl \ rlca \ jr nc,$+3 \ add hl,de

add hl,hl \ rlca \ jr nc,$+3 \ add hl,de

add hl,hl \ rlca \ jr nc,$+3 \ add hl,de

add hl,hl \ rlca \ jr nc,$+3 \ add hl,de

add hl,hl \ rlca \ jr nc,$+3 \ add hl,de

add hl,hl \ rlca \ jr nc,$+3 \ add hl,de

add a,a

ret nc

ld d,e

ld e,0

or a

sbc hl,de

ret

Also, I am assuming you already have a sine table of the first 64 elements