source: soft/giet_vm/applications/raycast/game.c @ 677

Last change on this file since 677 was 673, checked in by guerin, 9 years ago

raycast: initial port

Raycast is a small game that looks like Wolfenstein 3D. I created
it for my SESI project, on a Cortex M4 devboard.

Imported from
github.com/libcg/tiva-c/tree/master/boards/dk-tm4c129x/upmc_raycast

File size: 4.6 KB
RevLine 
[673]1#include "game.h"
2#include "disp.h"
3#include "ctrl.h"
4#include <math.h>
5
6// Globals
7
8static Map map[] =
9{
10    { // map0
11        .tile =
12        {
13            {1, 0, 0, 0, 0, 1, 0, 0, 1, 1},
14            {0, 0, 0, 0, 0, 1, 0, 0, 0, 2},
15            {0, 0, 0, 0, 1, 0, 0, 0, 1, 1},
16            {0, 0, 0, 1, 3, 0, 3, 0, 0, 0},
17            {0, 0, 0, 1, 3, 0, 3, 0, 0, 1},
18            {0, 0, 0, 1, 3, 0, 3, 0, 0, 0},
19            {0, 0, 0, 1, 1, 0, 3, 0, 0, 1},
20            {4, 0, 0, 0, 0, 0, 1, 0, 0, 0},
21            {4, 0, 0, 0, 0, 0, 1, 0, 0, 1},
22            {0, 4, 4, 4, 4, 0, 0, 0, 1, 0}
23        },
24        .w = 10,
25        .h = 10,
26        .startX = 2.f,
27        .startY = 3.f,
28        .startDir = 70.f * M_PI / 180.f
29    },
30    { // map1
31        .tile =
32        {
33            {0, 1, 0, 1, 0, 3, 0, 0, 0, 0},
34            {0, 1, 0, 0, 0, 3, 0, 0, 0, 0},
35            {0, 0, 0, 1, 0, 3, 0, 0, 0, 0},
36            {1, 1, 1, 1, 0, 0, 0, 0, 0, 0},
37            {4, 2, 4, 1, 3, 0, 3, 3, 3, 0},
38            {4, 0, 0, 1, 3, 3, 3, 0, 0, 0},
39            {4, 0, 0, 1, 3, 0, 0, 0, 3, 3},
40            {4, 0, 0, 0, 0, 0, 4, 0, 0, 3},
41            {4, 0, 0, 0, 0, 0, 4, 0, 0, 0},
42            {4, 4, 4, 4, 4, 4, 4, 0, 1, 0}
43        },
44        .w = 10,
45        .h = 10,
46        .startX = 0.5f,
47        .startY = 0.5f,
48        .startDir = 90.f * M_PI / 180.f
49    },
50    { // map2
51        .tile =
52        {
53            {4, 4, 4, 4, 4, 4, 4, 0, 0, 0},
54            {0, 0, 0, 0, 0, 0, 0, 0, 3, 0},
55            {3, 0, 0, 0, 4, 4, 4, 0, 0, 0},
56            {3, 0, 0, 4, 0, 0, 0, 1, 1, 0},
57            {3, 0, 4, 2, 0, 0, 0, 0, 0, 0},
58            {3, 0, 4, 2, 0, 0, 0, 0, 0, 0},
59            {3, 0, 0, 4, 0, 0, 0, 1, 1, 0},
60            {3, 0, 0, 0, 4, 4, 4, 0, 0, 0},
61            {0, 0, 0, 0, 0, 0, 0, 0, 3, 0},
62            {4, 4, 4, 4, 4, 4, 4, 0, 0, 0}
63        },
64        .w = 10,
65        .h = 10,
66        .startX = 4.5f,
67        .startY = 5.f,
68        .startDir = 0.f * M_PI / 180.f
69    },
70};
71
72static Game game =
73{
74    .mapId = 0
75};
76
77static bool g_exit;
78
79// Local functions
80
81static void gameOnBlockHit(int type)
82{
83        g_exit = true;
84}
85
86static void gameCollision(float opx, float opy)
87{
88    static bool collided_x = false;
89    static bool collided_y = false;
90
91    float px = game.player.x;
92    float py = game.player.y;
93    int fpx = floor(px);
94    int fpy = floor(py);
95    bool colliding_x = false;
96    bool colliding_y = false;
97    int collide_type_x = 0;
98    int collide_type_y = 0;
99    int type;
100
101    // Check for x axis collisions
102    if      ((type = gameLocate(floor(px + COLLIDE_GAP), fpy))) {
103        colliding_x = true, collide_type_x = type;
104        game.player.x = fpx - COLLIDE_GAP + 1;
105    }
106    else if ((type = gameLocate(floor(px - COLLIDE_GAP), fpy))) {
107        colliding_x = true, collide_type_x = type;
108        game.player.x = fpx + COLLIDE_GAP;
109    }
110
111    // Check for y axis collisions
112    if      ((type = gameLocate(fpx, floor(py + COLLIDE_GAP)))) {
113        colliding_y = true, collide_type_y = type;
114        game.player.y = fpy - COLLIDE_GAP + 1;
115    }
116    else if ((type = gameLocate(fpx, floor(py - COLLIDE_GAP)))) {
117        colliding_y = true, collide_type_y = type;
118        game.player.y = fpy + COLLIDE_GAP;
119    }
120
121    // Check if we're inside a wall
122    if ((type = gameLocate(fpx, fpy))) {
123        colliding_x = true, collide_type_x = type;
124        colliding_y = true, collide_type_y = type;
125        game.player.x = opx, game.player.y = opy;
126    }
127
128    // Take action when the player hits a block
129    if (colliding_x && !collided_x)
130        gameOnBlockHit(collide_type_x);
131    if (colliding_y && !collided_y)
132        gameOnBlockHit(collide_type_y);
133
134    collided_x = colliding_x;
135    collided_y = colliding_y;
136}
137
138static void gameLogic()
139{
140    float opx = game.player.x;
141    float opy = game.player.y;
142
143    ctrlLogic(&game);
144    gameCollision(opx, opy);
145}
146
147static void gameInitMap()
148{
149    game.map = &map[game.mapId];
150    game.player.x = game.map->startX;
151    game.player.y = game.map->startY;
152    game.player.dir = game.map->startDir;
153    game.timeLeft = TIME_TOTAL;
154}
155
156// Exported functions
157
158int gameLocate(int x, int y)
159{
160    if ((x < 0 || x >= game.map->w) ||
161        (y < 0 || y >= game.map->h)) {
162        // Outside the map bounds
163        return 1;
164    }
165
166    return game.map->tile[y][x];
167}
168
169void gameRun()
170{
171    gameInitMap();
172
173    g_exit = false;
174
175    // Game loop
176    while (!g_exit) {
177        gameLogic();
178        dispRender(&game);
179    }
180
181    if (game.timeLeft == 0) {
182        // Time's up!
183        game.mapId = 0;
184    }
185    else {
186        // Go to next map
187        game.mapId++;
188    }
189}
190
191void gameTick()
192{
193    game.timeLeft--;
194
195    if (game.timeLeft == 0) {
196        g_exit = true;
197    }
198}
Note: See TracBrowser for help on using the repository browser.