xbox-scene.com - your xbox news information source
Quick Links: Main Forums | Xbox360 Forums | Xbox1 Forums | PS3 Forums
Xbox-Scene Forum Help  Search Xbox-Scene Forums   Xbox-Scene Forum Members   Xbox-Scene Calendar

Giganews Usenet Offers: +1150 days binary retention, 99%+ Completion, and Unlimited Speed/Access!

360 ODD Emulators: X360 Key $99 | Wasabi360 FAT $99 | Wasabi360 Slim $99
C4E's iXtreme Burner MAX Drive: LiteOn iHAS124 DROPPED TO JUST $17


Welcome Guest ( Log In | Register )

 Forum Rules Rules
 
Reply to this topicStart new topic
> Wrote This Xbox Raycaster Example Code. (here Is Both Source And Xbe)
miker00lz
post Jan 24 2010, 11:59 AM
Post #1


X-S Enthusiast


Group: Members
Posts: 10
Joined: 23-January 10
Member No.: 431241



if anybody is interested, i programmed this untextured raycaster for the xbox today. i think the source code is pretty easy to follow, so i'm going to paste it here along with a link to the pre-compiled XBE. the source compiles with openxdk 0.7. i'm definitely going to be adding wall/ceiling/floor textures to the engine, but i thought it would be best to post this if somebody just wanted to have a look at the basics first.

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

and here is the source code:

CODE
#include <hal/input.h>
#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. ph34r.gif
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Pulsemasta
post Jan 28 2010, 02:24 PM
Post #2


X-S Expert
***

Group: Members
Posts: 725
Joined: 29-November 08
Member No.: 397380
Xbox Version: v1.1
360 version: unknown



Hey. I couldnt get this running. Is there something special I have to do?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
openxdkman
post Jan 28 2010, 03:11 PM
Post #3


X-S Genius
****

Group: Moderator
Posts: 822
Joined: 2-August 06
Member No.: 292548
Xbox Version: unk
360 version: unknown



playing with pixels only with CPU is the logical path of learning graphics, so keep on the good work.

but once you are done (and disappointed by slow speed of unaccelerated complex graphics)
don't forget to check this :
http://minilgos.perso.sfr.fr/pbkit/changelog.txt

it's harder to learn but executes much faster...
(of course that means giving up the ray tracing concept, but don't forget
that smooth raytracing can only be achieved at the moment with some beast like 3 ps3's connected together... xbox1 is a bit too weak for that...)

This post has been edited by openxdkman: Jan 28 2010, 03:14 PM
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
miker00lz
post Jan 31 2010, 07:47 AM
Post #4


X-S Enthusiast


Group: Members
Posts: 10
Joined: 23-January 10
Member No.: 431241



QUOTE(Pulsemasta @ Jan 28 2010, 07:24 AM) *

Hey. I couldnt get this running. Is there something special I have to do?


hmm. copying the compiled XBE over to your xbox and running it should be all you need to do. there are no external files it needs or anything like that. what happens when you try to run it?

QUOTE(openxdkman @ Jan 28 2010, 08:11 AM) *

playing with pixels only with CPU is the logical path of learning graphics, so keep on the good work.

but once you are done (and disappointed by slow speed of unaccelerated complex graphics)
don't forget to check this :
http://minilgos.perso.sfr.fr/pbkit/changelog.txt

it's harder to learn but executes much faster...
(of course that means giving up the ray tracing concept, but don't forget
that smooth raytracing can only be achieved at the moment with some beast like 3 ps3's connected together... xbox1 is a bit too weak for that...)


yep. i wasn't really planning on going much beyond a textured raycaster. maybe throw in some guns and some enemies to shoot to kill some time. if i can play wolf 3d smoothly on my old 286 i'm sure the xbox could handle this. biggrin.gif
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Pulsemasta
post Jan 31 2010, 11:16 PM
Post #5


X-S Expert
***

Group: Members
Posts: 725
Joined: 29-November 08
Member No.: 397380
Xbox Version: v1.1
360 version: unknown



hey, when I start the text comes up to press start, but when I press start nothing happens.

User is offlineProfile CardPM
Go to the top of the page
+Quote Post
miker00lz
post Feb 1 2010, 12:07 AM
Post #6


X-S Enthusiast


Group: Members
Posts: 10
Joined: 23-January 10
Member No.: 431241



QUOTE(Pulsemasta @ Jan 31 2010, 04:16 PM) *

hey, when I start the text comes up to press start, but when I press start nothing happens.


make sure the controller you're using is plugged into port 1 all the way on the left.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Pulsemasta
post Feb 1 2010, 01:54 AM
Post #7


X-S Expert
***

Group: Members
Posts: 725
Joined: 29-November 08
Member No.: 397380
Xbox Version: v1.1
360 version: unknown



QUOTE(miker00lz @ Feb 1 2010, 12:07 AM) *

make sure the controller you're using is plugged into port 1 all the way on the left.


yeah it is.

could it have something to do with the type of controller? I am using a madcatz controller. not a official MS one.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
obcd
post Feb 1 2010, 12:17 PM
Post #8


X-S Hacker
******

Group: Moderator
Posts: 2737
Joined: 5-April 07
Member No.: 337188
Xbox Version: v1.0
360 version: none



Very likely. For some unknown reason, programs written with the openxdk only like original M$ controllers. Some modchip setup menus suffer from the same issues.

regards.
User is offlineProfile CardPM
Go to the top of the page
+Quote Post
Pulsemasta
post Mar 11 2010, 09:09 AM
Post #9


X-S Expert
***

Group: Members
Posts: 725
Joined: 29-November 08
Member No.: 397380
Xbox Version: v1.1
360 version: unknown



Hey, I was just wondering if you were still adding to this, or working on a new project?
User is offlineProfile CardPM
Go to the top of the page
+Quote Post





Reply to this topicStart new topic

 

Lo-Fi Version Time is now: 22nd May 2013 - 09:27 AM