|
8 | 8 | #include "Runtime/GameGlobalObjects.hpp" |
9 | 9 | #include "Runtime/World/CWorld.hpp" |
10 | 10 | #include "Runtime/CBasics.hpp" |
| 11 | +#include "Runtime/Graphics/CGX.hpp" |
11 | 12 |
|
12 | 13 | namespace metaforce { |
13 | 14 | constexpr std::array<zeus::CVector3f, 3> MinesPostTransforms{{ |
@@ -101,49 +102,10 @@ void CMapArea::PostConstruct() { |
101 | 102 | tmp += 12; |
102 | 103 | } |
103 | 104 |
|
104 | | - std::vector<u32> index; |
105 | 105 | m_surfaces.reserve(x30_surfaceCount); |
106 | 106 | for (u32 i = 0, j = 0; i < x30_surfaceCount; ++i, j += 32) { |
107 | | - m_surfaces.emplace_back(x40_surfaceStart + j).PostConstruct(x44_buf.get(), index); |
| 107 | + m_surfaces.emplace_back(x40_surfaceStart + j).PostConstruct(x44_buf.get()); |
108 | 108 | } |
109 | | - |
110 | | -// CGraphics::CommitResources([this, &index](boo::IGraphicsDataFactory::Context& ctx) { |
111 | | -// m_vbo = ctx.newStaticBuffer(boo::BufferUse::Vertex, m_verts.data(), 16, m_verts.size()); |
112 | | -// m_ibo = ctx.newStaticBuffer(boo::BufferUse::Index, index.data(), 4, index.size()); |
113 | | -// |
114 | | -// /* Only the map universe specifies Always; it draws a maximum of 1016 instances */ |
115 | | -// size_t instCount = (xc_visibilityMode == EVisMode::Always) ? 1024 : 1; |
116 | | -// |
117 | | -// for (u32 i = 0; i < x30_surfaceCount; ++i) { |
118 | | -// CMapAreaSurface& surf = m_surfaces[i]; |
119 | | -// surf.m_instances.reserve(instCount); |
120 | | -// for (u32 inst = 0; inst < instCount; ++inst) { |
121 | | -// CMapAreaSurface::Instance& instance = surf.m_instances.emplace_back(ctx, m_vbo, m_ibo); |
122 | | -// |
123 | | -// athena::io::MemoryReader r(surf.x1c_outlineOffset, INT_MAX); |
124 | | -// u32 outlineCount = r.ReadLong(); |
125 | | -// |
126 | | -// std::vector<CLineRenderer>& linePrims = instance.m_linePrims; |
127 | | -// linePrims.reserve(outlineCount * 2); |
128 | | -// for (u32 j = 0; j < 2; ++j) { |
129 | | -// r.seek(4, athena::SeekOrigin::Begin); |
130 | | -// for (u32 k = 0; k < outlineCount; ++k) { |
131 | | -// const u32 count = r.ReadLong(); |
132 | | -// r.seek(count); |
133 | | -// r.seekAlign4(); |
134 | | -// linePrims.emplace_back(ctx, CLineRenderer::EPrimitiveMode::LineStrip, count, nullptr, false, false, true); |
135 | | -// } |
136 | | -// } |
137 | | -// } |
138 | | -// } |
139 | | -// |
140 | | -// for (u32 i = 0; i < x28_mappableObjCount; ++i) { |
141 | | -// CMappableObject& mapObj = m_mappableObjects[i]; |
142 | | -// if (CMappableObject::IsDoorType(mapObj.GetType())) |
143 | | -// mapObj.CreateDoorSurface(ctx); |
144 | | -// } |
145 | | -// return true; |
146 | | -// } BooTrace); |
147 | 109 | } |
148 | 110 |
|
149 | 111 | bool CMapArea::GetIsVisibleToAutoMapper(bool worldVis, bool areaVis) const { |
@@ -183,131 +145,89 @@ CMapArea::CMapAreaSurface::CMapAreaSurface(const void* surfBuf) { |
183 | 145 | CMemoryInStream r(surfBuf, 32, CMemoryInStream::EOwnerShip::NotOwned); |
184 | 146 | x0_normal = r.Get<zeus::CVector3f>(); |
185 | 147 | xc_centroid = r.Get<zeus::CVector3f>(); |
186 | | - x18_surfOffset = reinterpret_cast<const u8*>(uintptr_t(r.ReadLong())); |
187 | | - x1c_outlineOffset = reinterpret_cast<const u8*>(uintptr_t(r.ReadLong())); |
| 148 | + x18_surfOffset = reinterpret_cast<const u32*>(static_cast<uintptr_t>(r.ReadLong())); |
| 149 | + x1c_outlineOffset = reinterpret_cast<const u32*>(static_cast<uintptr_t>(r.ReadLong())); |
188 | 150 | } |
189 | 151 |
|
190 | | -void CMapArea::CMapAreaSurface::PostConstruct(const u8* buf, std::vector<u32>& index) { |
191 | | - x18_surfOffset = buf + reinterpret_cast<uintptr_t>(x18_surfOffset); |
192 | | - x1c_outlineOffset = buf + reinterpret_cast<uintptr_t>(x1c_outlineOffset); |
193 | | - |
194 | | - m_primStart = index.size(); |
195 | | - bool start = true; |
196 | | - { |
197 | | - CMemoryInStream r(x18_surfOffset, INT_MAX, CMemoryInStream::EOwnerShip::NotOwned); |
198 | | - u32 primCount = r.ReadLong(); |
199 | | - for (u32 i = 0; i < primCount; ++i) { |
200 | | - GXPrimitive prim = GXPrimitive(r.ReadLong()); |
201 | | - u32 count = r.ReadLong(); |
202 | | - switch (prim) { |
203 | | - case GX_TRIANGLES: { |
204 | | - for (u32 v = 0; v < count; v += 3) { |
205 | | - if (!start) { |
206 | | - index.push_back(index.back()); |
207 | | - index.push_back(r.ReadUint8()); |
208 | | - index.push_back(index.back()); |
209 | | - } else { |
210 | | - index.push_back(r.ReadUint8()); |
211 | | - start = false; |
212 | | - } |
213 | | - index.push_back(r.ReadUint8()); |
214 | | - index.push_back(r.ReadUint8()); |
215 | | - index.push_back(index.back()); |
216 | | - } |
217 | | - break; |
218 | | - } |
219 | | - case GX_TRIANGLESTRIP: { |
220 | | - if (!start) { |
221 | | - index.push_back(index.back()); |
222 | | - index.push_back(r.ReadUint8()); |
223 | | - index.push_back(index.back()); |
224 | | - } else { |
225 | | - index.push_back(r.ReadUint8()); |
226 | | - start = false; |
227 | | - } |
228 | | - for (u32 v = 1; v < count; ++v) |
229 | | - index.push_back(r.ReadUint8()); |
230 | | - if (count & 1) |
231 | | - index.push_back(index.back()); |
232 | | - break; |
233 | | - } |
234 | | - case GX_TRIANGLEFAN: { |
235 | | - u8 firstVert = r.ReadUint8(); |
236 | | - if (!start) { |
237 | | - index.push_back(index.back()); |
238 | | - index.push_back(r.ReadUint8()); |
239 | | - } else { |
240 | | - index.push_back(r.ReadUint8()); |
241 | | - index.push_back(index.back()); |
242 | | - start = false; |
243 | | - } |
244 | | - for (u32 v = 1; v < count; ++v) { |
245 | | - index.push_back(firstVert); |
246 | | - index.push_back(r.ReadUint8()); |
247 | | - } |
248 | | - break; |
249 | | - } |
250 | | - default: |
251 | | - break; |
252 | | - } |
253 | | - u32 pos = r.GetReadPosition(); |
254 | | - while (r.GetReadPosition() != ROUND_UP_4(pos)) { |
255 | | - r.ReadUint8(); |
256 | | - } |
257 | | - } |
258 | | - } |
259 | | - m_primCount = index.size() - m_primStart; |
| 152 | +void CMapArea::CMapAreaSurface::PostConstruct(const void* buf) { |
| 153 | + x18_surfOffset = |
| 154 | + reinterpret_cast<const u32*>(static_cast<const u8*>(buf) + reinterpret_cast<uintptr_t>(x18_surfOffset)); |
| 155 | + x1c_outlineOffset = |
| 156 | + reinterpret_cast<const u32*>(static_cast<const u8*>(buf) + reinterpret_cast<uintptr_t>(x1c_outlineOffset)); |
260 | 157 | } |
261 | 158 |
|
262 | | -void CMapArea::CMapAreaSurface::Draw(const zeus::CVector3f* verts, const zeus::CColor& surfColor, |
263 | | - const zeus::CColor& lineColor, float lineWidth, size_t instIdx) { |
264 | | - if (instIdx >= m_instances.size()) { |
265 | | - return; |
| 159 | +void CMapArea::CMapAreaSurface::Draw(TConstVectorRef verts, const CColor& surfColor, const CColor& lineColor, |
| 160 | + float lineWidth) const { |
| 161 | + bool hasSurfAlpha = surfColor.a() > 0.0f; |
| 162 | + bool hasLineAlpha = lineColor.a() > 0.0f; |
| 163 | + u32 numSurfaces = CBasics::SwapBytes(*x18_surfOffset); |
| 164 | + u32 numOutlines = CBasics::SwapBytes(*x1c_outlineOffset); |
| 165 | + if (!verts.empty()) { |
| 166 | + CGX::SetArray(GX_VA_POS, verts); |
266 | 167 | } |
267 | | - |
268 | | - Instance& instance = m_instances[instIdx]; |
269 | | - |
270 | | - if (surfColor.a()) { |
271 | | - instance.m_surfacePrims.draw(surfColor, m_primStart, m_primCount); |
| 168 | + if (hasSurfAlpha) { |
| 169 | + CGX::SetTevKColor(GX_KCOLOR0, surfColor); |
| 170 | + const u32* surface = &x18_surfOffset[1]; |
| 171 | + for (u32 i = 0; i < numSurfaces; ++i) { |
| 172 | + GXPrimitive primType = static_cast<GXPrimitive>(CBasics::SwapBytes(*surface++)); |
| 173 | + u32 numVertices = CBasics::SwapBytes(*surface++); |
| 174 | + const u8* data = reinterpret_cast<const u8*>(surface); |
| 175 | + surface += ((numVertices + 3) & ~3) / 4; |
| 176 | + |
| 177 | + CGX::Begin(primType, GX_VTXFMT0, numVertices); |
| 178 | + for (u32 v = 0; v < numVertices; ++v) { |
| 179 | + GXPosition1x8(data[v]); |
| 180 | + } |
| 181 | + CGX::End(); |
| 182 | + } |
272 | 183 | } |
| 184 | + if (hasLineAlpha) { |
| 185 | + bool thickLine = lineWidth > 1.f; |
| 186 | + for (u32 j = 0; j < (thickLine ? 1 : 0) + 1; ++j) { |
| 187 | + const u32* outline = &x1c_outlineOffset[1]; |
273 | 188 |
|
274 | | - if (lineColor.a()) { |
275 | | - bool draw2 = lineWidth > 1.f; |
276 | | - u32 outlineCount = *reinterpret_cast<const u32*>(x1c_outlineOffset); |
277 | | -#if METAFORCE_TARGET_BYTE_ORDER == __ORDER_LITTLE_ENDIAN__ |
278 | | - outlineCount = CBasics::SwapBytes(outlineCount); |
279 | | -#endif |
280 | | - |
281 | | - std::vector<CLineRenderer>& linePrims = instance.m_linePrims; |
282 | | - zeus::CColor color = lineColor; |
283 | | - if (draw2) |
284 | | - color.a() *= 0.5f; |
285 | | - float width = lineWidth; |
| 189 | + if (thickLine) { |
| 190 | + CGraphics::SetLineWidth(lineWidth - j, ERglTexOffset::One); |
| 191 | + } |
| 192 | + CColor clr = lineColor; |
| 193 | + if (thickLine) { |
| 194 | + clr.a() *= 0.5f; |
| 195 | + } |
| 196 | + CGX::SetTevKColor(GX_KCOLOR0, clr); |
286 | 197 |
|
287 | | - auto primIt = linePrims.begin(); |
288 | | - for (u32 j = 0; j <= u32(draw2); ++j) { |
289 | | - CMemoryInStream r(x1c_outlineOffset, INT_MAX, CMemoryInStream::EOwnerShip::NotOwned); |
290 | | - r.ReadLong(); |
291 | | - for (u32 i = 0; i < outlineCount; ++i) { |
292 | | - CLineRenderer& prim = *primIt++; |
293 | | - prim.Reset(); |
294 | | - u32 count = r.ReadLong(); |
295 | | - for (u32 v = 0; v < count; ++v) { |
296 | | - u8 idx = r.ReadUint8(); |
297 | | - prim.AddVertex(verts[idx], color, width); |
298 | | - } |
| 198 | + for (u32 i = 0; i < numOutlines; ++i) { |
| 199 | + u32 numVertices = CBasics::SwapBytes(*outline++); |
| 200 | + const u8* data = reinterpret_cast<const u8*>(outline); |
| 201 | + outline += ((numVertices + 3) & ~3) / 4; |
299 | 202 |
|
300 | | - u32 pos = r.GetReadPosition(); |
301 | | - while (r.GetReadPosition() != ROUND_UP_4(pos)) { |
302 | | - r.ReadUint8(); |
| 203 | + CGX::Begin(GX_LINESTRIP, GX_VTXFMT0, numVertices); |
| 204 | + for (u32 v = 0; v < numVertices; ++v) { |
| 205 | + GXPosition1x8(data[v]); |
303 | 206 | } |
304 | | - prim.Render(); |
| 207 | + CGX::End(); |
305 | 208 | } |
306 | | - width -= 1.f; |
307 | 209 | } |
308 | 210 | } |
309 | 211 | } |
310 | 212 |
|
| 213 | +void CMapArea::CMapAreaSurface::SetupGXMaterial() { |
| 214 | + const GXVtxDescList list[2] = { |
| 215 | + {GX_VA_POS, GX_INDEX8}, |
| 216 | + {GX_VA_NULL, GX_NONE}, |
| 217 | + }; |
| 218 | + CGX::SetVtxDescv(list); |
| 219 | + CGX::SetNumChans(1); |
| 220 | + CGX::SetNumTexGens(0); |
| 221 | + CGX::SetNumTevStages(1); |
| 222 | + CGX::SetChanCtrl(CGX::EChannelId::Channel0, false, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE); |
| 223 | + CGX::SetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_KONST); |
| 224 | + CGX::SetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); |
| 225 | + CGX::SetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); |
| 226 | + CGX::SetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, true, GX_TEVPREV); |
| 227 | + CGX::SetTevKColorSel(GX_TEVSTAGE0, GX_TEV_KCSEL_K0); |
| 228 | + CGX::SetTevKAlphaSel(GX_TEVSTAGE0, GX_TEV_KASEL_K0_A); |
| 229 | +} |
| 230 | + |
311 | 231 | CFactoryFnReturn FMapAreaFactory(const SObjectTag& objTag, CInputStream& in, const CVParamTransfer&, |
312 | 232 | CObjectReference*) { |
313 | 233 | u32 size = g_ResFactory->ResourceSize(objTag); |
|
0 commit comments