first, here's the xbe you can just copy to your xbox and run: http://rubbermallet....-untextured.xbe

and here is the source code:

#include <hal/xbox.h>

#include <openxdk/debug.h>

#include "hal/fileio.h"

#include <hal/video.h>

#include "string.h"

#include "stdio.h"

#include <stdlib.h>

#include <math.h>

unsigned char *fb;

unsigned char *pb;

int width = 640;

int height = 480;

int bpp = 32; //should work with either 24 or 32 bit mode

int pixmulty;

int pixmultx;

#define mapWidth 24

#define mapHeight 24

int worldMap[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,2,2,2,2,2,0,0,0,0,3,0,3,0,3,0,0,0,1},

{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},

{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,3,0,0,0,3,0,0,0,1},

{1,0,0,0,0,0,2,0,0,0,2,0,0,0,0,0,0,0,0,0,0,0,0,1},

{1,0,0,0,0,0,2,2,0,2,2,0,0,0,0,3,0,3,0,3,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,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},

{1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},

{1,4,0,0,0,0,5,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},

{1,4,0,4,0,0,0,0,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},

{1,4,0,4,4,4,4,4,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},

{1,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1},

{1,4,4,4,4,4,4,4,4,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}

};

void XPlot(int xp, int yp, BYTE r, BYTE g, BYTE b) {

pb[(yp*pixmulty)+(xp*pixmultx)] = b;

pb[(yp*pixmulty)+(xp*pixmultx)+1] = g;

pb[(yp*pixmulty)+(xp*pixmultx)+2] = r;

}

void XBoxStartup(void) {

int lastTickCount;

int passedMilliseconds;

pixmulty = width * (bpp / 8);

pixmultx = bpp / 8;

XInput_Init();

int padnum = 0;

debugPrint("\n\n XCast: A simple raycaster example for the Microsoft XBOX.\n");

debugPrint(" Written and compiled on 1/24/2010.\n");

debugPrint(" Created by Mike Chambers [miker00lz@gmail.com]\n\n\n\n\n");

debugPrint(" Controls: Just use the d-pad to move around the map.\n");

debugPrint(" To reboot your XBOX, press start + back.\n\n");

debugPrint(" Press start now to begin...");

int breakloop = 0;

while (breakloop==0) {

//twiddle thumbs here...

XInput_GetEvents();

if (g_Pads[padnum].PressedButtons.usDigitalButtons & XPAD_START) breakloop = 1;

}

VIDEO_MODE current;

current = XVideoGetMode();

int i;

int j;

int vstep = 1;

BOOL result;

result = XVideoSetMode(width, height, bpp, 60);

if (result==FALSE) {

debugPrint("There was an error setting the video mode! Reboot in 5 seconds...");

XSleep(5000);

XReboot();

}

fb = XVideoGetFB(); //get pointer to beginning of xbox video memory

pb = malloc(width*height*pixmultx); //allocate a full video buffer so we dont draw directly.

//it will look sexier this way.

int x, y;

double posX = 22, posY = 12; //x and y start position

double dirX = -1, dirY = 0; //initial direction vector

double planeX = 0, planeY = 0.66; //the 2d raycaster version of camera plane

double time = 0; //time of current frame

double oldTime = 0; //time of previous frame

int stopcast = 0;

while(stopcast==0) {

lastTickCount = XGetTickCount();

for(x = 0; x < width; x++)

{

//calculate ray position and direction

double cameraX = 2 * x / (double)width - 1; //x-coordinate in camera space

double rayPosX = posX;

double rayPosY = posY;

double rayDirX = dirX + planeX * cameraX;

double rayDirY = dirY + planeY * cameraX;

//which box of the map we're in

int mapX = (int)rayPosX;

int mapY = (int)rayPosY;

//length of ray from current position to next x or y-side

double sideDistX;

double sideDistY;

//length of ray from one x or y-side to next x or y-side

double deltaDistX = sqrt(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));

double deltaDistY = sqrt(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));

double perpWallDist;

//what direction to step in x or y-direction (either +1 or -1)

int stepX;

int stepY;

int hit = 0; //was there a wall hit?

int side; //was a NS or a EW wall hit?

//calculate step and initial sideDist

if (rayDirX < 0)

{

stepX = -1;

sideDistX = (rayPosX - mapX) * deltaDistX;

}

else

{

stepX = 1;

sideDistX = (mapX + 1.0 - rayPosX) * deltaDistX;

}

if (rayDirY < 0)

{

stepY = -1;

sideDistY = (rayPosY - mapY) * deltaDistY;

}

else

{

stepY = 1;

sideDistY = (mapY + 1.0 - rayPosY) * deltaDistY;

}

//perform DDA

while (hit == 0)

{

//jump to next map square, OR in x-direction, OR in y-direction

if (sideDistX < sideDistY)

{

sideDistX += deltaDistX;

mapX += stepX;

side = 0;

}

else

{

sideDistY += deltaDistY;

mapY += stepY;

side = 1;

}

//Check if ray has hit a wall

if (worldMap[mapX][mapY] > 0) hit = 1;

}

//Calculate distance projected on camera direction (oblique distance will give fisheye effect!)

if (side == 0)

perpWallDist = fabs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX);

