c2f9dfe93575de5c00b956b0054a43b2e9b8f807
[hackover2013-badge-firmware.git] / badge / jumpnrun / level_load.c
1 #include "levels.h"
2 #include "tiles.h"
3 #include "items.h"
4 #include "enemies.h"
5
6 #include <drivers/fatfs/ff.h>
7
8 #include <stdio.h>
9
10 typedef struct {
11 uint8_t x;
12 uint16_t y;
13 uint8_t type;
14 } level_thing;
15
16 static level_thing jumpnrun_level_parse_blob(unsigned char blob[3]) {
17 level_thing result;
18
19 result.y = blob[0] >> 4;
20 result.x = ((blob[0] & 0xf) << 8) | blob[1];
21 result.type = blob[2];
22
23 return result;
24 }
25
26 static void jumpnrun_level_make_tile(jumpnrun_tile *dest, level_thing thing) {
27 dest->type = thing.type;
28 dest->pos.x = thing.x;
29 dest->pos.y = thing.y;
30 }
31
32 static void jumpnrun_level_make_item(jumpnrun_item *dest, level_thing thing) {
33 dest->type = &jumpnrun_item_type_data[thing.type];
34 dest->pos.x = FIXED_POINT(thing.x * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
35 dest->pos.y = FIXED_POINT(thing.y * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
36 }
37
38 static void jumpnrun_level_make_enemy(jumpnrun_enemy *dest, level_thing thing) {
39 dest->type = &jumpnrun_enemy_type_data[thing.type];
40
41 dest->spawn_pos.x = FIXED_POINT(thing.x * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
42 dest->spawn_pos.y = FIXED_POINT(thing.y * JUMPNRUN_TILE_PIXEL_HEIGHT, 0);
43 dest->current_pos = dest->spawn_pos;
44 dest->inertia = dest->type->spawn_inertia;
45 dest->flags = 0;
46 dest->tick_counter = 0;
47 dest->current_frame = 0;
48 }
49
50 int jumpnrun_load_level_header_from_file(jumpnrun_level *dest, FIL *fd) {
51 uint16_t head[3];
52 UINT count;
53
54 if(FR_OK != f_read(fd, head, sizeof(head), &count) || count != sizeof(head)) {
55 return JUMPNRUN_LEVEL_LOAD_ERROR;
56 }
57
58 dest->header. tile_count = head[0];
59 dest->header. item_count = head[1];
60 dest->header.enemy_count = head[2];
61
62 return JUMPNRUN_LEVEL_LOAD_OK;
63 }
64
65 int jumpnrun_load_level_from_file(jumpnrun_level *dest, FIL *fd) {
66 size_t i;
67 unsigned char buf[3];
68 uint16_t spos[2];
69 UINT count;
70
71 if(FR_OK != f_read(fd, spos, sizeof(spos), &count) || count != sizeof(spos)) {
72 return JUMPNRUN_LEVEL_LOAD_ERROR;
73 } else {
74 dest->start_pos.x = FIXED_POINT(spos[0] * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
75 dest->start_pos.y = FIXED_POINT(spos[1] * JUMPNRUN_TILE_PIXEL_HEIGHT, 0);
76 }
77
78 for(i = 0; i < dest->header.tile_count; ++i) {
79 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
80 return JUMPNRUN_LEVEL_LOAD_ERROR;
81 }
82
83 jumpnrun_level_make_tile(&dest->tiles[i], jumpnrun_level_parse_blob(buf));
84 if(i != 0 &&
85 ((dest->tiles[i - 1].pos.x > dest->tiles[i].pos.x) ||
86 (dest->tiles[i - 1].pos.x == dest->tiles[i].pos.x && dest->tiles[i - 1].pos.y >= dest->tiles[i].pos.y))) {
87 return JUMPNRUN_LEVEL_LOAD_ERROR;
88 }
89 }
90
91 for(i = 0; i < dest->header.item_count; ++i) {
92 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
93 return JUMPNRUN_LEVEL_LOAD_ERROR;
94 }
95
96 jumpnrun_level_make_item(&dest->items[i], jumpnrun_level_parse_blob(buf));
97 if(i != 0 &&
98 (fixed_point_gt(dest->items[i - 1].pos.x, dest->items[i].pos.x) ||
99 (fixed_point_eq(dest->items[i - 1].pos.x, dest->items[i].pos.x) && fixed_point_ge(dest->items[i - 1].pos.y, dest->items[i].pos.y)))) {
100 return JUMPNRUN_LEVEL_LOAD_ERROR;
101 }
102 }
103
104 for(i = 0; i < dest->header.enemy_count; ++i) {
105 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
106 return JUMPNRUN_LEVEL_LOAD_ERROR;
107 }
108
109 jumpnrun_level_make_enemy(&dest->enemies[i], jumpnrun_level_parse_blob(buf));
110 if(i != 0 &&
111 (fixed_point_gt(dest->enemies[i - 1].spawn_pos.x, dest->enemies[i].spawn_pos.x) ||
112 (fixed_point_eq(dest->enemies[i - 1].spawn_pos.x, dest->enemies[i].spawn_pos.x) && fixed_point_ge(dest->enemies[i - 1].spawn_pos.y, dest->enemies[i].spawn_pos.y)))) {
113 return JUMPNRUN_LEVEL_LOAD_ERROR;
114 }
115 }
116
117 return JUMPNRUN_LEVEL_LOAD_OK;
118 }
This page took 0.046805 seconds and 3 git commands to generate.