Source Code:
#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;
}