omi-eikyo/src/g_stage.c

152 lines
3.3 KiB
C

// Copyright © 2017 Project Golan, all rights reserved.
#include "g_stage.h"
#include "g_object.h"
#include "m_binio.h"
#include "m_str.h"
#include <Doominati.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// Extern Objects ------------------------------------------------------------|
__str G_Place = s"place/default";
__str G_PlaceIntro = s"place/default";
unsigned long G_Time;
// Static Functions ----------------------------------------------------------|
//
// G_Stage_readSector
//
static void G_Stage_readSector(FILE *fp, G_stage *s, hword *size, mword time)
{
*size -= 4 * 6;
G_mfsec sec;
sec.x = M_IO_ReadLE4k(fp);
sec.y = M_IO_ReadLE4k(fp);
sec.w = M_IO_ReadLE4k(fp);
sec.h = M_IO_ReadLE4k(fp);
sec.f = M_IO_ReadLE4k(fp);
sec.c = M_IO_ReadLE4k(fp);
M_Vec_grow(s->map, 1);
M_Vec_next(s->map) = (G_mfptr){time, {.sec = sec}, G_Sector_Create};
}
//
// G_Stage_readEntity
//
static void G_Stage_readEntity(FILE *fp, G_stage *s, hword *size, mword time, char *name)
{
*size -= 4 * 3;
G_mfent ent;
ent.x = M_IO_ReadLE4k(fp);
ent.y = M_IO_ReadLE4k(fp);
ent.z = M_IO_ReadLE4k(fp);
M_strbufcpy(ent.name, name);
M_Vec_grow(s->map, 1);
M_Vec_next(s->map) = (G_mfptr){time, {.ent = ent}, G_Entity_Create};
}
// Extern Functions ----------------------------------------------------------|
//
// G_Stage_LoadMap
//
G_stage G_Stage_LoadMap(char const *fname)
{
FILE *fp = fopen(fname, "r");
char *name = NULL;
char magic[8];
G_stage s = {};
if(!fp) {
fprintf(stderr, "Stage: invalid file '%s'\n", fname);
goto done;
}
fread(magic, 1, 8, fp);
if(memcmp(magic, "Gmf0\r\n\xF7\0", 8) != 0) {
fprintf(stderr, "Stage: invalid file header in '%s'\n", fname);
goto done;
}
do {
mword time = M_IO_ReadLE4u(fp);
mbyte slen = fgetc(fp);
name = realloc(name, slen + 1);
fread(name, 1, slen, fp);
hword size = M_IO_ReadLE2u(fp);
if(time == 0 && slen == 0 && size == 0)
break;
name[slen] = '\0';
if(strcmp(name, "Sector") == 0 && size >= 4 * 6)
G_Stage_readSector(fp, &s, &size, time);
else if(size >= 4 * 3)
G_Stage_readEntity(fp, &s, &size, time, name);
if(size) fseek(fp, size, SEEK_CUR);
}
while(!feof(fp));
printf("Stage: Done loading stage '%s'.\n", fname);
done:
free(name);
fclose(fp);
return s;
}
//
// G_Stage_LoadBase
//
void G_Stage_LoadBase(void)
{
printf("Stage: Loading base map.\n");
G_stage s = G_Stage_LoadMap("maps/base.gmf0");
for(size_t i = 0; i < s.mapC && s.mapV[i].time == 0; i++)
s.mapV[i].proc(&s.mapV[i].data);
printf("Stage: Splitting blockmap.\n");
DGE_BlockMap_Split(16, 1);
M_Vec_clear(s.map);
}
//
// G_Stage_Run
//
void G_Stage_Run(unsigned stagenum)
{
printf("Stage: Beginning stage %u.\n", stagenum);
G_Place = M_strmk("place/stage%u", stagenum);
G_PlaceIntro = M_strmk("place/stage%u/intro", stagenum);
G_stage s = G_Stage_LoadMap(M_StrFmt("maps/stage%u.gmf0", stagenum));
size_t i;
for(G_Time = 0;; G_Time++)
{
for(; i < s.mapC && s.mapV[i].time == G_Time; i++)
s.mapV[i].proc(&s.mapV[i].data);
DGE_Task_Sleep(0, 1);
}
M_Vec_clear(s.map);
}
// EOF