else

perpWallDist = fabs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY);

//Calculate height of line to draw on screen

int lineHeight = abs((int)(height / perpWallDist));

//calculate lowest and highest pixel to fill in current stripe

int drawStart = -lineHeight / 2 + height / 2;

if(drawStart < 0)drawStart = 0;

int drawEnd = lineHeight / 2 + height / 2;

if(drawEnd >= height)drawEnd = height - 1;

//choose wall color

BYTE cr;

BYTE cg;

BYTE cb;

switch(worldMap[mapX][mapY])

{

case 1:

cr = 255; //red

cg = 0;

cb = 0;

break;

case 2:

cr = 0; //green

cg = 255;

cb = 0;

break;

case 3:

cr = 0; //blue

cg = 0;

cb = 255;

break;

case 4:

cr = 255; //white

cg = 255;

cb = 255;

break;

default:

cr = 0; //yellow

cg = 255;

cb = 255;

}

//give x and y sides different brightness

if (side == 1) {

cr = (BYTE)(cr / 2);

cg = (BYTE)(cg / 2);

cb = (BYTE)(cb / 2);

}

//draw the pixels of the stripe as a vertical line

int tmpy;

for (tmpy=0; tmpy<drawStart; tmpy++) XPlot(x, tmpy, 100, 100, 255);

for (tmpy=drawStart; tmpy<drawEnd; tmpy++) XPlot(x, tmpy, cr, cg, cb);

for (tmpy=drawEnd; tmpy<height; tmpy++) XPlot(x, tmpy, 0, 100, 0);

}

memcpy(fb, pb, width*height*pixmultx); //do the actual copy of video buffer to screen

// NOW lets do the input functions...

XInput_GetEvents();

passedMilliseconds = XGetTickCount() - lastTickCount;

lastTickCount = XGetTickCount();

if (passedMilliseconds < 10) passedMilliseconds = 10;

//speed modifiers

double moveSpeed = passedMilliseconds * 0.005; //the constant value is in squares/second

double rotSpeed = passedMilliseconds * 0.0015; //the constant value is in radians/second

if(g_Pads[padnum].CurrentButtons.usDigitalButtons & XPAD_DPAD_UP) {

if(worldMap[(int)(posX + dirX * moveSpeed)][(int)(posY)] == false) posX += dirX * moveSpeed;

if(worldMap[(int)(posX)][(int)(posY + dirY * moveSpeed)] == false) posY += dirY * moveSpeed;

}

if(g_Pads[padnum].CurrentButtons.usDigitalButtons & XPAD_DPAD_DOWN) {

if(worldMap[(int)(posX - dirX * moveSpeed)][(int)(posY)] == false) posX -= dirX * moveSpeed;

if(worldMap[(int)(posX)][(int)(posY - dirY * moveSpeed)] == false) posY -= dirY * moveSpeed;

}

if(g_Pads[padnum].CurrentButtons.usDigitalButtons & XPAD_DPAD_LEFT) {

//both camera direction and camera plane must be rotated

double oldDirX = dirX;

dirX = dirX * cos(rotSpeed) - dirY * sin(rotSpeed);

dirY = oldDirX * sin(rotSpeed) + dirY * cos(rotSpeed);

double oldPlaneX = planeX;

planeX = planeX * cos(rotSpeed) - planeY * sin(rotSpeed);

planeY = oldPlaneX * sin(rotSpeed) + planeY * cos(rotSpeed);

}

if(g_Pads[padnum].CurrentButtons.usDigitalButtons & XPAD_DPAD_RIGHT) {

//both camera direction and camera plane must be rotated

double oldDirX = dirX;

dirX = dirX * cos(-rotSpeed) - dirY * sin(-rotSpeed);

dirY = oldDirX * sin(-rotSpeed) + dirY * cos(-rotSpeed);

double oldPlaneX = planeX;

planeX = planeX * cos(-rotSpeed) - planeY * sin(-rotSpeed);

planeY = oldPlaneX * sin(-rotSpeed) + planeY * cos(-rotSpeed);

}

if(g_Pads[padnum].CurrentButtons.usDigitalButtons & XPAD_START && g_Pads[padnum].CurrentButtons.usDigitalButtons & XPAD_BACK)

{

stopcast = 1;

XReboot();

}

}

}

i'd love to get feedback on it, especially regarding optimization. i need to sit down and have a real good look at it all again and see if i can squeeze some extra speed out of it. this runs very fast, but adding textures will for sure have a big impact. i'm still a C newbie really.

i hope this isn't against the rules, but i'm going to post this in "homebrew software" too because it fits in both subforums.