diff --git a/Source/Contents/Effects/EffectPrim.h b/Source/Contents/Effects/EffectPrim.h index 98ff8bd09..45591aef1 100644 --- a/Source/Contents/Effects/EffectPrim.h +++ b/Source/Contents/Effects/EffectPrim.h @@ -3,6 +3,7 @@ #include "Contents/Effects/EffectPrimitiveState.h" #include "Contents/Actors/RenderObject.h" +#include "Utility/Math/AffineMatrix.h" #include @@ -75,6 +76,9 @@ struct CEffectPrim : CRenderObject { void FollowMasterAndTickSlots2(); void ShiftSegment(); void InitSegment(); + void RenderTeiRect(int* rpCnt, short alpha, vector3d vec1, vector3d vec2, vector3d vec3, vector3d vec4, matrix& wtm, short pw, char tn, char f1, unsigned char r, unsigned char g, unsigned char b, float ty1, float ty2, float tx, float tx2, char extra); + void RenderTeiRect(int* rpCnt, int texPart, short alphaB, short alphaT, vector3d vec1, vector3d vec2, vector3d vec3, vector3d vec4, matrix& wtm, char pw); + void RenderTeiRect(int* rpCnt, int texPart, short alphaB, short alphaT, vector3d vec1, vector3d vec2, vector3d vec3, vector3d vec4, matrix& wtm, char pw, unsigned char r, unsigned char g, unsigned char b); /* 0138 */ EffectPrimitiveState state; }; diff --git a/Source/Contents/Effects/EffectPrimitiveMotion.cpp b/Source/Contents/Effects/EffectPrimitiveMotion.cpp index 01c9cfb58..3c9ddd3c8 100644 --- a/Source/Contents/Effects/EffectPrimitiveMotion.cpp +++ b/Source/Contents/Effects/EffectPrimitiveMotion.cpp @@ -16,6 +16,9 @@ #include "Contents/Actors/RenderObjectState.h" #include "Utility/Math/AffineMatrix.h" #include "Utility/Math/ScalarConversion.h" +#include "Render/Renderer.h" +#include "Render/Primitives/RenderPrimitive.h" +#include "Render/Projection/RenderProjection.h" #include #include @@ -4401,3 +4404,19 @@ void CEffectPrim::Tei_TowardScreen(vector3d& vec1, vector3d& vec2, vector3d& vec RotatePairY(vec3, rot0); RotatePairY(vec4, rot0); } + +// OFFSET: 0x00BE7570 +// FUNCTION: fn_19933 +RenderVertex TransformVert(const matrix& view, const vector3d& position) { + RenderVertex vertex; + vertex.x = 0.0f; + vertex.y = 0.0f; + vertex.z = 0.0f; + vertex.rhw = 0.0f; + vertex.diffuse = 0; + vertex.specular = 0xFF000000; + vertex.u = 0.0f; + vertex.v = 0.0f; + g_renderer->viewport.Projection().Project(&position.x, view.values, vertex); + return vertex; +} diff --git a/Source/Contents/Effects/EffectPrimitiveMotion.h b/Source/Contents/Effects/EffectPrimitiveMotion.h index 5dc5967ba..f3e45325c 100644 --- a/Source/Contents/Effects/EffectPrimitiveMotion.h +++ b/Source/Contents/Effects/EffectPrimitiveMotion.h @@ -4,6 +4,9 @@ #include "Contents/Ground/TerrainHeight.h" struct EffectPrimitiveState; +struct RenderVertex; +struct matrix; +struct vector3d; struct RenderObjectState; struct EffectMotionContext { @@ -21,4 +24,6 @@ bool Prim3DCylinderHalf(EffectPrimitiveState& particle, RenderObjectState& rende void AdvanceEffectPrimitive(EffectPrimitiveState& particle, RenderObjectState& render, EffectMotionContext& context); bool UpdateEffectPrimitive15(EffectPrimitiveState& particle, RenderObjectState& render, EffectMotionContext& context, int updateTick); +RenderVertex TransformVert(const matrix& view, const vector3d& position); + #endif diff --git a/Source/Contents/Effects/EffectPrimitiveRendering.cpp b/Source/Contents/Effects/EffectPrimitiveRendering.cpp index 23c60c472..7a3b63609 100644 --- a/Source/Contents/Effects/EffectPrimitiveRendering.cpp +++ b/Source/Contents/Effects/EffectPrimitiveRendering.cpp @@ -5,6 +5,12 @@ #include "Contents/Actors/RenderObjectState.h" #include "Render/Projection/RenderProjection.h" #include "Render/Primitives/RenderQueues.h" +#include "Contents/Effects/EffectPrim.h" +#include "Contents/Effects/EffectPrimitiveMotion.h" +#include "Contents/Effects/RagEffectState.h" +#include "Render/Renderer.h" +#include "Render/TextureQuad.h" +#include "Utility/Math/AffineMatrix.h" // OFFSET: 0x00BCD960 // FUNCTION: fn_19865 @@ -91,3 +97,485 @@ void RenderEffectPrimitive15( DrawEffectPrimitive15(particle, render, context); } } + +// OFFSET: 0x00BE4210 +// FUNCTION: fn_19923 +void CEffectPrim::RenderTeiRect( + int* rpCnt, short alpha, vector3d vec1, vector3d vec2, vector3d vec3, vector3d vec4, matrix& wtm, short pw, char tn, char f1, unsigned char r, + unsigned char g, unsigned char b, float ty1, float ty2, float tx, float tx2, char extra +) { + const RagEffectState& master = this->state.master->state; + const int blend = pw != 0 ? 6 : 2; + int red = r; + if (master.unknown_11C88[0] != -1) { + red = static_cast(master.unknown_11C88[0]); + } + int green = g; + if (master.unknown_11C88[1] != -1) { + green = static_cast(master.unknown_11C88[1]); + } + int blue = b; + if (master.unknown_11C88[2] != -1) { + blue = static_cast(master.unknown_11C88[2]); + } + int destBlend = master.unknown_11C88[3]; + if (destBlend == -1) { + destBlend = blend; + } + + if (*rpCnt >= 510) { + return; + } + + const std::uint32_t color = static_cast(((((alpha << 8) + static_cast(red)) << 8) + static_cast(green)) << 8) + + static_cast(blue); + + if (f1 == 0) { + const vector3d& position = this->render.position; + vec1.x += position.x; + vec1.y += position.y; + vec1.z += position.z; + vec2.x += position.x; + vec2.y += position.y; + vec2.z += position.z; + vec3.x += position.x; + vec3.y += position.y; + vec3.z += position.z; + vec4.x += position.x; + vec4.y += position.y; + vec4.z += position.z; + } + + const vector3d* const corners[2][3] = {{&vec1, &vec2, &vec3}, {&vec4, &vec3, &vec1}}; + const float us[2][3] = {{tx, tx2, tx2}, {tx, tx2, tx}}; + const float vs[2][3] = {{ty2, ty2, ty1}, {ty1, ty1, ty2}}; + + for (int half = 0; half < 2; ++half) { + RenderTriangle& triangle = this->state.triangles[*rpCnt]; + + if (pw == 10) { + triangle.unknown_0064 = 2; + triangle.unknown_0068 = 1; + } else { + triangle.unknown_0064 = 5; + triangle.unknown_0068 = pw == 99 ? 6 : destBlend; + } + + for (int index = 0; index < 3; ++index) { + RenderVertex& vertex = triangle.vertices[index]; + vertex = TransformVert(wtm, *corners[half][index]); + vertex.diffuse = color; + vertex.u = us[half][index]; + vertex.v = vs[half][index]; + } + + triangle.texture = this->state.textures[tn]; + + if (extra == 2) { + for (int index = 0; index < 3; ++index) { + RenderVertex& vertex = triangle.vertices[index]; + vertex.rhw += 0.000045f; + vertex.z = RhwToDepth(vertex.rhw); + } + } else if (extra == 1 || extra == 3) { + if (extra == 3) { + const RenderVertex center = TransformVert(wtm, this->render.position); + const float width = std::fabs(triangle.vertices[0].x - triangle.vertices[1].x) * 0.5f; + triangle.vertices[0].x = center.x + width; + triangle.vertices[1].x = center.x - width; + triangle.vertices[2].x = half == 0 ? center.x - width : center.x + width; + + for (int index = 0; index < 3; ++index) { + triangle.vertices[index].y += static_cast(-30 * g_renderer->viewport.height / 480) * this->render.unknown_005C; + } + } + + for (int index = 0; index < 3; ++index) { + triangle.vertices[index].z = 1e-09f; + triangle.vertices[index].rhw = 1.0f; + } + } + + if (triangle.Visible()) { + g_renderer->queues.SubmitTriangle( + triangle, static_cast(this->state.unknown_01C4), g_renderer->commands, g_renderer->fog.supported != 0, g_depthStart, g_depthEnd + ); + ++*rpCnt; + } + } +} + +// OFFSET: 0x00BE4C60 +// FUNCTION: fn_19924 +void CEffectPrim::RenderTeiRect( + int* rpCnt, int texPart, short alphaB, short alphaT, vector3d vec1, vector3d vec2, vector3d vec3, vector3d vec4, matrix& wtm, char pw +) { + if (*rpCnt >= 510) { + return; + } + + int alpha = alphaB; + int blend = 2; + int red = 255; + int green = 255; + int blue = 255; + float textureV = 1.0f; + + switch (static_cast(this->state.scale)) { + case 0: + blend = 6; + break; + case 1: + green = 175; + blue = 175; + break; + case 2: + red = 195; + green = 195; + blend = 6; + break; + case 3: + alpha = 80; + blend = 6; + break; + case 4: + red = 100; + green = 100; + break; + case 6: + green = 100; + blue = 100; + break; + case 7: + red = 100; + blue = 100; + break; + case 8: + blue = 170; + break; + case 9: + red = 140; + green = 210; + blue = 140; + break; + case 10: + green = 89; + blue = 182; + break; + case 11: + red = 170; + green = 170; + break; + case 12: + red = 50; + green = 50; + blue = 50; + blend = 6; + break; + case 13: + green = 50; + blend = 6; + break; + case 14: + red = 120; + green = 120; + blend = 6; + break; + case 15: + red = 10; + blue = 10; + break; + case 16: + red = 20; + blue = 20; + break; + case 17: + red = 0; + green = 0; + break; + case 18: + green = 0; + blue = 0; + break; + case 19: + red = 0; + blue = 0; + break; + case 20: + blue = 0; + break; + case 21: + green = 0; + break; + case 22: + red = 0; + break; + case 23: + red = 41; + green = 94; + blue = 188; + blend = 6; + break; + case 24: + red = 10; + green = 66; + blue = 114; + break; + case 25: + red = 35; + green = 146; + blue = 185; + break; + case 26: + red = 164; + green = 205; + blue = 254; + break; + case 27: + red = 84; + green = 169; + blue = 205; + break; + case 28: + red = 108; + green = 26; + break; + case 29: + red = 177; + blue = 58; + break; + case 30: + red = 85; + green = 30; + blue = 185; + break; + case 31: + red = 244; + green = 187; + blue = 124; + break; + case 32: + red = 0; + green = 0; + blue = 0; + blend = 6; + break; + case 40: + red = 70; + green = 70; + break; + case 41: + red = 30; + green = 30; + break; + case 42: + red = 43; + green = 40; + blue = 46; + blend = 6; + break; + case 43: + red = 125; + green = 182; + blue = 160; + blend = 6; + break; + case 44: + red = 180; + green = 55; + blue = 30; + blend = 6; + break; + case 45: + red = 65; + green = 141; + blue = 231; + break; + case 46: + red = 164; + green = 47; + blue = 29; + break; + case 47: + red = 172; + green = 154; + blue = 56; + break; + case 48: + red = 80; + green = 20; + blue = 20; + break; + case 49: + red = 200; + green = 130; + blue = 84; + break; + case 50: + green = 198; + blue = 91; + break; + case 100: + red = 250; + green = 250; + textureV = 0.9f; + blend = 6; + break; + default: + break; + } + + const RagEffectState& master = this->state.master->state; + if (master.unknown_11C88[3] != -1) { + blend = master.unknown_11C88[3]; + } + if (master.unknown_11C88[0] != -1) { + red = master.unknown_11C88[0]; + } + if (master.unknown_11C88[1] != -1) { + green = master.unknown_11C88[1]; + } + if (master.unknown_11C88[2] != -1) { + blue = master.unknown_11C88[2]; + } + const std::uint32_t color = static_cast(((((alpha << 8) + red) << 8) + green) << 8) + blue; + + float left; + float right; + if (texPart < 100) { + left = static_cast(texPart) / 21.0f; + if (texPart == 0) { + left = 0.0f; + } + right = static_cast(texPart + 1) / 21.0f; + } else if (texPart == 100) { + left = 0.35f; + right = 0.45f; + } else if (texPart == 101) { + left = 0.45f; + right = 0.55f; + } else { + left = 0.55f; + right = 0.65f; + } + + const vector3d& position = this->render.position; + vec1.x += position.x; + vec1.y += position.y; + vec1.z += position.z; + vec2.x += position.x; + vec2.y += position.y; + vec2.z += position.z; + vec3.x += position.x; + vec3.y += position.y; + vec3.z += position.z; + vec4.x += position.x; + vec4.y += position.y; + vec4.z += position.z; + + const vector3d* const corners[2][3] = {{&vec1, &vec2, &vec3}, {&vec4, &vec3, &vec1}}; + const float us[2][3] = {{left, right, right}, {left, right, left}}; + const float vs[2][3] = {{textureV, textureV, 0.0f}, {0.0f, 0.0f, textureV}}; + + for (int half = 0; half < 2; ++half) { + RenderTriangle& triangle = this->state.triangles[*rpCnt]; + triangle.unknown_0064 = 5; + triangle.unknown_0068 = blend; + + for (int index = 0; index < 3; ++index) { + RenderVertex& vertex = triangle.vertices[index]; + vertex = TransformVert(wtm, *corners[half][index]); + vertex.diffuse = color; + vertex.u = us[half][index]; + vertex.v = vs[half][index]; + } + + triangle.texture = this->state.textures[pw]; + + if (triangle.Visible()) { + g_renderer->queues.SubmitTriangle( + triangle, static_cast(this->state.unknown_01C4), g_renderer->commands, g_renderer->fog.supported != 0, g_depthStart, g_depthEnd + ); + ++*rpCnt; + } + } +} + +// OFFSET: 0x00BE5640 +// FUNCTION: fn_19925 +void CEffectPrim::RenderTeiRect( + int* rpCnt, int texPart, short alphaB, short alphaT, vector3d vec1, vector3d vec2, vector3d vec3, vector3d vec4, matrix& wtm, char pw, unsigned char r, + unsigned char g, unsigned char b +) { + const RagEffectState& master = this->state.master->state; + const int blend = pw != 0 ? 6 : 2; + int red = r; + if (master.unknown_11C88[0] != -1) { + red = static_cast(master.unknown_11C88[0]); + } + int green = g; + if (master.unknown_11C88[1] != -1) { + green = static_cast(master.unknown_11C88[1]); + } + int blue = b; + if (master.unknown_11C88[2] != -1) { + blue = static_cast(master.unknown_11C88[2]); + } + int destBlend = master.unknown_11C88[3]; + if (destBlend == -1) { + destBlend = blend; + } + + if (*rpCnt >= 510) { + return; + } + + const std::uint32_t color = static_cast(((((alphaB << 8) + static_cast(red)) << 8) + static_cast(green)) << 8) + + static_cast(blue); + float top = static_cast(texPart) / 21.0f; + if (texPart == 0) { + top = 0.0f; + } + const float bottom = static_cast(texPart + 1) / 21.0f; + + const vector3d& position = this->render.position; + vec1.x += position.x; + vec1.y += position.y; + vec1.z += position.z; + vec2.x += position.x; + vec2.y += position.y; + vec2.z += position.z; + vec3.x += position.x; + vec3.y += position.y; + vec3.z += position.z; + vec4.x += position.x; + vec4.y += position.y; + vec4.z += position.z; + + const vector3d* const corners[2][3] = {{&vec1, &vec2, &vec3}, {&vec4, &vec3, &vec1}}; + const float us[2][3] = {{1.0f, 1.0f, 0.0f}, {0.0f, 0.0f, 1.0f}}; + const float vs[2][3] = {{top, bottom, bottom}, {top, bottom, top}}; + + for (int half = 0; half < 2; ++half) { + RenderTriangle& triangle = this->state.triangles[*rpCnt]; + triangle.unknown_0064 = 5; + triangle.unknown_0068 = destBlend; + + for (int index = 0; index < 3; ++index) { + RenderVertex& vertex = triangle.vertices[index]; + vertex = TransformVert(wtm, *corners[half][index]); + vertex.diffuse = color; + vertex.u = us[half][index]; + vertex.v = vs[half][index]; + } + + triangle.texture = this->state.textures[0]; + + if (triangle.Visible()) { + g_renderer->queues.SubmitTriangle( + triangle, static_cast(this->state.unknown_01C4), g_renderer->commands, g_renderer->fog.supported != 0, g_depthStart, g_depthEnd + ); + ++*rpCnt; + } + } +}