CalcCity/src/core.c

312 lines
6.3 KiB
C
Raw Normal View History

2021-10-31 15:12:30 +01:00
#include <gint/keyboard.h>
2021-11-05 16:37:09 +01:00
#include <gint/display.h>
2021-10-31 15:12:30 +01:00
#include <gint/std/string.h>
#include <gint/timer.h>
#include <gint/clock.h>
2021-11-05 16:37:09 +01:00
#include <stdlib.h>
#include <math.h>
2021-10-31 15:12:30 +01:00
#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);
2021-10-31 15:12:30 +01:00
// Initialisation of struct calccity
memset(calccity, 0, sizeof *calccity);
// Treasure
calccity->misc[0] = 5000;
2021-10-31 15:12:30 +01:00
for (int i = 0; i < 4; i++)
{
2021-10-31 15:12:30 +01:00
calccity->taxes[i] = 10;
calccity->funds[i] = 100;
}
2021-10-31 15:12:30 +01:00
calccity->month = 1;
calccity->year = 1900;
calccity->blinker = 0;
calccity->disaster = 1;
calccity->animation = 1;
calccity->time_speed = 5100;
2021-10-31 15:12:30 +01:00
// Initialisation of struct camera
memset(camera, 0, sizeof *camera);
camera->cursor_x = 2;
camera->cursor_y = 2;
2021-11-05 16:37:09 +01:00
camera->cursor_size[0] = 8;
camera->cursor_size[1] = 8;
2021-10-31 15:12:30 +01:00
// 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
2021-10-31 15:12:30 +01:00
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;
}
}
2021-10-31 15:12:30 +01:00
}
}
}
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 ++;
}
}
}
2021-10-31 15:12:30 +01:00
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;
2021-10-31 15:12:30 +01:00
while (!end)
{
// Real-time clock system
while (!tick) sleep();
tick = 0;
2021-10-31 15:12:30 +01:00
if (!build_mode) next_step(calccity);
2021-11-05 16:37:09 +01:00
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);
}
2021-11-05 16:37:09 +01:00
dupdate();
2021-10-31 15:12:30 +01:00
// Get and manage input
key = rtc_key();
end = keyboard_managment(camera, key);
// Menu gestion
switch (key)
{
case KEY_F1: case KEY_F2:
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->cursor_x / (floor(camera->cursor_size[0] / 8) + 1));
unsigned short loc_y = building.size[1] * floor(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;
}
}
2021-10-31 15:12:30 +01:00
}
// Free timer
if (t >= 0) timer_stop(t);
}
int keyboard_managment(struct camera *camera, const int key)
{
2021-11-05 16:37:09 +01:00
int end = 0;
switch (key)
{
case KEY_UP:
if (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->x < 42) camera->x ++;
break;
case KEY_DOWN:
if (camera->cursor_y < 6) camera->cursor_y ++;
else if (camera->y < 46) camera->y ++;
break;
case KEY_LEFT:
if (camera->cursor_x > 0) camera->cursor_x --;
else if (camera->x > 0) camera->x --;
break;
}
2021-11-05 16:37:09 +01:00
return end;
}
bool can_build(struct calccity *calccity, struct camera *camera, struct map *map, struct building *building)
2021-11-05 16:37:09 +01:00
{
unsigned short loc_x = building->size[0] * floor(camera->cursor_x / (floor(camera->cursor_size[0] / 8) + 1));
unsigned short loc_y = building->size[1] * floor(camera->cursor_y / (floor(camera->cursor_size[1] / 8) + 1));
2021-11-05 16:37:09 +01:00
// Not enougth money
if (calccity->misc[0] < building->cost)
2021-11-05 16:37:09 +01:00
{
display_message("VOUS N'AVEZ PAS ASSEZ D'ARGENT POUR CONSTRUIRE.");
return false;
}
2021-11-05 16:37:09 +01:00
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;
}
2021-11-05 16:37:09 +01:00
// 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;
}
2021-11-05 16:37:09 +01:00
}
}
return true;
}
2021-11-05 17:33:19 +01:00
void exit_build_mode(struct camera *camera, int *build_mode)
{
*build_mode = 0;
2021-11-05 17:33:19 +01:00
camera->cursor_size[0] = 8;
camera->cursor_size[1] = 8;
2021-10-31 15:12:30 +01:00
}