cube

Dependencies:   mbed

Fork of manworm_tv_gpu by Jared DiCarlo

Revision:
6:0a34891a82c7
Parent:
5:2859a892497f
Child:
7:25acb844f424
--- a/main.cpp	Mon Nov 20 02:32:57 2017 +0000
+++ b/main.cpp	Mon Nov 20 06:28:29 2017 +0000
@@ -112,6 +112,15 @@
 1,0,0,0,0,1,
 1,0,0,0,0,1,};
 
+uint8_t chr_L[] = {
+1,0,0,0,0,0,
+1,0,0,0,0,0,
+1,0,0,0,0,0,
+1,0,0,0,0,0,
+1,0,0,0,0,0,
+1,0,0,0,0,0,
+1,1,1,1,1,1,};
+
 uint8_t chr_M[] = {
 1,0,0,0,0,1,
 1,1,0,0,1,1,
@@ -175,6 +184,15 @@
 0,1,0,0,1,0,
 0,0,1,1,0,0,};
 
+uint8_t chr_W[] = {
+1,0,0,0,0,1,
+1,0,0,0,0,1,
+1,0,0,0,0,1,
+1,0,1,1,0,1,
+1,0,1,1,0,1,
+1,1,0,0,1,1,
+1,0,0,0,0,1,};
+
 uint8_t sprite_tree[] = {
 0,0,0,1,0,0,0,
 0,0,1,1,1,0,0,
@@ -195,6 +213,34 @@
 0,1,0,0,0,1,0,
 0,1,0,0,0,1,0};
 
+uint8_t sprite_manl[] = {
+0,0,0,1,0,0,0,
+0,0,1,1,1,0,0,
+0,0,0,1,0,0,1,
+0,1,1,1,1,1,0,
+1,0,1,1,1,0,0,
+0,0,1,1,1,0,0,
+0,1,0,0,0,1,0,
+0,1,0,0,0,0,0};
+
+uint8_t sprite_manr[] = {
+0,0,0,1,0,0,0,
+0,0,1,1,1,0,0,
+0,0,0,1,0,0,1,
+0,1,1,1,1,1,0,
+1,0,1,1,1,0,0,
+0,0,1,1,1,0,0,
+0,1,0,0,0,1,0,
+0,0,0,0,0,1,0};
+
+uint8_t *menu[] = {
+chr_P,chr_A,chr_N,chr_G,
+chr_F,chr_A,chr_S,chr_H,
+chr_D,chr_A,chr_M,chr_O,
+chr_D,chr_R,chr_A,chr_V,
+chr_W,chr_A,chr_L,chr_F,
+};
+
 uint16_t l=0; //current line of scan
 
 uint8_t im_line_s[H_RES]; //image sync buffer
@@ -251,14 +297,53 @@
 float uvy[8] = {1,1,1,-1,-1,-1,-1,1};
 int ulive[8] = {1,1,1,1,1,1,1,1};
 
+int fdeath_ticker = FDEATH_RESET;
+float fs = 0;
+
 //tunnel variables
 #define TUN_LEN (SY_MAX - SY_MIN)
 uint8_t tunnel[TUN_LEN];
 float tunnp = 50;
 int tundir = 1;
+int leg_ctr = 0;
 
-int fdeath_ticker = FDEATH_RESET;
-float fs = 0;
+//raycaster variables
+#define mapWidth 24
+#define mapHeight 24
+
+uint8_t 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}
+};
+
+float posX = 12, posY = 12;
+float dirX = -1, dirY = 0;
+float planeX = 0, planeY = 0.66;
+float rc_cos = cosf(0.03f);
+float rc_sin = sinf(0.03f);
 
 DigitalIn p1_in(A1);
 DigitalIn p2_in(A0);
@@ -796,15 +881,126 @@
     if (cmd2) tunnp-=1.0f;
     if (tunnp<SX_MIN+8) tunnp = SX_MIN+8;
     if (tunnp>SX_MAX-8) tunnp = SX_MAX-8;
-    dispsprite((int)(tunnp-SX_MIN), 31, sprite_man);
+    leg_ctr++;
+    if (leg_ctr == 50) leg_ctr = 0;
+    if (leg_ctr < 25) dispsprite((int)(tunnp-SX_MIN), 31, sprite_manl);
+    else dispsprite((int)(tunnp-SX_MIN), 31, sprite_manr);
     
     wait(0.01);
 }
