Author Topic: Nspire Raycaster  (Read 94328 times)

0 Members and 1 Guest are viewing this topic.

Offline bwang

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 634
  • Rating: +30/-11
    • View Profile
Re: Nspire Raycaster
« Reply #75 on: March 28, 2010, 08:02:02 pm »
Hmm...the clock speed stuff doesn't seem to work on my calculator, either. Maybe it has something to do with hardware changes in newer calcs?

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Nspire Raycaster
« Reply #76 on: March 28, 2010, 11:26:22 pm »
You might want to post the source code in case there might be something wrong in it so people can help figuring out. But again, it could be due to hardware change (which I hope not)
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)

Offline bwang

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 634
  • Rating: +30/-11
    • View Profile
Re: Nspire Raycaster
« Reply #77 on: March 28, 2010, 11:34:22 pm »
Source Code:
Code: [Select]
#include <os.h>
#include "utils.h"
#include "rayheader.h"
#define mapWidth 24
#define mapHeight 24
#define texW 32
#define texH 32
#define cos1 0.9950
#define sin1 0.09983
#define stpsize 0.2

asm(".string \"PRG\"\n");

int main(void)
{
  *(unsigned*) 0x900B0000 = 0x00000002;
  *(unsigned*) 0x900B000C = 4;

  int map[mapWidth][mapHeight]=
  {
  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,1,1,1,1,1,0,0,0,0,1,0,1,0,1,0,0,0,1},
  {1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,1,0,0,0,1,0,0,0,1},
  {1,0,0,0,0,0,1,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,1,1,0,1,1,0,0,0,0,1,0,1,0,1,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,0,0,0,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,0,1,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,0,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},
  {1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1}
  };
  char* scrbuf = (char*) malloc(SCREEN_BYTES_SIZE);
  int tex[texW][texH]; 
  int u, v;
  for (u = 0; u < texW; u++) {
    for (v = 0; v < texH; v++) {
      tex[u][v] = 6;
    }
  }
  for (u = 0; u < texW; u++) {
    for (v = 0; v < texH; v++) {
      if (u % 4 == 3 || (v % 8 == 2 && ((u / 4) % 2) == 0) ||
         (v % 8 == 6 && ((u / 4) % 2) == 1)) {
        tex[u][v] = 15;
      }
    }
  }
  float px = 12, py = 12; 
  float dx = -1, dy = 0;
  float plx = 0, ply = 0.66;
  int w = 320, h = 240;
  int x, y;
  int redraw;
  while (!isKeyPressed(KEY_NSPIRE_ESC)) {
    redraw = 0;
    if (isKeyPressed(KEY_NSPIRE_LEFT)) {
      float olddx = dx;
      dx = dx * cos1 - dy * sin1;
      dy = olddx * sin1 + dy * cos1;
      float oldplx = plx;
      plx = plx * cos1 - ply * sin1;
      ply = oldplx * sin1 + ply * cos1;
      redraw = 1;
    }
    if (isKeyPressed(KEY_NSPIRE_RIGHT)) {
      float olddx = dx;
      dx = dx * cos1 + dy * sin1;
      dy = -olddx * sin1 + dy * cos1;
      float oldplx = plx;
      plx = plx * cos1 + ply * sin1;
      ply = -oldplx * sin1 + ply * cos1;
      redraw = 1;
    }
    if (isKeyPressed(KEY_NSPIRE_UP)) {
      if (map[(int) (px + stpsize * dx)][(int) (py)] == 0) px += stpsize * dx;
      if (map[(int) (px)][(int) (py + stpsize * dy)] == 0) py += stpsize * dy;
      if (px < 0) px = 0;
      if (px > 24) px = 24;
      if (py < 0) py = 0;
      if (py > 24) py = 24;
      redraw = true;
    }
    if (isKeyPressed(KEY_NSPIRE_DOWN)) {
      if (map[(int) (px - stpsize * dx)][(int) (py)] == 0) px -= stpsize * dx;
      if (map[(int) (px)][(int) (py - stpsize * dy)] == 0) py -= stpsize * dy;
      if (px < 0) px = 0;
      if (px > 24) px = 24;
      if (py < 0) py = 0;
      if (py > 24) py = 24;
      redraw = true;
    }
    if (redraw) {
      memset(scrbuf, 0x00, SCREEN_BYTES_SIZE);
      for(x = 0; x < w; x++) {
        float raypx = px;
        float raypy = py;
        int mapX = (int) raypx;
        int mapY = (int) raypy;
        float cameraX = 2 * x / (float) (w) - 1;
        float raydx = dx + plx * cameraX;
        float raydy = dy + ply * cameraX;       
        float sideDistX;
        float sideDistY;
        float raydx2 = raydx * raydx, raydy2 = raydy * raydy;
        float deltaDistX = sqrt(1 + raydy2 / raydx2);
        float deltaDistY = sqrt(1 + raydx2 / raydy2);
        float perpWallDist;
           
        int stepX;
        int stepY;

        int hit = 0;
        int side;
     
        if (raydx < 0) {
          stepX = -1;
          sideDistX = (raypx - mapX) * deltaDistX;
        } else {
          stepX = 1;
          sideDistX = (mapX + 1.0 - raypx) * deltaDistX;
        }
        if (raydy < 0) {
          stepY = -1;
          sideDistY = (raypy - mapY) * deltaDistY;
        } else {
          stepY = 1;
          sideDistY = (mapY + 1.0 - raypy) * deltaDistY;
        }
        while (!hit) {
          if (sideDistX < sideDistY) {
            sideDistX += deltaDistX;
            mapX += stepX;
            side = 0;
          } else {
            sideDistY += deltaDistY;
            mapY += stepY;
            side = 1;
          }
          if (map[mapX][mapY]) hit = 1;
        }
        if (side == 0) {
          perpWallDist = fabs((mapX - raypx + (1 - stepX) / 2) / raydx);
        } else {
          perpWallDist = fabs((mapY - raypy + (1 - stepY) / 2) / raydy);
        }

        int lineHeight = abs((int) (h / perpWallDist));
         
        int drawStart = (-lineHeight + h) / 2;
        if(drawStart < 0) drawStart = 0;
        int drawEnd = (lineHeight + h) / 2;
        if(drawEnd >= h) drawEnd = h - 1;

        float wallX;
        if (side == 1) {
          wallX = raypx + ((mapY - raypy + (1 - stepY) / 2) / raydy) * raydx;
        } else {       
          wallX = raypy + ((mapX - raypx + (1 - stepX) / 2) / raydx) * raydy;
        }
        wallX -= (int) wallX;
        int texX = (int) (wallX * (float) (texW));
        if(side == 0 && raydx > 0) texX = texW - texX - 1;
        if(side == 1 && raydy < 0) texX = texW - texX - 1;

        for (y = drawStart; y <= drawEnd; y++) {
          int d = (y << 8) - (h << 7)  + (lineHeight << 7);
          int texY = ((d * texH) / lineHeight) >> 8 ;
          int color = tex[texY][texX];
          if (side == 1) color = color / 2  ;
          setPixelBuf(scrbuf, x, y, color);
        }
      }
      refresh(scrbuf);
    }
  }

  *(unsigned*) 0x900B0000 = 0x00141002;
  *(unsigned*) 0x900B000C = 4;
  return 0;
}

