149 lines
3.4 KiB
C
149 lines
3.4 KiB
C
|
// Copyright © 2017 Project Golan, all rights reserved.
|
||
|
#include "m_tokbuf.h"
|
||
|
#include "m_str.h"
|
||
|
|
||
|
#include <Doominati.h>
|
||
|
|
||
|
#include <setjmp.h>
|
||
|
#include <string.h>
|
||
|
#include <stdlib.h>
|
||
|
|
||
|
// Static Functions ----------------------------------------------------------|
|
||
|
|
||
|
_Noreturn static void R_ResDec_throw (struct R_rdcst *st, char const *emsg);
|
||
|
static M_token *R_ResDec_expect(struct R_rdcst *st, M_tokty t, char const *exp);
|
||
|
|
||
|
// Types ---------------------------------------------------------------------|
|
||
|
|
||
|
typedef struct R_rdcst
|
||
|
{
|
||
|
__prop throw {call: R_ResDec_throw (this)}
|
||
|
__prop expect {call: R_ResDec_expect(this)}
|
||
|
|
||
|
M_tkbuf tb;
|
||
|
jmp_buf ejmp;
|
||
|
} R_rdcst;
|
||
|
|
||
|
// Static Functions ----------------------------------------------------------|
|
||
|
|
||
|
//
|
||
|
// R_ResDec_throw
|
||
|
//
|
||
|
_Noreturn static void R_ResDec_throw(R_rdcst *st, char const *emsg)
|
||
|
{
|
||
|
fprintf(stderr, "ResDec: %s\n", emsg);
|
||
|
longjmp(st->ejmp, 1);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// R_ResDec_expect
|
||
|
//
|
||
|
static M_token *R_ResDec_expect(R_rdcst *st, M_tokty t, char const *exp)
|
||
|
{
|
||
|
M_token *tok;
|
||
|
if((tok = st->tb.get())->type != t)
|
||
|
st->throw(M_StrFmt("expected %s", exp));
|
||
|
return tok;
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// R_ResDec_getFont
|
||
|
//
|
||
|
static void R_ResDec_getFont(R_rdcst *st)
|
||
|
{
|
||
|
char const *fname;
|
||
|
__str name;
|
||
|
int pt;
|
||
|
|
||
|
name = M_StrCreate(st->expect(tok_string, "alias name")->textV);
|
||
|
st->expect(tok_eq, "'='");
|
||
|
|
||
|
fname = st->expect(tok_string, "file name")->textV;
|
||
|
st->expect(tok_comma, "','");
|
||
|
|
||
|
pt = strtoi(st->expect(tok_number, "pt size")->textV, NULL, 0);
|
||
|
DGE_Font_Create(name, fname, pt);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// R_ResDec_getTexture
|
||
|
//
|
||
|
static void R_ResDec_getTexture(R_rdcst *st)
|
||
|
{
|
||
|
char const *fname;
|
||
|
__str name;
|
||
|
|
||
|
name = M_StrCreate(st->expect(tok_string, "alias name")->textV);
|
||
|
st->expect(tok_eq, "'='");
|
||
|
|
||
|
fname = st->expect(tok_string, "file name")->textV;
|
||
|
DGE_Texture_Create(name, fname);
|
||
|
}
|
||
|
|
||
|
//
|
||
|
// R_ResDec_getShader
|
||
|
//
|
||
|
static void R_ResDec_getShader(R_rdcst *st)
|
||
|
{
|
||
|
char const *fp, *vp;
|
||
|
__str name;
|
||
|
bool data = false;
|
||
|
|
||
|
name = M_StrCreate(st->expect(tok_string, "alias name")->textV);
|
||
|
st->expect(tok_eq, "'='");
|
||
|
|
||
|
if(st->tb.drop(tok_identi) && strcmp(st->tb.reget()->textV, "data") == 0)
|
||
|
data = true;
|
||
|
|
||
|
fp = st->expect(tok_string, "fragment shader")->textV;
|
||
|
st->expect(tok_comma, "','");
|
||
|
|
||
|
vp = st->expect(tok_string, "vertex shader")->textV;
|
||
|
if(data) DGE_Shader_CreateData(name, fp, vp);
|
||
|
else DGE_Shader_CreateFile(name, fp, vp);
|
||
|
}
|
||
|
|
||
|
// Extern Functions ----------------------------------------------------------|
|
||
|
|
||
|
//
|
||
|
// R_ResDec_Load
|
||
|
//
|
||
|
void R_ResDec_Load(char const *fname)
|
||
|
{
|
||
|
R_rdcst st = {{.bbeg = 4, .bend = 10, .fp = fopen(fname, "r")}};
|
||
|
|
||
|
if(!st.tb.fp) {
|
||
|
fprintf(stderr, "ResDec: couldn't open file '%s'\n", fname);
|
||
|
goto done;
|
||
|
}
|
||
|
|
||
|
st.tb.ctor();
|
||
|
|
||
|
if(setjmp(st.ejmp) == 1)
|
||
|
goto done;
|
||
|
|
||
|
for(M_token *tok; (tok = st.tb.get())->type != tok_eof;)
|
||
|
{
|
||
|
if(tok->type != tok_identi)
|
||
|
st.throw("expected identifier");
|
||
|
else if(strcmp(tok->textV, "font") == 0)
|
||
|
R_ResDec_getFont(&st);
|
||
|
else if(strcmp(tok->textV, "texture") == 0)
|
||
|
R_ResDec_getTexture(&st);
|
||
|
else if(strcmp(tok->textV, "shader") == 0)
|
||
|
R_ResDec_getShader(&st);
|
||
|
else if(strcmp(tok->textV, "include") == 0)
|
||
|
R_ResDec_Load(st.expect(tok_string, "file name")->textV);
|
||
|
else
|
||
|
st.throw(M_StrFmt("invalid resource type '%s'", tok->textV));
|
||
|
}
|
||
|
|
||
|
printf("ResDec: '%s' loaded.\n", fname);
|
||
|
|
||
|
done:
|
||
|
st.tb.dtor();
|
||
|
fclose(st.tb.fp);
|
||
|
}
|
||
|
|
||
|
// EOF
|