Lebensscreen.
[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
42 uint8_t xoff = (JUMPNRUN_TILE_PIXEL_WIDTH - (dest->type->sprite.width % JUMPNRUN_TILE_PIXEL_WIDTH)) / 2;
43 uint8_t yoff = thing.type != JUMPNRUN_ITEM_TYPE_CHECKPOINT ? 1 : 0; // HACK: spezielle Ausnahme
44
45 dest->pos.x = FIXED_POINT( thing.x * JUMPNRUN_TILE_PIXEL_WIDTH + xoff, 0);
46 dest->pos.y = FIXED_POINT((thing.y + 1) * JUMPNRUN_TILE_PIXEL_WIDTH - dest->type->sprite.height - yoff, 0);
47 }
48
49 static void jumpnrun_level_make_enemy(jumpnrun_enemy *dest, level_thing thing) {
50 memset(dest, 0, sizeof(*dest));
51
52 dest->type = &jumpnrun_enemy_type_data[thing.type];
53
54 dest->spawn_pos.x = FIXED_POINT( thing.x * JUMPNRUN_TILE_PIXEL_WIDTH , 0);
55 dest->spawn_pos.y = FIXED_POINT((thing.y + 1) * JUMPNRUN_TILE_PIXEL_HEIGHT - dest->type->animation_frames[0].height, 0);
56 dest->base.current_box = rectangle_new(dest->spawn_pos, dest->type->extent);
57 dest->base.inertia = dest->type->spawn_inertia;
58 }
59
60 #ifdef __linux__
61 int jumpnrun_load_level_header_from_file(jumpnrun_level *dest, FILE *fd) {
62 #else
63 int jumpnrun_load_level_header_from_file(jumpnrun_level *dest, FIL *fd) {
64 UINT count;
65 #endif
66 uint16_t head[3];
67
68 #ifdef __linux__
69 if(1 != fread(&head, sizeof(head), 1, fd)) {
70 #else
71 if(FR_OK != f_read(fd, head, sizeof(head), &count) || count != sizeof(head)) {
72 #endif
73 return JUMPNRUN_LEVEL_LOAD_ERROR;
74 }
75
76 dest->header. tile_count = head[0];
77 dest->header. item_count = head[1];
78 dest->header.enemy_count = head[2];
79
80 return JUMPNRUN_LEVEL_LOAD_OK;
81 }
82
83 #ifdef __linux__
84 int jumpnrun_load_level_from_file(jumpnrun_level *dest, FILE *fd) {
85 #else
86 int jumpnrun_load_level_from_file(jumpnrun_level *dest, FIL *fd) {
87 UINT count;
88 #endif
89 size_t i;
90 unsigned char buf[3];
91 uint16_t spos[2];
92
93 #ifdef __linux__
94 if(1 != fread(spos, sizeof(spos), 1, fd)) {
95 #else
96 if(FR_OK != f_read(fd, spos, sizeof(spos), &count) || count != sizeof(spos)) {
97 #endif
98 return JUMPNRUN_LEVEL_LOAD_ERROR;
99 } else {
100 dest->start_pos.x = fixed_point_sub(FIXED_INT((spos[0] + 1) * JUMPNRUN_TILE_PIXEL_WIDTH ), hacker_extents().x);
101 dest->start_pos.y = FIXED_INT( spos[1] * JUMPNRUN_TILE_PIXEL_HEIGHT);
102 }
103
104 for(i = 0; i < dest->header.tile_count; ++i) {
105 #ifdef __linux__
106 if(1 != fread(buf, 3, 1, fd)) {
107 #else
108 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
109 #endif
110 return JUMPNRUN_LEVEL_LOAD_ERROR;
111 }
112
113 jumpnrun_level_make_tile(&dest->tiles[i], jumpnrun_level_parse_blob(buf));
114 if(i != 0 &&
115 ((dest->tiles[i - 1].pos.x > dest->tiles[i].pos.x) ||
116 (dest->tiles[i - 1].pos.x == dest->tiles[i].pos.x && dest->tiles[i - 1].pos.y >= dest->tiles[i].pos.y))) {
117 return JUMPNRUN_LEVEL_LOAD_ERROR;
118 }
119 }
120
121 for(i = 0; i < dest->header.item_count; ++i) {
122 #ifdef __linux__
123 if(1 != fread(buf, 3, 1, fd)) {
124 #else
125 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
126 #endif
127 return JUMPNRUN_LEVEL_LOAD_ERROR;
128 }
129
130 jumpnrun_level_make_item(&dest->items[i], jumpnrun_level_parse_blob(buf));
131 if(i != 0 &&
132 (fixed_point_gt(dest->items[i - 1].pos.x, dest->items[i].pos.x) ||
133 (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)))) {
134 return JUMPNRUN_LEVEL_LOAD_ERROR;
135 }
136 }
137
138 for(i = 0; i < dest->header.enemy_count; ++i) {
139 #ifdef __linux__
140 if(1 != fread(buf, 3, 1, fd)) {
141 #else
142 if(FR_OK != f_read(fd, buf, sizeof(buf), &count) || count != sizeof(buf)) {
143 #endif
144 return JUMPNRUN_LEVEL_LOAD_ERROR;
145 }
146
147 jumpnrun_level_make_enemy(&dest->enemies[i], jumpnrun_level_parse_blob(buf));
148 if(i != 0 &&
149 (fixed_point_gt(dest->enemies[i - 1].spawn_pos.x, dest->enemies[i].spawn_pos.x) ||
150 (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)))) {
151 return JUMPNRUN_LEVEL_LOAD_ERROR;
152 }
153 }
154
155 return JUMPNRUN_LEVEL_LOAD_OK;
156 }
This page took 0.055586 seconds and 5 git commands to generate.