148 lines
3.1 KiB
C
148 lines
3.1 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"地球軌道・朝";
|
|
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_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
|