Skip to content

Instantly share code, notes, and snippets.

Created August 12, 2009 08:46
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save anonymous/166406 to your computer and use it in GitHub Desktop.
Save anonymous/166406 to your computer and use it in GitHub Desktop.
Raycast for msx2
#include <HITECH.H>
#define uint unsigned int
#include "msx2lib.h"
#include "doom.h"
// *INDENT-OFF*
#asm
psect doom,global,size=0x6000
#endasm
// *INDENT-ON*
#pragma psect ltext=doom
struct commands
{
int sx;
int sy;
int dx;
int dy;
int nx;
int ny;
uchar clr;
uchar arg;
uchar cmd;
};
static struct commands cmd;
#asm
_send_vdpcmd:
ex de,hl
ld a,32
di
out (0x99),a
ld a,17+128
out (0x99),a
ei
ld c,0x9B
1: ld a,2 ; wait VDPready
di
out (0x99),a ; select s#2
ld a,15+128
out (0x99),a
in a,(0x99)
rra
ld a,0
out (0x99),a
ld a,15+128
ei
out (0x99),a
jp c,1b
rept 15
dw 0xA3ED ; 15x OUTI (faster than OTIR)
endm
ret
#endasm
static char currentpage = 0;
near void swap_buffer(void)
{
if (currentpage)
{
setpage(1);
currentpage = 0;
}
else
{
setpage(0);
currentpage = 1;
}
}
near void colRender ( uchar x, uchar lineHeight, uchar color )
{
register uchar drawStart = (h - lineHeight) / 2;
cmd.dx = x;
cmd.nx = Xres;
cmd.arg = 0;
cmd.cmd = 0xC0;
*(((uchar*) &cmd.dy) + 1) = currentpage;
if (lineHeight >= h)
{
// plot just one color column
*(((uchar*) &cmd.dy) + 0) = 0;
cmd.ny = h;
cmd.clr = color;
send_vdpcmd(&cmd);
}
else
{
cmd.dy = drawStart + (currentpage<<8);
cmd.ny = 1;
cmd.clr = 0x00;
send_vdpcmd(&cmd);
//cmd.dy = drawStart + lineHeight - 1 + (currentpage<<8);
*(((uchar*) &cmd.dy) + 0) = drawStart + lineHeight - 1 ;
send_vdpcmd(&cmd);
if (drawStart<lineHeight)
{
// plot first floor and celing
// and after walls
cmd.ny = drawStart;
//cmd.dy = 0 + (currentpage<<8);
*(((uchar*) &cmd.dy) + 0) = 0;
cmd.clr = 0xDD;
send_vdpcmd(&cmd);
cmd.ny++;
//cmd.dy = (drawStart+lineHeight) + (currentpage<<8);
*(((uchar*) &cmd.dy) + 0) = (drawStart+lineHeight) ;
cmd.clr = 0xCC;
send_vdpcmd(&cmd);
//cmd.dy = (drawStart+1) + (currentpage<<8);
*(((uchar*) &cmd.dy) + 0) = (drawStart+1) ;
cmd.ny = lineHeight - 2;
cmd.clr = color;
if (cmd.ny) send_vdpcmd(&cmd);
}
else
{
// plot first walls
// and after floor and celing
//cmd.dy = (drawStart+1) + (currentpage<<8);
*(((uchar*) &cmd.dy) + 0) = (drawStart+1) ;
cmd.ny = lineHeight - 2;
cmd.clr = color;
if (cmd.ny) send_vdpcmd(&cmd);
cmd.ny = drawStart;
//cmd.dy = 0 + (currentpage<<8);
*(((uchar*) &cmd.dy) + 0) = 0 ;
cmd.clr = 0xDD;
send_vdpcmd(&cmd);
cmd.ny++;
//cmd.dy = (drawStart+lineHeight) + (currentpage<<8);
*(((uchar*) &cmd.dy) + 0) = (drawStart+lineHeight) ;
cmd.clr = 0xCC;
send_vdpcmd(&cmd);
}
}
}
near void cmd_cls(void)
{
cmd.dx = 0;
cmd.dy = currentpage<<8;
cmd.nx = w;
cmd.ny = h;
cmd.clr = 0;
cmd.arg = 0;
cmd.cmd = 0xC0;
send_vdpcmd(&cmd);
}
ld a,(_mapY)
ld e,a
ld d,0
ld a,(_mapX)
ld l,a
ld h,d
add hl,hl
add hl,hl
add hl,hl
ld b,h
ld c,l
add hl,hl
add hl,bc
add hl,de
ld de,_worldMap
add hl,de
ex de,hl
;while (1)
_while:
;{
;if (sideDistX < sideDistY)
ld hl,(__sideDistX)
ld bc,(__sideDistY)
and a
sbc hl,bc
jp nc,_else
;{
; sideDistX += deltaDistX;
ld hl,(__deltaDistX)
ld bc,(__sideDistX)
add hl,bc
ld (__sideDistX),hl
; mapX += stepX;
ld hl,_stepX
ld a,(_mapX)
add a,(hl)
ld (_mapX),a
bit 7,(hl)
jp z,_incx
_decx:
ld hl,-24
jp 1f
_incx:
ld hl,24
1: add hl,de
ex de,hl
; side = 0;
xor a
;}
jp _L3
;else
_else:
;{
; sideDistY += deltaDistY;
ld hl,(__deltaDistY)
ld bc,(__sideDistY)
add hl,bc
ld (__sideDistY),hl
; mapY += stepY;
ld hl,_stepY
ld a,(_mapY)
add a,(hl)
ld (_mapY),a
bit 7,(hl)
jp z,_incy
_decy:
dec de
jp 1f
_incy:
inc de
1:
; side = 1;
ld a,01h
_L3:
ld (_side),a
;}
;if (worldMap[mapX][mapY] > 0) break;
ld a,(de)
or a
jp z,_while
ld (_color),a
near void colRender ( uchar x, uchar lineHeight, uchar color );
near void swap_buffer(void);
near void send_vdpcmd(struct commands *cmd);
near void cmd_cls(void);
#define abs(a) fabs(a)
#define Xres 4
#define Wscr 212
#define Hscr 192
extern int h;
extern int w;
#define RGB_Red 0x98
#define RGB_Green 0x32
#define RGB_Blue 0x54
#define RGB_White 0xFE
#define RGB_Yellow 0xBA
#define RGB_dark_Red 0x88
#define RGB_dark_Green 0x22
#define RGB_dark_Blue 0x44
#define RGB_Gray 0xEE
#define RGB_dark_Yellow 0xAA
/*
Copyright (c) 2004-2007, Lode Vandevenne
All rights reserved.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <float.h>
#include <math.h>
#include <string.h>
#include <HITECH.H>
#define uint unsigned int
#include "msx2lib.h"
#include "doom.h"
// *INDENT-OFF*
#asm
psect doom,global,size=0x6000
#endasm
// *INDENT-ON*
#pragma psect ltext=doom
////////////////////////////////////////////////////////////////////////////////
//GLOBAL VARIABLES//////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
int w = Wscr;
int h = Hscr;
near void screen(void)
{
int ww,hh;
ww = w;
hh = h;
scr(5);
w = 256;
h = 256*4;
cmd_cls();
#asm
ld a,8 | 2
out (0x99),a
ld a,8 | 010000000B
out (0x99),a
#endasm
w = ww;
h = hh;
};
extern uchar right, left, up, down, key1, key2;
static uchar kbd, kb0;
//static uchar kb2;
static uchar jst;
#define getTicks() (*((unsigned int *) 0xFC9E))
#define mapWidth 24
#define mapHeight 24
uchar *p;
uchar 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}
};
double oldPlaneX;
double oldDirX ;
int lineHeight;
int drawStart;
int drawEnd;
#define frameTime (1.0/20.0)
#define moveSpeed (frameTime * 5.0)
#define rotSpeed (frameTime * 3.0)
double c,s;
uchar color;
uchar mapX,mapY;
//what direction to step in x or y-direction (either +1 or -1)
char stepX;
char stepY;
char side; //was a NS or a EW wall hit?
//length of ray from current position to next x or y-side
double perpWallDist;
uint x;
double rayPosX,rayPosY;
double rayDirX,rayDirY;
static double cameraX;
double temp1,temp2;
// fractional part of rayPos
//double deltaMapX,deltaMapY;
int _sideDistY,_sideDistX;
int _deltaDistX,_deltaDistY;
double posX, posY;
double dirX, dirY;
double planeX, planeY;
int doom_main(int /*argc*/, char */*argv*/[])
{
posX = 22.0;
posY = 11.5; //x and y start position
dirX = -1.0;
dirY = 0.0; //initial direction vector
planeX = 0.0;
planeY = 0.66; //the 2d raycaster version of camera plane
c = cos(rotSpeed);
s = sin(rotSpeed);
screen();
while(1)
{
for(x = 0; x < w; x+=Xres)
{
//calculate ray position and direction
cameraX = (x<<1) / (double) (w) - 1; //x-coordinate in camera space
rayPosX = posX;
rayPosY = posY;
rayDirX = dirX + planeX * cameraX;
rayDirY = dirY + planeY * cameraX;
//length of ray from one x or y-side to next x or y-side
{
temp1 = rayDirY / rayDirX;
temp2 = temp1 * temp1;
_deltaDistX = sqrt(1 + temp2) * 0x100;
_deltaDistY = sqrt(1 + 1/temp2) * 0x100;
}
//which box of the map we're in
mapX = (char) rayPosX;
mapY = (char) rayPosY;
//calculate step and initial sideDist
if (rayDirX < 0)
{
stepX = -1;
_sideDistX = (rayPosX - mapX) * _deltaDistX ;
}
else
{
stepX = 1;
_sideDistX = ((mapX + 1) - rayPosX) * _deltaDistX ;
}
if (rayDirY < 0)
{
stepY = -1;
_sideDistY = (rayPosY - mapY) * _deltaDistY ;
}
else
{
stepY = 1;
_sideDistY = ((mapY + 1) - rayPosY) * _deltaDistY ;
}
//perform DDA
/* while (1)
{
// jump to next map square, OR in x-direction, OR in y-direction
if (sideDistX < sideDistY)
{
sideDistX += deltaDistX;
side = 0;
mapX+=stepX;
}
else
{
sideDistY += deltaDistY;
side = 1;
mapY+=stepY;
}
// Check if ray has hit a wall
if (worldMap[mapX][mapY] > 0)
break;
}
color = worldMap[mapX][mapY];
*/
//perform DDA
#asm
*include ddaloop.asm
#endasm
//Calculate distance projected on camera direction (oblique distance will give fisheye effect!)
if (side == 0)
{
lineHeight = (uint) ( h / abs((mapX - rayPosX + (1 - stepX) / 2) / rayDirX) );
}
else
{
lineHeight = (uint) ( h / abs((mapY - rayPosY + (1 - stepY) / 2) / rayDirY) );
}
//Calculate height of line to draw on screen
// lineHeight = (uint) ( h / perpWallDist );
if (lineHeight >= h) lineHeight = h;
//give x and y sides different brightness
if (side == 0)
{
//choose wall color
switch(color)
{
case 1: color = RGB_Red; break; //red
case 2: color = RGB_Green; break; //green
case 3: color = RGB_Blue; break; //blue
case 4: color = RGB_White; break; //white
default: color = RGB_Yellow; break; //yellow
}
}
else
{
//choose wall color
switch(color)
{
case 1: color = RGB_dark_Red; break; //red
case 2: color = RGB_dark_Green; break; //green
case 3: color = RGB_dark_Blue; break; //blue
case 4: color = RGB_Gray; break; //white
default: color = RGB_dark_Yellow; break; //yellow
}
}
//draw the pixels of the stripe as a vertical line
colRender ( x, lineHeight, color );
}
swap_buffer();
kb0 = checkkbd (0);
kbd = checkkbd (8);
// kb2 = checkkbd (4);
jst = joy ();
//////////////////////////////////////
right = ((!(kbd & 128))|| !(jst & 8));
left = ((!(kbd & 16)) || !(jst & 4));
up = ((!(kbd & 32)) || !(jst & 1));
down = ((!(kbd & 64)) || !(jst & 2));
// key1 = ((!(kbd & 1)) || !(jst & 16));
// key2 = ((!(kb2 & 4)) || !(jst & 32));
//move forward if no wall in front of you
if (up) //up
{
int temp1 = posX + dirX * moveSpeed;
int temp2 = posY + dirY * moveSpeed;
if(worldMap[temp1][(int)(posY)] == 0) posX = temp1;
if(worldMap[(int)(posX)][temp2] == 0) posY = temp2;
}
//move backwards if no wall behind you
if (down) //down
{
int temp1 = posX - dirX * moveSpeed;
int temp2 = posY - dirY * moveSpeed;
if(worldMap[temp1][(int)(posY)] == 0) posX = temp1;
if(worldMap[(int)(posX)][temp2] == 0) posY = temp2;
}
//rotate to the right
if (right)//right
{
//both camera direction and camera plane must be rotated
oldDirX = dirX;
dirX = dirX * c + dirY * s;
dirY = dirY * c - oldDirX * s;
oldPlaneX = planeX;
planeX = planeX * c + planeY * s;
planeY = planeY * c - oldPlaneX * s;
}
//rotate to the left
if (left)//left
{
//both camera direction and camera plane must be rotated
oldDirX = dirX;
dirX = dirX * c - dirY * s;
dirY = oldDirX * s + dirY * c;
oldPlaneX = planeX;
planeX = planeX * c - planeY * s;
planeY = oldPlaneX * s + planeY * c;
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment