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

Last change on this file since 706 was 683, checked in by guerin, 9 years ago

raycast: initial distributed implementation

The main task runs on processor (0,0,0). It manages game logic and
initialization, and participates in the rendering process.
The render task runs on all other processors. It tries to render a frame
slice when available, which is raycasting + pixel drawing for a pixel
column of the frame.

File size: 4.6 KB
Line 
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}
199
200Game *gameInstance()
201{
202    return &game;
203}
Note: See TracBrowser for help on using the repository browser.