mirror of
https://github.com/TwilitRealm/dusklight
synced 2026-06-19 22:33:04 -04:00
Merge branch 'main' of https://github.com/TwilitRealm/dusklight into randomizer
This commit is contained in:
@@ -15,6 +15,12 @@ const u16 l_J_Ohana00_64TEX__height = 63;
|
||||
using GameVersion = dusk::version::GameVersion;
|
||||
static u8* l_J_Ohana00_64TEX_get() { static u8 buf[0x800]; static bool _ = (dusk::LoadArchivedRelAsset(buf, 'AMEM', "d_a_grass.rel", {{GameVersion::GcnUsa, 0x9060}, {GameVersion::GcnPal, 0x9060}}, 0x800), true); return buf; }
|
||||
#define l_J_Ohana00_64TEX (l_J_Ohana00_64TEX_get())
|
||||
|
||||
// from d_grass.inc
|
||||
static MtxP get_model_mtx(Mtx modelMtx, Mtx storage);
|
||||
static void transform_positions(
|
||||
const dusk::batch::LeafTemplate& tpl, const Vec* posArray, const Mtx mtx, Vec* xfPos);
|
||||
static void split_batch(u32& emitted, u32 vtxCount);
|
||||
#else
|
||||
#include "assets/l_J_Ohana00_64TEX.h"
|
||||
#endif
|
||||
@@ -588,6 +594,12 @@ dFlower_packet_c::dFlower_packet_c() {
|
||||
GXInitTexObj(&mTexObj_l_J_Ohana01_64128_0419TEX, l_J_Ohana01_64128_0419TEX,
|
||||
l_J_Ohana01_64128_0419TEX__width + 1, l_J_Ohana01_64128_0419TEX__height + 1, GX_TF_CMPR, GX_MIRROR, GX_MIRROR, GX_FALSE
|
||||
);
|
||||
|
||||
dusk::batch::decode_leaf_template(l_J_hana00DL, 0x140, mTplHana00);
|
||||
dusk::batch::decode_leaf_template(l_J_hana00_cDL, 0xC0, mTplHana00Cut);
|
||||
dusk::batch::decode_leaf_template(l_J_hana01DL, 0x120, mTplHana01);
|
||||
dusk::batch::decode_leaf_template(l_J_hana01_c_00DL, 0xC0, mTplHana01Cut00);
|
||||
dusk::batch::decode_leaf_template(l_J_hana01_c_01DL, 0x120, mTplHana01Cut);
|
||||
#endif
|
||||
|
||||
m_deleteRoom = &dFlower_packet_c::deleteRoom;
|
||||
@@ -597,6 +609,371 @@ dFlower_packet_c::dFlower_packet_c() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
static void batch_setup_tev(u32 lightMask) {
|
||||
GXSetCullMode(GX_CULL_NONE);
|
||||
|
||||
GXSetNumChans(2);
|
||||
GXSetChanCtrl(GX_COLOR0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE);
|
||||
GXSetChanCtrl(GX_COLOR1, GX_TRUE, GX_SRC_VTX, GX_SRC_REG, lightMask, GX_DF_CLAMP, GX_AF_SPOT);
|
||||
|
||||
GXSetNumTevStages(3);
|
||||
|
||||
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR1A1);
|
||||
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_RASC);
|
||||
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
|
||||
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
|
||||
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_CPREV, GX_CC_RASC, GX_CC_ZERO);
|
||||
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
|
||||
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
||||
GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_CPREV, GX_CC_C0);
|
||||
GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_4, GX_TRUE, GX_TEVPREV);
|
||||
GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA);
|
||||
GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
||||
}
|
||||
|
||||
static GXColor hana00_amb_color(const dFlower_data_c* flower, const dKy_tevstr_c* tevstr) {
|
||||
GXColor amb = {0, 0, 0, 0xFF};
|
||||
if (DEBUG && g_kankyoHIO.navy.grass_adjust_ON != 0) {
|
||||
amb.r = g_kankyoHIO.navy.grass_ambcol.r * 2;
|
||||
amb.g = g_kankyoHIO.navy.grass_ambcol.g * 2;
|
||||
amb.b = g_kankyoHIO.navy.grass_ambcol.b * 2;
|
||||
} else {
|
||||
amb.r = (flower->field_0x04 & 0x1F) * 2;
|
||||
amb.g = ((flower->field_0x04 >> 5) & 0x1F) * 2;
|
||||
amb.b = ((flower->field_0x04 >> 0xA) & 0x1F) * 2;
|
||||
}
|
||||
|
||||
if (daPy_py_c::checkNowWolfPowerUp()) {
|
||||
f32 ambRate = g_env_light.bg_amb_col[0].r / 255.0f;
|
||||
f32 col = (((flower->field_0x04 & 0x1F) * 2 + 0x10));
|
||||
amb.r = col * (ambRate * 4.0f);
|
||||
|
||||
ambRate = g_env_light.bg_amb_col[0].g / 255.0f;
|
||||
f32 col2 = (((flower->field_0x04 >> 5) & 0x1F) * 2 + 0x10);
|
||||
amb.g = col2 * (4.0f * ambRate);
|
||||
|
||||
ambRate = g_env_light.bg_amb_col[0].b / 255.0f;
|
||||
f32 col3 = (((flower->field_0x04 >> 10) & 0x1F) * 2 + 0x10);
|
||||
amb.b = col3 * (4.0f * ambRate);
|
||||
}
|
||||
|
||||
if (amb.r == 0x3E) {
|
||||
amb.r = tevstr->AmbCol.r;
|
||||
}
|
||||
|
||||
if (amb.g == 0x3E) {
|
||||
amb.g = tevstr->AmbCol.g;
|
||||
}
|
||||
|
||||
if (amb.b == 0x3E) {
|
||||
amb.b = tevstr->AmbCol.b;
|
||||
}
|
||||
|
||||
return amb;
|
||||
}
|
||||
|
||||
static GXColor hana01_amb_color(int idx, const dKy_tevstr_c* tevstr) {
|
||||
f32 rRate = tevstr->AmbCol.r * 0.03125f;
|
||||
if (rRate > 1.0f) {
|
||||
rRate = 1.0f;
|
||||
}
|
||||
|
||||
f32 gRate = tevstr->AmbCol.g * 0.03125f;
|
||||
if (gRate > 1.0f) {
|
||||
gRate = 1.0f;
|
||||
}
|
||||
|
||||
f32 bRate = tevstr->AmbCol.b * 0.03125f;
|
||||
if (bRate > 1.0f) {
|
||||
bRate = 1.0f;
|
||||
}
|
||||
|
||||
GXColor amb = {1, 1, 1, 1};
|
||||
|
||||
GXColor sub;
|
||||
sub.r = -0.4f * tevstr->AmbCol.r * rRate;
|
||||
sub.g = -0.4f * tevstr->AmbCol.g * gRate;
|
||||
sub.b = -0.4f * tevstr->AmbCol.b * bRate;
|
||||
|
||||
switch (idx & 7) {
|
||||
case 0:
|
||||
amb.r = tevstr->AmbCol.r + sub.r;
|
||||
amb.g = tevstr->AmbCol.g;
|
||||
amb.b = tevstr->AmbCol.b;
|
||||
break;
|
||||
case 1:
|
||||
amb.r = tevstr->AmbCol.r;
|
||||
amb.g = tevstr->AmbCol.g + sub.g;
|
||||
amb.b = tevstr->AmbCol.b;
|
||||
break;
|
||||
case 2:
|
||||
amb.r = tevstr->AmbCol.r;
|
||||
amb.g = tevstr->AmbCol.g;
|
||||
amb.b = tevstr->AmbCol.b + sub.b;
|
||||
break;
|
||||
case 3:
|
||||
amb.r = tevstr->AmbCol.r + sub.r;
|
||||
amb.g = tevstr->AmbCol.g + sub.g;
|
||||
amb.b = tevstr->AmbCol.b;
|
||||
break;
|
||||
case 4:
|
||||
amb.r = tevstr->AmbCol.r;
|
||||
amb.g = tevstr->AmbCol.g + sub.g;
|
||||
amb.b = tevstr->AmbCol.b + sub.b;
|
||||
break;
|
||||
case 5:
|
||||
amb.r = tevstr->AmbCol.r + sub.r;
|
||||
amb.g = tevstr->AmbCol.g;
|
||||
amb.b = tevstr->AmbCol.b + sub.b;
|
||||
break;
|
||||
case 6:
|
||||
amb.r = tevstr->AmbCol.r + sub.r;
|
||||
amb.g = tevstr->AmbCol.g + sub.g;
|
||||
amb.b = tevstr->AmbCol.b + sub.b;
|
||||
break;
|
||||
case 7:
|
||||
break;
|
||||
}
|
||||
|
||||
if (daPy_py_c::checkNowWolfPowerUp()) {
|
||||
f32 ambRate = g_env_light.bg_amb_col[0].r / 255.0f;
|
||||
amb.r = (amb.r + 8) * (6.0f * ambRate);
|
||||
|
||||
ambRate = g_env_light.bg_amb_col[0].g / 255.0f;
|
||||
amb.g = (amb.g + 8) * (6.0f * ambRate);
|
||||
|
||||
ambRate = g_env_light.bg_amb_col[0].b / 255.0f;
|
||||
amb.b = (amb.b + 8) * (6.0f * ambRate);
|
||||
}
|
||||
|
||||
amb.a = 0xFF;
|
||||
return amb;
|
||||
}
|
||||
|
||||
static void flower_emit(const dusk::batch::LeafTemplate& tpl, const Vec* xformedPos, GXColor amb) {
|
||||
for (u32 i = 0; i < tpl.vtxCount; i++) {
|
||||
const dusk::batch::LeafTemplate::Vtx& v = tpl.vtx[i];
|
||||
const Vec& p = xformedPos[v.pos];
|
||||
GXPosition3f32(p.x, p.y, p.z);
|
||||
GXNormal1x8(v.nrm);
|
||||
GXColor1x8(v.clr);
|
||||
GXColor4u8(amb.r, amb.g, amb.b, amb.a);
|
||||
GXTexCoord1x8(v.tex);
|
||||
}
|
||||
}
|
||||
|
||||
void dFlower_packet_c::draw() {
|
||||
ZoneScoped;
|
||||
dScnKy_env_light_c* kankyo = dKy_getEnvlight();
|
||||
j3dSys.reinitGX();
|
||||
|
||||
GXSetNumIndStages(0);
|
||||
dKy_setLight_again();
|
||||
GXClearVtxDesc();
|
||||
GXSetVtxDesc(GX_VA_POS, GX_INDEX8);
|
||||
GXSetVtxDesc(GX_VA_NRM, GX_INDEX8);
|
||||
GXSetVtxDesc(GX_VA_CLR0, GX_INDEX8);
|
||||
GXSetVtxDesc(GX_VA_TEX0, GX_INDEX8);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR1, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GXSETARRAY(GX_VA_POS, &l_flowerPos, sizeof(l_flowerPos), sizeof(Vec), true);
|
||||
GXSETARRAY(GX_VA_NRM, &l_flowerNormal, sizeof(l_flowerNormal), sizeof(Vec), true);
|
||||
GXSETARRAY(GX_VA_CLR0, &l_flowerColor, sizeof(l_flowerColor), sizeof(GXColor), true);
|
||||
GXSETARRAY(GX_VA_TEX0, &l_flowerTexCoord, sizeof(l_flowerTexCoord), 8, true);
|
||||
|
||||
static GXVtxDescList vtxDescList[] = {
|
||||
{GX_VA_POS, GX_DIRECT},
|
||||
{GX_VA_NRM, GX_INDEX8},
|
||||
{GX_VA_CLR0, GX_INDEX8},
|
||||
{GX_VA_CLR1, GX_DIRECT},
|
||||
{GX_VA_TEX0, GX_INDEX8},
|
||||
{GX_VA_NULL, GX_NONE},
|
||||
};
|
||||
static Vec xfPos[256];
|
||||
Mtx identity;
|
||||
MTXIdentity(identity);
|
||||
|
||||
// --- hana00 ---
|
||||
for (int i = 0; i < 64; i++) {
|
||||
dFlower_data_c* first = m_room[i].getData();
|
||||
if (first == nullptr || !dComIfGp_roomControl_checkStatusFlag(i, 0x10)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dKy_tevstr_c* tevstr = dComIfGp_roomControl_getTevStr(i);
|
||||
int lightCount = 6;
|
||||
|
||||
if (dComIfGp_roomControl_getStatusRoomDt(i) != nullptr) {
|
||||
lightCount = dComIfGp_roomControl_getStatusRoomDt(i)->getLightVecInfoNum();
|
||||
}
|
||||
|
||||
if (dKy_SunMoon_Light_Check() && lightCount < 2) {
|
||||
lightCount = 2;
|
||||
}
|
||||
|
||||
for (int j = 0; j < 6; j++) {
|
||||
if (kankyo->field_0x0c18[j].field_0x26 == 1) {
|
||||
lightCount++;
|
||||
}
|
||||
}
|
||||
|
||||
if (lightCount <= 2) {
|
||||
GXCallDisplayList(l_matLight4DL, 0x80);
|
||||
} else {
|
||||
GXCallDisplayList(l_matDL, 0x80);
|
||||
}
|
||||
|
||||
GXSetTevColorS10(GX_TEVREG0, {0, 0, 0, 0});
|
||||
dKy_Global_amb_set(tevstr);
|
||||
dKy_GxFog_tevstr_set(tevstr);
|
||||
dKy_setLight_nowroom_grass(tevstr->room_no, 1.0f);
|
||||
|
||||
GXLoadTexObj(&mTexObj_l_J_Ohana00_64TEX, GX_TEXMAP0);
|
||||
batch_setup_tev(lightCount <= 2 ? (GX_LIGHT1 | GX_LIGHT2 | GX_LIGHT3 | GX_LIGHT4) :
|
||||
(GX_LIGHT1 | GX_LIGHT2 | GX_LIGHT3 | GX_LIGHT4 |
|
||||
GX_LIGHT5 | GX_LIGHT6 | GX_LIGHT7));
|
||||
GXSetVtxDescv(vtxDescList);
|
||||
GXLoadPosMtxImm(identity, GX_PNMTX0);
|
||||
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
|
||||
|
||||
for (int bucket = 0; bucket < 2; bucket++) {
|
||||
const bool cut = bucket != 0;
|
||||
const dusk::batch::LeafTemplate& tpl = cut ? mTplHana00Cut : mTplHana00;
|
||||
|
||||
bool open = false;
|
||||
u32 emitted = 0;
|
||||
for (dFlower_data_c* flower = first; flower != nullptr; flower = flower->mp_next) {
|
||||
if (cLib_checkBit<u8>(flower->m_state, 4) ||
|
||||
cLib_checkBit<u8>(flower->m_state, 0x40))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if ((cLib_checkBit<u8>(flower->m_state, 8) != 0) != cut) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!open) {
|
||||
GXBegin(GX_TRIANGLES, GX_VTXFMT1, GX_AUTO);
|
||||
open = true;
|
||||
}
|
||||
split_batch(emitted, tpl.vtxCount);
|
||||
|
||||
Mtx interpMtx;
|
||||
MtxP mtx = get_model_mtx(flower->m_modelMtx, interpMtx);
|
||||
transform_positions(tpl, reinterpret_cast<Vec*>(l_flowerPos), mtx, xfPos);
|
||||
flower_emit(tpl, xfPos, hana00_amb_color(flower, tevstr));
|
||||
}
|
||||
if (open) {
|
||||
GXEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// --- hana01 ---
|
||||
GXSETARRAY(GX_VA_POS, mp_pos, sizeof(l_flowerPos2), sizeof(Vec), true);
|
||||
GXSETARRAY(GX_VA_NRM, &l_flowerNormal2, sizeof(l_flowerNormal2), sizeof(Vec), true);
|
||||
GXSETARRAY(GX_VA_CLR0, mp_colors, sizeof(l_flowerColor2), sizeof(GXColor), true);
|
||||
GXSETARRAY(GX_VA_TEX0, mp_texCoords, sizeof(l_flowerTexCoord2), 8, true);
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
dFlower_data_c* first = m_room[i].getData();
|
||||
if (first == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
dKy_tevstr_c* tevstr = dComIfGp_roomControl_getTevStr(i);
|
||||
int lightCount = 6;
|
||||
|
||||
if (dComIfGp_roomControl_getStatusRoomDt(i) != NULL) {
|
||||
lightCount = dComIfGp_roomControl_getStatusRoomDt(i)->getLightVecInfoNum();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (g_kankyoHIO.light.m_HOSTIO_setting != 0) {
|
||||
lightCount = g_kankyoHIO.dungeonLight.usedLights;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dKy_SunMoon_Light_Check() == TRUE && lightCount < 2) {
|
||||
lightCount = 2;
|
||||
}
|
||||
|
||||
if (lightCount <= 2) {
|
||||
GXCallDisplayList(mp_mat2Light4DL, m_mat2Light4DL_size);
|
||||
} else {
|
||||
GXCallDisplayList(mp_mat2DL, m_mat2DL_size);
|
||||
}
|
||||
|
||||
GXSetTevColorS10(GX_TEVREG0, {0, 0, 0, 0});
|
||||
dKy_Global_amb_set(tevstr);
|
||||
dKy_GxFog_tevstr_set(tevstr);
|
||||
dKy_setLight_nowroom_grass(tevstr->room_no, 1.0f);
|
||||
|
||||
GXLoadTexObj(&mTexObj_l_J_Ohana01_64128_0419TEX, GX_TEXMAP0);
|
||||
batch_setup_tev(lightCount <= 2 ? (GX_LIGHT1 | GX_LIGHT2 | GX_LIGHT3 | GX_LIGHT4) :
|
||||
(GX_LIGHT1 | GX_LIGHT2 | GX_LIGHT3 | GX_LIGHT4 |
|
||||
GX_LIGHT5 | GX_LIGHT6 | GX_LIGHT7));
|
||||
GXSetVtxDescv(vtxDescList);
|
||||
GXLoadPosMtxImm(identity, GX_PNMTX0);
|
||||
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
|
||||
|
||||
const dusk::batch::LeafTemplate* const buckets[3] = {
|
||||
&mTplHana01, &mTplHana01Cut00, &mTplHana01Cut};
|
||||
for (int bucket = 0; bucket < 3; bucket++) {
|
||||
const dusk::batch::LeafTemplate& tpl = *buckets[bucket];
|
||||
|
||||
bool open = false;
|
||||
u32 emitted = 0;
|
||||
int idx = 0;
|
||||
for (dFlower_data_c* flower = first; flower != NULL; flower = flower->mp_next, idx++) {
|
||||
if (cLib_checkBit<u8>(flower->m_state, 4) ||
|
||||
!cLib_checkBit<u8>(flower->m_state, 0x40))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const int flowerBucket = cLib_checkBit<u8>(flower->m_state, 8) ? 2 :
|
||||
cLib_checkBit<u8>(flower->m_state, 0x10) ? 1 :
|
||||
0;
|
||||
if (flowerBucket != bucket) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!open) {
|
||||
GXBegin(GX_TRIANGLES, GX_VTXFMT1, GX_AUTO);
|
||||
open = true;
|
||||
}
|
||||
split_batch(emitted, tpl.vtxCount);
|
||||
|
||||
Mtx interpMtx;
|
||||
MtxP mtx = get_model_mtx(flower->m_modelMtx, interpMtx);
|
||||
transform_positions(tpl, mp_pos, mtx, xfPos);
|
||||
flower_emit(tpl, xfPos, hana01_amb_color(idx, tevstr));
|
||||
}
|
||||
if (open) {
|
||||
GXEnd();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
GXSetNumTevStages(1);
|
||||
GXSetNumChans(1);
|
||||
J3DShape::resetVcdVatCache();
|
||||
}
|
||||
#else
|
||||
void dFlower_packet_c::draw() {
|
||||
ZoneScoped;
|
||||
dScnKy_env_light_c* kankyo = dKy_getEnvlight();
|
||||
@@ -886,6 +1263,7 @@ void dFlower_packet_c::draw() {
|
||||
|
||||
J3DShape::resetVcdVatCache();
|
||||
}
|
||||
#endif
|
||||
|
||||
void dFlower_packet_c::calc() {
|
||||
dFlower_anm_c* anm_p = getAnm();
|
||||
|
||||
@@ -512,11 +512,366 @@ dGrass_packet_c::dGrass_packet_c() {
|
||||
m_Mkusa_9q_cDL_size = 0xC0;
|
||||
field_0x1d714 = 0;
|
||||
|
||||
#if TARGET_PC
|
||||
dusk::batch::decode_leaf_template(mp_Mkusa_9q_DL, m_Mkusa_9q_DL_size, mTplKusa9q);
|
||||
dusk::batch::decode_leaf_template(mp_Mkusa_9q_cDL, m_Mkusa_9q_cDL_size, mTplKusa9qCut);
|
||||
dusk::batch::decode_leaf_template(l_M_TenGusaDL, 0xC0, mTplTengusa);
|
||||
#endif
|
||||
|
||||
OS_REPORT("草群メモリ=%fK\n", 117.7734375f);
|
||||
|
||||
m_deleteRoom = &dGrass_packet_c::deleteRoom;
|
||||
}
|
||||
|
||||
#if TARGET_PC
|
||||
static MtxP get_model_mtx(Mtx modelMtx, Mtx storage) {
|
||||
if (dusk::frame_interp::lookup_replacement(modelMtx, storage)) {
|
||||
cMtx_concat(j3dSys.getViewMtx(), storage, storage);
|
||||
return storage;
|
||||
}
|
||||
return modelMtx;
|
||||
}
|
||||
|
||||
static void transform_positions(
|
||||
const dusk::batch::LeafTemplate& tpl, const Vec* posArray, const Mtx mtx, Vec* xfPos) {
|
||||
for (u32 i = 0; i < tpl.posRefCount; i++) {
|
||||
const u8 idx = tpl.posRefs[i];
|
||||
MTXMultVec(mtx, &posArray[idx], &xfPos[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
static void split_batch(u32& emitted, u32 vtxCount) {
|
||||
if (emitted + vtxCount > 0xFFFF) {
|
||||
GXEnd();
|
||||
GXBegin(GX_TRIANGLES, GX_VTXFMT1, GX_AUTO);
|
||||
emitted = 0;
|
||||
}
|
||||
emitted += vtxCount;
|
||||
}
|
||||
|
||||
static GXColor blade_amb_color(const dGrass_data_c* blade, const dKy_tevstr_c* tevstr) {
|
||||
GXColor amb;
|
||||
amb.a = 0;
|
||||
|
||||
#if DEBUG
|
||||
if (g_kankyoHIO.navy.grass_adjust_ON) {
|
||||
amb.r = g_kankyoHIO.navy.grass_ambcol.r * 2;
|
||||
amb.g = g_kankyoHIO.navy.grass_ambcol.g * 2;
|
||||
amb.b = g_kankyoHIO.navy.grass_ambcol.b * 2;
|
||||
return amb;
|
||||
}
|
||||
#endif
|
||||
|
||||
amb.r = (blade->m_addCol & 0x1F) * 2;
|
||||
amb.g = ((blade->m_addCol >> 5) & 0x1F) * 2;
|
||||
amb.b = ((blade->m_addCol >> 0xA) & 0x1F) * 2;
|
||||
|
||||
if (daPy_py_c::checkNowWolfPowerUp()) {
|
||||
f32 ambRate = g_env_light.bg_amb_col[0].r / 255.0f;
|
||||
f32 col = (((blade->m_addCol & 0x1F) * 2 + 0x10));
|
||||
amb.r = col * (ambRate * 4.0f);
|
||||
|
||||
ambRate = g_env_light.bg_amb_col[0].g / 255.0f;
|
||||
f32 col2 = (((blade->m_addCol >> 5) & 0x1F) * 2 + 0x10);
|
||||
amb.g = col2 * (4.0f * ambRate);
|
||||
|
||||
ambRate = g_env_light.bg_amb_col[0].b / 255.0f;
|
||||
f32 col3 = (((blade->m_addCol >> 10) & 0x1F) * 2 + 0x10);
|
||||
amb.b = col3 * (4.0f * ambRate);
|
||||
}
|
||||
|
||||
f32 roomAmbScale = 1.0f - (static_cast<int>(blade->m_pos.x) & 0xFF) * 0.001953125f;
|
||||
f32 colScale = 1.1f - (static_cast<u8>(static_cast<int>(blade->m_pos.x)) & 0xFF) / 2000.0f;
|
||||
colScale -= (static_cast<int>(blade->m_pos.z) & 0xFF) / 2000.0f;
|
||||
|
||||
if (colScale > 1.0f) {
|
||||
colScale = 1.0f;
|
||||
}
|
||||
|
||||
if (amb.r == 0x3E) {
|
||||
amb.r = tevstr->AmbCol.r * roomAmbScale;
|
||||
} else {
|
||||
amb.r = amb.r * colScale;
|
||||
}
|
||||
|
||||
if (amb.g == 0x3E) {
|
||||
amb.g = tevstr->AmbCol.g * roomAmbScale;
|
||||
} else {
|
||||
amb.g = amb.g * colScale;
|
||||
}
|
||||
|
||||
if (amb.b == 0x3E) {
|
||||
amb.b = tevstr->AmbCol.b * roomAmbScale;
|
||||
} else {
|
||||
amb.b = amb.b * colScale;
|
||||
}
|
||||
|
||||
return amb;
|
||||
}
|
||||
|
||||
static void blade_emit(const dusk::batch::LeafTemplate& tpl, const Vec* xformedPos,
|
||||
const GXColor* colors, GXColor amb) {
|
||||
for (u32 i = 0; i < tpl.vtxCount; i++) {
|
||||
const dusk::batch::LeafTemplate::Vtx& v = tpl.vtx[i];
|
||||
const Vec& p = xformedPos[v.pos];
|
||||
GXPosition3f32(p.x, p.y, p.z);
|
||||
GXNormal1x8(v.nrm);
|
||||
GXColor4u8(amb.r, amb.g, amb.b, colors[v.clr].a);
|
||||
GXTexCoord1x8(v.tex);
|
||||
}
|
||||
}
|
||||
|
||||
void dGrass_packet_c::draw() {
|
||||
ZoneScoped;
|
||||
dScnKy_env_light_c* kankyo = dKy_getEnvlight();
|
||||
|
||||
j3dSys.reinitGX();
|
||||
GXSetNumIndStages(0);
|
||||
dKy_setLight_again();
|
||||
GXClearVtxDesc();
|
||||
|
||||
static GXVtxDescList l_vtxDescList[] = {
|
||||
{GX_VA_POS, GX_INDEX8},
|
||||
{GX_VA_NRM, GX_INDEX8},
|
||||
{GX_VA_CLR0, GX_INDEX8},
|
||||
{GX_VA_TEX0, GX_INDEX8},
|
||||
{GX_VA_NULL, GX_NONE},
|
||||
};
|
||||
|
||||
static GXVtxDescList l_batchVtxDescList[] = {
|
||||
{GX_VA_POS, GX_DIRECT},
|
||||
{GX_VA_NRM, GX_INDEX8},
|
||||
{GX_VA_CLR0, GX_DIRECT},
|
||||
{GX_VA_TEX0, GX_INDEX8},
|
||||
{GX_VA_NULL, GX_NONE},
|
||||
};
|
||||
|
||||
GXSetVtxDescv(l_vtxDescList);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_POS, GX_POS_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_NRM, GX_NRM_XYZ, GX_F32, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
||||
GXSetVtxAttrFmt(GX_VTXFMT1, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0);
|
||||
GXSETARRAY(GX_VA_POS, mp_pos, sizeof(l_pos), sizeof(Vec), true);
|
||||
GXSETARRAY(GX_VA_NRM, mp_normal, sizeof(l_normal), sizeof(Vec), true);
|
||||
GXSETARRAY(GX_VA_CLR0, mp_colors, sizeof(l_color), sizeof(GXColor), true);
|
||||
GXSETARRAY(GX_VA_TEX0, mp_texCoords, sizeof(l_texCoord), 8, true);
|
||||
|
||||
GXColorS10 reg1 = {0, 0, 0, 0};
|
||||
|
||||
// daytime "shine" alpha curve (TEVREG1 alpha)
|
||||
f32 daytime = g_env_light.getDaytime();
|
||||
f32 ratio;
|
||||
f32 shine;
|
||||
if (daytime >= 90.0f && daytime < 135.0f) {
|
||||
ratio = 1.0f - (0.022222223f * (135.0f - daytime));
|
||||
shine = 100.0f - (18.0f * ratio);
|
||||
} else if (daytime >= 135.0f && daytime < 225.0f) {
|
||||
ratio = 1.0f - (0.011111111f * (225.0f - daytime));
|
||||
shine = 82.0f - (25.0f * ratio);
|
||||
} else if (daytime >= 225.0f && daytime < 270.0f) {
|
||||
ratio = 1.0f - (0.022222223f * (270.0f - daytime));
|
||||
shine = 57.0f - (-25.0f * ratio);
|
||||
} else if (daytime >= 270.0f && daytime < 315.0f) {
|
||||
ratio = (1.0f - (0.022222223f * (315.0f - daytime)));
|
||||
shine = 82.0f - (-18.0f * ratio);
|
||||
} else {
|
||||
shine = 100.0f;
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (g_kankyoHIO.navy.grass_shine_value != 0.0f) {
|
||||
shine = g_kankyoHIO.navy.grass_shine_value;
|
||||
}
|
||||
#endif
|
||||
|
||||
static Vec xfPos[256];
|
||||
Mtx identity;
|
||||
PSMTXIdentity(identity);
|
||||
|
||||
for (int i = 0; i < 64; i++) {
|
||||
dGrass_data_c* first = m_room[i].getData();
|
||||
if (first == NULL || !dComIfGp_roomControl_checkStatusFlag(i, 0x10)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
int lightCount = 6;
|
||||
dKy_tevstr_c* tevstr = dComIfGp_roomControl_getTevStr(i);
|
||||
|
||||
f32 lightInf = g_env_light.grass_light_inf_rate * g_env_light.bg_light_influence;
|
||||
lightInf += 0.5f * (1.0f - lightInf);
|
||||
|
||||
J3DLightInfo* lightInfo = tevstr->mLights[0].getLightInfo();
|
||||
reg1.r = lightInfo->mColor.r * lightInf;
|
||||
reg1.g = lightInfo->mColor.g * lightInf;
|
||||
reg1.b = lightInfo->mColor.b * lightInf;
|
||||
reg1.a = shine;
|
||||
if (memcmp(dComIfGp_getStartStageName(), "D_MN01", 6) == 0) {
|
||||
reg1.r = 0;
|
||||
reg1.g = 0x1E;
|
||||
reg1.b = 5;
|
||||
reg1.a = 0x50;
|
||||
}
|
||||
GFSetTevColorS10(GX_TEVREG1, reg1);
|
||||
|
||||
if (dComIfGp_roomControl_getStatusRoomDt(i) != nullptr) {
|
||||
lightCount = dComIfGp_roomControl_getStatusRoomDt(i)->getLightVecInfoNum();
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
if (g_kankyoHIO.light.m_HOSTIO_setting != 0) {
|
||||
lightCount = g_kankyoHIO.dungeonLight.usedLights;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dKy_SunMoon_Light_Check() == TRUE && lightCount < 2) {
|
||||
lightCount = 2;
|
||||
}
|
||||
|
||||
for (int j = 0; j < 6; j++) {
|
||||
if (kankyo->field_0x0c18[j].field_0x26 == 1) {
|
||||
lightCount++;
|
||||
}
|
||||
}
|
||||
|
||||
// room-level setup
|
||||
if (first->field_0x05 <= 3 || first->field_0x05 >= 10) {
|
||||
GXLoadTexObj(&mTexObj_l_M_kusa05_RGBATEX, GX_TEXMAP0);
|
||||
if (lightCount <= 3) {
|
||||
GXCallDisplayList(mp_kusa9q_14_DL, m_kusa9q_DL_14_size);
|
||||
} else {
|
||||
GXCallDisplayList(mp_kusa9q_DL, m_kusa9q_DL_size);
|
||||
}
|
||||
} else {
|
||||
GXLoadTexObj(&mTexObj_l_M_Hijiki00TEX, GX_TEXMAP0);
|
||||
GXCallDisplayList(l_Tengusa_matDL, 0xA0);
|
||||
}
|
||||
|
||||
GFSetTevColorS10(GX_TEVREG2, {0, 0, 0, 0});
|
||||
|
||||
dKy_Global_amb_set(tevstr);
|
||||
dKy_GfFog_tevstr_set(tevstr);
|
||||
dKy_setLight_nowroom_grass(tevstr->room_no, 0.0f);
|
||||
|
||||
GXSetVtxDescv(l_batchVtxDescList);
|
||||
GXLoadPosMtxImm(identity, GX_PNMTX0);
|
||||
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
|
||||
|
||||
// buckets: (kusa05 vs tengusa) x (standing vs cut)
|
||||
bool hasRegrowing = false;
|
||||
for (int bucket = 0; bucket < 4; bucket++) {
|
||||
const bool kusaTex = bucket < 2;
|
||||
const bool cut = (bucket & 1) != 0;
|
||||
const dusk::batch::LeafTemplate& tpl =
|
||||
cut ? mTplKusa9qCut : (kusaTex ? mTplKusa9q : mTplTengusa);
|
||||
|
||||
bool open = false;
|
||||
u32 emitted = 0;
|
||||
for (dGrass_data_c* blade = first; blade != NULL; blade = blade->mp_next) {
|
||||
if (cLib_checkBit<u8>(blade->field_0x01, 2)) {
|
||||
continue; // clipped
|
||||
}
|
||||
if (blade->field_0x02 < -1) {
|
||||
hasRegrowing = true;
|
||||
continue;
|
||||
}
|
||||
const bool bladeKusaTex = blade->field_0x05 <= 3 || blade->field_0x05 >= 10;
|
||||
if (bladeKusaTex != kusaTex || (blade->field_0x02 < 0) != cut) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!open) {
|
||||
if (kusaTex) {
|
||||
GXLoadTexObj(&mTexObj_l_M_kusa05_RGBATEX, GX_TEXMAP0);
|
||||
if (lightCount <= 2) {
|
||||
GXCallDisplayList(mp_kusa9q_14_DL, m_kusa9q_DL_14_size);
|
||||
} else {
|
||||
GXCallDisplayList(mp_kusa9q_DL, m_kusa9q_DL_size);
|
||||
}
|
||||
} else {
|
||||
GXLoadTexObj(&mTexObj_l_M_Hijiki00TEX, GX_TEXMAP0);
|
||||
GXCallDisplayList(l_Tengusa_matDL, 0xA0);
|
||||
}
|
||||
// change amb_src to GX_SRC_VTX
|
||||
const u32 lightMask =
|
||||
(kusaTex && lightCount <= 2)
|
||||
? (GX_LIGHT1 | GX_LIGHT2 | GX_LIGHT3 | GX_LIGHT4)
|
||||
: (GX_LIGHT1 | GX_LIGHT2 | GX_LIGHT3 | GX_LIGHT4 | GX_LIGHT5 |
|
||||
GX_LIGHT6 | GX_LIGHT7);
|
||||
GXSetChanCtrl(GX_COLOR0, GX_TRUE, GX_SRC_VTX, GX_SRC_REG, lightMask,
|
||||
GX_DF_CLAMP, GX_AF_SPOT);
|
||||
reg1.a = cut ? 0 : shine;
|
||||
GFSetTevColorS10(GX_TEVREG1, reg1);
|
||||
GXBegin(GX_TRIANGLES, GX_VTXFMT1, GX_AUTO);
|
||||
open = true;
|
||||
}
|
||||
|
||||
split_batch(emitted, tpl.vtxCount);
|
||||
|
||||
Mtx interpMtx;
|
||||
MtxP mtx = get_model_mtx(blade->m_modelMtx, interpMtx);
|
||||
transform_positions(tpl, mp_pos, mtx, xfPos);
|
||||
blade_emit(tpl, xfPos, mp_colors, blade_amb_color(blade, tevstr));
|
||||
}
|
||||
if (open) {
|
||||
GXEnd();
|
||||
}
|
||||
}
|
||||
|
||||
// regrowing blades have per-blade TEVREG2 alpha
|
||||
// draw them with the original immediate path
|
||||
if (hasRegrowing) {
|
||||
GXSetVtxDescv(l_vtxDescList);
|
||||
for (dGrass_data_c* blade = first; blade != NULL; blade = blade->mp_next) {
|
||||
if (blade->field_0x02 >= -1 || cLib_checkBit<u8>(blade->field_0x01, 2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
const bool kusaTex = blade->field_0x05 <= 3 || blade->field_0x05 >= 10;
|
||||
if (kusaTex) {
|
||||
GXLoadTexObj(&mTexObj_l_M_kusa05_RGBATEX, GX_TEXMAP0);
|
||||
if (lightCount <= 2) {
|
||||
GXCallDisplayList(mp_kusa9q_14_DL, m_kusa9q_DL_14_size);
|
||||
} else {
|
||||
GXCallDisplayList(mp_kusa9q_DL, m_kusa9q_DL_size);
|
||||
}
|
||||
} else {
|
||||
GXLoadTexObj(&mTexObj_l_M_Hijiki00TEX, GX_TEXMAP0);
|
||||
GXCallDisplayList(l_Tengusa_matDL, 0xA0);
|
||||
}
|
||||
|
||||
reg1.a = 0;
|
||||
GFSetTevColorS10(GX_TEVREG1, reg1);
|
||||
GXSetChanAmbColor(GX_COLOR0A0, blade_amb_color(blade, tevstr));
|
||||
|
||||
Mtx modelMtx;
|
||||
GXLoadPosMtxImm(get_model_mtx(blade->m_modelMtx, modelMtx), GX_PNMTX0);
|
||||
GXLoadNrmMtxImm(j3dSys.getViewMtx(), 0);
|
||||
|
||||
GFSetTevColorS10(GX_TEVREG2,
|
||||
{0, 0, 0, static_cast<s16>(-0x100 - (blade->field_0x02 << 8) / 40)});
|
||||
|
||||
if (blade->field_0x02 != -2) {
|
||||
if (kusaTex) {
|
||||
GXCallDisplayList(mp_Mkusa_9q_DL, m_Mkusa_9q_DL_size);
|
||||
} else {
|
||||
GXCallDisplayList(l_M_TenGusaDL, 0xC0);
|
||||
}
|
||||
} else {
|
||||
GXCallDisplayList(mp_Mkusa_9q_cDL, m_Mkusa_9q_cDL_size);
|
||||
}
|
||||
|
||||
GFSetTevColorS10(GX_TEVREG2, {0, 0, 0, 0});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
J3DShape::resetVcdVatCache();
|
||||
}
|
||||
#else
|
||||
void dGrass_packet_c::draw() {
|
||||
ZoneScoped;
|
||||
dScnKy_env_light_c* kankyo = dKy_getEnvlight();
|
||||
@@ -811,6 +1166,7 @@ void dGrass_packet_c::draw() {
|
||||
|
||||
J3DShape::resetVcdVatCache();
|
||||
}
|
||||
#endif
|
||||
|
||||
void dGrass_packet_c::calc() {
|
||||
cXyz* temp_r29 = dKyw_get_wind_vec();
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
#include "dusk/batch.hpp"
|
||||
#include "dusk/logging.h"
|
||||
|
||||
#include <aurora/dl.hpp>
|
||||
#include <dolphin/gx/GXEnum.h>
|
||||
|
||||
namespace dusk::batch {
|
||||
|
||||
void decode_leaf_template(const u8* dl, u32 size, LeafTemplate& out) {
|
||||
out.vtxCount = 0;
|
||||
out.posRefCount = 0;
|
||||
bool posSeen[256] = {};
|
||||
|
||||
static constexpr GXVtxDescList kLeafDesc[] = {
|
||||
{GX_VA_POS, GX_INDEX8},
|
||||
{GX_VA_NRM, GX_INDEX8},
|
||||
{GX_VA_CLR0, GX_INDEX8},
|
||||
{GX_VA_TEX0, GX_INDEX8},
|
||||
{GX_VA_NULL, GX_NONE},
|
||||
};
|
||||
|
||||
aurora::gx::dl::Reader reader{dl, size, kLeafDesc};
|
||||
while (const auto cmd = reader.next()) {
|
||||
if (cmd->kind == aurora::gx::dl::Command::Kind::Passthrough) {
|
||||
if (cmd->data[0] != GX_NOP) {
|
||||
DuskLog.fatal("decode_leaf_template: unexpected opcode {:#x}", cmd->data[0]);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
if (cmd->kind != aurora::gx::dl::Command::Kind::Draw) {
|
||||
DuskLog.fatal("decode_leaf_template: unexpected pre-optimized draw");
|
||||
}
|
||||
|
||||
const auto& draw = cmd->draw;
|
||||
bool overflow = false;
|
||||
const bool expanded =
|
||||
aurora::gx::dl::expand_triangles(draw.prim, draw.vtxCount, [&](u16 i0, u16 i1, u16 i2) {
|
||||
if (overflow || out.vtxCount + 3 > LeafTemplate::kMaxVtx) {
|
||||
overflow = true;
|
||||
return;
|
||||
}
|
||||
for (const u16 elem : {i0, i1, i2}) {
|
||||
LeafTemplate::Vtx& v = out.vtx[out.vtxCount++];
|
||||
v.pos = draw.attr_idx(elem, GX_VA_POS);
|
||||
v.nrm = draw.attr_idx(elem, GX_VA_NRM);
|
||||
v.clr = draw.attr_idx(elem, GX_VA_CLR0);
|
||||
v.tex = draw.attr_idx(elem, GX_VA_TEX0);
|
||||
if (!posSeen[v.pos]) {
|
||||
posSeen[v.pos] = true;
|
||||
if (out.posRefCount >= LeafTemplate::kMaxPosRefs) {
|
||||
overflow = true;
|
||||
return;
|
||||
}
|
||||
out.posRefs[out.posRefCount++] = v.pos;
|
||||
}
|
||||
}
|
||||
});
|
||||
if (!expanded) {
|
||||
DuskLog.fatal("decode_leaf_template: untriangulable draw (prim {:#x}, {} verts)",
|
||||
static_cast<u32>(draw.prim), draw.vtxCount);
|
||||
}
|
||||
if (overflow) {
|
||||
DuskLog.fatal("decode_leaf_template: template overflow ({} verts, {} positions)",
|
||||
out.vtxCount, out.posRefCount);
|
||||
}
|
||||
}
|
||||
if (reader.failed()) {
|
||||
DuskLog.fatal("decode_leaf_template: failed to walk display list");
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace dusk::batch
|
||||
@@ -0,0 +1,25 @@
|
||||
#pragma once
|
||||
|
||||
#include <dolphin/types.h>
|
||||
|
||||
namespace dusk::batch {
|
||||
|
||||
struct LeafTemplate {
|
||||
static constexpr u32 kMaxVtx = 192;
|
||||
static constexpr u32 kMaxPosRefs = 64;
|
||||
|
||||
struct Vtx {
|
||||
u8 pos;
|
||||
u8 nrm;
|
||||
u8 clr;
|
||||
u8 tex;
|
||||
};
|
||||
Vtx vtx[kMaxVtx];
|
||||
u16 vtxCount = 0;
|
||||
u8 posRefs[kMaxPosRefs];
|
||||
u8 posRefCount = 0;
|
||||
};
|
||||
|
||||
void decode_leaf_template(const u8* dl, u32 size, LeafTemplate& out);
|
||||
|
||||
} // namespace dusk
|
||||
Reference in New Issue
Block a user