Continue the project : taxes & funds, statistics and in-game options

This commit is contained in:
Shadow15510 2021-11-04 18:08:43 +01:00
parent f40c8464ae
commit bad46c8c8e
13 changed files with 512 additions and 36 deletions

View File

@ -13,14 +13,17 @@ set(SOURCES
src/main.c
src/core.c
src/display.c
src/menus.c
)
set(ASSETS)
set(ASSETS_fx
assets-fx/calccity.png
assets-fx/large_tileset.png
assets-fx/large_water.png
assets-fx/title.png
assets-fx/fn_keys.png
)
set(ASSETS_cg)

BIN
assets-fx/calccity.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

BIN
assets-fx/fn_keys.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 771 B

View File

@ -1,3 +1,11 @@
*.png:
type: bopti-image
name_regex: (.*)\.png img_\1
name_regex: (.*)\.png img_\1
calccity.png:
type: font
name: font_calccity
charset: print
grid.size: 5x6
grid.padding: 1
proportional: True

View File

@ -1,2 +1,3 @@
#include "calccity.h"
static const char tiles_names = {};

View File

@ -3,41 +3,42 @@
#include <gint/std/stdlib.h>
struct calccity
{
// human's statistics = {happyness, health, education, housing, work, food}
signed long humans[6];
unsigned long humans[6];
// population evolution = {population, birth_rate, death_rate, immigration, emigration}
signed long population[5];
unsigned long population[5];
// trade statistics = {import, export, production, commercial, industrial, annual_cost}
signed long trade[6];
unsigned long trade[6];
// production = {water, power}
signed long production[2];
unsigned long production[2];
// consumption = {water, power}
signed long consumption[2];
unsigned long consumption[2];
// some others statistics = {treasure, crime, safety, fire_hazard, nuclear_hazard, pollution, transport, grabage, graves}
signed long misc[9];
unsigned long misc[9];
// taxes in percents on {housing, trade, industry, export}
int taxes[4];
unsigned int taxes[4];
// fund in percents on {police, fireman, education, heathcare}
int funds[4];
unsigned int funds[4];
// in-game time
int month, year;
int blinker;
int tick;
// in-game options
uint8_t disaster;
uint8_t animation;
int time_speed;
int menu;
};
@ -57,6 +58,6 @@ struct map
};
#define ENGINE_TICK 1000
#define ENGINE_TICK 100
#endif /* _CALCCITY_H */

View File

@ -17,14 +17,19 @@ int callback_tick(volatile int *tick)
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] = 500000;
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;
@ -32,13 +37,13 @@ void default_values(struct calccity *calccity, struct camera *camera, struct map
calccity->disaster = 1;
calccity->animation = 1;
calccity->time_speed = 30;
calccity->time_speed = 5100;
// Initialisation of struct camera
memset(camera, 0, sizeof *camera);
camera->cursor_x = 64;
camera->cursor_y = 32;
camera->cursor_x = 2;
camera->cursor_y = 2;
// Initialisation of struct map
@ -49,15 +54,55 @@ void default_values(struct calccity *calccity, struct camera *camera, struct map
// Water
if ((x * y == 0) || (x == 49 || y == 49))
map->data[y][x] = 139;
// Shorelines
// 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;
}
}
}
}
@ -76,6 +121,27 @@ int rtc_key(void)
}
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
@ -89,12 +155,92 @@ void main_loop(struct calccity *calccity, struct camera *camera, struct map *map
while (!end)
{
display_map(calccity, camera, map);
// Real-time clock system
while (!tick) sleep();
tick = 0;
next_step(calccity);
// Display map
display_large_map(calccity, camera, map);
display_around(calccity, camera);
// Get and manage input
key = rtc_key();
keyboard_managment(calccity, camera, key);
// Open the menu
switch (calccity->menu)
{
// Tax and funds
case 4:
menu_4(calccity);
break;
case 5:
menu_5(calccity);
break;
// Options
case 6:
end = menu_6(calccity);
break;
}
calccity->menu = 0;
}
// Free timer
if (t >= 0) timer_stop(t);
}
void keyboard_managment(struct calccity *calccity, struct camera *camera, const int key)
{
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;
case KEY_F1:
calccity->menu = 1;
break;
case KEY_F2:
calccity->menu = 2;
break;
case KEY_F3:
calccity->menu = 3;
break;
case KEY_F4:
calccity->menu = 4;
break;
case KEY_F5:
calccity->menu = 5;
break;
case KEY_F6:
calccity->menu = 6;
break;
}
}

