kitchen: README + MISSIONS/engine-c keep-drop notes
This commit is contained in:
parent
1d351918da
commit
575d7d29b8
130 changed files with 9817 additions and 1 deletions
167
engine-c/src/main.c
Normal file
167
engine-c/src/main.c
Normal file
|
|
@ -0,0 +1,167 @@
|
|||
#include "kknd.h"
|
||||
#include <unistd.h>
|
||||
|
||||
/* =========================================================================
|
||||
* main.c - Entry point, headless sim mode and the real-time game loop.
|
||||
* ========================================================================= */
|
||||
|
||||
static void print_stats(Game *g) {
|
||||
Faction human = g->human, enemy = g->enemy;
|
||||
int hu = 0, eu = 0, hb = 0, eb = 0;
|
||||
for (int i = 0; i < g->unit_count; i++) {
|
||||
if (g->units[i].dead) continue;
|
||||
if (g->units[i].faction == human) hu++;
|
||||
else if (g->units[i].faction == enemy) eu++;
|
||||
}
|
||||
for (int i = 0; i < g->bld_count; i++) {
|
||||
if (g->buildings[i].dead) continue;
|
||||
if (g->buildings[i].faction == human) hb++;
|
||||
else if (g->buildings[i].faction == enemy) eb++;
|
||||
}
|
||||
const char *st = (g->state == GAME_WON) ? "WON" :
|
||||
(g->state == GAME_LOST) ? "LOST" :
|
||||
(g->state == GAME_PAUSED) ? "PAUSED" : "PLAY";
|
||||
printf("[t=%6.1f] state=%-6s %s u=%3d b=%2d scrap=%5d | %s u=%3d b=%2d scrap=%5d | bullets=%d parts=%d obj=%s\n",
|
||||
g->time, st, faction_name(human), hu, hb, g->scrap[human],
|
||||
faction_name(enemy), eu, eb, g->scrap[enemy], g->bullet_count, g->particle_count,
|
||||
g->objective == OBJ_SURVIVE ? "survive" :
|
||||
g->objective == OBJ_GATHER ? "scrap" : "destroy");
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void save_snapshot(Game *g, int n) {
|
||||
char path[64];
|
||||
snprintf(path, sizeof path, "shot_%04d.png", n);
|
||||
void *pixels = malloc((size_t)VIEW_W * VIEW_H * 4);
|
||||
if (!pixels) return;
|
||||
if (SDL_RenderReadPixels(g->ren, NULL, SDL_PIXELFORMAT_RGBA32,
|
||||
pixels, VIEW_W * 4) == 0) {
|
||||
if (png_save(path, VIEW_W, VIEW_H, (const uint8_t *)pixels) == 0)
|
||||
engine_log("snapshot -> %s", path);
|
||||
}
|
||||
free(pixels);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
Game *g = (Game *)malloc(sizeof(Game));
|
||||
if (!g) { fprintf(stderr, "Out of memory\n"); return 1; }
|
||||
|
||||
int headless = 0; float sim_seconds = 0;
|
||||
Difficulty diff = DIFF_NORMAL;
|
||||
int mission = 0;
|
||||
int loaded = 0;
|
||||
float speed = 1.0f;
|
||||
Faction faction_override = FACTION_NONE;
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--speed") == 0 && i + 1 < argc)
|
||||
speed = (float)atof(argv[++i]);
|
||||
}
|
||||
for (int i = 1; i < argc; i++) {
|
||||
if (strcmp(argv[i], "--easy") == 0) diff = DIFF_EASY;
|
||||
else if (strcmp(argv[i], "--hard") == 0) diff = DIFF_HARD;
|
||||
else if (strcmp(argv[i], "--mission") == 0 && i + 1 < argc)
|
||||
mission = atoi(argv[++i]);
|
||||
else if (strcmp(argv[i], "--headless") == 0 && i + 1 < argc)
|
||||
{ headless = 1; sim_seconds = (float)atof(argv[++i]); }
|
||||
else if (strcmp(argv[i], "--auto") == 0)
|
||||
{ g_auto = 1; }
|
||||
else if (strcmp(argv[i], "--faction") == 0 && i + 1 < argc) {
|
||||
i++;
|
||||
if (!strcmp(argv[i], "evolved")) faction_override = FACTION_EVOLVED;
|
||||
else if (!strcmp(argv[i], "series9")) faction_override = FACTION_SERIES9;
|
||||
else faction_override = FACTION_SURVIVOR;
|
||||
}
|
||||
else if (strcmp(argv[i], "--load") == 0 && i + 1 < argc) {
|
||||
g_headless = headless;
|
||||
engine_init(g, KKND_NAME);
|
||||
engine_setup_match(g, mission);
|
||||
load_game(g, argv[++i]);
|
||||
loaded = 1;
|
||||
}
|
||||
}
|
||||
|
||||
g_headless = headless;
|
||||
if (getenv("KKND_SHOT")) g_headless = 1; /* snapshot mode = pure software, no SDL */
|
||||
if (!loaded) engine_init(g, KKND_NAME);
|
||||
if (faction_override != FACTION_NONE) g->human = faction_override;
|
||||
if (getenv("KKND_SPEED")) speed = (float)atof(getenv("KKND_SPEED"));
|
||||
g->speed_mul = speed;
|
||||
/* load campaign progress (highest unlocked mission id + 1) */
|
||||
{
|
||||
FILE *pf = fopen("progress.kknd", "r");
|
||||
if (pf) { int u = 0; if (fscanf(pf, "%d", &u) == 1 && u > 0) g->unlocked = u; fclose(pf); }
|
||||
}
|
||||
int shot_mode = (!headless && getenv("KKND_SHOT")) ? 1 : 0;
|
||||
if (shot_mode) engine_setup_match(g, mission);
|
||||
|
||||
if (headless) {
|
||||
if (!loaded) engine_setup_match(g, mission);
|
||||
engine_log("Headless simulation for %.0f s (mission %d)", sim_seconds, mission);
|
||||
float t = 0, step = 1.0f/30.0f, stat = 0;
|
||||
print_stats(g);
|
||||
while (t < sim_seconds && g->state == GAME_PLAYING) {
|
||||
engine_update(g, step);
|
||||
t += step; stat += step;
|
||||
if (stat >= 1.0f) { print_stats(g); stat -= 1.0f; }
|
||||
}
|
||||
print_stats(g);
|
||||
engine_log("Simulation complete (winner=%s)",
|
||||
g->winner ? faction_name(g->winner) : "none");
|
||||
engine_shutdown(g);
|
||||
free(g);
|
||||
return 0;
|
||||
}
|
||||
|
||||
engine_log("%s %s - choose a mission, SPACE pause, F5 save, RMB command", KKND_NAME, KKND_VERSION);
|
||||
|
||||
/* Snapshot mode: fast-forward the simulation headlessly (no SDL), then
|
||||
* draw the world to an RGBA buffer with the software renderer and save a
|
||||
* PNG. Avoids the broken GPU readback on this box entirely. */
|
||||
if (shot_mode) {
|
||||
float pre = 8.0f;
|
||||
if (getenv("KKND_SHOT_T")) pre = (float)atof(getenv("KKND_SHOT_T"));
|
||||
float hdt = 1.0f / 30.0f;
|
||||
int steps = (int)(pre / hdt);
|
||||
for (int i = 0; i < steps; i++) engine_update(g, hdt);
|
||||
char path[64]; snprintf(path, sizeof path, "shot_%04d.png", 1);
|
||||
snapshot_capture(g, path);
|
||||
engine_log("snapshot -> %s", path);
|
||||
_exit(0);
|
||||
}
|
||||
|
||||
Uint32 last = SDL_GetTicks();
|
||||
int running = 1;
|
||||
while (running) {
|
||||
SDL_Event e;
|
||||
while (SDL_PollEvent(&e)) {
|
||||
if (e.type == SDL_QUIT) { running = 0; break; }
|
||||
input_handle(g, &e);
|
||||
}
|
||||
if (!running) break;
|
||||
Uint32 now = SDL_GetTicks();
|
||||
float dt = (float)(now - last) / 1000.0f;
|
||||
last = now;
|
||||
if (dt > 0.05f) dt = 0.05f;
|
||||
if (g->state != GAME_MENU) {
|
||||
int prev_state = g->state;
|
||||
input_camera(g, dt);
|
||||
engine_update(g, dt);
|
||||
if (g->state == GAME_WON && prev_state != GAME_WON) {
|
||||
int next = g->mission_id + 2; /* unlock the following mission */
|
||||
if (next > g->unlocked) {
|
||||
g->unlocked = next;
|
||||
FILE *pf = fopen("progress.kknd", "w");
|
||||
if (pf) { fprintf(pf, "%d\n", g->unlocked); fclose(pf); }
|
||||
engine_log("Unlocked next mission (%d)", g->unlocked - 1);
|
||||
}
|
||||
g->menu_sel = (g->mission_id + 1 < g->unlocked) ? g->mission_id + 1 : g->mission_id;
|
||||
}
|
||||
}
|
||||
render_frame(g);
|
||||
}
|
||||
|
||||
save_game(g, "savegame.kknd");
|
||||
engine_shutdown(g);
|
||||
free(g);
|
||||
return 0;
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue