SegaRaycast/src/main.c

264 lines
6.1 KiB
C
Raw Normal View History

2024-08-29 17:51:49 -06:00
#include <genesis.h>
2024-08-31 09:00:42 -06:00
#include "sinTable.h"
#include "cosTable.h"
#define TABLE_LENGTH 720
2024-08-30 15:32:58 -06:00
#define SPEED 5
2024-08-31 09:00:42 -06:00
#define FRAC_BITS 8
2024-08-29 18:49:38 -06:00
2024-08-29 18:17:52 -06:00
Line l;
2024-08-30 09:09:31 -06:00
s16 angle = 0;
2024-08-30 15:54:02 -06:00
s16 x, y;
2024-08-29 18:17:52 -06:00
2024-08-31 09:00:42 -06:00
2024-08-29 19:39:58 -06:00
const u8 map[10][10] = {{1,1,1,1,1,1,1,1,1,1},
{1,0,0,0,0,0,0,0,0,1},
{1,1,1,1,0,0,1,1,1,1},
{1,0,0,1,0,0,1,0,0,1},
{1,0,0,0,0,0,1,0,0,1},
{1,0,0,1,0,0,1,1,0,1},
{1,1,1,1,0,0,1,0,0,1},
{1,0,0,0,0,0,0,0,0,1},
{1,0,0,0,0,0,1,0,0,1},
{1,1,1,1,1,1,1,1,1,1}};
2024-08-30 12:12:20 -06:00
int dist(int ax, int ay, int bx, int by){
return (ax-bx)*(ax-bx) + (ay-by)*(ay-by);
}
2024-08-29 21:04:02 -06:00
void castRay(s16 angle){
2024-08-30 15:32:58 -06:00
if(angle >= 360) angle = angle - 360;
if(angle < 0) angle = 360 + angle;
2024-08-30 12:12:20 -06:00
u16 r,mx,my,mp,dof;
2024-08-31 09:00:42 -06:00
s16 rx,ry,ra,xo,yo;
s16 dy = sinTable[angle << 1];
s16 dx = cosTable[angle << 1];
s16 tan = 0;
if(dx != 0) tan = (dy << FRAC_BITS)/dx;
s16 aTan = 0;
if(tan != 0) aTan = -(1 << (FRAC_BITS*2))/tan;
2024-08-30 09:09:31 -06:00
dof = 0;
2024-08-31 09:00:42 -06:00
s16 distH = 500;
s16 hx = l.pt1.x << FRAC_BITS;
s16 hy = l.pt1.y << FRAC_BITS;
2024-08-30 14:04:02 -06:00
if(dy == 0){
2024-08-31 09:00:42 -06:00
rx = l.pt1.x << FRAC_BITS;
ry = l.pt1.y << FRAC_BITS;
2024-08-30 12:12:20 -06:00
dof = 8;
}else {
if(angle > 180) {
2024-08-31 09:00:42 -06:00
ry = ((l.pt1.y / 10 * 10)-1) << FRAC_BITS;
rx = (((l.pt1.y - (ry >> FRAC_BITS))*aTan)) + (l.pt1.x << FRAC_BITS);
yo = -(10 << FRAC_BITS);
xo = ((-yo >> FRAC_BITS)*aTan);
2024-08-30 12:12:20 -06:00
}
if(angle < 180) {
2024-08-31 09:00:42 -06:00
ry = ((l.pt1.y / 10 * 10)+10) << FRAC_BITS;
rx = (((l.pt1.y - (ry >> FRAC_BITS))*aTan)) + (l.pt1.x << FRAC_BITS);
yo = 10 << FRAC_BITS;
xo = (-(yo >> FRAC_BITS)*aTan);
2024-08-30 12:12:20 -06:00
}
2024-08-30 09:09:31 -06:00
}
2024-08-30 12:12:20 -06:00
while(dof<8){
2024-08-31 09:00:42 -06:00
mx = (rx >> FRAC_BITS) / 10;
my = (ry >> FRAC_BITS) / 10;
2024-08-30 14:04:02 -06:00
if(rx < 0 || ry < 0){
dof = 8;
continue;
}
if(mx < 10 && my < 10 && map[my][mx] == 1){
2024-08-30 12:12:20 -06:00
dof = 8;
hx = rx;
hy = ry;
2024-08-31 09:00:42 -06:00
distH = dist(l.pt1.x, l.pt1.y, rx >> FRAC_BITS, ry >> FRAC_BITS);
2024-08-30 12:12:20 -06:00
}else{
rx = rx + xo;
ry = ry + yo;
dof += 1;
}
2024-08-30 09:09:31 -06:00
}
2024-08-30 12:12:20 -06:00
dof = 0;
2024-08-31 09:00:42 -06:00
s16 distV = 500;
s16 vx = l.pt1.x << FRAC_BITS;
s16 vy = l.pt1.y << FRAC_BITS;
s16 nTan = -tan;
//s16 threshold = (51 << FRAC_BITS);
//if(nTan > threshold){
// nTan = threshold;
//}
//if(nTan < -threshold){
// nTan = -threshold;
//}
2024-08-30 12:12:20 -06:00
if(angle > 90 && r < 270) {
2024-08-31 09:00:42 -06:00
rx = ((l.pt1.x / 10 * 10)-1) << FRAC_BITS;
ry = ((l.pt1.x) - (rx >> FRAC_BITS)*nTan) + (l.pt1.y << FRAC_BITS);
xo = -(10 << FRAC_BITS);
yo = ((-xo >> FRAC_BITS)*nTan);
2024-08-30 12:12:20 -06:00
}
if(angle < 90 || angle > 270) {
2024-08-31 09:00:42 -06:00
rx = ((l.pt1.x / 10 * 10)+10) << FRAC_BITS;
ry = ((l.pt1.x) - (rx >> FRAC_BITS)*nTan) + (l.pt1.y << FRAC_BITS);
xo = 10 << FRAC_BITS;
yo = -(xo >> FRAC_BITS)*nTan;
2024-08-30 12:12:20 -06:00
}
2024-08-30 14:04:02 -06:00
if(dx == 0){
2024-08-31 09:00:42 -06:00
rx = l.pt1.x << FRAC_BITS;
ry = l.pt1.y << FRAC_BITS;
xo = 0;
yo = 0;
2024-08-30 09:09:31 -06:00
dof = 8;
}
while(dof<8){
2024-08-31 09:00:42 -06:00
mx = (rx >> FRAC_BITS) / 10;
my = (ry >> FRAC_BITS) / 10;
2024-08-30 21:09:42 -06:00
if(rx < 0 || ry < 0){
dof = 8;
continue;
}
2024-08-30 16:58:36 -06:00
if(mx < 10 && my < 10 && map[my][mx] == 1){
2024-08-30 12:12:20 -06:00
dof = 8;
vx = rx;
vy = ry;
2024-08-31 09:00:42 -06:00
distV = dist(l.pt1.x, l.pt1.y, rx >> FRAC_BITS, ry >> FRAC_BITS);
2024-08-30 12:12:20 -06:00
}else{
rx = rx + xo;
ry = ry + yo;
dof += 1;
}
}
2024-08-31 09:00:42 -06:00
//if(distV < distH){
l.pt2.x = vx >> FRAC_BITS;
l.pt2.y = vy >> FRAC_BITS;
//}else {
//l.pt2.x = hx >> FRAC_BITS;
//l.pt2.y = hy >> FRAC_BITS;
//}
2024-08-30 22:53:22 -06:00
2024-08-29 21:04:02 -06:00
}
2024-08-29 19:39:58 -06:00
void mapscan(){
2024-08-29 21:04:02 -06:00
u8 mapcolor = 12;
2024-08-29 19:39:58 -06:00
mapcolor |= mapcolor << 4;
int mapscale = 10;
for(u8 x = 0; x < 10; x++){
for(u8 y = 0; y < 10; y++){
if(map[y][x] == 1){
Vect2D_s16 mapverts[4] = {{x*mapscale,y*mapscale},{(x+1)*mapscale,y*mapscale},{(x+1)*mapscale,(y+1)*mapscale},{x*mapscale,(y+1)*mapscale}};
BMP_drawPolygon(mapverts, 4, mapcolor);
}
}
}
}
2024-08-29 18:49:38 -06:00
2024-08-29 18:17:52 -06:00
void render(){
2024-08-30 15:54:02 -06:00
l.pt1.x = x / 10;
l.pt1.y = y / 10;
2024-08-29 18:17:52 -06:00
//Clear the bitmap
BMP_clear();
//Draw the line defined above (in the background, hidden)
2024-08-29 19:39:58 -06:00
mapscan();
2024-08-30 14:04:02 -06:00
if(angle >= 360) angle = angle - 360;
if(angle < 0) angle = 360 + angle;
2024-08-30 22:53:22 -06:00
castRay(angle-20);
BMP_drawLine(&l);
castRay(angle-10);
BMP_drawLine(&l);
for (int i = 0; i < 16; i++){
2024-08-30 12:12:20 -06:00
castRay(angle);
2024-08-30 20:33:43 -06:00
//BMP_drawLine(&l);
2024-08-30 22:53:22 -06:00
}
castRay(angle+10);
BMP_drawLine(&l);
castRay(angle+20);
2024-08-30 12:12:20 -06:00
BMP_drawLine(&l);
2024-08-30 14:04:02 -06:00
BMP_showFPS(0);
2024-08-29 19:39:58 -06:00
2024-08-29 18:17:52 -06:00
//Flip the data to the screen - i.e. actually draw the complete image on screen
BMP_flip(1);
//Increment the destination y coordinate
2024-08-30 15:54:02 -06:00
//l.pt2.y = l.pt2.y + 2;
2024-08-29 18:17:52 -06:00
//Reset the destination y coordinate if it hits 160
2024-08-30 15:54:02 -06:00
//if (l.pt2.y == 160)
//{
//l.pt2.y = 0;
//}
2024-08-29 18:17:52 -06:00
2024-08-29 18:49:38 -06:00
SYS_doVBlankProcess();
2024-08-29 18:17:52 -06:00
}
void update(){
2024-08-29 18:49:38 -06:00
u16 joy = JOY_readJoypad(JOY_1);
if(joy & BUTTON_LEFT) {
2024-08-30 12:12:20 -06:00
//l.pt1.x -= SPEED;
2024-08-30 14:04:02 -06:00
angle -= 1;
2024-08-29 18:49:38 -06:00
}
if(joy & BUTTON_RIGHT) {
2024-08-30 12:12:20 -06:00
//l.pt1.x += SPEED;
2024-08-30 14:04:02 -06:00
angle += 1;
2024-08-29 18:49:38 -06:00
}
if(joy & BUTTON_UP) {
2024-08-30 15:32:58 -06:00
s16 ind = (int)((float)angle/360.0f*1024.0f);
fix16 dy = sinFix16(ind);
fix16 dx = cosFix16(ind);
2024-08-30 15:54:02 -06:00
y += fix16ToInt(fix16Mul(dy, FIX16(SPEED)));
x += fix16ToInt(fix16Mul(dx, FIX16(SPEED)));
2024-08-29 18:49:38 -06:00
}
if(joy & BUTTON_DOWN) {
2024-08-30 15:32:58 -06:00
s16 ind = (int)((float)angle/360.0f*1024.0f);
fix16 dy = sinFix16(ind);
fix16 dx = cosFix16(ind);
2024-08-30 15:54:02 -06:00
y -= fix16ToInt(fix16Mul(dy, FIX16(SPEED)));
x -= fix16ToInt(fix16Mul(dx, FIX16(SPEED)));
2024-08-29 18:49:38 -06:00
}
}
2024-08-29 18:17:52 -06:00
2024-08-29 18:49:38 -06:00
void initVDP(){
SYS_disableInts();
VDP_setPlaneSize(64,32,TRUE);
SYS_enableInts();
2024-08-29 18:17:52 -06:00
}
2024-08-29 17:51:49 -06:00
int main()
{
2024-08-30 15:54:02 -06:00
x = 150;
y = 150;
2024-08-29 18:49:38 -06:00
initVDP();
2024-08-29 17:51:49 -06:00
//Initialise the bitmap engine
2024-08-29 18:49:38 -06:00
BMP_init(FALSE, BG_A, PAL0, FALSE);
2024-08-29 17:51:49 -06:00
//Set the colour of the line. We are using pallete 0 for the bitmap, so we have 0->15. 15 is used for white text, so we set an unused pallet colour, 14 to blue - RGB 0000FF.
u16 colour_blue = RGB24_TO_VDPCOLOR(0x0000ff);
2024-08-29 19:39:58 -06:00
u16 colour_red = RGB24_TO_VDPCOLOR(0x756a4a);
2024-08-29 18:08:02 -06:00
PAL_setColor(14, colour_blue);
2024-08-29 18:13:30 -06:00
PAL_setColor(13, colour_red);
2024-08-29 21:04:02 -06:00
PAL_setColor(12, RGB24_TO_VDPCOLOR(0x00ff00));
PAL_setColor(15, RGB24_TO_VDPCOLOR(0xff0000));
2024-08-29 18:13:30 -06:00
VDP_setBackgroundColor(13);
2024-08-29 17:51:49 -06:00
//A line needs a source coordinate x,y and a destination coordinate x,y along with a pallete colour.
2024-08-29 21:04:02 -06:00
l.pt1.x = 15;
l.pt1.y = 15;
2024-08-29 17:51:49 -06:00
l.pt2.x = 255;
l.pt2.y = 0;
2024-08-29 18:08:02 -06:00
l.col = 14;
2024-08-29 17:51:49 -06:00
l.col |= l.col << 4; // if we do not left shift the colour, we get gaps in the line
while(TRUE)
{
2024-08-29 18:17:52 -06:00
render();
2024-08-29 18:49:38 -06:00
update();
2024-08-29 17:51:49 -06:00
}
return 0;
}