// Copyright © 2017 Project Golan, all rights reserved. // See COPYING for more information. #include "m_tokbuf.h" #include "m_str.h" #include #include #include #include // 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_toktype 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_toktype 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