Offline bwang

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 634
  • Rating: +30/-11
    • View Profile
Re: Nspire Raycaster
« Reply #78 on: March 30, 2010, 02:41:02 am »
How much FPS does the FAT engine get (so I have an idea of what to aim for)?
I think I'm going to rewrite the engine, since I found a tutorial that seems to be much more like the FAT engine's code.

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Nspire Raycaster
« Reply #79 on: March 30, 2010, 03:35:00 am »
Mhmm, I think the FAT engine gets around 6-10 fps, but I could be wrong. That's what I got from some games at least. Keep in mind FAT engine is very old, though, so idk if it's optimized to maximum. Also most games I tried were not written in pure ASM.
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: Nspire Raycaster
« Reply #80 on: March 30, 2010, 07:54:04 am »
Hmm, that is odd about the clock speed. I've never actually set it using C... maybe you need "volatile unsigned" since they are memory-mapped ports.
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline bwang

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 634
  • Rating: +30/-11
    • View Profile
Re: Nspire Raycaster
« Reply #81 on: March 30, 2010, 06:20:45 pm »
Making it volatile unsigned did the trick. Hooray for 67% more speed!

Offline ztrumpet

  • The Rarely Active One
  • CoT Emeritus
  • LV13 Extreme Addict (Next: 9001)
  • *
  • Posts: 5712
  • Rating: +364/-4
  • If you see this, send me a PM. Just for fun.
    • View Profile
