Skip to content

Commit

Permalink
feat: UV and TEX0 support
Browse files Browse the repository at this point in the history
  • Loading branch information
F0bes committed Mar 28, 2024
1 parent 39e0a19 commit c68a6ac
Show file tree
Hide file tree
Showing 6 changed files with 394 additions and 16 deletions.
62 changes: 52 additions & 10 deletions backend/c_code.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ void c_code_backend::print_help() const

c_code_backend::~c_code_backend()
{
if(file != nullptr && file != stdout)
if (file != nullptr && file != stdout)
{
fclose(file);
}
Expand All @@ -60,9 +60,9 @@ c_code_backend::~c_code_backend()
void c_code_backend::emit(GIFBlock* block)
{
std::string prim_str;
if(block->prim)
if (block->prim)
{
if(emit_mode == EmitMode::USE_DEFS)
if (emit_mode == EmitMode::USE_DEFS)
{
prim_str = fmt::format("GS_SET_PRIM({},{},{},{},0,{},GS_ENABLE,0,0)", PrimTypeStrings[block->prim->GetType()],
block->prim->IsGouraud() ? "GS_ENABLE" : "GS_DISABLE",
Expand All @@ -83,8 +83,7 @@ void c_code_backend::emit(GIFBlock* block)
std::string buffer = fmt::format("u64 {1}_data_size = {0};\n"
"u64 {1}_data[] __attribute__((aligned(16))) = {{\n\t"
"GIF_SET_TAG({2},1,{3},{4},0,1),GIF_REG_AD,\n\t",
(block->registers.size() + 1) * 16, block->name, block->registers.size()
, block->prim ? 1 : 0, block->prim ? prim_str : "0");
(block->registers.size() + 1) * 16, block->name, block->registers.size(), block->prim ? 1 : 0, block->prim ? prim_str : "0");
fmt::print("Emitting block: {}\n", block->name);
for (auto& reg : block->registers)
{
Expand Down Expand Up @@ -152,6 +151,16 @@ std::string c_code_backend::emit_rgbaq(c_code_backend* inst, std::shared_ptr<Gif
val.x, val.y, val.z, val.w, 0, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_RGBAQ" : "0x01");
}

std::string c_code_backend::emit_uv(c_code_backend* inst, std::shared_ptr<GifRegister> reg)
{
UV uv = dynamic_cast<UV&>(*reg);

auto val = uv.GetValue();

return fmt::format("GS_SET_UV({}<<4,{}<<4),{},",
val.x, val.y, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_UV" : "0x03");
}

std::string c_code_backend::emit_xyz2(c_code_backend* inst, std::shared_ptr<GifRegister> reg)
{
XYZ2 xyz2 = dynamic_cast<XYZ2&>(*reg);
Expand All @@ -162,6 +171,39 @@ std::string c_code_backend::emit_xyz2(c_code_backend* inst, std::shared_ptr<GifR
val.x, val.y, val.z, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_XYZ2" : "0x05");
}

std::string c_code_backend::emit_tex0(c_code_backend* inst, std::shared_ptr<GifRegister> reg)
{
TEX0 tex0 = dynamic_cast<TEX0&>(*reg);

if (inst->emit_mode == EmitMode::USE_DEFS)
{
std::string PSM_STR;
switch (tex0.GetPSM())
{
case PSM::CT32:
PSM_STR = "GS_PSM_32";
break;
case PSM::CT24:
PSM_STR = "GS_PSM_24";
break;
case PSM::CT16:
PSM_STR = "GS_PSM_16";
break;
}

// Todo: Support gs_psm defines
return fmt::format("GS_SET_TEX0(0x{:x},0x{:x},{},{:x},{:x},{:d},{},0,0,0,0,0),GS_REG_TEX0,",
tex0.GetTBP(), tex0.GetTBW(), PSM_STR,
tex0.GetTW(), tex0.GetTH(), tex0.GetTCC(), static_cast<uint32_t>(tex0.GetTFX()));
}
else
{
return fmt::format("GS_SET_TEX0(0x{:02x},0x{:02x},{},{:02x},{:02x},{:d},{},0,0,0,0,0),0x06,",
tex0.GetTBP(), tex0.GetTBW(), static_cast<uint32_t>(tex0.GetPSM()),
tex0.GetTW(), tex0.GetTH(), tex0.GetTCC(), static_cast<uint32_t>(tex0.GetTFX()));
}
}

std::string c_code_backend::emit_fog(c_code_backend* inst, std::shared_ptr<GifRegister> reg)
{
FOG fog = dynamic_cast<FOG&>(*reg);
Expand Down Expand Up @@ -199,21 +241,21 @@ std::string c_code_backend::emit_signal(c_code_backend* inst, std::shared_ptr<Gi
auto val = signal.GetValue();

return fmt::format("GS_SET_SIGNAL(0x{:02x},0x{:02x}),{},",
val.x,val.y, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_SIGNAL" : "0x60");
val.x, val.y, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_SIGNAL" : "0x60");
}

std::string c_code_backend::emit_finish(c_code_backend* inst, std::shared_ptr<GifRegister> reg)
{
FINISH finish = dynamic_cast<FINISH&>(*reg);

auto val = finish.GetValue();
if(inst->emit_mode == EmitMode::USE_DEFS)
if (inst->emit_mode == EmitMode::USE_DEFS)
{
return fmt::format("GS_SET_FINISH({}),GS_REG_FINISH,",val);
return fmt::format("GS_SET_FINISH({}),GS_REG_FINISH,", val);
}
else
{
return fmt::format("0x{:x},{},",val, "0x61");
return fmt::format("0x{:x},{},", val, "0x61");
}
}

Expand All @@ -224,5 +266,5 @@ std::string c_code_backend::emit_label(c_code_backend* inst, std::shared_ptr<Gif
auto val = label.GetValue();

return fmt::format("GS_SET_LABEL(0x{:02x},0x{:02x}),{},",
val.x,val.y, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_LABEL" : "0x62");
val.x, val.y, inst->emit_mode == EmitMode::USE_DEFS ? "GS_REG_LABEL" : "0x62");
}
4 changes: 4 additions & 0 deletions backend/c_code.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,9 @@ class c_code_backend : public Backend
// Primitive dispatching
static std::string emit_primitive(c_code_backend*, std::shared_ptr<GifRegister> reg);
static std::string emit_rgbaq(c_code_backend*, std::shared_ptr<GifRegister> reg);
static std::string emit_uv(c_code_backend*, std::shared_ptr<GifRegister> reg);
static std::string emit_xyz2(c_code_backend*, std::shared_ptr<GifRegister> reg);
static std::string emit_tex0(c_code_backend*, std::shared_ptr<GifRegister> reg);
static std::string emit_fog(c_code_backend*, std::shared_ptr<GifRegister> reg);
static std::string emit_fogcol(c_code_backend*, std::shared_ptr<GifRegister> reg);
static std::string emit_scissor(c_code_backend*, std::shared_ptr<GifRegister> reg);
Expand All @@ -48,7 +50,9 @@ class c_code_backend : public Backend
{
{0x00, c_code_backend::emit_primitive},
{0x01, c_code_backend::emit_rgbaq},
{0x03, c_code_backend::emit_uv},
{0x05, c_code_backend::emit_xyz2},
{0x06, c_code_backend::emit_tex0},
{0x0A, c_code_backend::emit_fog},
{0x3D, c_code_backend::emit_fogcol},
{0x40, c_code_backend::emit_scissor},
Expand Down
38 changes: 38 additions & 0 deletions examples/textured.gs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
This expects a 128x128 CT23 texture to be placed at vram location 0x2300
The vram address is not divided by 64 by gifscript, you must do that before
In other words, the actual vram address is 0x2300 * 64
UV (and XY coords) are automatically shifted, there is no way to do half
pixel offsets at this moment
*/

textured_tri {
rgbaq 0x80,0,0,127;
prim tri textured;

// By default DECAL is used

// This draws half of the texture as-is
tex0 0x2300 2 ct24 7,7;
uv 0,0;
xyz2 100,100,0;
uv 0,128;
xyz2 100,228,0;
uv 128,128;
xyz2 228,228,0;

// This draws the other half of the texture, modulated by vertex colours
// with gouraud shading to make it a bit more interesting
prim tri textured gouraud;
tex0 0x2300 2 ct24 7,7 modulate;
rgbaq 0x00,0x80,0x00,127;
uv 0,0;
xyz2 100,100,0;
rgbaq 0x00,0x00,0x80,127;
uv 128,0;
xyz2 228,100,0;
rgbaq 0x80,0x00,0x00,127;
uv 128,128;
xyz2 228,228,0;
}
92 changes: 88 additions & 4 deletions gifscript.rl
Original file line number Diff line number Diff line change
Expand Up @@ -35,22 +35,36 @@ void FailError(const char* ts, const char* te);
}

# Registers
action prim_tok {
Parse(lparser, REG, new std::any(GifRegisters::PRIM), &valid);
if(!valid) {
FailError(ts, te);
}
}

action rgbaq_tok {
Parse(lparser, REG, new std::any(GifRegisters::RGBAQ), &valid);
if(!valid) {
FailError(ts, te);
}
}

action uv_tok {
Parse(lparser, REG, new std::any(GifRegisters::UV), &valid);
if(!valid) {
FailError(ts, te);
}
}

action xyz2_tok {
Parse(lparser, REG, new std::any(GifRegisters::XYZ2), &valid);
if(!valid) {
FailError(ts, te);
}
}

action prim_tok {
Parse(lparser, REG, new std::any(GifRegisters::PRIM), &valid);
action tex0_tok {
Parse(lparser, REG, new std::any(GifRegisters::TEX0), &valid);
if(!valid) {
FailError(ts, te);
}
Expand Down Expand Up @@ -178,6 +192,56 @@ void FailError(const char* ts, const char* te);
}
}

# TEX0 Modifiers
action mod_ct32_tok {
Parse(lparser, MOD, new std::any(RegModifier::CT32), &valid);
if(!valid) {
FailError(ts, te);
}
}

action mod_ct24_tok {
Parse(lparser, MOD, new std::any(RegModifier::CT24), &valid);
if(!valid) {
FailError(ts, te);
}
}

action mod_ct16_tok {
Parse(lparser, MOD, new std::any(RegModifier::CT16), &valid);
if(!valid) {
FailError(ts, te);
}
}

action mod_modulate_tok {
Parse(lparser, MOD, new std::any(RegModifier::Modulate), &valid);
if(!valid) {
FailError(ts, te);
}
}

action mod_decal_tok {
Parse(lparser, MOD, new std::any(RegModifier::Decal), &valid);
if(!valid) {
FailError(ts, te);
}
}

action mod_highlight_tok {
Parse(lparser, MOD, new std::any(RegModifier::Highlight), &valid);
if(!valid) {
FailError(ts, te);
}
}

action mod_highlight2_tok {
Parse(lparser, MOD, new std::any(RegModifier::Highlight2), &valid);
if(!valid) {
FailError(ts, te);
}
}

# Vectors
action vec4_tok {
std::string s(ts, te - ts);
Expand Down Expand Up @@ -276,9 +340,11 @@ void FailError(const char* ts, const char* te);
semi = ';';

# Registers
prim = /prim/i;
rgbaq = (/rgbaq/i|/rgba/i);
uv = /uv/i;
xyz2 = /xyz2/i;
prim = /prim/i;
tex0 = /tex0/i;
fog = /fog/i;
fogcol = /fogcol/i;
scissor = /scissor/i;
Expand All @@ -300,6 +366,14 @@ void FailError(const char* ts, const char* te);
mod_fogging = (/fogging/i|/fog/i);
mod_aa1 = /aa1/i;
mod_texture = (/texture/i|/textured/i);
# TEX0 Modifiers
mod_ct32 = (/ct32/i|/psmct32/i);
mod_ct24 = (/ct24/i|/psmct24/i);
mod_ct16 = (/ct16/i|/psmct16/i);
mod_modulate = (/modulate/i);
mod_decal = (/decal/i);
mod_highlight = (/highlight/i);
mod_highlight2 = (/highlight2/i);

# Constants
int_const = digit+;
Expand All @@ -326,9 +400,11 @@ void FailError(const char* ts, const char* te);
semi => semi_tok;

# Registers
prim => prim_tok;
rgbaq => rgbaq_tok;
uv => uv_tok;
xyz2 => xyz2_tok;
prim => prim_tok;
tex0 => tex0_tok;
fog => fog_tok;
fogcol => fogcol_tok;
scissor => scissor_tok;
Expand All @@ -350,6 +426,14 @@ void FailError(const char* ts, const char* te);
mod_fogging => mod_fogging_tok;
mod_aa1 => mod_aa1_tok;
mod_texture => mod_texture_tok;
# TEX0 Modifiers
mod_ct32 => mod_ct32_tok;
mod_ct24 => mod_ct24_tok;
mod_ct16 => mod_ct16_tok;
mod_modulate => mod_modulate_tok;
mod_decal => mod_decal_tok;
mod_highlight => mod_highlight_tok;
mod_highlight2 => mod_highlight2_tok;

# Vectors
vec4 => vec4_tok;
Expand Down
4 changes: 4 additions & 0 deletions registers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,12 @@ std::shared_ptr<GifRegister> GenReg(GifRegisters reg)
return std::make_shared<PRIM>();
case GifRegisters::RGBAQ:
return std::make_shared<RGBAQ>();
case GifRegisters::UV:
return std::make_shared<UV>();
case GifRegisters::XYZ2:
return std::make_shared<XYZ2>();
case GifRegisters::TEX0:
return std::make_shared<TEX0>();
case GifRegisters::FOG:
return std::make_shared<FOG>();
case GifRegisters::FOGCOL:
Expand Down
Loading

0 comments on commit c68a6ac

Please sign in to comment.