8 #include <drivers/fatfs/ff.h>
19 static level_thing
jumpnrun_level_parse_blob(unsigned char blob
[3]) {
22 result
.y
= blob
[0] >> 4;
23 result
.x
= ((blob
[0] & 0xf) << 8) | blob
[1];
24 result
.type
= blob
[2];
29 static void jumpnrun_level_make_tile(jumpnrun_tile
*dest
, level_thing thing
) {
30 memset(dest
, 0, sizeof(*dest
));
32 dest
->type
= thing
.type
;
33 dest
->pos
.x
= thing
.x
;
34 dest
->pos
.y
= thing
.y
;
37 static void jumpnrun_level_make_item(jumpnrun_item
*dest
, level_thing thing
) {
38 memset(dest
, 0, sizeof(*dest
));
40 dest
->type
= &jumpnrun_item_type_data
[thing
.type
];
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
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);
49 static void jumpnrun_level_make_enemy(jumpnrun_enemy
*dest
, level_thing thing
) {
50 memset(dest
, 0, sizeof(*dest
));
52 dest
->type
= &jumpnrun_enemy_type_data
[thing
.type
];
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
;
61 int jumpnrun_load_level_header_from_file(jumpnrun_level
*dest
, FILE *fd
) {
63 int jumpnrun_load_level_header_from_file(jumpnrun_level
*dest
, FIL
*fd
) {
69 if(1 != fread(&head
, sizeof(head
), 1, fd
)) {
71 if(FR_OK
!= f_read(fd
, head
, sizeof(head
), &count
) || count
!= sizeof(head
)) {
73 return JUMPNRUN_LEVEL_LOAD_ERROR
;
76 dest
->header
. tile_count
= head
[0];
77 dest
->header
. item_count
= head
[1];
78 dest
->header
.enemy_count
= head
[2];
80 return JUMPNRUN_LEVEL_LOAD_OK
;
84 int jumpnrun_load_level_from_file(jumpnrun_level
*dest
, FILE *fd
) {
86 int jumpnrun_load_level_from_file(jumpnrun_level
*dest
, FIL
*fd
) {
94 if(1 != fread(spos
, sizeof(spos
), 1, fd
)) {
96 if(FR_OK
!= f_read(fd
, spos
, sizeof(spos
), &count
) || count
!= sizeof(spos
)) {
98 return JUMPNRUN_LEVEL_LOAD_ERROR
;
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
);
104 for(i
= 0; i
< dest
->header
.tile_count
; ++i
) {
106 if(1 != fread(buf
, 3, 1, fd
)) {
108 if(FR_OK
!= f_read(fd
, buf
, sizeof(buf
), &count
) || count
!= sizeof(buf
)) {
110 return JUMPNRUN_LEVEL_LOAD_ERROR
;
113 jumpnrun_level_make_tile(&dest
->tiles
[i
], jumpnrun_level_parse_blob(buf
));
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
;
121 for(i
= 0; i
< dest
->header
.item_count
; ++i
) {
123 if(1 != fread(buf
, 3, 1, fd
)) {
125 if(FR_OK
!= f_read(fd
, buf
, sizeof(buf
), &count
) || count
!= sizeof(buf
)) {
127 return JUMPNRUN_LEVEL_LOAD_ERROR
;
130 jumpnrun_level_make_item(&dest
->items
[i
], jumpnrun_level_parse_blob(buf
));
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
;
138 for(i
= 0; i
< dest
->header
.enemy_count
; ++i
) {
140 if(1 != fread(buf
, 3, 1, fd
)) {
142 if(FR_OK
!= f_read(fd
, buf
, sizeof(buf
), &count
) || count
!= sizeof(buf
)) {
144 return JUMPNRUN_LEVEL_LOAD_ERROR
;
147 jumpnrun_level_make_enemy(&dest
->enemies
[i
], jumpnrun_level_parse_blob(buf
));
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
;
155 return JUMPNRUN_LEVEL_LOAD_OK
;