6 #include <drivers/fatfs/ff.h>
16 static level_thing
jumpnrun_level_parse_blob(unsigned char blob
[3]) {
19 result
.y
= blob
[0] >> 4;
20 result
.x
= ((blob
[0] & 0xf) << 8) | blob
[1];
21 result
.type
= blob
[2];
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
;
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);
38 static void jumpnrun_level_make_enemy(jumpnrun_enemy
*dest
, level_thing thing
) {
39 dest
->type
= &jumpnrun_enemy_type_data
[thing
.type
];
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
;
46 dest
->tick_counter
= 0;
47 dest
->current_frame
= 0;
50 int jumpnrun_load_level_header_from_file(jumpnrun_level
*dest
, FIL
*fd
) {
54 if(FR_OK
!= f_read(fd
, head
, sizeof(head
), &count
) || count
!= sizeof(head
)) {
55 return JUMPNRUN_LEVEL_LOAD_ERROR
;
58 dest
->header
. tile_count
= head
[0];
59 dest
->header
. item_count
= head
[1];
60 dest
->header
.enemy_count
= head
[2];
62 return JUMPNRUN_LEVEL_LOAD_OK
;
65 int jumpnrun_load_level_from_file(jumpnrun_level
*dest
, FIL
*fd
) {
71 if(FR_OK
!= f_read(fd
, spos
, sizeof(spos
), &count
) || count
!= sizeof(spos
)) {
72 return JUMPNRUN_LEVEL_LOAD_ERROR
;
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);
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
;
83 jumpnrun_level_make_tile(&dest
->tiles
[i
], jumpnrun_level_parse_blob(buf
));
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
;
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
;
96 jumpnrun_level_make_item(&dest
->items
[i
], jumpnrun_level_parse_blob(buf
));
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
;
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
;
109 jumpnrun_level_make_enemy(&dest
->enemies
[i
], jumpnrun_level_parse_blob(buf
));
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
;
117 return JUMPNRUN_LEVEL_LOAD_OK
;