Advertisement
GeeckoDev

upmc raycast

Feb 17th, 2015
216
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 6.03 KB | None | 0 0
  1. #include <stdbool.h>
  2. #include <stdint.h>
  3. #include <math.h>
  4. #include "inc/hw_types.h"
  5. #include "driverlib/rom.h"
  6. #include "driverlib/rom_map.h"
  7. #include "driverlib/sysctl.h"
  8. #include "driverlib/udma.h"
  9. #include "grlib/grlib.h"
  10. #include "grlib/widget.h"
  11. #include "utils/ustdlib.h"
  12. #include "drivers/frame.h"
  13. #include "drivers/kentec320x240x16_ssd2119.h"
  14. #include "drivers/pinout.h"
  15. #include "drivers/sound.h"
  16. #include "drivers/touch.h"
  17.  
  18. #define SCREEN_WIDTH    (320)
  19. #define SCREEN_HEIGHT   (240)
  20. #define PI              (3.14159f)
  21. #define FIELD_OF_VIEW   (50.f * PI / 180.f)
  22.  
  23. typedef struct
  24. {
  25.     bool touch;
  26.     int x;
  27.     int y;
  28. } Touchscreen;
  29.  
  30. typedef struct
  31. {
  32.     float x;
  33.     float y;
  34.     float dir;
  35. } Player;
  36.  
  37. typedef struct
  38. {
  39.     int tile[10][10];
  40.     int w;
  41.     int h;
  42. } Map;
  43.  
  44. typedef struct
  45. {
  46.     Player player;
  47.     Map map;
  48. } Game;
  49.  
  50. static Touchscreen ts =
  51. {
  52.     .touch = false,
  53.     .x = 0,
  54.     .y = 0
  55. };
  56.  
  57. static int
  58. gameLocate(Game *game, int x, int y)
  59. {
  60.     if ((x < 0 || x >= game->map.w) ||
  61.         (y < 0 || y >= game->map.h))
  62.     {
  63.         /* We are outside the bounds of the map. */
  64.         return 1;
  65.     }
  66.  
  67.     return game->map.tile[y][x];
  68. }
  69.  
  70. static float
  71. gameRaycast(Game *game, float angle)
  72. {
  73.     float ox = game->player.x;
  74.     float oy = game->player.y;
  75.  
  76.     if (gameLocate(game, floorf(ox), floorf(oy)))
  77.     {
  78.         return 0.f;
  79.     }
  80.    
  81.     /* Precompute */
  82.     float vsin = sinf(angle);
  83.     float vcos = cosf(angle);
  84.     float vtan = vsin / vcos;
  85.    
  86.     /* Calculate position increments */
  87.     int incix = (vcos < 0.f ? -1 : 1);
  88.     int inciy = (vsin < 0.f ? -1 : 1);
  89.     float incfx = inciy / vtan;
  90.     float incfy = incix * vtan;
  91.    
  92.     /* Calculate the start position */
  93.     int ix = floorf(ox) + (incix > 0);
  94.     int iy = floorf(oy) + (inciy > 0);
  95.     float fx = ox + (iy - oy) * incfx;
  96.     float fy = oy + (ix - ox) * incfy;
  97.    
  98.     /* Find the first colliding tile in each direction */
  99.     while (gameLocate(game, ix - (incix < 0), fy) == 0)
  100.     {
  101.         ix += incix;
  102.         fy += incfy;
  103.     }
  104.     while (gameLocate(game, fx, iy - (inciy < 0)) == 0)
  105.     {
  106.         fx += incfx;
  107.         iy += inciy;
  108.     }
  109.    
  110.     /* Find the shortest ray */
  111.     float dx = (ix - ox) / vcos;
  112.     float dy = (iy - oy) / vsin;
  113.  
  114.     return (dx < dy ? dx : dy);
  115. }
  116.  
  117. static void
  118. gameLogic(Game *game)
  119. {
  120.     if (ts.touch) {
  121.         if (ts.x > 2 * SCREEN_WIDTH / 3) {
  122.             game->player.dir += 0.1f;
  123.         }
  124.         else if (ts.x < 1 * SCREEN_WIDTH / 3) {
  125.             game->player.dir -= 0.1f;
  126.         }
  127.         if (ts.y > 2 * SCREEN_HEIGHT / 3) {
  128.             game->player.x -= 0.07f * cosf(game->player.dir);
  129.             game->player.y -= 0.07f * sinf(game->player.dir);
  130.         }
  131.         else if (ts.y < 1 * SCREEN_HEIGHT / 3) {
  132.             game->player.x += 0.07f * cosf(game->player.dir);
  133.             game->player.y += 0.07f * sinf(game->player.dir);
  134.         }
  135.     }
  136. }
  137.  
  138. static void
  139. gameRender(Game *game)
  140. {
  141.     float angle = game->player.dir - FIELD_OF_VIEW / 2.f;
  142.  
  143.     for (int i = 0; i < SCREEN_WIDTH; i++)
  144.     {
  145.         float dist;
  146.         int height;
  147.  
  148.         dist = gameRaycast(game, angle);
  149.         dist *= cosf(game->player.dir - angle);
  150.         height = SCREEN_HEIGHT / dist;
  151.  
  152.         g_sKentec320x240x16_SSD2119.pfnLineDrawV
  153.         (
  154.             NULL, i,
  155.             0, (SCREEN_HEIGHT - height) / 2,
  156.             0x0000
  157.         );
  158.         g_sKentec320x240x16_SSD2119.pfnLineDrawV
  159.         (
  160.             NULL, i,
  161.             (SCREEN_HEIGHT - height) / 2, (SCREEN_HEIGHT + height) / 2,
  162.             0xFFFF
  163.         );
  164.         g_sKentec320x240x16_SSD2119.pfnLineDrawV
  165.         (
  166.             NULL, i,
  167.             (SCREEN_HEIGHT + height) / 2, SCREEN_HEIGHT,
  168.             0x0000
  169.         );
  170.  
  171.         angle += FIELD_OF_VIEW / SCREEN_WIDTH;
  172.     }
  173. }
  174.  
  175. static int
  176. gameRun(void)
  177. {
  178.     static Game game =
  179.     {
  180.         .player.x = 2.f,
  181.         .player.y = 3.f,
  182.         .player.dir = 50.f * PI / 180.f,
  183.         .map.tile =
  184.         {
  185.             {0, 0, 0, 1, 1, 0, 0, 0, 0, 1},
  186.             {0, 0, 0, 1, 1, 0, 0, 0, 0, 0},
  187.             {0, 0, 0, 1, 1, 0, 0, 0, 0, 1},
  188.             {0, 0, 0, 1, 1, 0, 1, 0, 0, 0},
  189.             {0, 0, 0, 1, 1, 0, 1, 0, 0, 1},
  190.             {0, 0, 0, 1, 1, 0, 1, 0, 0, 0},
  191.             {0, 0, 0, 1, 1, 0, 1, 0, 0, 1},
  192.             {1, 0, 0, 0, 0, 0, 1, 0, 0, 0},
  193.             {1, 0, 0, 0, 0, 0, 1, 0, 0, 1},
  194.             {1, 0, 0, 1, 1, 0, 0, 0, 1, 0}
  195.         },
  196.         .map.w = sizeof(game.map.tile[0]) / sizeof(game.map.tile[0][0]),
  197.         .map.h = sizeof(game.map.tile) / sizeof(game.map.tile[0])
  198.     };
  199.  
  200.     while (1)
  201.     {
  202.         gameLogic(&game);
  203.         gameRender(&game);
  204.     }
  205.  
  206.     return 0;
  207. }
  208.  
  209. static long
  210. touchscreenCallback(unsigned long ulMessage, long lX, long lY)
  211. {
  212.     ts.touch = (ulMessage == WIDGET_MSG_PTR_MOVE || ulMessage == WIDGET_MSG_PTR_DOWN);
  213.     ts.x = lX;
  214.     ts.y = lY;
  215.     return 0;
  216. }
  217.  
  218. int
  219. main(void)
  220. {
  221.     static tDMAControlTable psDMAControlTable[64] __attribute__ ((aligned(1024)));
  222.     tContext sContext;
  223.     uint32_t ui32SysClock;
  224.  
  225.     //
  226.     // Run from the PLL at 120 MHz.
  227.     //
  228.     ui32SysClock = MAP_SysCtlClockFreqSet((SYSCTL_XTAL_25MHZ |
  229.                                            SYSCTL_OSC_MAIN | SYSCTL_USE_PLL |
  230.                                            SYSCTL_CFG_VCO_480), 120000000);
  231.  
  232.     //
  233.     // Configure the device pins.
  234.     //
  235.     PinoutSet();
  236.  
  237.     //
  238.     // Initialize the display driver.
  239.     //
  240.     Kentec320x240x16_SSD2119Init(ui32SysClock);
  241.  
  242.     //
  243.     // Initialize the graphics context.
  244.     //
  245.     GrContextInit(&sContext, &g_sKentec320x240x16_SSD2119);
  246.  
  247.     //
  248.     // Configure and enable uDMA
  249.     //
  250.     ROM_SysCtlPeripheralEnable(SYSCTL_PERIPH_UDMA);
  251.     SysCtlDelay(10);
  252.     ROM_uDMAControlBaseSet(&psDMAControlTable[0]);
  253.     ROM_uDMAEnable();
  254.  
  255.     //
  256.     // Initialize the touch screen driver.
  257.     //
  258.     TouchScreenInit(ui32SysClock);
  259.     TouchScreenCallbackSet(touchscreenCallback);
  260.  
  261.     return gameRun();
  262. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement