omi-eikyo/src/g_stage.c

120 lines
2.6 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 ------------------------------------------------------------|
char const *G_place = u8"地球軌道・朝";
// Static Functions ----------------------------------------------------------|
//
// G_Stage_readSector
//
static void G_Stage_readSector(FILE *fp, G_stage *s, hword *size, mword time)
{
*size -= 4 * 4;
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);
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 * 2;
G_mfent ent;
ent.x = M_IO_ReadLE4k(fp);
ent.y = 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);
fread(name, 1, slen, fp);
hword size = M_IO_ReadLE2u(fp);
if(time == 0 && slen == 0 && size == 0)
break;
if(M_membufcmp(name, "Sector") == 0 && size >= 4 * 4)
G_Stage_readSector(fp, &s, &size, time);
else if(size >= 4 * 2)
G_Stage_readEntity(fp, &s, &size, time, name);
if(size) fseek(fp, size, SEEK_CUR);
}
while(!feof(fp));
done:
free(name);
fclose(fp);
return s;
}
//
// G_Stage_Begin
//
void G_Stage_Begin(unsigned stagenum)
{
printf("Stage: Beginning stage %u.\n", stagenum);
G_stage s = G_Stage_LoadMap("maps/base.gmf0");
for(int i = 0; i < s.mapC; i++)
s.mapV[i].proc(&s.mapV[i].data);
M_Vec_clear(s.map);
printf("Stage: Done loading, splitting blockmap.\n");
DGE_BlockMap_Split(16, 1);
printf("Stage: Done loading stage %u.\n", stagenum);
}
// EOF