+
+void update_rc() {
+    int cmd1 = p1_in.read();
+    int cmd2 = p2_in.read();
+    if (!cmd1) {
+        float oldDirX = dirX;
+        dirX = dirX * rc_cos - dirY * rc_sin;
+        dirY = oldDirX * rc_sin + dirY * rc_cos;
+        float oldPlaneX = planeX;
+        planeX = planeX * rc_cos - planeY * rc_sin;
+        planeY = oldPlaneX * rc_sin + planeY * rc_cos;
+    }
+    if (!cmd2) {
+        float oldDirX = dirX;
+        dirX = dirX * rc_cos + dirY * rc_sin;
+        dirY = -oldDirX * rc_sin + dirY * rc_cos;
+        float oldPlaneX = planeX;
+        planeX = planeX * rc_cos + planeY * rc_sin;
+        planeY = -oldPlaneX * rc_sin + planeY * rc_cos;
+    }
+    if(worldMap[int(posX + dirX * 0.01f)][int(posY)] == false) posX += dirX * 0.01f;
+    if(worldMap[int(posX)][int(posY + dirY * 0.01f)] == false) posY += dirY * 0.01f;
+    
+    int w = SX_MAX-SX_MIN;
+    int h = SY_MAX-SY_MIN;
+    for (int x = 0; x < SX_MAX - SX_MIN; x++) {
+        float cameraX = 2 * x / float(w) - 1; //x-coordinate in camera space
+        float rayPosX = posX;
+        float rayPosY = posY;
+        float rayDirX = dirX + planeX * cameraX;
+        float rayDirY = dirY + planeY * cameraX;
+        
+        int mapX = int(rayPosX);
+        int mapY = int(rayPosY);
+        
+        float sideDistX, sideDistY;
+        
+        float deltaDistX = sqrtf(1 + (rayDirY * rayDirY) / (rayDirX * rayDirX));
+        float deltaDistY = sqrtf(1 + (rayDirX * rayDirX) / (rayDirY * rayDirY));
+        float perpWallDist;
+        
+        int stepX, stepY;
+        int hit = 0, side;
+        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;
+        }
+        
+         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 = (mapX - rayPosX + (1 - stepX) / 2) / rayDirX;
+        else           perpWallDist = (mapY - rayPosY + (1 - stepY) / 2) / rayDirY;
+        
+        //Calculate height of line to draw on screen
+        int drawStart,drawEnd;
+        int lineHeight = (int)(h / perpWallDist);
+        if (lineHeight > h) {
+            drawStart = 0;
+            drawEnd = h;
+        } else {
+            drawStart = -lineHeight / 2 + h / 2;
+            drawEnd = lineHeight / 2 + h / 2;
+        }
+        if (side == 0) {
+            for(int y = 0; y < drawStart; y++) {
+                im_line_va[H_RES*(y+SY_MIN)+x+SX_MIN] = 0;
+            }
+            for(int y = drawStart;y < drawEnd;y++) {
+                im_line_va[H_RES*(y+SY_MIN)+x+SX_MIN] = 1;
+            }
+            for(int y = drawEnd; y < h; y++) {
+                im_line_va[H_RES*(y+SY_MIN)+x+SX_MIN] = 0;
+            }
+        } else {
+            for(int y = 0; y < h; y++) im_line_va[H_RES*(y+SY_MIN)+x+SX_MIN] = 0;
+            im_line_va[H_RES*(drawStart+SY_MIN)+x+SX_MIN] = 1;
+            im_line_va[H_RES*(drawEnd-1+SY_MIN)+x+SX_MIN] = 1;
+        }
+    }
+}
+
 int main() {
     potato:
     init_buffers();
     t.attach_us(&isr,63);
-
+    
     int bmi = 0;
     
     for(int y = SY_MIN; y < SY_MIN + BY2; y++)
@@ -816,6 +1012,7 @@
         }
     }
     
+    /*
     dispchr(4, BY2+1, chr_P);
     dispchr(11, BY2+1, chr_A);
     dispchr(18, BY2+1, chr_N);
@@ -835,8 +1032,9 @@
     dispchr(11, BY2+25, chr_R);
     dispchr(18, BY2+25, chr_A);
     dispchr(25, BY2+25, chr_V);
-    
+    */
     int cursor_pos = 0;
+    int menu_offs = 0;
     
     for (;;) {
         int cmd1 = p1_in.read();
@@ -852,10 +1050,18 @@
         if (!cmd1 && !cmd2) break;
         
         if (cursor_pos < 0) cursor_pos = 0;
-        if (cursor_pos > 3) cursor_pos = 3;
+        if (cursor_pos > 4) cursor_pos = 4;
+        if (cursor_pos > 3) menu_offs = cursor_pos - 3; else menu_offs = 0;
         
         cursor_x = SX_MIN;
-        cursor_y = SY_MIN + 8*cursor_pos + BY2 + 5;
+        if (cursor_pos < 4) cursor_y = SY_MIN + 8*cursor_pos + BY2 + 5;
+        else cursor_y = SY_MIN + 8*3 + BY2 + 5;
+        
+        for(int y = 0; y < 4; y++) {
+            for(int x = 0; x < 4; x++) {
+                dispchr(4+7*x,BY2+1+8*y,menu[4*(y+menu_offs)+x]);
+            }
+        }
         
         im_line_va[H_RES*cursor_y+cursor_x] = 1;
         
@@ -872,12 +1078,16 @@
         for (;;) fishy();
     } else if (cursor_pos == 2) {
         for (;;) update_image();
-    } else {
+    } else if (cursor_pos == 3) {
         init_tunnel();    
         for (;;) 
         {
             update_tunnel();
         }
+    } else if (cursor_pos == 4) {
+        for (;;) {
+            update_rc();
+        }
     }
     goto potato;
 }