summaryrefslogtreecommitdiff
path: root/src/m/m3d/m_bline.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/m/m3d/m_bline.cpp')
-rw-r--r--src/m/m3d/m_bline.cpp252
1 files changed, 252 insertions, 0 deletions
diff --git a/src/m/m3d/m_bline.cpp b/src/m/m3d/m_bline.cpp
new file mode 100644
index 00000000..326ae6c1
--- /dev/null
+++ b/src/m/m3d/m_bline.cpp
@@ -0,0 +1,252 @@
+#include <egg/core/eggColorFader.h>
+#include <egg/core/eggHeap.h>
+#include <egg/gfx/eggDrawGX.h>
+#include <m/m3d/m3d.h>
+#include <m/m3d/m_bline.h>
+#include <nw4r/g3d/g3d_light.h>
+#include <nw4r/g3d/g3d_state.h>
+
+namespace m3d {
+
+blineMat_c::~blineMat_c() {
+ remove();
+}
+
+bool blineMat_c::create(mAllocator_c *pAllocator, int numLines, u16 numLinePts, f32 width, f32 repeat,
+ nw4r::ut::Color &color, EGG::ResTIMG *pTex, bool p9) {
+ if (!proc_c::create(pAllocator, nullptr)) {
+ return false;
+ }
+ nw4r::ut::List_Init(&mLines, 0);
+ if (numLines) {
+ mpLineArr = new (pAllocator) bline_c[numLines];
+
+ if (!mpLineArr) {
+ return false;
+ }
+ bline_c *pLineArr = mpLineArr;
+ EGG::Heap *pHeap = pAllocator->mHeap;
+ for (int i = 0; i < numLines; ++i) {
+ if (!pLineArr->create(pHeap, numLinePts, width, repeat, color)) {
+ remove();
+ return false;
+ }
+ nw4r::ut::List_Append(&mLines, pLineArr);
+ pLineArr++;
+ }
+ }
+
+ mLineArrNum = numLines;
+ mpTex = pTex;
+ field_0x4A = p9;
+
+ return true;
+}
+
+void blineMat_c::remove() {
+ if (mpLineArr) {
+ delete[] mpLineArr;
+ mpLineArr = nullptr;
+ }
+ scnLeaf_c::remove();
+}
+
+void blineMat_c::update() {
+ nw4r::math::MTX34 camMtx;
+ mVec3_c vec;
+
+ getCurrentCamera().GetCameraMtx(&camMtx);
+ PSMTXInverse(camMtx, camMtx);
+ PSMTXMultVec(camMtx, mVec3_c::zero, vec);
+
+ for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
+ line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
+ if ((line->mFlags & 1) == 0) {
+ line->update(&vec);
+ }
+ }
+}
+
+bline_c *blineMat_c::getLine(u16 idx) {
+ return (bline_c *)nw4r::ut::List_GetNth(&mLines, idx);
+}
+
+void blineMat_c::setupGX(bool bTransparent) {
+ EGG::DrawGX::LoadTexture(mpTex, GX_TEXMAP0);
+ if (field_0x4A) {
+ u32 mask_diff_color, mask_diff_alpha, mask_spec_color, mask_spec_alpha;
+ nw4r::g3d::AmbLightObj ambObj;
+
+ nw4r::g3d::G3DState::LoadLightSet(0, &mask_diff_color, &mask_diff_alpha, &mask_spec_color, &mask_spec_alpha,
+ &ambObj);
+
+ nw4r::ut::Color ambColor(0xFF, 0xFF, 0xFF, 0xFF);
+ nw4r::ut::Color matColor(0xFF, 0xFF, 0xFF, 0xFF);
+ GXSetChanMatColor(GX_COLOR0, matColor);
+
+ ambColor.r = ambObj.r;
+ ambColor.g = ambObj.g;
+ ambColor.b = ambObj.b;
+ ambColor.a = ambObj.a;
+ GXSetChanAmbColor(GX_COLOR0, ambColor);
+
+ GXSetNumChans(1);
+ GXSetChanCtrl(GX_COLOR0, TRUE, GX_SRC_REG, GX_SRC_REG, (GXLightID)mask_diff_color, GX_DF_CLAMP, GX_AF_NONE);
+ GXSetChanCtrl(GX_ALPHA0, FALSE, GX_SRC_REG, GX_SRC_REG, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
+ GXSetNumTevStages(2);
+ GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
+ GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_RASC, GX_CC_CPREV, GX_CC_ZERO);
+ GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+ GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_APREV);
+ GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+ } else {
+ GXSetNumChans(0);
+ GXSetNumTevStages(1);
+ }
+ GXSetNumTexGens(1);
+ GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_TEXMTX_IDENT, 0, GX_DUALMTX_IDENT);
+ GXSetNumIndStages(0);
+ GXSetTevDirect(GX_TEVSTAGE0);
+ GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
+ GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_C0, GX_CC_TEXC, GX_CC_ZERO);
+ GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+ GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_A0, GX_CA_TEXA, GX_CA_ZERO);
+ GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, TRUE, GX_TEVPREV);
+ GXSetZCompLoc(1);
+ if (!bTransparent) {
+ GXSetBlendMode(GX_BM_NONE, GX_BL_ONE, GX_BL_ONE, GX_LO_SET);
+ GXSetZMode(TRUE, GX_LEQUAL, TRUE);
+ } else {
+ GXSetBlendMode(GX_BM_BLEND, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_SET);
+ GXSetZMode(TRUE, GX_LEQUAL, FALSE);
+ }
+ GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_OR, GX_GREATER, 0);
+ nw4r::ut::Color fogColor = 0x0;
+ GXSetFog(GX_FOG_NONE, fogColor, 0.0f, 0.0f, 0.0f, 0.0f);
+ GXSetFogRangeAdj(FALSE, 0, NULL);
+ GXSetCullMode(GX_CULL_BACK);
+ GXSetDither(1);
+ GXSetClipMode(GX_CLIP_ENABLE);
+ GXClearVtxDesc();
+ GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
+ GXSetVtxDesc(GX_VA_NRM, GX_DIRECT);
+ GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
+ GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGBA, GX_F32, 0);
+ GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_NRM, GX_CLR_RGB, GX_RGB8, 6);
+ GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_F32, 0);
+
+ nw4r::math::MTX34 camMtx;
+ getCurrentCamera().GetCameraMtx(&camMtx);
+ GXLoadPosMtxImm(camMtx, 0);
+ GXLoadNrmMtxImm(camMtx, 0);
+ GXSetCurrentMtx(0);
+}
+
+void blineMat_c::drawOpa() {
+ update();
+ setupGX(false);
+ for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
+ line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
+ if ((line->mFlags & 1) == 0 && line->mColor.a == 0xFF) {
+ line->draw();
+ }
+ }
+}
+
+void blineMat_c::drawXlu() {
+ update();
+ setupGX(true);
+ for (bline_c *line = (bline_c *)nw4r::ut::List_GetNext(&mLines, 0); line != nullptr;
+ line = (bline_c *)nw4r::ut::List_GetNext(&mLines, line)) {
+ if ((line->mFlags & 1) == 0 && line->mColor.a != 0xFF) {
+ line->draw();
+ }
+ }
+}
+
+bline_c::~bline_c() {
+ remove();
+}
+
+bool bline_c::create(EGG::Heap *pHeap, u16 numPts, f32 width, f32 repeat, const nw4r::ut::Color &color) {
+ mpPathArr = new (pHeap) mVec3_c[numPts];
+ if (!mpPathArr) {
+ return false;
+ }
+
+ mpVtxPosArr = new (pHeap) VtxPos[numPts];
+ if (!mpVtxPosArr) {
+ remove();
+ return false;
+ }
+
+ mpVtxNrmArr = new (pHeap) VtxNrm[numPts];
+ if (!mpVtxNrmArr) {
+ remove();
+ return false;
+ }
+
+ mpVtxTexArr = new (pHeap) VtxTex[numPts];
+ if (!mpVtxTexArr) {
+ remove();
+ return false;
+ }
+
+ mPathNum = numPts;
+ mVtxNum = numPts;
+ mWidth = width;
+ mColor = color;
+ mTexRepeat = repeat;
+ field_0x2C = 0;
+
+ return true;
+}
+
+void bline_c::remove() {
+ if (mpPathArr) {
+ delete[] mpPathArr;
+ mpPathArr = nullptr;
+ }
+ if (mpVtxPosArr) {
+ delete[] mpVtxPosArr;
+ mpVtxPosArr = nullptr;
+ }
+ if (mpVtxNrmArr) {
+ delete[] mpVtxNrmArr;
+ mpVtxNrmArr = nullptr;
+ }
+ if (mpVtxTexArr) {
+ delete[] mpVtxTexArr;
+ mpVtxTexArr = nullptr;
+ }
+}
+
+void bline_c::update(mVec3_c *startPos) {}
+
+void bline_c::draw() {
+ GXSetTevColor(GX_TEVREG0, mColor);
+
+ VtxPos *vtxPos = mpVtxPosArr;
+ VtxNrm *vtxNrm = mpVtxNrmArr;
+ VtxTex *vtxTex = mpVtxTexArr;
+
+ GXBegin(GX_TRIANGLESTRIP, GX_VTXFMT0, mVtxNum * 2);
+
+ for (int i = 0; i < mVtxNum; i++) {
+ // First Vtx
+ GXPosition3f32(vtxPos->pos1.x, vtxPos->pos1.y, vtxPos->pos1.z);
+ GXNormal3s8(vtxNrm->nrm1.x, vtxNrm->nrm1.y, vtxNrm->nrm1.z);
+ GXTexCoord2f32(0.0f, vtxTex->tex);
+
+ // Second Vtx
+ GXPosition3f32(vtxPos->pos2.x, vtxPos->pos2.y, vtxPos->pos2.z);
+ GXNormal3s8(vtxNrm->nrm2.x, vtxNrm->nrm2.y, vtxNrm->nrm2.z);
+ GXTexCoord2f32(0.0f, vtxTex->tex);
+
+ vtxPos++;
+ vtxNrm++;
+ vtxTex++;
+ }
+}
+
+} // namespace m3d