Page 1 of 1

Wolfenstein 3D - raycasting demo with textures

Posted: Fri Feb 19, 2021 3:06 pm
by Jeffrey


Raycaster demo (written in c and assembly)




This version is a big improvement in performance: it now runs at 10+ fps! ?




I am quite happy with the speed. The demo plays quite nicely now.




See below description of version 1.3.0 for details.




---

This is a raycaster demo written in c and assembly for the Commander x16. I've been trying out the x16 and thought it would be a cool idea to start working on a raycaster.




Ultimately it would be great if "Wolfenstein 3D" can somehow be ported to the x16. That would be a BIG challenge though! ?




This is how it looks now:




raycasting_demo_1.3.0a.gif




Speed improvements in 1.3.0:




Now running at 10+ fps! ?




- Using zero page addresses for pretty much all my variables

- Using fast multipliers that use "square" tables: https://codebase64.org/doku.php?id=base:seriously_fast_multiplication

- Inlined the fast multipliers, so less copying of values, no jsr and rts

- Re-using the somewhat "static" parts of the multiplications, so it won't be re-loaded/calculate each ray (this was harder than it sounds, quite of bit of refactoring done)

    - Cosine and Sine fractions are player-related, and even though they are negated sometimes, they (that is their squares) could be reused for (almost) each ray

    - The (square of the) fraction of the tile the player is standing in -to be used for calculating the initial x/y interception for each ray- could be reused

- Cleaned up the main loop and several other parts

- Replaced the 16-bit slow divider with a 512-entry table: distance2height (major improvement!!) ?

 




New in this version 1.2.0:




- draw functions have been ported to assembly. Much faster!

- dda casting functions have been ported to assembly. Much faster!

- drawing textures!

- automatic generation of routine to draw ceiling and floor (only 4 cycles per plain pixel)

- automatic generation of around 512 routines for drawing textures (only 8 cycles per textures pixel)

- using joystick controls (you can use arrow keys and alt to control, you can hold down keys)

- a few textures from Wolfenstein 3D (shareware version) have been added (loaded at startup)

- changed the map to look like the first level in Wolfenstein 3D

- added a border around the render area, just like Wolfenstein 3D




Usage




Unpack the zip. Make sure you have the .BIN files in the same folder as the source files.




To compile: (this assumes cc65 is installed)




    cl65 -t cx16 -o RAY.PRG ray.c ray_asm.asm -O3




To run:




    x16emu.exe -prg RAY.PRG -run




To play:




    up - move forwards

    down - move backwards

    left - turn left

    right - turn right

    alt-left - strafe left

    alt-right - strafe right




To debug:

    p - turn on log screen

    o - turn off log screen

    t - turn on test ray

    l - rotate test ray left

    j - rotate test ray right




Known issues (1.2.0)




- Sometimes there is a corner of a wall not drawn correctly

- Since there is no real V-sync you get "shearing" in the screen (requires double buffering)




 Next up:

- Lots of speed improvements

- Lots of cleanup of code (its messy now)

- Add a time-per-frame indicator (using a vsync interrupt counter)

- Mooaarr wall-textures!

- Double buffer to prevent shearing

- Show a map on the screen

- Bigger map (limit is now 16x16)

- Opening doors

- Add (scaled) "sprites"

- Lamps (scaled) hanging from ceiling

- Stats in lower part, gun visible

- AI, enemies




Having fun! ?




Jeffrey



This verion is a big improvement in performance: it now runs at 10+ fps! ?




Speed improvments in 1.3.0:




- Using zero page addresses for pretty much all my variables

- Using fast multipliers that use "square" tables: https://codebase64.org/doku.php?id=base:seriously_fast_multiplication

- Inlined the fast multipliers, so less copying of values, no jsr and rts

- Re-using the somewhat "static" parts of the multiplications, so it won't be re-loaded/calculate each ray (this was harder than it sounds, quite of bit of refactoring done)

    - Cosine and Sine fractions are player-related, and even though they are negated sometimes, they (that is their squares) could be reused for (almost) each ray

    - The (square of the) fraction of the tile the player is standing in -to be used for calculating the initial x/y interception for each ray- could be reused

- Cleaned up the main loop and several other parts

- Replaced the 16-bit slow divider with a 512-entry table: distance2height (major improvement!!) ?




Known issues (1.3.0)




- Sometimes there is a corner of a wall not drawn correctly (although not detected for some time, maybe this bug is gone?)

- Since there is no real V-sync you get "shearing" in the screen (requires double buffering)