» Goto page Previous  1, 2, 3  Next
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.

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!
jr nz,\$+7
ld d,48
jp accept
push af     ;save this for later
jr nc,\$+4
neg
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
ld a,d
cpl
ld d,a
ccf
rla
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
ld b,a
xor a
jr c,\$+7
sub c
jr nc,\$+5
ld c,a
xor a
push af
ld a,b
ld e,a
ld a,h
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
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
ld c,a
ld b,0
ldir
pop de
pop bc
ld a,b
ld c,a
ld b,0
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
;;    "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
xor c
ld a,c
jp p,\$+5
neg
and %00111111
ld hl,sine_table
ld l,a
jr nc,\$+3
inc h
ld a,(hl)
bit 7,c
jr z,\$+4
neg
ld b,a
ld a,c

ld c,a
xor c
ld a,c
jp p,\$+5
neg
and %00111111
ld hl,sine_table
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
pop de
ld a,e
ld a,d
ld d,a
ld a,l
ld a,h
ld e,a
ret

A_Times_E_signed:
;;Inputs: A,E
;;Outputs: HL
;;250+6b+34a
;;worst: 332cc
ld a,e
sbc a,a
ld d,a
ld a,l
ld hl,0
rlca \ jr nc,\$+5 \ ld l,e \ ld h,d
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
The last 5 errors stopping compile of Slender:

Code:
Warning: Instruction ld b,* does not expect an index - check parentheses. [slender_movement.asm:22]
Warning: Instruction ld b,* does not expect an index - check parentheses. [slender_movement.asm:36]
Warning: Instruction ld b,* does not expect an index - check parentheses. [slender_movement.asm:54]
Warning: Instruction ld b,* does not expect an index - check parentheses. [slender_movement.asm:62]
Error: Could not parse expression 'backgroundSelect' (Invalid number). [main_loop.asm:7]

As for the first four, I'm hoping i can still use ld b,(**). If not, i'll have to work around that.

As for the last one, that's a routine I have yet to write, so yeah. That will set the background for the game (so that I can make it alterable since "The Arrival" occurs during the day too).
There's no ld b,(addr) command. You can do ld bc,(addr-1) if you want (puts (addr-1) into c, (addr) into b). Otherwise, you generally do ld a,(addr) \ ld b,a. Not that ld bc/de/sp,(addr) are prefixed instructions and thus take an extra byte (4 bytes total) and 4 cycles (20 total). ld hl,(addr) is not prefixed so it's slightly faster and smaller, though i think you can use the same prefix as with bc/de (\$ED) and it'll still work the same. Don't know why you'd wanna do that, though.
Update: First official compile of Slender this morning. It crashed immediately. So, time to debug :p

Also, anyone with Git access to my Slender repo can download the beta from the path "/home/git/projects/slender/MONTH/DAY/slender.8xp". If anyone else wants to test.
Update: we now see a splash screen, then a crash. Screenshot posted on project page, under Gallery/Screenshots.

Screenshot of title screen.

Progress Update:

Project page. After Deep pointed me to the jQuery.mobile plugin, was able to use the "tap" method to integrate with my onclick triggers. The project page for Slender is now mobile-capable.

Slender. After being poked by Xeda on the fact that her text routine crashes if text goes off screen, I revised my calls to the routine such that text wraps manually. Crash persists.
The older screenshots were irking me bc the text wasn't entirely readable so I made a simpler, cleaned up version of it. And yes, that's a high-res, scaled down Slender font.

Update

New font to the project page. http://clrhome.org/slender. Also changed logo from Slender, to Slender-TI to distinguish it from the original, both so my project has a distinct name and to avoid copyright issues.

A few changes to the source code to try to find this bug and still it persists. It crashes immediately after the splash screen (pressing 2nd). I'm toying with the idea that it may be the keypress itself that is crashing it (somehow the value of a is getting distorted during the keypresses, but i added some push/pop af and it persists. My second thought is that its somewhere in my object rendering loop, and since I'm still pending a sorting algorithm, it seems pointless to debug that at this point.
Update

Finally resolved the Slender crash. Turns out if I'm activating a second keygroup, I need to reset the driver. Well, lesson learned. Currently waiting on a sorting revision to my rendering code and 2 & 1/2 sprites. Then, we can have a release.
Update

A bit of restructuring of the slender repository. Files renamed, consolidated, folders renamed to more explanative things. Main game loop moved into main file. Support for multiple keypresses at once added. This allows you to do things like walk and collect a page, or turn while walking, but it also allows you to do dumb things like turn both ways, and walk back and forth at the same time. Also streamlined and fixed the filtering of objects into a stack of objects on screen, so still have the by-distance sorter to do. Still have 2 sprites left to do. User's Guide is in progress.

