Major refactoring. Hitboxes.
[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 #ifndef __linux__
7 #include <drivers/fatfs/ff.h>
8 #endif
9
10 #include <stdio.h>
11
12 typedef struct {
13 uint8_t x;
14 uint16_t y;
15 uint8_t type;
16 } level_thing;
17
18 static level_thing jumpnrun_level_parse_blob(unsigned char blob[3]) {
19 level_thing result;
20
21 result.y = blob[0] >> 4;
22 result.x = ((blob[0] & 0xf) << 8) | blob[1];
23 result.type = blob[2];
24
25 return result;
26 }
27
28 static void jumpnrun_level_make_tile(jumpnrun_tile *dest, level_thing thing) {
29 dest->type = thing.type;
30 dest->pos.x = thing.x;
31 dest->pos.y = thing.y;
32 }
33
34 static void jumpnrun_level_make_item(jumpnrun_item *dest, level_thing thing) {
35 dest->type = &jumpnrun_item_type_data[thing.type];
36 dest->pos.x = FIXED_POINT(thing.x * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
37 dest->pos.y = FIXED_POINT(thing.y * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
38 }
39
40 static void jumpnrun_level_make_enemy(jumpnrun_enemy *dest, level_thing thing) {
41 dest->type = &jumpnrun_enemy_type_data[thing.type];
42
43 dest->spawn_pos.x = FIXED_POINT(thing.x * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
44 dest->spawn_pos.y = FIXED_POINT(thing.y * JUMPNRUN_TILE_PIXEL_HEIGHT, 0);
45 dest->base.current_box = rectangle_new(dest->spawn_pos, dest->type->extent);
46 dest->base.inertia = dest->type->spawn_inertia;
47 dest->flags = 0;
48 dest->base.tick_minor = 0;
49 dest->base.anim_frame = 0;
50 dest->base.anim_direction = 0;
51 dest->base.touching_ground = 0;
52 dest->base.jumpable_frames = 0;
53 }
54
55 #ifdef __linux__
56 int jumpnrun_load_level_header_from_file(jumpnrun_level *dest, FILE *fd) {
57 #else
58 int jumpnrun_load_level_header_from_file(jumpnrun_level *dest, FIL *fd) {
59 UINT count;
60 #endif
61 uint16_t head[3];
62
63 #ifdef __linux__
64 if(1 != fread(&head, sizeof(head), 1, fd)) {
65 #else
66 if(FR_OK != f_read(fd, head, sizeof(head), &count) || count != sizeof(head)) {
67 #endif
68 return JUMPNRUN_LEVEL_LOAD_ERROR;
69 }
70
71 dest->header. tile_count = head[0];
72 dest->header. item_count = head[1];
73 dest->header.enemy_count = head[2];
74
75 return JUMPNRUN_LEVEL_LOAD_OK;
76 }
77
78 #ifdef __linux__
79 int jumpnrun_load_level_from_file(jumpnrun_level *dest, FILE *fd) {
80 #else
81 int jumpnrun_load_level_from_file(jumpnrun_level *dest, FIL *fd) {
82 UINT count;
83 #endif
84 size_t i;
85 unsigned char buf[3];
86 uint16_t spos[2];
87
88 #ifdef __linux__
89 if(1 != fread(spos, sizeof(spos), 1, fd)) {
90 #else
91 if(FR_OK != f_read(fd, spos, sizeof(spos), &count) || count != sizeof(spos)) {
92 #endif
93 return JUMPNRUN_LEVEL_LOAD_ERROR;
94 } else {
95 dest->start_pos.x = FIXED_POINT(spos[0] * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
96 dest->start_pos.y = FIXED_POINT(spos[1] * JUMPNRUN_TILE_PIXEL_HEIGHT, 0);
97 }
98
99 for(i = 0; i < dest->header.tile_count; ++i) {
100 #ifdef __linux__
101 if(1 != fread(buf, 3, 1, fd)) {
102 #else
103 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
104 #endif
105 return JUMPNRUN_LEVEL_LOAD_ERROR;
106 }
107
108 jumpnrun_level_make_tile(&dest->tiles[i], jumpnrun_level_parse_blob(buf));
109 if(i != 0 &&
110 ((dest->tiles[i - 1].pos.x > dest->tiles[i].pos.x) ||
111 (dest->tiles[i - 1].pos.x == dest->tiles[i].pos.x && dest->tiles[i - 1].pos.y >= dest->tiles[i].pos.y))) {
112 return JUMPNRUN_LEVEL_LOAD_ERROR;
113 }
114 }
115
116 for(i = 0; i < dest->header.item_count; ++i) {
117 #ifdef __linux__
118 if(1 != fread(buf, 3, 1, fd)) {
119 #else
120 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
121 #endif
122 return JUMPNRUN_LEVEL_LOAD_ERROR;
123 }
124
125 jumpnrun_level_make_item(&dest->items[i], jumpnrun_level_parse_blob(buf));
126 if(i != 0 &&
127 (fixed_point_gt(dest->items[i - 1].pos.x, dest->items[i].pos.x) ||
128 (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)))) {
129 return JUMPNRUN_LEVEL_LOAD_ERROR;
130 }
131 }
132
133 for(i = 0; i < dest->header.enemy_count; ++i) {
134 #ifdef __linux__
135 if(1 != fread(buf, 3, 1, fd)) {
136 #else
137 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
138 #endif
139 return JUMPNRUN_LEVEL_LOAD_ERROR;
140 }
141
142 jumpnrun_level_make_enemy(&dest->enemies[i], jumpnrun_level_parse_blob(buf));
143 if(i != 0 &&
144 (fixed_point_gt(dest->enemies[i - 1].spawn_pos.x, dest->enemies[i].spawn_pos.x) ||
145 (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)))) {
146 return JUMPNRUN_LEVEL_LOAD_ERROR;
147 }
148 }
149
150 return JUMPNRUN_LEVEL_LOAD_OK;
151 }
This page took 0.057393 seconds and 5 git commands to generate.