@@ -46,60 +46,32 @@ void GPU::reset() {
4646 gp0_e6._reg = 0 ;
4747}
4848
49- void GPU::drawPolygon (int16_t x[4 ], int16_t y[4 ], RGB c[4 ], TextureInfo t, bool isQuad, bool textured, int flags) {
50- int baseX = 0 , baseY = 0 , clutX = 0 , clutY = 0 , bitcount = 0 ;
51-
52- for (int i = 0 ; i < (isQuad ? 4 : 3 ); i++) {
53- x[i] += drawingOffsetX;
54- y[i] += drawingOffsetY;
55- }
56-
57- if (textured) {
58- clutX = t.getClutX ();
59- clutY = t.getClutY ();
60- baseX = t.getBaseX ();
61- baseY = t.getBaseY ();
62- bitcount = t.getBitcount ();
63- flags |= ((int )t.semiTransparencyBlending ()) << 5 ;
64- } else {
65- flags |= ((int )gp0_e1.semiTransparency ) << 5 ;
49+ void GPU::drawTriangle (const primitive::Triangle& triangle) {
50+ if (hardwareRendering) {
51+ int flags = 0 ;
52+ if (triangle.isSemiTransparent ) flags |= Vertex::Flags::SemiTransparency;
53+ if (triangle.isRawTexture ) flags |= Vertex::Flags::RawTexture;
54+ if (gp0_e1.dither24to15 ) flags |= Vertex::Flags::Dithering;
55+ if (triangle.gouroudShading ) flags |= Vertex::Flags::GouroudShading;
56+ flags |= static_cast <int >(triangle.transparency ) << 5 ;
57+
58+ for (int i : {0 , 1 , 2 }) {
59+ auto & v = triangle.v [i];
60+ vertices.push_back ({Vertex::Type::Polygon,
61+ {v.pos .x + drawingOffsetX, v.pos .y + drawingOffsetY},
62+ {v.color .r , v.color .g , v.color .b },
63+ {v.uv .x , v.uv .y },
64+ triangle.bits ,
65+ {triangle.clut .x , triangle.clut .y },
66+ {triangle.texpage .x , triangle.texpage .y },
67+ flags,
68+ gp0_e2,
69+ gp0_e6});
70+ }
6671 }
6772
68- Vertex v[3 ];
69- for (int i : {0 , 1 , 2 }) {
70- v[i] = {Vertex::Type::Polygon,
71- {x[i], y[i]},
72- {c[i].r , c[i].g , c[i].b },
73- {t.uv [i].x , t.uv [i].y },
74- bitcount,
75- {clutX, clutY},
76- {baseX, baseY},
77- flags,
78- gp0_e2,
79- gp0_e6};
80- vertices.push_back (v[i]);
81- }
8273 if (softwareRendering) {
83- Render::drawTriangle (this , v);
84- }
85-
86- if (isQuad) {
87- for (int i : {1 , 2 , 3 }) {
88- v[i - 1 ] = {Vertex::Type::Polygon,
89- {x[i], y[i]},
90- {c[i].r , c[i].g , c[i].b },
91- {t.uv [i].x , t.uv [i].y },
92- bitcount,
93- {clutX, clutY},
94- {baseX, baseY},
95- flags,
96- gp0_e2,
97- gp0_e6};
98- vertices.push_back (v[i - 1 ]);
99- }
100- if (softwareRendering) {
101- Render::drawTriangle (this , v);
102- }
74+ Render::drawTriangle (this , triangle);
10375 }
10476}
10577
@@ -241,29 +213,53 @@ void GPU::cmdFillRectangle(uint8_t command) {
241213
242214void GPU::cmdPolygon (PolygonArgs arg) {
243215 int ptr = 1 ;
244- int16_t x[ 4 ], y[ 4 ];
245- RGB c [4 ] = {} ;
216+
217+ primitive::Triangle::Vertex v [4 ];
246218 TextureInfo tex;
219+
247220 for (int i = 0 ; i < arg.getVertexCount (); i++) {
248- x [i] = extend_sign<10 >(arguments[ptr] & 0xffff );
249- y [i] = extend_sign<10 >((arguments[ptr++] & 0xffff0000 ) >> 16 );
221+ v [i]. pos . x = extend_sign<10 >(arguments[ptr] & 0xffff );
222+ v [i]. pos . y = extend_sign<10 >((arguments[ptr++] & 0xffff0000 ) >> 16 );
250223
251- if (!arg.isRawTexture && (!arg.gouroudShading || i == 0 )) c [i].raw = arguments[0 ] & 0xffffff ;
224+ if (!arg.isRawTexture && (!arg.gouroudShading || i == 0 )) v [i]. color .raw = arguments[0 ] & 0xffffff ;
252225 if (arg.isTextureMapped ) {
253226 if (i == 0 ) tex.palette = arguments[ptr];
254227 if (i == 1 ) tex.texpage = arguments[ptr];
255- tex. uv [i].x = arguments[ptr] & 0xff ;
256- tex. uv [i].y = (arguments[ptr] >> 8 ) & 0xff ;
228+ v [i]. uv .x = arguments[ptr] & 0xff ;
229+ v [i]. uv .y = (arguments[ptr] >> 8 ) & 0xff ;
257230 ptr++;
258231 }
259- if (arg.gouroudShading && i < arg.getVertexCount () - 1 ) c[i + 1 ].raw = arguments[ptr++];
232+ if (arg.gouroudShading && i < arg.getVertexCount () - 1 ) v[i + 1 ].color .raw = arguments[ptr++] & 0xffffff ;
233+ }
234+
235+ primitive::Triangle triangle;
236+
237+ for (int i : {0 , 1 , 2 }) triangle.v [i] = v[i];
238+
239+ triangle.bits = 0 ;
240+ triangle.isSemiTransparent = arg.semiTransparency ;
241+ triangle.transparency = gp0_e1.semiTransparency ;
242+ triangle.isRawTexture = arg.isRawTexture ;
243+ triangle.gouroudShading = arg.gouroudShading ;
244+
245+ if (arg.isTextureMapped ) {
246+ triangle.bits = tex.getBitcount ();
247+ triangle.texpage .x = tex.getBaseX ();
248+ triangle.texpage .y = tex.getBaseY ();
249+ triangle.clut .x = tex.getClutX ();
250+ triangle.clut .y = tex.getClutY ();
251+ triangle.transparency = tex.semiTransparencyBlending ();
252+ }
253+
254+ triangle.assureCcw ();
255+ drawTriangle (triangle);
256+
257+ if (arg.isQuad ) {
258+ for (int i : {1 , 2 , 3 }) triangle.v [i - 1 ] = v[i];
259+
260+ triangle.assureCcw ();
261+ drawTriangle (triangle);
260262 }
261- int flags = 0 ;
262- if (arg.semiTransparency ) flags |= Vertex::SemiTransparency;
263- if (arg.isRawTexture ) flags |= Vertex::RawTexture;
264- if (arg.gouroudShading ) flags |= Vertex::GouroudShading;
265- if (gp0_e1.dither24to15 ) flags |= Vertex::Dithering;
266- drawPolygon (x, y, c, tex, arg.isQuad , arg.isTextureMapped , flags);
267263
268264 cmd = Command::None;
269265}
0 commit comments