View File

@ -3,6 +3,7 @@
#include "calccity.h"
#include "display.h"
#include "menus.h"
// callback_tick : time function
int callback_tick(volatile int *tick);
@ -13,7 +14,13 @@ void default_values(struct calccity *current_game, struct camera *camera, struct
// rtc_key : get a key with RTC system
int rtc_key(void);
// next_step : compute in-game time
void next_step(struct calccity *calccity);
// main_loop : game main loop
void main_loop(struct calccity *calccity, struct camera *camera, struct map *map);
// keyboard_managment : get the key and manage input
void keyboard_managment(struct calccity *calccity, struct camera *camera, const int key);
#endif /* _CORE_H */

View File

@ -15,33 +15,57 @@ void title_screen(void)
}
void display_map(struct calccity *calccity, struct camera *camera, struct map *map)
void display_large_map(struct calccity *calccity, struct camera *camera, struct map *map)
{
extern const bopti_image_t img_large_tileset;
extern const bopti_image_t img_large_water;
if (calccity->animation)
calccity->blinker = (calccity->blinker + 1 ) % 2;
else
calccity->blinker = 0;
dclear(C_WHITE);
for (int y = camera->y; y <= camera->y + 3; y++)
for (int y = 0; y < 4; y++)
{
for (int x = camera->x; x <= camera->x + 7; x ++)
for (int x = 0; x < 8; x ++)
{
int cam_x = x + camera->x, cam_y = y + camera->y;
// Water
if (map->data[y][x] == 139)
dsubimage(x * 15, y * 15, &img_large_water, 15 * calccity->blinker, 0, 15 * (calccity->blinker + 1), 15, DIMAGE_NONE);
if (cam_y > 49 || cam_x > 49 || map->data[cam_y][cam_x] == 139)
dsubimage(3 + x * 15, y * 15, &img_large_water, 15 * calccity->blinker, 0, 15 * (calccity->blinker + 1), 15, DIMAGE_NONE);
else
{
unsigned tile_id = map->data[y][x];
unsigned int tile_x = 16 * (tile_id % 10);
unsigned int tile_y = 16 * (tile_id / 10);
unsigned tile_id = map->data[cam_y][cam_x];
unsigned int tile_x = 15 * (tile_id % 10);
unsigned int tile_y = 15 * (tile_id / 10);
dsubimage(x * 15, y * 15, &img_large_tileset, tile_x, tile_y, 15, 15, DIMAGE_NONE);
dsubimage(3 + x * 15, y * 15, &img_large_tileset, tile_x, tile_y, 15, 15, DIMAGE_NONE);
}
}
}
}
void display_around(struct calccity *calccity, struct camera *camera)
{
extern const bopti_image_t img_fn_keys;
// Functions keys
dimage(3, 57, &img_fn_keys);
// Frame around screen
dline(3, 0, 123, 0, C_BLACK);
dline(3, 56, 123, 56, C_BLACK);
dline(3, 0, 3, 56, C_BLACK);
dline(123, 0, 123, 56, C_BLACK);
// Date in the top-left corner
dprint_opt(4, 1, C_BLACK, C_WHITE, DTEXT_LEFT, DTEXT_TOP, "%d-%d", calccity->month, calccity->year);
// Cursor
drect_border(8 * camera->cursor_x + 3, 8 * camera->cursor_y, 8 * camera->cursor_x + 11, 8 * camera->cursor_y + 8, C_WHITE, 1, C_BLACK);
dline(8 * camera->cursor_x + 6, 8 * camera->cursor_y + 4, 8 * camera->cursor_x + 8, 8 * camera->cursor_y + 4, C_BLACK);
dline(8 * camera->cursor_x + 7, 8 * camera->cursor_y + 3, 8 * camera->cursor_x + 7, 8 * camera->cursor_y + 5, C_BLACK);
dupdate();
}

