// Copyright © 2017 Project Golan, all rights reserved. // See COPYING for more information. #include "g_stage.h" #include "g_object.h" #include "m_binio.h" #include "m_str.h" #include #include #include #include // 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_mapsector 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_mapobj){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_mapentity 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_mapobj){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