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