Also, I asked this in another topic, but I'll post it here since it technically belongs here. There is a header somewhere for a shell that supports no-stub. I thought it was Mirage, but was told that it was Ion. Is there documentation for this? And if the header is, for example, an Ion header, will it work for DCS, and will it also work if no shell at all is present?
ACagliano wrote:
Also, I asked this in another topic, but I'll post it here since it technically belongs here. There is a header somewhere for a shell that supports no-stub. I thought it was Mirage, but was told that it was Ion. Is there documentation for this? And if the header is, for example, an Ion header, will it work for DCS, and will it also work if no shell at all is present?

There might be other documentation for this that's better, but some info about the Ion header is available here: http://www.joewing.net/projects/ti83/ion/devel.shtml

By choosing between ret and xor a at the beginning of your program, you can choose if it will work when it's run without a shell. DCS supports both of these types of Ion headers and will display the description when one is present.
Yeah, you just need to change the ret to xor a. You don't even need to put a description, a .db 0 would probably be enough for shells like Mirage and DoorsCS to handle it. It will work with any recent shell or without a shell, as long as you don't use any ion libraries. Also, keep in mind that nostub programs are much more limited than non-shell programs because the OS limits them to 8kb. It'll refuse to run the program if it's too large, so you'll need to run it with a shell or write a launcher that copies itself to saferam and then copies your program to 9D95 and deletes it afterwards. You'd have to handle program writeback yourself, though.
Program size is not a problem. The game seems like it will clock in around 6-7k. And is that executable size limit whole-program or executable-part only?

Also, I use no libraries. It is a stand-alone program. Just wanted shell support, should one choose to be used. So I'm assuming DCS/Ion/MOS will interpret this properly:

Code:

.nolist
#include "ti83plus.inc"
#include "dcs7.inc"      ; just bc i use some RAM equates from it
.list
#include "includes/defines.inc"

.variablename "SLEND8P"
.org progstart
.db \$BB,\$6D

Init:
xor a
jr nc,Start
Description:
.db "Slender: Eight Pages",0
Start:
\\ program here

.end
.end

Also, I now have, but will not reveal yet, a storyline for a 4-title original Slender series.
That should work fine, yeah. And it's a total program size limit when run from the TI-OS, not an executable code limit.
With the return to progress on this game comes another redesign of the project page at http://clrhome.org/slender. Also comes substantial progress-- completed saving/loading, keypress detection, movement, looking, death conditions, assorted math routines, a raycaster and frame rendering (by Zeda). All that is left is one part of the frame rendering, sprites, and the map, and then we are finished.

ps: no screenshots yet bc i made the incredible choice of doing the rendering last :p
Without rendering things to the screen how do you know things are working correctly?
chickendude wrote:
Without rendering things to the screen how do you know things are working correctly?

Rendering simply projects data that is already there and monitorable. I step the code one line at a time, watch how it flows, and watch the registers/RAM state. Seems to do what it's supposed to.
While I've been working on Star Trek MP for the CE, I decided to give my Slender CE project a bit of a nudge in the "complete" direction, by tossing in a ported version of Star Trek's rendering engine and modifying the mapdata structures a bit. I was inspired to do this bc of the upcoming release of an official Slenderman movie.

I built and created a working program, but the renderer is a little... off. Firstly, you seem to only see one tree, nothing else. Looking around (left/right) works properly but moving forward or backward does not. Regardless of what direction you're moving in you seem to move away and then towards. I wonder if this is an issue with my rendering algorithm or my map generation algorithm, or possibly because you're overflowing the range quickly.

Here's a link to the source, for anyone wishing to review: https://bitbucket.org/anthonycagliano/ti-slender-ce/.

Teaser:
Any updates, or is this just another forgotten game?
Legoman314 wrote:
Any updates, or is this just another forgotten game?

This game is still in progress, but I'm having a weird and frustrating issue. The rendering engine seems to render only the Slender sprite and one of the other sprites. I'm wondering if this is actually an issue with the spawning algorithm instead. I've tried re-writing, checking data types etc, but cant figure this out.

Moving causes even more weirdness. I've enclosed a screenshot and a link to the source:
Source: https://bitbucket.org/anthonycagliano/ti-slender-ce/

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.

»
» Goto page Previous  1, 2, 3  Next
» 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