View File

@ -6,7 +6,10 @@
// title_screen : display title screen
void title_screen(void);
// display_map : display the current state of the map
void display_map(struct calccity *calccity, struct camera *camera, struct map *map);
// display_large_map : display the current state of the large map
void display_large_map(struct calccity *calccity, struct camera *camera, struct map *map);
// display_around : display the screen frame and cursor
void display_around(struct calccity *calccity, struct camera *camera);
#endif /* _DISPLAY_H */

View File

@ -1,8 +1,12 @@
#include <gint/display.h>
#include "core.h"
int main(void)
{
extern font_t font_calccity;
dfont(&font_calccity);
title_screen();
// Game initialisation

263
src/menus.c Normal file
View File

@ -0,0 +1,263 @@
#include <gint/keyboard.h>
#include <gint/display.h>
#include <gint/std/stdlib.h>
#include "menus.h"
void menu_5(struct calccity *calccity)
{
int scroll = 0, key = 0;
int opt = GETKEY_DEFAULT & GETKEY_REP_ARROWS;
int timeout = 0;
static const char *names[23] = {
"GENERAL",
"ARGENT",
"POPULATION",
"BONHEUR",
"SANTE",
"EDUCATION",
"LOGEMENT",
"TRAVAIL",
"NOURRITURE",
"EAU",
"ENERGIE",
"TRANSPORT",
"DECHETS",
"TOMBES",
"RISQUES",
"CRIME",
"RISQUE INCENDIE",
"RISQUE NUCLEAIRE",
"POLLUTION",
"COMMERCE",
"PRODUCTION",
"IMPORT",
"EXPORT"
};
long int values[23] = {
-1,
calccity->misc[0],
calccity->population[0],
calccity->humans[0],
calccity->humans[1],
calccity->humans[2],
calccity->humans[3],
calccity->humans[4],
calccity->humans[5],
calccity->production[0],
calccity->production[1],
calccity->misc[6],
calccity->misc[7],
calccity->misc[8],
-1,
calccity->misc[1],
calccity->misc[3],
calccity->misc[4],
calccity->misc[5],
-1,
calccity->trade[2],
calccity->trade[0],
calccity->trade[1]
};
while (key != KEY_ALPHA)
{
dclear(C_WHITE);
// Title
drect(0, 0, 127, 6, C_BLACK);
dtext(27, 1, C_WHITE, "STATISTIQUES");
// Frame
dhline(0, C_BLACK);
dhline(63, C_BLACK);
dvline(0, C_BLACK);
dvline(127, C_BLACK);
// Scroll bar
dline(5, 6, 5, 63, C_BLACK);
drect(2, scroll + 8, 3, 8 + scroll + 38, C_BLACK);
for (int i = 0; i < 8; i ++)
{
if (values[i + scroll] < 0)
{
drect(5, 7 + i * 7, 127, 13 + i * 7, C_BLACK);
dtext(12, 8 + i * 7, C_WHITE, names[i + scroll]);
}
else
dprint(7, 8 + i * 7, C_BLACK, "%s %lu", names[i + scroll], values[i + scroll]);
}
dupdate();
key = getkey_opt(opt, &timeout).key;
switch (key)
{
case KEY_UP:
if (scroll > 0) scroll --;
break;
case KEY_DOWN:
if (scroll < 15) scroll ++;
break;
}
}
}
void menu_4(struct calccity *calccity)
{
int choice = 0, key = 0;
int opt = GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA & GETKEY_REP_ARROWS;
int timeout = 0;
while (key != KEY_ALPHA)
{
dclear(C_WHITE);
drect(0, 0, 127, 6, C_BLACK);
dtext(24, 1, C_WHITE, "TAXES & FONDS");
dhline(0, C_BLACK);
dhline(63, C_BLACK);
dvline(0, C_BLACK);
dvline(127, C_BLACK);
dtext(7, 8, C_BLACK, "TAXE HABITATION");
dtext(7, 15, C_BLACK, "TAXE COMMERCE");
dtext(7, 22, C_BLACK, "TAXE INDUSTRIE");
dtext(7, 29, C_BLACK, "TAXE EXPORT");
dtext(7, 36, C_BLACK, "FOND POLICE");
dtext(7, 43, C_BLACK, "FOND POMPIER");
dtext(7, 50, C_BLACK, "FOND ECOLE");
dtext(7, 57, C_BLACK, "FOND S.SOCIALE");
for (int i = 0; i < 4; i ++)
{
dprint(97, 8 + i * 7, C_BLACK, "%d%%", calccity->taxes[i]);
dprint(97, 36 + i * 7, C_BLACK, "%d%%", calccity->funds[i]);
}
dtext(2, 8 + choice * 7, C_BLACK, ">");
dtext(121, 8 + choice * 7, C_BLACK, "<");
dupdate();
key = getkey_opt(opt, &timeout).key;
switch (key)
{
case KEY_UP:
if (choice > 0) choice --;
break;
case KEY_DOWN:
if (choice < 7) choice ++;
break;
case KEY_LEFT:
if (choice < 5 && calccity->taxes[choice] > 0) calccity->taxes[choice] --;
if (choice >= 5 && calccity->funds[choice - 5] > 0) calccity->funds[choice - 5] --;
break;
case KEY_RIGHT:
if (choice < 5 && calccity->taxes[choice] < 100) calccity->taxes[choice] ++;
if (choice >= 5 && calccity->funds[choice - 5] < 100) calccity->funds[choice - 5] ++;
break;
}
}
}
int menu_6(struct calccity *calccity)
{
int choice = 0, key = 0;
int opt = GETKEY_DEFAULT & ~GETKEY_MOD_SHIFT & ~GETKEY_MOD_ALPHA & GETKEY_REP_ARROWS;
int timeout = 0;
while (key != KEY_ALPHA)
{
int prcnt = 100 - (calccity->time_speed * 100 / 10000);
dclear(C_WHITE);
drect(0, 0, 127, 6, C_BLACK);
dtext(39, 1, C_WHITE, "OPTIONS");
dhline(0, C_BLACK);
dhline(63, C_BLACK);
dvline(0, C_BLACK);
dvline(127, C_BLACK);
dtext(7, 9, C_BLACK, "ANIMATIONS ");
dtext(7, 16, C_BLACK, "CATASTROPHES");
dtext(7, 23, C_BLACK, "VITESSE DU JEU");
dtext(7, 30, C_BLACK, "QUITTER LE JEU");
dtext(7, 37, C_BLACK, "REPRENDRE");
if (calccity->animation)
dtext(85, 9, C_BLACK, "on");
else
dtext(85, 9, C_BLACK, "off");
if (calccity->disaster)
dtext(85, 16, C_BLACK, "on");
else
dtext(85, 16, C_BLACK, "off");
dprint(97, 23, C_BLACK, "%d%%", prcnt + 1);
dtext(2, 9 + choice * 7, C_BLACK, ">");
dtext(121, 9 + choice * 7, C_BLACK, "<");
dupdate();
key = getkey_opt(opt, &timeout).key;
switch (key)
{
case KEY_UP:
if (choice > 0) choice --;
break;
case KEY_DOWN:
if (choice < 4) choice ++;
break;
case KEY_SHIFT:
switch (choice)
{
case 0:
calccity->animation = (calccity->animation + 1) % 2;
break;
case 1:
calccity->disaster = (calccity->disaster + 1) % 2;
break;
case 3:
return 1;
break;
case 4:
return 0;
}
break;
case KEY_LEFT:
if (choice == 2 && calccity->time_speed < 10000) calccity->time_speed += 100;
break;
case KEY_RIGHT:
if (choice == 2 && calccity->time_speed > 100) calccity->time_speed -= 100;
break;
}
}
return 0;
}

16
src/menus.h Normal file
View File

@ -0,0 +1,16 @@
#ifndef _MENUS_H
#define _MENUS_H
#include "calccity.h"
// menu_4 : tax and funds
void menu_4(struct calccity *calccity);
// menu_5 : informations
void menu_5(struct calccity *calccity);
// menu_6 : options
int menu_6(struct calccity *calccity);
#endif /* _MENUS_H */