#include #include #include #include #include #include #include #include "core.h" int callback_tick(volatile int *tick) { *tick = 1; return TIMER_CONTINUE; } void default_values(struct calccity *calccity, struct camera *camera, struct map *map) { srand(20211104); // Initialisation of struct calccity memset(calccity, 0, sizeof *calccity); // Treasure calccity->misc[0] = 5000; for (int i = 0; i < 4; i++) { calccity->taxes[i] = 10; calccity->funds[i] = 100; } calccity->month = 1; calccity->year = 1900; calccity->blinker = 0; calccity->disaster = 1; calccity->animation = 1; calccity->time_speed = 5100; // Initialisation of struct camera memset(camera, 0, sizeof *camera); camera->cursor_x = 2; camera->cursor_y = 2; camera->cursor_size[0] = 8; camera->cursor_size[1] = 8; // Initialisation of struct map for (int y = 0; y < 50; y++) { for (int x = 0; x < 50; x++) { // Water if ((x * y == 0) || (x == 49 || y == 49)) map->data[y][x] = 139; // Ground else map->data[y][x] = 48 + rand() % 2; // Shorelines switch (y) { case 1: switch (x) { case 1: map->data[y][x] = 110; break; case 48: map->data[y][x] = 112; break; default: if (x != 0 && x != 49) map->data[y][x] = 111; break; } break; case 48: switch (x) { case 1: map->data[y][x] = 130; break; case 48: map->data[y][x] = 132; break; default: if (x != 0 && x != 49) map->data[y][x] = 131; break; } break; default: if (y != 0 && y != 49) { if (x == 1) map->data[y][x] = 120; if (x == 48) map->data[y][x] = 122; } } } } } int rtc_key(void) { int opt = GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA & ~GETKEY_REP_ARROWS; int timeout = 1; key_event_t ev = getkey_opt(opt, &timeout); if(ev.type == KEYEV_NONE) return 0; return ev.key; } void next_step(struct calccity *calccity) { calccity->tick += ENGINE_TICK; // In-game animation if (calccity->animation && !(calccity->tick % 1000)) calccity->blinker = (calccity->blinker + 1 ) % 2; // In-game time if (!(calccity->tick % calccity->time_speed)) { calccity->month ++; if (calccity->month > 12) { calccity->month = 1; calccity->year ++; } } } void main_loop(struct calccity *calccity, struct camera *camera, struct map *map) { // Timer initialisation static volatile int tick = 1; int t = timer_configure(TIMER_ANY, ENGINE_TICK*1000, GINT_CALL(callback_tick, &tick)); if (t >= 0) timer_start(t); struct building building = {0}; int end = 0, key = 0, build_mode = 0; while (!end) { // Real-time clock system while (!tick) sleep(); tick = 0; if (!build_mode) next_step(calccity); dclear(C_WHITE); display_main(calccity, camera, map, 1); if (build_mode) { dprint_opt(4, 7, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "$%d", building.cost); dprint_opt(4, 13, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "%s", building.name); } dupdate(); // Get and manage input key = rtc_key(); keyboard_managment(camera, key); // Menu gestion switch (key) { case KEY_F1: case KEY_F2: camera->zoom = 0; exit_build_mode(camera, &build_mode); if (key == KEY_F1) building = menu_12(calccity, camera, map, &build_mode, 1); if (key == KEY_F2) building = menu_12(calccity, camera, map, &build_mode, 2); if (build_mode) { camera->cursor_size[0] = building.size[0] * 15; camera->cursor_size[1] = building.size[1] * 15; } break; case KEY_F4: menu_4(calccity); break; case KEY_F5: menu_5(calccity); break; case KEY_F6: end = menu_6(calccity); break; } if (build_mode) { // Build annulation if (key == KEY_ALPHA) exit_build_mode(camera, &build_mode); // Build validation if (key == KEY_SHIFT && can_build(calccity, camera, map, &building)) { unsigned short loc_x = building.size[0] * floor(camera->x + camera->cursor_x / (floor(camera->cursor_size[0] / 8) + 1)); unsigned short loc_y = building.size[1] * floor(camera->y + camera->cursor_y / (floor(camera->cursor_size[1] / 8) + 1)); int index = 0; for (int y = loc_y; y < loc_y + building.size[1]; y ++) { for (int x = loc_x; x < loc_x + building.size[0]; x ++) { map->data[y][x] = building.id[index]; index ++; } } calccity->misc[0] -= building.cost; } } } // Free timer if (t >= 0) timer_stop(t); } void keyboard_managment(struct camera *camera, const int key) { switch (key) { case KEY_UP: if (!camera->zoom && camera->cursor_y > 0) camera->cursor_y --; else if (camera->y > 0) camera->y --; break; case KEY_RIGHT: if (camera->cursor_x < 14) camera->cursor_x ++; else { if (!camera->zoom && camera->x < 42) camera->x ++; if (camera->zoom && camera->x < 35) camera->x ++; } break; case KEY_DOWN: if (camera->cursor_y < 6) camera->cursor_y ++; else { if (!camera->zoom && camera->y < 46) camera->y ++; if (camera->zoom && camera->y < 43) camera->y ++; } break; case KEY_LEFT: if (!camera->zoom && camera->cursor_x > 0) camera->cursor_x --; else if (camera->x > 0) camera->x --; break; case KEY_PLUS: camera->zoom = 0; break; case KEY_MINUS: if (camera->x > 35) camera->x = 35; if (camera->y > 43) camera->y = 43; camera->zoom = 1; break; } } bool can_build(struct calccity *calccity, struct camera *camera, struct map *map, struct building *building) { unsigned short loc_x = building->size[0] * floor(camera->x + camera->cursor_x / (floor(camera->cursor_size[0] / 8) + 1)); unsigned short loc_y = building->size[1] * floor(camera->y + camera->cursor_y / (floor(camera->cursor_size[1] / 8) + 1)); // Not enougth money if (calccity->misc[0] < building->cost) { display_message("VOUS N'AVEZ PAS ASSEZ D'ARGENT POUR CONSTRUIRE."); return false; } for (int y = loc_y; y < loc_y + building->size[1]; y ++) { for (int x = loc_x; x < loc_x + building->size[0]; x ++) { // Build on water if (map->data[y][x] == 139) { display_message("VOUS NE POUVEZ PAS CONSTRUIRE SUR L'EAU."); return false; } // Build on another building if (map->data[y][x] != 48 && map->data[y][x] != 49 && map->data[y][x] < 110) { display_message("VOUS NE POUVEZ PAS CONSTRUIRE SUR BATIMENT EXISTANT."); return false; } } } return true; } void exit_build_mode(struct camera *camera, int *build_mode) { *build_mode = 0; camera->cursor_size[0] = 8; camera->cursor_size[1] = 8; }