Browse Source

Add stage loader

master
Marrub 5 years ago
parent
commit
af8b61e9a5
  1. 1
      .gitignore
  2. 7
      Makefile
  3. 2
      data/resdecl.rd
  4. 11
      maps/base.gmf9
  5. 1
      src/g_objdef.c
  6. 51
      src/g_object.c
  7. 4
      src/g_object.h
  8. 24
      src/g_player.c
  9. 119
      src/g_stage.c
  10. 50
      src/g_stage.h
  11. 39
      src/golan5.c
  12. 32
      src/m_binio.c
  13. 3
      src/m_binio.h
  14. 1
      src/m_str.c
  15. 3
      src/m_str.h
  16. 1
      src/m_token.c
  17. 73
      src/main.c
  18. 67
      src/r_draw.c
  19. 14
      src/r_draw.h

1
.gitignore vendored

@ -5,6 +5,7 @@ src_crap
data/codedefs
data/fonts
data/maps
data/music
data/sounds
data/sprites
data/textures

7
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:

2
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"

11
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

1
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"

51
src/g_object.c

@ -0,0 +1,51 @@
// Copyright © 2017 Project Golan, all rights reserved.
#include "g_object.h"
#include "g_stage.h"
#include <Doominati.h>
// 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

4
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

24
src/g_player.c

@ -3,12 +3,15 @@
#include <Doominati.h>
#include <stdio.h>
// 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

119
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 <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

50
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

39
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);

32
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
}

3
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);

1
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__

3
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 ----------------------------------------------------------|

1
src/m_token.c

@ -1,5 +1,6 @@
// Copyright © 2017 Project Golan, all rights reserved.
#include "m_token.h"
#include "m_darray.h"
#include <ctype.h>

73
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 <Doominati.h>
#include <stdio.h>
// 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");

67
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 <Doominati.h>
// 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

14
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 <Doominati.h>
// Extern Functions ----------------------------------------------------------|
DGE_Callback void R_Draw(ulfra delta);
DGE_Callback void R_DrawPost(ulfra delta);
#endif
Loading…
Cancel
Save