diff --git a/.gitignore b/.gitignore index 570339d..014f956 100644 --- a/.gitignore +++ b/.gitignore @@ -5,6 +5,7 @@ src_crap data/codedefs data/fonts data/maps +data/music data/sounds data/sprites data/textures diff --git a/Makefile b/Makefile index dc19cae..6ce0cca 100644 --- a/Makefile +++ b/Makefile @@ -51,10 +51,11 @@ LIBC_OUTPUTS=$(IR)/libc.ir $(IR)/libGDCC.ir LIBC_BINARYS=$(CODEDEFS)/stdlib.bin .PHONY: clean +.SECONDARY: $(MISC_LIBOUTS) all: $(FOLDERS) $(LIBC_BINARYS) $(GAME_BINARYS) $(MAIN_BINARYS) $(MISC_BINARYS) $(RNDR_BINARYS) $(MAPS_OUTPUTS) -$(GOL5_BINARYS): $(GOL5_OUTPUTS) $(MISC_LIBOUTS) +$(GOL5_BINARYS): $(GOL5_OUTPUTS) $(GAME_BINARYS): $(GAME_OUTPUTS) $(MAIN_BINARYS): $(MAIN_OUTPUTS) $(MISC_BINARYS): $(MISC_OUTPUTS) @@ -70,10 +71,10 @@ clean: $(MAPBIN)/%.gmf0: $(MAPSRC)/%.gmf9 $(GOL5_BINARYS) $(GOL5_BINARYS) $< $@ -$(BIN)/%: +$(BIN)/%: $(MISC_LIBOUTS) $(CC) $(LFLAGS) -o $@ $^ -$(BIN)/%.o: $(SRC)/%.c +$(BIN)/%.o: $(SRC)/%.c $(MISC_HEADERS) $(CC) $(CFLAGS) -o $@ $< $(CODEDEFS)/%.bin: diff --git a/data/resdecl.rd b/data/resdecl.rd index 77d4eda..b39e8f8 100644 --- a/data/resdecl.rd +++ b/data/resdecl.rd @@ -3,6 +3,8 @@ font "base" = "fonts/base.ttf", 24pt texture "gui/border" = "textures/Border.png" texture "ent/player" = "sprites/Particle3.png" +texture "box" = "textures/Box.png" +texture "empty" = "textures/Empty.png" shader "plasma" = "shaders/plasma.fp", "shaders/base.vp" diff --git a/maps/base.gmf9 b/maps/base.gmf9 index fa87abb..3c671a5 100644 --- a/maps/base.gmf9 +++ b/maps/base.gmf9 @@ -1,8 +1,9 @@ // Copyright © 2017 Project Golan, all rights reserved. -{0 Sector -250 -200 200 200} -{0 Sector -260 -210 10 220} -{0 Sector -50 -210 10 220} -{0 Sector -250 -210 200 10} -{0 Sector -250 -10 200 10} +{0 Player -200 250} +{0 Sector -450 -330 510 660} // center +{0 Sector -450 -355 510 25} // top +{0 Sector -450 330 510 25} // bottom +{0 Sector -475 -355 25 710} // left +{0 Sector 60 -355 25 710} // right // EOF diff --git a/src/g_objdef.c b/src/g_objdef.c index a4ce3f6..8cc6f07 100644 --- a/src/g_objdef.c +++ b/src/g_objdef.c @@ -1,5 +1,6 @@ // Copyright © 2017 Project Golan, all rights reserved. #include "g_object.h" + #include "m_tokbuf.h" #include "m_str.h" #include "m_darray.h" diff --git a/src/g_object.c b/src/g_object.c new file mode 100644 index 0000000..c06b675 --- /dev/null +++ b/src/g_object.c @@ -0,0 +1,51 @@ +// Copyright © 2017 Project Golan, all rights reserved. +#include "g_object.h" + +#include "g_stage.h" + +#include + +// Extern Functions ----------------------------------------------------------| + +// +// G_Entity_Create +// +void G_Entity_Create(G_mfdat *info) +{ + DGE_Entity ent = {DGE_Entity_Create(0)}; + + ent.x = info->ent.x; + ent.y = info->ent.y; + + G_entty const *type; + if((type = G_ObjDef_GetType(info->ent.name))) { + G_ObjDef_setupEntity(type, ent); + G_ObjDef_createTask (type, ent); + } +} + +// +// G_Sector_Create +// +void G_Sector_Create(G_mfdat *info) +{ + DGE_Sector sec = {DGE_Sector_Create(4, 0)}; + + DGE_Object_RefAdd(sec.id); + + sec.friction = 0.875lr; + sec.gz = -1; + + fixed xl = info->sec.x , yl = info->sec.y; + fixed xu = info->sec.w + xl, yu = info->sec.h + yl; + + DGE_Sector_PointSet(sec.id, 0, (DGE_Point2){xl, yl}); + DGE_Sector_PointSet(sec.id, 1, (DGE_Point2){xl, yu}); + DGE_Sector_PointSet(sec.id, 2, (DGE_Point2){xu, yu}); + DGE_Sector_PointSet(sec.id, 3, (DGE_Point2){xu, yl}); + + DGE_Sector_CalcBounds(sec.id); + DGE_Sector_Block(sec.id); +} + +// EOF diff --git a/src/g_object.h b/src/g_object.h index 26806f6..9f9bff5 100644 --- a/src/g_object.h +++ b/src/g_object.h @@ -65,7 +65,9 @@ void G_ObjDef_Init(void); void G_ObjDef_Load(char const *fname); void G_ObjDef_LoadFunc(char const *name, DGE_CallbackType fptr); -DGE_Entity G_Player_Create(fixed x, fixed y); DGE_Callback void G_Player_Think(DGE_Entity ent); +void G_Entity_Create(union G_mfdat *info); +void G_Sector_Create(union G_mfdat *info); + #endif diff --git a/src/g_player.c b/src/g_player.c index 3b40a92..4512801 100644 --- a/src/g_player.c +++ b/src/g_player.c @@ -3,12 +3,15 @@ #include +#include + // Extern Functions ----------------------------------------------------------| // // G_Player_Think // -DGE_Callback void G_Player_Think(DGE_Entity ent) +DGE_Callback +void G_Player_Think(DGE_Entity ent) { DGE_Object_RefAdd(ent.id); @@ -26,23 +29,4 @@ DGE_Callback void G_Player_Think(DGE_Entity ent) DGE_Object_RefSub(ent.id); } -// -// G_Player_Create -// -DGE_Entity G_Player_Create(fixed x, fixed y) -{ - DGE_Entity ent = {DGE_Entity_Create(0)}; - - ent.x = x; - ent.y = y; - - G_entty const *type; - if((type = G_ObjDef_GetType("Player"))) { - G_ObjDef_setupEntity(type, ent); - G_ObjDef_createTask (type, ent); - } - - return ent; -} - // EOF diff --git a/src/g_stage.c b/src/g_stage.c new file mode 100644 index 0000000..df13029 --- /dev/null +++ b/src/g_stage.c @@ -0,0 +1,119 @@ +// Copyright © 2017 Project Golan, all rights reserved. +#include "g_stage.h" + +#include "g_object.h" +#include "m_binio.h" +#include "m_str.h" + +#include + +#include +#include +#include + +// 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 diff --git a/src/g_stage.h b/src/g_stage.h new file mode 100644 index 0000000..93e7a7a --- /dev/null +++ b/src/g_stage.h @@ -0,0 +1,50 @@ +// Copyright © 2017 Project Golan, all rights reserved. +#ifndef g_stage_h +#define g_stage_h + +#include "m_darray.h" +#include "m_types.h" + +// Types ---------------------------------------------------------------------| + +typedef struct G_mfsec +{ + fixed x, y; + fixed w, h; +} G_mfsec; + +typedef struct G_mfent +{ + fixed x, y; + char name[32]; +} G_mfent; + +typedef union G_mfdat +{ + G_mfsec sec; + G_mfent ent; +} G_mfdat; + +typedef struct G_mfptr +{ + mword time; + G_mfdat data; + + void (*proc)(G_mfdat *data); +} G_mfptr; + +typedef struct G_stage +{ + M_Vec_decl(G_mfptr, map); +} G_stage; + +// Extern Objects ------------------------------------------------------------| + +extern char const *G_place; + +// Extern Functions ----------------------------------------------------------| + +G_stage G_Stage_LoadMap(char const *fname); +void G_Stage_Begin(unsigned stagenum); + +#endif diff --git a/src/golan5.c b/src/golan5.c index 56e82b7..468bcea 100644 --- a/src/golan5.c +++ b/src/golan5.c @@ -26,6 +26,14 @@ static M_token *Expect(M_tkbuf *tb, M_tokty t) return tok; } +// +// WriteNum +// +static void WriteNum(FILE *fp, M_tkbuf *tb) +{ + M_IO_WriteLE4k(fp, strtof(Expect(tb, tok_number)->textV, NULL)); +} + // Extern Functions ----------------------------------------------------------| // @@ -60,19 +68,34 @@ int main(int argc, char **argv) fwrite("Gmf0\r\n\xF7\0", 1, 8, out); - do { - if(M_TokBuf_Drop(&tb, tok_braceo)) + for(M_token *tok; (tok = M_TokBuf_Get(&tb))->type != tok_eof;) + { + if(tok->type == tok_braceo) { M_IO_WriteLE4u(out, strtoul(Expect(&tb, tok_number)->textV, NULL, 0)); - M_token *tok = Expect(&tb, tok_identi); - fwrite(tok->textV, 1, tok->textC, out); - if(strcmp(tok->textV, "Sector") == 0) - for(int i = 0; i < 4; i++) - M_IO_WriteLE4k(out, strtof(Expect(&tb, tok_number)->textV, NULL)); + + tok = Expect(&tb, tok_identi); + + // Write length and content of name. + fputc(tok->textC - 1, out); + fwrite(tok->textV, 1, tok->textC - 1, out); + + // Write content size and content. + if(strcmp(tok->textV, "Sector") == 0) { + M_IO_WriteLE2u(out, 4 * 4); + for(int i = 0; i < 4; i++) WriteNum(out, &tb); + } else { + M_IO_WriteLE2u(out, 4 * 2); + for(int i = 0; i < 2; i++) WriteNum(out, &tb); + } + Expect(&tb, tok_bracec); } } - while(!M_TokBuf_Drop(&tb, tok_eof)); + + M_IO_WriteLE4u(out, 0); + fputc(0, out); + M_IO_WriteLE2u(out, 0); done: fclose(out); diff --git a/src/m_binio.c b/src/m_binio.c index 58a7c7a..c3dcb0b 100644 --- a/src/m_binio.c +++ b/src/m_binio.c @@ -6,6 +6,15 @@ // Extern Functions ----------------------------------------------------------| +// +// M_IO_WriteLE2u +// +void M_IO_WriteLE2u(FILE *fp, hword v) +{ + fputc((v >> 8) & 0xFF, fp); + fputc((v >> 0) & 0xFF, fp); +} + // // M_IO_WriteLE4u // @@ -23,16 +32,26 @@ void M_IO_WriteLE4u(FILE *fp, mword v) void M_IO_WriteLE4k(FILE *fp, fixed v) { #if __GDCC__ - M_IO_WriteLE4u(fp, *(mword *)&v); + M_IO_WriteLE4u(fp, (union {fixed k; mword u;}){v}.u); #else float a = fabsf(v); mword k = ((mword)a << 7) & 0x7FFFFF80; k |= (mword)(fmod(a, 1) * 0x7F) & 0x7F; - if(v < 0) k |= 0x80000000; + if(v < 0) k = ~k + 1; M_IO_WriteLE4u(fp, k); #endif } +// +// M_IO_ReadLE2u +// +hword M_IO_ReadLE2u(FILE *fp) +{ + mbyte data[2]; + fread(data, 1, 2, fp); + return ((hword)data[1] << 0) | ((hword)data[0] << 8); +} + // // M_IO_ReadLE4u // @@ -40,8 +59,8 @@ mword M_IO_ReadLE4u(FILE *fp) { mbyte data[4]; fread(data, 1, 4, fp); - return ((mword)data[0] << 0) | ((mword)data[1] << 8) | - ((mword)data[2] << 16) | ((mword)data[3] << 24); + return ((mword)data[3] << 0) | ((mword)data[2] << 8) | + ((mword)data[1] << 16) | ((mword)data[0] << 24); } // @@ -53,10 +72,7 @@ fixed M_IO_ReadLE4k(FILE *fp) return (union {mword u; fixed k;}){M_IO_ReadLE4u(fp)}.k; #else mword u = M_IO_ReadLE4u(fp); - float res = (u & 0x7FFFFF80) >> 7; - res += (u & 0x7F) / 127.f; - if(u & 0x80000000) res *= -1; - return res; + return (integ)u / 127.0; #endif } diff --git a/src/m_binio.h b/src/m_binio.h index de2e5da..6d914e7 100644 --- a/src/m_binio.h +++ b/src/m_binio.h @@ -8,8 +8,11 @@ // Extern Functions ----------------------------------------------------------| +void M_IO_WriteLE2u(FILE *fp, hword v); void M_IO_WriteLE4u(FILE *fp, mword v); void M_IO_WriteLE4k(FILE *fp, fixed v); + +hword M_IO_ReadLE2u(FILE *fp); mword M_IO_ReadLE4u(FILE *fp); fixed M_IO_ReadLE4k(FILE *fp); diff --git a/src/m_str.c b/src/m_str.c index 90db549..858e10d 100644 --- a/src/m_str.c +++ b/src/m_str.c @@ -1,5 +1,6 @@ // Copyright © 2017 Project Golan, all rights reserved. #include "m_str.h" + #include "m_types.h" #if __GDCC__ diff --git a/src/m_str.h b/src/m_str.h index 2de1b92..4b91bd2 100644 --- a/src/m_str.h +++ b/src/m_str.h @@ -4,7 +4,8 @@ #include "m_types.h" -#define M_strbufcpy(a, b) strncpy((a), (b), M_countof(a)) +#define M_strbufcpy(a, b) (strncpy((a), (b), M_countof(a))) +#define M_membufcmp(a, b) (memcmp ((a), (b), M_countof(b))) // Extern Functions ----------------------------------------------------------| diff --git a/src/m_token.c b/src/m_token.c index 9ea0853..25ecce8 100644 --- a/src/m_token.c +++ b/src/m_token.c @@ -1,5 +1,6 @@ // Copyright © 2017 Project Golan, all rights reserved. #include "m_token.h" + #include "m_darray.h" #include diff --git a/src/main.c b/src/main.c index 46f5fdb..dfb3a6a 100644 --- a/src/main.c +++ b/src/main.c @@ -1,87 +1,22 @@ // Copyright © 2017 Project Golan, all rights reserved. #include "g_object.h" -#include "m_str.h" +#include "g_stage.h" +#include "r_draw.h" #include #include -// Extern Objects ------------------------------------------------------------| - -char const *G_place = u8"地球軌道・朝"; - -// Static Functions ----------------------------------------------------------| - -// -// R_drawHitboxes -// -static void R_drawHitboxes(void) -{ - DGE_Texture_Bind(0); - DGE_Draw_SetColor(1lr, 0, 0, 0.5lr); - - unsigned head = DGE_Thinker_Head(); - DGE_Point2 vp = DGE_Renderer_GetViewpoint(); - - for(DGE_Thinker th = {head}; (th.id = th.next) != head;) { - DGE_PhysicsThinker pth; - if((pth.id = DGE_Object_Cast(th.id, DGE_OT_PhysicsThinker))) { - fixed tx = pth.x - vp.x, ty = pth.y - vp.y; - DGE_Draw_Rectangle(tx - pth.sx, ty - pth.sy, tx + pth.sx, ty + pth.sy); - } - } - - DGE_Draw_SetColor(); -} - -// -// R_Draw -// -static DGE_Callback void R_Draw(ulfra delta) -{ - DGE_Shader_Bind(DGE_Shader_Get(s"plasma")); - DGE_Texture_Bind(0); - DGE_Draw_Rectangle(0, 0, 960, 720); - DGE_Shader_Bind(0); -} - -// -// R_DrawPost -// -static DGE_Callback void R_DrawPost(ulfra delta) -{ - DGE_Texture_Bind(DGE_Texture_Get(s"gui/border")); - DGE_Draw_Rectangle(0, 0, 960, 720); - - DGE_Font_Bind(DGE_Font_Get(s"base")); - DGE_Draw_SetTextAlign(DGE_Align_Center); - DGE_Draw_Text(760, 20, G_place); - DGE_Draw_SetTextAlign(DGE_Align_Left); - DGE_Draw_Text(585, 70, u8"ハイスコア\nスコア\n\n残り再試行回"); - DGE_Draw_SetTextAlign(DGE_Align_Right); - DGE_Draw_Text(945, 70, M_StrFmt("%.15i\n%.15i\n\n%i", 0, 0, 5)); - - R_drawHitboxes(); -} - -// -// G_Stage_Begin -// -static void G_Stage_Begin(unsigned stagenum) -{ - G_Player_Create(-200, 250); -} - // Extern Functions ----------------------------------------------------------| -void R_ResDec_Load(char const *fname); - // // main // [[__extern("asm")]] DGE_Callback void main(void) { + extern void R_ResDec_Load(char const *fname); + printf("\n=====================\n" u8"オミ:影響の目 1.0\n" u8"Copyright © 2017 Project Golan, all rights reserved.\n\n"); diff --git a/src/r_draw.c b/src/r_draw.c new file mode 100644 index 0000000..341cfcc --- /dev/null +++ b/src/r_draw.c @@ -0,0 +1,67 @@ +// Copyright © 2017 Project Golan, all rights reserved. +#include "r_draw.h" + +#include "g_stage.h" +#include "m_str.h" + +#include + +// Static Functions ----------------------------------------------------------| + +// +// R_drawHitboxes +// +static void R_drawHitboxes(void) +{ + DGE_Texture_Bind(0); + DGE_Draw_SetColor(1lr, 0, 0, 0.5lr); + + unsigned head = DGE_Thinker_Head(); + DGE_Point2 vp = DGE_Renderer_GetViewpoint(); + + for(DGE_Thinker th = {head}; (th.id = th.next) != head;) { + DGE_PhysicsThinker pth; + if((pth.id = DGE_Object_Cast(th.id, DGE_OT_PhysicsThinker))) { + fixed tx = pth.x - vp.x, ty = pth.y - vp.y; + DGE_Draw_Rectangle(tx - pth.sx, ty - pth.sy, tx + pth.sx, ty + pth.sy); + } + } + + DGE_Draw_SetColor(); +} + +// Extern Functions ----------------------------------------------------------| + +// +// R_Draw +// +DGE_Callback +void R_Draw(ulfra delta) +{ + DGE_Shader_Bind(DGE_Shader_Get(s"plasma")); + DGE_Texture_Bind(0); + DGE_Draw_Rectangle(0, 0, 960, 720); + DGE_Shader_Bind(0); +} + +// +// R_DrawPost +// +DGE_Callback +void R_DrawPost(ulfra delta) +{ + DGE_Texture_Bind(DGE_Texture_Get(s"gui/border")); + DGE_Draw_Rectangle(0, 0, 960, 720); + + DGE_Font_Bind(DGE_Font_Get(s"base")); + DGE_Draw_SetTextAlign(DGE_Align_Center); + DGE_Draw_Text(760, 20, G_place); + DGE_Draw_SetTextAlign(DGE_Align_Left); + DGE_Draw_Text(585, 70, u8"ハイスコア\nスコア\n\n残り再試行回"); + DGE_Draw_SetTextAlign(DGE_Align_Right); + DGE_Draw_Text(945, 70, M_StrFmt("%.15i\n%.15i\n\n%i", 0, 0, 5)); + + R_drawHitboxes(); +} + +// EOF diff --git a/src/r_draw.h b/src/r_draw.h new file mode 100644 index 0000000..0ba2a5c --- /dev/null +++ b/src/r_draw.h @@ -0,0 +1,14 @@ +// Copyright © 2017 Project Golan, all rights reserved. +#ifndef r_draw_h +#define r_draw_h + +#include "m_types.h" + +#include + +// Extern Functions ----------------------------------------------------------| + +DGE_Callback void R_Draw(ulfra delta); +DGE_Callback void R_DrawPost(ulfra delta); + +#endif