#include <client_api.h>
#include "parse.h"
pbm_t* player;
pbm_t* player_out;
typedef struct
{
char* tile;
pbm_t* pbm;
} bg_t;
bg_t bg[100];
int num_bg = 0;
int grid[10][9];
#define OUTLINE 2
bool load_level(fname);
void unload_bg();
int setup(int a)
{
player = f_bitmap("/player.pbm");
player_out = d_expand_bitmap(player, OUTLINE, true, true);
if (!load_level("/level.txt"))
{
return 1;
}
return 0;
}
char* last_level = NULL;
void unload_bg()
{
for (int i = 0; i < num_bg; i++)
{
free(bg[i].pbm);
}
num_bg = 0;
if (last_level)
{
free(last_level);
last_level = NULL;
}
}
bool is_space(char c) { return isspace(c); }
bool is_comma_or_space(char c) { return c == ',' || is_space(c); }
bool load_level(char* fname)
{
unload_bg();
memset(grid, 0, sizeof(grid));
size_t len;
last_level = (char*)f_contents(fname, &len);
if (!last_level)
{
printf("Couldn't find level: %s\n", fname);
return false;
}
reset_parse = true;
char* tile_def[] = { NULL, NULL };
while (true)
{
int res = parse(last_level, len, is_space, false);
//printf("Parse res: %d\n", res);
if (res == DONE)
{
printf("No tile grid given in level %s\n", fname);
return false;
}
if (res == NL)
{
if (tile_def[0] == NULL || tile_def[1] == NULL)
{
printf("Invalid tile def on line %d\n", parse_line - 1);
return false;
}
bool found = false;
char f[100];
sprintf(f, "/%s.pbm", tile_def[1]);
pbm_t* n = f_bitmap(f);
if (n)
{
found = true;
bg_t b = { tile_def[0], n };
bg[num_bg++] = b;
printf("Tile %s registered as word %s\n", f, tile_def[0]);
}
else
{
int i = 1;
sprintf(f, "/%s%d.pbm", tile_def[1], i);
while (n = f_bitmap(f))
{
found = true;
char name[10];
sprintf(name, "%s%d", tile_def[0], i);
bg_t b = { malloc(strlen(name) + 1), n };
strcpy(b.tile, name);
bg[num_bg++] = b;
printf("Tile %s registered as word %s\n", f, name);
i++;
sprintf(f, "/%s%d.pbm", tile_def[1], i);
}
}
if (!found)
{
printf("Not found: graphic with name %s\n", tile_def[1]);
}
tile_def[0] = tile_def[1] = NULL;
continue;
}
if (res == BREAK) break;
if (tile_def[0] == NULL)
{
tile_def[0] = parse_word;
}
else if (tile_def[1] == NULL)
{
tile_def[1] = parse_word;
}
else
{
printf("Too many words on line %d\n", parse_line);
}
}
int x = 0;
int y = 0;
while (true)
{
int res = parse(last_level, len, is_comma_or_space, false);
//printf("Parse res: %d\n", res);
if (res == DONE || res == BREAK)
{
if (y < 9)
{
printf("Didn't read full grid, only %d,%d\n", x, y);
return false;
}
break;
}
if (res == NL)
{
if (x < 10)
{
printf("Couldn't read full row, only to index %d on line %d\n", x - 1, parse_line);
return false;
}
x = 0;
y++;
}
if (res == WORD)
{
if (x >= 10 || y >= 9)
{
printf("Grid is too big, reached %d,%d on line %d\n", x, y, parse_line);
return false;
}
size_t l = strlen(parse_word);
char* prob = NULL;
for (int i = 0; i < l; i++)
{
if (parse_word[i] == '.')
{
parse_word[i] = 0;
prob = parse_word + (i + 1);
break;
}
}
//printf("Searching %s\n", parse_word);
for (int i = 0; i < num_bg; i++)
{
//printf(" Check %s\n", bg[i].tile);
if (strcmp(bg[i].tile, parse_word) == 0)
{
if (prob)
{
int p = max(0, min(9, atoi(prob)));
if (random(1, 10) > p) continue;
}
//printf("Tile %d on %d,%d\n", i, x, y);
grid[x][y] = i + 1;
}
}
x++;
}
}
return 0;
}
float x = 0;
float y = 0;
int rot = 0;
float speed = 80;
bool flipX = false, flipY = false;
void d_pbm_outline(int16_t x, int16_t y, pbm_t* pbm)
{
for (int i = x - 1; i <= x + 1; i++)
{
for (int j = y - 1; j <= y + 1; j++)
{
d_pbm(i, j, pbm, 0, 0, 0, 0, WHITE, TRANSPARENT, R_NONE, false, false);
}
}
}
int loop(int ms)
{
d_clear();
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 9; j++)
{
if (grid[i][j] != 0)
{
d_pbm(4 + i * 16, j * 16, bg[grid[i][j] - 1].pbm, 0,0,0,0, BLACK, TRANSPARENT, R_NONE, false, false);
}
}
}
//d_fillRect(0, 0, SCREEN_W, SCREEN_H, BLACK);
d_pbm((uint16_t)roundf(x) - OUTLINE, (uint16_t)roundf(y) - OUTLINE, player_out, 0, 0, 0, 0, WHITE, TRANSPARENT, rot, flipX, flipY);
d_pbm((uint16_t)roundf(x), (uint16_t)roundf(y), player, 0, 0, 0, 0, BLACK, TRANSPARENT, rot, flipX, flipY);
if (button_pressed(BUTTON_A))
{
rot = (rot + 1) % 4;
}
if (button_pressed(BUTTON_B))
{
flipX = !flipX;
if (!flipX)
{
flipY = !flipY;
}
printf("Flip: %d %d\n", flipX, flipY);
}
float t = ms / 1000.0f;
if (button_down(DPAD_RIGHT)) x += t * speed;
if (button_down(DPAD_LEFT)) x -= t * speed;
if (button_down(DPAD_DOWN)) y += t * speed;
if (button_down(DPAD_UP)) y -= t * speed;
return 0;
}