7 #include <drivers/fatfs/ff.h>
18 static level_thing
jumpnrun_level_parse_blob(unsigned char blob
[3]) {
21 result
.y
= blob
[0] >> 4;
22 result
.x
= ((blob
[0] & 0xf) << 8) | blob
[1];
23 result
.type
= blob
[2];
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
;
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);
40 static void jumpnrun_level_make_enemy(jumpnrun_enemy
*dest
, level_thing thing
) {
41 dest
->type
= &jumpnrun_enemy_type_data
[thing
.type
];
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
;
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;
56 int jumpnrun_load_level_header_from_file(jumpnrun_level
*dest
, FILE *fd
) {
58 int jumpnrun_load_level_header_from_file(jumpnrun_level
*dest
, FIL
*fd
) {
64 if(1 != fread(&head
, sizeof(head
), 1, fd
)) {
66 if(FR_OK
!= f_read(fd
, head
, sizeof(head
), &count
) || count
!= sizeof(head
)) {
68 return JUMPNRUN_LEVEL_LOAD_ERROR
;
71 dest
->header
. tile_count
= head
[0];
72 dest
->header
. item_count
= head
[1];
73 dest
->header
.enemy_count
= head
[2];
75 return JUMPNRUN_LEVEL_LOAD_OK
;
79 int jumpnrun_load_level_from_file(jumpnrun_level
*dest
, FILE *fd
) {
81 int jumpnrun_load_level_from_file(jumpnrun_level
*dest
, FIL
*fd
) {
89 if(1 != fread(spos
, sizeof(spos
), 1, fd
)) {
91 if(FR_OK
!= f_read(fd
, spos
, sizeof(spos
), &count
) || count
!= sizeof(spos
)) {
93 return JUMPNRUN_LEVEL_LOAD_ERROR
;
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);
99 for(i
= 0; i
< dest
->header
.tile_count
; ++i
) {
101 if(1 != fread(buf
, 3, 1, fd
)) {
103 if(FR_OK
!= f_read(fd
, buf
, sizeof(buf
), &count
) || count
!= sizeof(buf
)) {
105 return JUMPNRUN_LEVEL_LOAD_ERROR
;
108 jumpnrun_level_make_tile(&dest
->tiles
[i
], jumpnrun_level_parse_blob(buf
));
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
;
116 for(i
= 0; i
< dest
->header
.item_count
; ++i
) {
118 if(1 != fread(buf
, 3, 1, fd
)) {
120 if(FR_OK
!= f_read(fd
, buf
, sizeof(buf
), &count
) || count
!= sizeof(buf
)) {
122 return JUMPNRUN_LEVEL_LOAD_ERROR
;
125 jumpnrun_level_make_item(&dest
->items
[i
], jumpnrun_level_parse_blob(buf
));
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
;
133 for(i
= 0; i
< dest
->header
.enemy_count
; ++i
) {
135 if(1 != fread(buf
, 3, 1, fd
)) {
137 if(FR_OK
!= f_read(fd
, buf
, sizeof(buf
), &count
) || count
!= sizeof(buf
)) {
139 return JUMPNRUN_LEVEL_LOAD_ERROR
;
142 jumpnrun_level_make_enemy(&dest
->enemies
[i
], jumpnrun_level_parse_blob(buf
));
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
;
150 return JUMPNRUN_LEVEL_LOAD_OK
;