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