Re: Nspire Raycaster
« Reply #82 on: March 30, 2010, 06:26:49 pm »
Awesome job again bwang!  You're a great coder! :D

150Mh!  Wow! ;D

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Nspire Raycaster
« Reply #83 on: March 30, 2010, 06:27:34 pm »
nice to hear!

First time I hear of "volatile unsigned", though. I heard about short signed/unsigned, long signed/unsigned, etc, but not that
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)

Offline calc84maniac

  • eZ80 Guru
  • Coder Of Tomorrow
  • LV11 Super Veteran (Next: 3000)
  • ***********
  • Posts: 2912
  • Rating: +471/-17
    • View Profile
    • TI-Boy CE
Re: Nspire Raycaster
« Reply #84 on: March 30, 2010, 07:12:44 pm »
nice to hear!

First time I hear of "volatile unsigned", though. I heard about short signed/unsigned, long signed/unsigned, etc, but not that
Yeah, using "volatile" tells the compiler that it's not normal memory and it must always read/write when told to, rather than optimizing like for normal memory access.

Edit: For example, with code
while (*timer) { };
that waits for a timer register to count down to zero, if "timer" is not specified as volatile, it will only be read once and the read value would be checked against z80 over and over. On the other hand, if it is volatile, it will actually read the register every loop.
« Last Edit: March 30, 2010, 07:16:49 pm by calc84maniac »
"Most people ask, 'What does a thing do?' Hackers ask, 'What can I make it do?'" - Pablos Holman

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Nspire Raycaster
« Reply #85 on: March 30, 2010, 07:18:55 pm »
mhmm I am even more confused x.x, I guess it's stuff that is way too low level for me to understand x.x
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)

Offline ztrumpet

  • The Rarely Active One
  • CoT Emeritus
  • LV13 Extreme Addict (Next: 9001)
  • *
  • Posts: 5712
  • Rating: +364/-4
  • If you see this, send me a PM. Just for fun.
    • View Profile
Re: Nspire Raycaster
« Reply #86 on: March 30, 2010, 07:24:14 pm »
Wow, that's way over my head. ;)  I have so much to learn! ;D
I'm glad it works, though! :D

Offline Builderboy

  • Physics Guru
  • CoT Emeritus
  • LV13 Extreme Addict (Next: 9001)
  • *
  • Posts: 5673
  • Rating: +613/-9
  • Would you kindly?
    • View Profile
Re: Nspire Raycaster
« Reply #87 on: March 30, 2010, 08:01:06 pm »
Hmmmm i think i see what is going on, the compiler is very smart, and can see that you are not modifying timer inside the loop, so it assumes that the timer cannot change, and so only checks it once? Crazyness... O.O
« Last Edit: April 02, 2010, 01:36:35 am by Builderboy »

Offline bwang

  • LV7 Elite (Next: 700)
  • *******
  • Posts: 634
  • Rating: +30/-11
    • View Profile
Re: Nspire Raycaster
« Reply #88 on: March 31, 2010, 12:03:59 am »
New demo! This one supports looking up and down (use +/- to do so).

Offline DJ Omnimaga

  • Clacualters are teh gr33t
  • CoT Emeritus
  • LV15 Omnimagician (Next: --)
  • *
  • Posts: 55942
  • Rating: +3154/-232
  • CodeWalrus founder & retired Omnimaga founder
    • View Profile
    • Dream of Omnimaga Music
Re: Nspire Raycaster
« Reply #89 on: March 31, 2010, 12:07:37 am »
wow I wish I could try this but my Nspire has OS 2.0 now. Someone really need to post a batch file to run Goplat's emu easier on Windows, I just can't figure out anything. Else, could someone do a screenshot? (animated, with Calccapture)?
Now active at https://discord.gg/cuZcfcF (CodeWalrus server)