mirror of https://github.com/PCSX2/pcsx2.git
1505 lines
37 KiB
C
1505 lines
37 KiB
C
/* GSsoft
|
|
* Copyright (C) 2002-2005 GSsoft Team
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; either version 2 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* This program is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program; if not, write to the Free Software
|
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
*/
|
|
|
|
#include <math.h>
|
|
|
|
#include "GS.h"
|
|
#include "Soft.h"
|
|
#include "Texts.h"
|
|
#include "Color.h"
|
|
#include "Mem.h"
|
|
|
|
#undef ABS
|
|
#define ABS(a) (((a)<0) ? -(a) : (a))
|
|
|
|
__inline int shl10idiv(int x, int y) {
|
|
s64 bi = x;
|
|
bi <<= 10;
|
|
return (int)(bi / y);
|
|
}
|
|
|
|
__inline s64 shl10idiv64(s64 x, s64 y) {
|
|
s64 bi = x;
|
|
bi <<= 10;
|
|
return (s64)(bi / y);
|
|
}
|
|
|
|
//
|
|
|
|
void drawLineF(Vertex * v) {
|
|
int dx = v[1].x - v[0].x;
|
|
int dy = v[1].y - v[0].y;
|
|
int ax = ABS(dx) << 1;
|
|
int ay = ABS(dy) << 1;
|
|
int sx = (dx >= 0) ? 1 : -1;
|
|
int sy = (dy >= 0) ? 1 : -1;
|
|
int x = v[0].x;
|
|
int y = v[0].y;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawLineF %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, gs.rgba);
|
|
#endif
|
|
|
|
SETdrawPixel();
|
|
|
|
if (ax > ay) {
|
|
int d = ay - (ax >> 1);
|
|
while (x != v[1].x) {
|
|
drawPixel(x, y, gs.rgba);
|
|
|
|
if (d > 0 || (d == 0 && sx == 1)) {
|
|
y += sy;
|
|
d -= ax;
|
|
}
|
|
x += sx;
|
|
d += ay;
|
|
}
|
|
} else {
|
|
int d = ax - (ay >> 1);
|
|
while (y != v[1].y) {
|
|
drawPixel(x, y, gs.rgba);
|
|
|
|
if (d > 0 || (d == 0 && sy == 1)) {
|
|
x += sx;
|
|
d -= ay;
|
|
}
|
|
y += sy;
|
|
d += ax;
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawLineF_F(Vertex * v) {
|
|
int dx = v[1].x - v[0].x;
|
|
int dy = v[1].y - v[0].y;
|
|
int ax = ABS(dx) << 1;
|
|
int ay = ABS(dy) << 1;
|
|
int sx = (dx >= 0) ? 1 : -1;
|
|
int sy = (dy >= 0) ? 1 : -1;
|
|
int x = v[0].x;
|
|
int y = v[0].y;
|
|
u32 f0, f1;
|
|
int df;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawLineF_F %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, gs.rgba);
|
|
#endif
|
|
|
|
SETdrawPixelF();
|
|
|
|
f0 = v[0].f << 16;
|
|
f1 = v[1].f << 16;
|
|
|
|
if (ax > ay) {
|
|
int d = ay - (ax >> 1);
|
|
df = (f1 - f0) / dx;
|
|
while (x != v[1].x) {
|
|
drawPixelF(x, y, gs.rgba, f0 >> 16);
|
|
|
|
if (d > 0 || (d == 0 && sx == 1)) {
|
|
y += sy; d -= ax;
|
|
}
|
|
x += sx; d += ay;
|
|
f0+= df;
|
|
}
|
|
} else {
|
|
int d = ax - (ay >> 1);
|
|
df = (f1 - f0) / dy;
|
|
while (y != v[1].y) {
|
|
drawPixelF(x, y, gs.rgba, f0 >> 16);
|
|
|
|
if (d > 0 || (d == 0 && sy == 1)) {
|
|
x += sx; d -= ay;
|
|
}
|
|
y += sy; d += ax;
|
|
f0+= df;
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawLineF_Z(Vertex * v) {
|
|
int dx = v[1].x - v[0].x;
|
|
int dy = v[1].y - v[0].y;
|
|
int ax = ABS(dx) << 1;
|
|
int ay = ABS(dy) << 1;
|
|
int sx = (dx >= 0) ? 1 : -1;
|
|
int sy = (dy >= 0) ? 1 : -1;
|
|
int x = v[0].x;
|
|
int y = v[0].y;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawLineF_Z %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, gs.rgba);
|
|
#endif
|
|
|
|
SETdrawPixelZ();
|
|
|
|
if (ax > ay) {
|
|
int d = ay - (ax >> 1);
|
|
while (x != v[1].x) {
|
|
drawPixelZ(x, y, gs.rgba, v[1].z);
|
|
|
|
if (d > 0 || (d == 0 && sx == 1)) {
|
|
y += sy; d -= ax;
|
|
}
|
|
x += sx; d += ay;
|
|
}
|
|
} else {
|
|
int d = ax - (ay >> 1);
|
|
while (y != v[1].y) {
|
|
drawPixelZ(x, y, gs.rgba, v[1].z);
|
|
|
|
if (d > 0 || (d == 0 && sy == 1)) {
|
|
x += sx; d -= ay;
|
|
}
|
|
y += sy; d += ax;
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawLineG(Vertex * v) {
|
|
int dx = v[1].x - v[0].x;
|
|
int dy = v[1].y - v[0].y;
|
|
int ax = ABS(dx) << 1;
|
|
int ay = ABS(dy) << 1;
|
|
int sx = (dx >= 0) ? 1 : -1;
|
|
int sy = (dy >= 0) ? 1 : -1;
|
|
int x = v[0].x;
|
|
int y = v[0].y;
|
|
u32 r0, g0, b0, a0;
|
|
u32 r1, g1, b1, a1;
|
|
int dr, dg, db, da;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawLineG %dx%d %x - %dx%d %x\n",
|
|
v[0].x, v[0].y, v[0].rgba, v[1].x, v[1].y, v[1].rgba);
|
|
#endif
|
|
|
|
SETdrawPixel();
|
|
|
|
r0 = (v[0].rgba & 0x00ff0000);
|
|
g0 = (v[0].rgba & 0x0000ff00) << 8;
|
|
b0 = (v[0].rgba & 0x000000ff) << 16;
|
|
a0 = (v[0].rgba & 0xff000000) >> 8;
|
|
r1 = (v[1].rgba & 0x00ff0000);
|
|
g1 = (v[1].rgba & 0x0000ff00) << 8;
|
|
b1 = (v[1].rgba & 0x000000ff) << 16;
|
|
a1 = (v[1].rgba & 0xff000000) >> 8;
|
|
|
|
if (ax > ay) {
|
|
int d = ay - (ax >> 1);
|
|
|
|
if (dx == 0) return;
|
|
dr = ((int)r1 - (int)r0) / dx;
|
|
dg = ((int)g1 - (int)g0) / dx;
|
|
db = ((int)b1 - (int)b0) / dx;
|
|
da = ((int)a1 - (int)a0) / dx;
|
|
|
|
while (x != v[1].x) {
|
|
drawPixel(x, y, ( r0 & 0xff0000) |
|
|
((g0 & 0xff0000) >> 8) |
|
|
((b0 & 0xff0000) >> 16) |
|
|
((a0 & 0xff0000) << 8));
|
|
|
|
if (d > 0 || (d == 0 && sx == 1)) {
|
|
y += sy;
|
|
d -= ax;
|
|
}
|
|
x += sx; d += ay;
|
|
r0+= dr; g0+= dg; b0+= db; a0+= da;
|
|
}
|
|
} else {
|
|
int d = ax - (ay >> 1);
|
|
|
|
if (dy == 0) return;
|
|
dr = ((int)r1 - (int)r0) / dy;
|
|
dg = ((int)g1 - (int)g0) / dy;
|
|
db = ((int)b1 - (int)b0) / dy;
|
|
da = ((int)a1 - (int)a0) / dy;
|
|
|
|
while (y != v[1].y) {
|
|
drawPixel(x, y, ( r0 & 0xff0000) |
|
|
((g0 & 0xff0000) >> 8) |
|
|
((b0 & 0xff0000) >> 16) |
|
|
((a0 & 0xff0000) << 8));
|
|
|
|
if (d > 0 || (d == 0 && sy == 1)) {
|
|
x += sx;
|
|
d -= ay;
|
|
}
|
|
y += sy; d += ax;
|
|
r0+= dr; g0+= dg; b0+= db; a0+= da;
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawLineG_Z(Vertex * v) {
|
|
int dx = v[1].x - v[0].x;
|
|
int dy = v[1].y - v[0].y;
|
|
int ax = ABS(dx) << 1;
|
|
int ay = ABS(dy) << 1;
|
|
int sx = (dx >= 0) ? 1 : -1;
|
|
int sy = (dy >= 0) ? 1 : -1;
|
|
int x = v[0].x;
|
|
int y = v[0].y;
|
|
u32 r0, g0, b0, a0;
|
|
u32 r1, g1, b1, a1;
|
|
int dr, dg, db, da;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawLineG_Z %dx%d %x - %dx%d %x\n",
|
|
v[0].x, v[0].y, v[0].rgba, v[1].x, v[1].y, v[1].rgba);
|
|
#endif
|
|
|
|
SETdrawPixelZ();
|
|
|
|
r0 = (v[0].rgba & 0x00ff0000);
|
|
g0 = (v[0].rgba & 0x0000ff00) << 8;
|
|
b0 = (v[0].rgba & 0x000000ff) << 16;
|
|
a0 = (v[0].rgba & 0xff000000) >> 8;
|
|
r1 = (v[1].rgba & 0x00ff0000);
|
|
g1 = (v[1].rgba & 0x0000ff00) << 8;
|
|
b1 = (v[1].rgba & 0x000000ff) << 16;
|
|
a1 = (v[1].rgba & 0xff000000) >> 8;
|
|
|
|
if (ax > ay) {
|
|
int d = ay - (ax >> 1);
|
|
|
|
if (dx == 0) return;
|
|
dr = ((int)r1 - (int)r0) / dx;
|
|
dg = ((int)g1 - (int)g0) / dx;
|
|
db = ((int)b1 - (int)b0) / dx;
|
|
da = ((int)a1 - (int)a0) / dx;
|
|
|
|
while (x != v[1].x) {
|
|
drawPixelZ(x, y, ( r0 & 0xff0000) |
|
|
((g0 & 0xff0000) >> 8) |
|
|
((b0 & 0xff0000) >> 16) |
|
|
((a0 & 0xff0000) << 8), v[1].z);
|
|
|
|
if (d > 0 || (d == 0 && sx == 1)) {
|
|
y += sy;
|
|
d -= ax;
|
|
}
|
|
x += sx; d += ay;
|
|
r0+= dr; g0+= dg; b0+= db;
|
|
}
|
|
} else {
|
|
int d = ax - (ay >> 1);
|
|
|
|
if (dy == 0) return;
|
|
dr = ((int)r1 - (int)r0) / dy;
|
|
dg = ((int)g1 - (int)g0) / dy;
|
|
db = ((int)b1 - (int)b0) / dy;
|
|
da = ((int)a1 - (int)a0) / dy;
|
|
|
|
while (y != v[1].y) {
|
|
drawPixelZ(x, y, ( r0 & 0xff0000) |
|
|
((g0 & 0xff0000) >> 8) |
|
|
((b0 & 0xff0000) >> 16) |
|
|
((a0 & 0xff0000) << 8), v[1].z);
|
|
|
|
if (d > 0 || (d == 0 && sy == 1)) {
|
|
x += sx;
|
|
d -= ay;
|
|
}
|
|
y += sy; d += ax;
|
|
r0+= dr; g0+= dg; b0+= db;
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
void drawSprite(Vertex * v) {
|
|
int x, y;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSprite %dx%d - %dx%d %lx\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, gs.rgba);
|
|
#endif
|
|
|
|
SETdrawPixel();
|
|
for (y = v[0].y; y < v[1].y; y++)
|
|
for (x = v[0].x; x < v[1].x; x++)
|
|
drawPixel(x, y, gs.rgba);
|
|
}
|
|
|
|
void drawSprite_F(Vertex * v) {
|
|
int x, y;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSprite_F %dx%d - %dx%d %lx\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, gs.rgba);
|
|
#endif
|
|
|
|
SETdrawPixelF();
|
|
for (y = v[0].y; y < v[1].y; y++)
|
|
for (x = v[0].x; x < v[1].x; x++)
|
|
drawPixelF(x, y, gs.rgba, v[1].f);
|
|
}
|
|
|
|
void drawSprite_Z(Vertex * v) {
|
|
int x, y;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSprite_Z %dx%d %lx - %dx%d %lx\n",
|
|
v[0].x, v[0].y, v[0].rgba, v[1].x, v[1].y, v[1].rgba);
|
|
#endif
|
|
|
|
SETdrawPixelZ();
|
|
|
|
for (y = v[0].y; y < v[1].y; y++) {
|
|
for (x = v[0].x; x < v[1].x; x++) {
|
|
drawPixelZ(x, y, gs.rgba, v[1].z);
|
|
}
|
|
}
|
|
}
|
|
|
|
void drawSprite_ZF(Vertex * v) {
|
|
int x, y;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSprite_ZF %dx%d %lx - %dx%d %lx\n",
|
|
v[0].x, v[0].y, v[0].rgba, v[1].x, v[1].y, v[1].rgba);
|
|
#endif
|
|
|
|
SETdrawPixelZF();
|
|
|
|
for (y = v[0].y; y < v[1].y; y++) {
|
|
for (x = v[0].x; x < v[1].x; x++) {
|
|
drawPixelZF(x, y, gs.rgba, v[1].z, v[1].f);
|
|
}
|
|
}
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// TEXTURED SPRITE
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#define _drawSpriteT(ftx) \
|
|
SetTexture(); \
|
|
SETdrawPixel(); \
|
|
\
|
|
if (vx[1].x == vx[0].x) uinc = 0; \
|
|
else uinc = ((vx[1].u - vx[0].u) << 16) / (vx[1].x - vx[0].x); \
|
|
if (vx[1].y == vx[0].y) vinc = 0; \
|
|
else vinc = ((vx[1].v - vx[0].v) << 16) / (vx[1].y - vx[0].y); \
|
|
\
|
|
for (y = vx[0].y, vpos = vx[0].v << 16; y < vx[1].y; y++, vpos+= vinc) { \
|
|
v = vpos >> 16; \
|
|
for (x = vx[0].x, upos = vx[0].u << 16; x < vx[1].x; x++, upos+= uinc) { \
|
|
u = upos >> 16; \
|
|
drawPixel(x, y, ftx); \
|
|
} \
|
|
}
|
|
|
|
void drawSpriteTDecal(Vertex * vx) {
|
|
int x, y;
|
|
int u, v;
|
|
int upos, uinc;
|
|
int vpos, vinc;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSpriteTDecal %dx%d - %dx%d %lx; tex: %dx%d - %dx%d (psm=%x, cbp=%x, csm=%x, cpsm=%x)\n",
|
|
vx[0].x, vx[0].y, vx[1].x, vx[1].y, gs.rgba,
|
|
vx[0].u, vx[0].v, vx[1].u, vx[1].v,
|
|
tex0->psm, tex0->cbp, tex0->csm, tex0->cpsm);
|
|
#endif
|
|
|
|
_drawSpriteT(
|
|
GetTexturePixel32(u, v)
|
|
);
|
|
}
|
|
|
|
void drawSpriteTModulate(Vertex * vx) {
|
|
int x, y;
|
|
int u, v;
|
|
int upos, uinc;
|
|
int vpos, vinc;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSpriteTModulate %dx%d - %dx%d %lx; tex: %dx%d - %dx%d (psm=%x, cbp=%x, csm=%x, cpsm=%x)\n",
|
|
vx[0].x, vx[0].y, vx[1].x, vx[1].y, gs.rgba,
|
|
vx[0].u, vx[0].v, vx[1].u, vx[1].v,
|
|
tex0->psm, tex0->cbp, tex0->csm, tex0->cpsm);
|
|
#endif
|
|
|
|
colSetCol(gs.rgba);
|
|
_drawSpriteT(
|
|
colModulate(GetTexturePixel32(u, v))
|
|
);
|
|
}
|
|
|
|
void drawSpriteTHighlight(Vertex * vx) {
|
|
int x, y;
|
|
int u, v;
|
|
int upos, uinc;
|
|
int vpos, vinc;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSpriteTHighlight %dx%d - %dx%d %lx; tex: %dx%d - %dx%d (psm=%x, cbp=%x, csm=%x, cpsm=%x)\n",
|
|
vx[0].x, vx[0].y, vx[1].x, vx[1].y, gs.rgba,
|
|
vx[0].u, vx[0].v, vx[1].u, vx[1].v,
|
|
tex0->psm, tex0->cbp, tex0->csm, tex0->cpsm);
|
|
#endif
|
|
|
|
colSetCol(gs.rgba);
|
|
_drawSpriteT(
|
|
colHighlight(GetTexturePixel32(u, v))
|
|
);
|
|
}
|
|
|
|
void drawSpriteTHighlight2(Vertex * vx) {
|
|
int x, y;
|
|
int u, v;
|
|
int upos, uinc;
|
|
int vpos, vinc;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSpriteTHighlight2 %dx%d - %dx%d %lx; tex: %dx%d - %dx%d (psm=%x, cbp=%x, csm=%x, cpsm=%x)\n",
|
|
vx[0].x, vx[0].y, vx[1].x, vx[1].y, gs.rgba,
|
|
vx[0].u, vx[0].v, vx[1].u, vx[1].v,
|
|
tex0->psm, tex0->cbp, tex0->csm, tex0->cpsm);
|
|
#endif
|
|
|
|
colSetCol(gs.rgba);
|
|
_drawSpriteT(
|
|
colHighlight2(GetTexturePixel32(u, v))
|
|
);
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
// TEXTURED SPRITE WITH Z-MAPPING
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
#define _drawSpriteT_Z(ftx) \
|
|
SetTexture(); \
|
|
SETdrawPixelZ(); \
|
|
\
|
|
if (vx[1].x == vx[0].x) uinc = 0; \
|
|
else uinc = ((vx[1].u - vx[0].u) << 16) / (vx[1].x - vx[0].x); \
|
|
if (vx[1].y == vx[0].y) vinc = 0; \
|
|
else vinc = ((vx[1].v - vx[0].v) << 16) / (vx[1].y - vx[0].y); \
|
|
\
|
|
for (y = vx[0].y, vpos = vx[0].v << 16; y < vx[1].y; y++, vpos+= vinc) { \
|
|
v = vpos >> 16; \
|
|
for (x = vx[0].x, upos = vx[0].u << 16; x < vx[1].x; x++, upos+= uinc) { \
|
|
u = upos >> 16; \
|
|
drawPixelZ(x, y, ftx, vx[1].z); \
|
|
} \
|
|
}
|
|
|
|
void drawSpriteTDecal_Z(Vertex * vx) {
|
|
int x, y;
|
|
int u, v;
|
|
int upos, uinc;
|
|
int vpos, vinc;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSpriteTDecal_Z %dx%d - %dx%d %lx; tex: %dx%d - %dx%d (psm=%x, cbp=%x, csm=%x, cpsm=%x)\n",
|
|
vx[0].x, vx[0].y, vx[1].x, vx[1].y, gs.rgba,
|
|
vx[0].u, vx[0].v, vx[1].u, vx[1].v,
|
|
tex0->psm, tex0->cbp, tex0->csm, tex0->cpsm);
|
|
#endif
|
|
|
|
_drawSpriteT_Z(
|
|
GetTexturePixel32(u, v)
|
|
);
|
|
}
|
|
|
|
void drawSpriteTModulate_Z(Vertex * vx) {
|
|
int x, y;
|
|
int u, v;
|
|
int upos, uinc;
|
|
int vpos, vinc;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSpriteTModulate_Z %dx%d - %dx%d %lx; tex: %dx%d - %dx%d (psm=%x, tbp0=%x, cbp=%x, csm=%x, cpsm=%x)\n",
|
|
vx[0].x, vx[0].y, vx[1].x, vx[1].y, gs.rgba,
|
|
vx[0].u, vx[0].v, vx[1].u, vx[1].v,
|
|
tex0->psm, tex0->tbp0, tex0->cbp, tex0->csm, tex0->cpsm);
|
|
#endif
|
|
|
|
colSetCol(gs.rgba);
|
|
_drawSpriteT_Z(
|
|
colModulate(GetTexturePixel32(u, v))
|
|
);
|
|
}
|
|
|
|
void drawSpriteTHighlight_Z(Vertex * vx) {
|
|
int x, y;
|
|
int u, v;
|
|
int upos, uinc;
|
|
int vpos, vinc;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSpriteTHighlight_Z %dx%d - %dx%d %lx; tex: %dx%d - %dx%d (psm=%x, cbp=%x, csm=%x, cpsm=%x)\n",
|
|
vx[0].x, vx[0].y, vx[1].x, vx[1].y, gs.rgba,
|
|
vx[0].u, vx[0].v, vx[1].u, vx[1].v,
|
|
tex0->psm, tex0->cbp, tex0->csm, tex0->cpsm);
|
|
#endif
|
|
|
|
colSetCol(gs.rgba);
|
|
_drawSpriteT_Z(
|
|
colHighlight(GetTexturePixel32(u, v))
|
|
);
|
|
}
|
|
|
|
void drawSpriteTHighlight2_Z(Vertex * vx) {
|
|
int x, y;
|
|
int u, v;
|
|
int upos, uinc;
|
|
int vpos, vinc;
|
|
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawSpriteTHighlight2_Z %dx%d - %dx%d %lx; tex: %dx%d - %dx%d (psm=%x, cbp=%x, csm=%x, cpsm=%x)\n",
|
|
vx[0].x, vx[0].y, vx[1].x, vx[1].y, gs.rgba,
|
|
vx[0].u, vx[0].v, vx[1].u, vx[1].v,
|
|
tex0->psm, tex0->cbp, tex0->csm, tex0->cpsm);
|
|
#endif
|
|
|
|
colSetCol(gs.rgba);
|
|
_drawSpriteT_Z(
|
|
colHighlight2(GetTexturePixel32(u, v))
|
|
);
|
|
}
|
|
|
|
|
|
|
|
typedef struct {
|
|
s32 X, U, V;
|
|
s32 R, G, B, A;
|
|
s64 Z;
|
|
} tagPolyEdge;
|
|
|
|
tagPolyEdge ForwardEdges[1024*8];
|
|
tagPolyEdge BackwardEdges[1024*8];
|
|
|
|
#define drawTriangle(scanFunc, drawFunc) { \
|
|
int i; \
|
|
int nYMin, nYMax; \
|
|
int nPosMin, nPosMax; \
|
|
int nPos1, nPos2; \
|
|
int nY; \
|
|
\
|
|
nYMin = v[0].y; \
|
|
nYMax = v[0].y; \
|
|
nPosMin = 0; \
|
|
nPosMax = 0; \
|
|
\
|
|
for (i=1; i<3; i++) { \
|
|
if (v[i].y > nYMax) { \
|
|
nYMax = v[i].y; \
|
|
nPosMax = i; \
|
|
} \
|
|
\
|
|
if (v[i].y < nYMin) { \
|
|
nYMin = v[i].y; \
|
|
nPosMin = i; \
|
|
} \
|
|
} \
|
|
\
|
|
if (nYMax == nYMin) \
|
|
return; \
|
|
\
|
|
nPos1 = nPosMin; \
|
|
nPos2 = nPos1; \
|
|
while (nPos1 != nPosMax) { \
|
|
nPos2 ++; \
|
|
if (nPos2 == 3) \
|
|
nPos2 = 0; \
|
|
\
|
|
scanFunc(ForwardEdges, &v[nPos1], &v[nPos2]); \
|
|
nPos1 = nPos2; \
|
|
} \
|
|
\
|
|
nPos1 = nPosMin; \
|
|
nPos2 = nPos1; \
|
|
while (nPos1 != nPosMax) { \
|
|
nPos2 --; \
|
|
if (nPos2 == -1) \
|
|
nPos2 = 2; \
|
|
\
|
|
scanFunc(BackwardEdges, &v[nPos1], &v[nPos2]); \
|
|
nPos1 = nPos2; \
|
|
} \
|
|
\
|
|
if (nYMin < 0) nYMin = 0; \
|
|
for (nY = nYMin; nY < nYMax; nY++) { \
|
|
if (BackwardEdges[nY].X < ForwardEdges[nY].X) { \
|
|
drawFunc(nY, &BackwardEdges[nY], &ForwardEdges[nY]); \
|
|
} else { \
|
|
drawFunc(nY, &ForwardEdges[nY], &BackwardEdges[nY]); \
|
|
} \
|
|
} \
|
|
}
|
|
|
|
|
|
void scanEdgeF(tagPolyEdge* pastEdge, Vertex *v1, Vertex *v2) {
|
|
int nX, nY;
|
|
int nXInc;
|
|
|
|
if (v1->y == v2->y)
|
|
return;
|
|
|
|
nX = v1->x << 16;
|
|
nXInc = ((v2->x - v1->x) << 16) / (v2->y - v1->y);
|
|
|
|
for (nY = v1->y; nY < 0; nY++) {
|
|
nX += nXInc;
|
|
}
|
|
for (; nY < v2->y; nY++) {
|
|
pastEdge[nY].X = nX >> 16; nX += nXInc;
|
|
}
|
|
}
|
|
|
|
void drawHLineF(int nY, tagPolyEdge *stEdgeIni, tagPolyEdge *stEdgeEnd) {
|
|
int nX;
|
|
|
|
if (stEdgeEnd->X <= stEdgeIni->X) {
|
|
return;
|
|
}
|
|
|
|
for (nX = stEdgeIni->X; nX <= stEdgeEnd->X; nX++) {
|
|
drawPixel(nX, nY, gs.rgba);
|
|
}
|
|
}
|
|
|
|
void drawTriangleF(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleF %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
#endif
|
|
|
|
SETdrawPixel();
|
|
|
|
drawTriangle(scanEdgeF, drawHLineF);
|
|
}
|
|
|
|
void scanEdgeFZ(tagPolyEdge* pastEdge, Vertex *v1, Vertex *v2) {
|
|
s32 nX, nY;
|
|
s32 nXInc;
|
|
s64 nZ;
|
|
s64 nZInc;
|
|
|
|
if (v1->y == v2->y)
|
|
return;
|
|
|
|
nX = v1->x << 16;
|
|
nZ = (u64)v1->z << 16;
|
|
|
|
nXInc = ((v2->x - v1->x) << 16) / (v2->y - v1->y);
|
|
nZInc = ((s64)((s64)v2->z - v1->z) << 16) / (v2->y - v1->y);
|
|
|
|
for (nY = v1->y; nY < 0; nY++) {
|
|
nX += nXInc;
|
|
nZ += nZInc;
|
|
}
|
|
for (; nY < v2->y; nY++) {
|
|
pastEdge[nY].X = nX >> 16; nX += nXInc;
|
|
pastEdge[nY].Z = nZ; nZ += nZInc;
|
|
}
|
|
}
|
|
|
|
void drawHLineFZ(int nY, tagPolyEdge *stEdgeIni, tagPolyEdge *stEdgeEnd) {
|
|
s32 nX;
|
|
s64 nZ;
|
|
s64 nZInc;
|
|
|
|
if (stEdgeEnd->X <= stEdgeIni->X) {
|
|
return;
|
|
}
|
|
|
|
nZ = stEdgeIni->Z;
|
|
nZInc = (s64)((s64)stEdgeEnd->Z - stEdgeIni->Z) / (stEdgeEnd->X - stEdgeIni->X);
|
|
|
|
for (nX = stEdgeIni->X; nX <= stEdgeEnd->X; nX++) {
|
|
drawPixelZ(nX, nY, gs.rgba, (u32)(nZ >> 16));
|
|
nZ += nZInc;
|
|
}
|
|
}
|
|
|
|
void drawTriangleF_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleF_Z %dx%dx%lx - %dx%dx%lx - %dx%dx%lx rgba=%x\n",
|
|
v[0].x, v[0].y, v[0].z, v[1].x, v[1].y, v[1].z, v[2].x, v[2].y, v[2].z, gs.rgba);
|
|
#endif
|
|
|
|
SETdrawPixelZ();
|
|
|
|
drawTriangle(scanEdgeFZ, drawHLineFZ);
|
|
}
|
|
|
|
|
|
void scanEdgeG(tagPolyEdge* pastEdge, Vertex *v1, Vertex *v2) {
|
|
s32 nX, nY, nR, nG, nB, nA;
|
|
s32 nXInc, nRInc, nGInc, nBInc, nAInc;
|
|
s32 r1, g1, b1, a1;
|
|
s32 r2, g2, b2, a2;
|
|
|
|
if (v1->y == v2->y)
|
|
return;
|
|
|
|
b1 = (v1->rgba & 0x000000FF);
|
|
g1 = (v1->rgba & 0x0000FF00) >> 8;
|
|
r1 = (v1->rgba & 0x00FF0000) >> 16;
|
|
a1 = (v1->rgba & 0xFF000000) >> 24;
|
|
b2 = (v2->rgba & 0x000000FF);
|
|
g2 = (v2->rgba & 0x0000FF00) >> 8;
|
|
r2 = (v2->rgba & 0x00FF0000) >> 16;
|
|
a2 = (v2->rgba & 0xFF000000) >> 24;
|
|
|
|
nX = v1->x << 16;
|
|
nR = r1 << 16;
|
|
nG = g1 << 16;
|
|
nB = b1 << 16;
|
|
nA = a1 << 16;
|
|
nXInc = ((v2->x - v1->x) << 16) / (v2->y - v1->y);
|
|
nRInc = (( r2 - r1) << 16) / (v2->y - v1->y);
|
|
nGInc = (( g2 - g1) << 16) / (v2->y - v1->y);
|
|
nBInc = (( b2 - b1) << 16) / (v2->y - v1->y);
|
|
nAInc = (( a2 - a1) << 16) / (v2->y - v1->y);
|
|
|
|
for (nY = v1->y; nY < 0; nY++) {
|
|
nX += nXInc;
|
|
nR += nRInc;
|
|
nG += nGInc;
|
|
nB += nBInc;
|
|
nA += nAInc;
|
|
}
|
|
for (; nY < v2->y; nY++) {
|
|
pastEdge[nY].X = nX >> 16; nX += nXInc;
|
|
pastEdge[nY].R = nR; nR += nRInc;
|
|
pastEdge[nY].G = nG; nG += nGInc;
|
|
pastEdge[nY].B = nB; nB += nBInc;
|
|
pastEdge[nY].A = nA; nA += nAInc;
|
|
}
|
|
}
|
|
|
|
void drawHLineG(int nY, tagPolyEdge *stEdgeIni, tagPolyEdge *stEdgeEnd) {
|
|
s32 nX, nR, nG, nB, nA;
|
|
s32 nRInc, nGInc, nBInc, nAInc;
|
|
|
|
if (stEdgeEnd->X <= stEdgeIni->X) {
|
|
return;
|
|
}
|
|
|
|
nR = stEdgeIni->R;
|
|
nG = stEdgeIni->G;
|
|
nB = stEdgeIni->B;
|
|
nA = stEdgeIni->A;
|
|
nRInc = (stEdgeEnd->R - stEdgeIni->R) / (stEdgeEnd->X - stEdgeIni->X);
|
|
nGInc = (stEdgeEnd->G - stEdgeIni->G) / (stEdgeEnd->X - stEdgeIni->X);
|
|
nBInc = (stEdgeEnd->B - stEdgeIni->B) / (stEdgeEnd->X - stEdgeIni->X);
|
|
nAInc = (stEdgeEnd->A - stEdgeIni->A) / (stEdgeEnd->X - stEdgeIni->X);
|
|
|
|
for (nX = stEdgeIni->X; nX <= stEdgeEnd->X; nX++) {
|
|
drawPixel(nX, nY, ( nR & 0xff0000) |
|
|
((nG & 0xff0000) >> 8) |
|
|
((nB & 0xff0000) >> 16) |
|
|
((nA & 0xff0000) << 8));
|
|
nR += nRInc; nG += nGInc; nB += nBInc; nA += nAInc;
|
|
}
|
|
}
|
|
|
|
void drawTriangleG(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleG %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, v[0].rgba);
|
|
#endif
|
|
|
|
SETdrawPixel();
|
|
|
|
drawTriangle(scanEdgeG, drawHLineG);
|
|
}
|
|
|
|
|
|
void scanEdgeGZ(tagPolyEdge* pastEdge, Vertex *v1, Vertex *v2) {
|
|
s32 nX, nY, nR, nG, nB, nA;
|
|
s32 nXInc, nRInc, nGInc, nBInc, nAInc;
|
|
s32 r1, g1, b1, a1;
|
|
s32 r2, g2, b2, a2;
|
|
s64 nZ;
|
|
s64 nZInc;
|
|
|
|
if (v1->y == v2->y)
|
|
return;
|
|
|
|
b1 = (v1->rgba & 0x000000FF);
|
|
g1 = (v1->rgba & 0x0000FF00) >> 8;
|
|
r1 = (v1->rgba & 0x00FF0000) >> 16;
|
|
a1 = (v1->rgba & 0xFF000000) >> 24;
|
|
b2 = (v2->rgba & 0x000000FF);
|
|
g2 = (v2->rgba & 0x0000FF00) >> 8;
|
|
r2 = (v2->rgba & 0x00FF0000) >> 16;
|
|
a2 = (v2->rgba & 0xFF000000) >> 24;
|
|
|
|
nX = v1->x << 16;
|
|
nZ = (u64)v1->z << 16;
|
|
nR = r1 << 16;
|
|
nG = g1 << 16;
|
|
nB = b1 << 16;
|
|
nA = a1 << 16;
|
|
nXInc = ((v2->x - v1->x) << 16) / (v2->y - v1->y);
|
|
nZInc = ((s64)((s64)v2->z - v1->z) << 16) / (v2->y - v1->y);
|
|
nRInc = (( r2 - r1) << 16) / (v2->y - v1->y);
|
|
nGInc = (( g2 - g1) << 16) / (v2->y - v1->y);
|
|
nBInc = (( b2 - b1) << 16) / (v2->y - v1->y);
|
|
nAInc = (( a2 - a1) << 16) / (v2->y - v1->y);
|
|
|
|
for (nY = v1->y; nY < 0; nY++) {
|
|
nX += nXInc;
|
|
nZ += nZInc;
|
|
nR += nRInc;
|
|
nG += nGInc;
|
|
nB += nBInc;
|
|
nA += nAInc;
|
|
}
|
|
for (;nY < v2->y; nY++) {
|
|
pastEdge[nY].X = nX >> 16; nX += nXInc;
|
|
pastEdge[nY].Z = nZ; nZ += nZInc;
|
|
pastEdge[nY].R = nR; nR += nRInc;
|
|
pastEdge[nY].G = nG; nG += nGInc;
|
|
pastEdge[nY].B = nB; nB += nBInc;
|
|
pastEdge[nY].A = nA; nA += nAInc;
|
|
}
|
|
}
|
|
|
|
void drawHLineGZ(int nY, tagPolyEdge *stEdgeIni, tagPolyEdge *stEdgeEnd) {
|
|
s32 nX, nR, nG, nB, nA;
|
|
s32 nRInc, nGInc, nBInc, nAInc;
|
|
s64 nZ;
|
|
s64 nZInc;
|
|
|
|
if (stEdgeEnd->X <= stEdgeIni->X) {
|
|
return;
|
|
}
|
|
|
|
nZ = stEdgeIni->Z;
|
|
nR = stEdgeIni->R;
|
|
nG = stEdgeIni->G;
|
|
nB = stEdgeIni->B;
|
|
nA = stEdgeIni->A;
|
|
nZInc = (s64)((s64)stEdgeEnd->Z - stEdgeIni->Z) / (stEdgeEnd->X - stEdgeIni->X);
|
|
nRInc = (stEdgeEnd->R - stEdgeIni->R) / (stEdgeEnd->X - stEdgeIni->X);
|
|
nGInc = (stEdgeEnd->G - stEdgeIni->G) / (stEdgeEnd->X - stEdgeIni->X);
|
|
nBInc = (stEdgeEnd->B - stEdgeIni->B) / (stEdgeEnd->X - stEdgeIni->X);
|
|
nAInc = (stEdgeEnd->A - stEdgeIni->A) / (stEdgeEnd->X - stEdgeIni->X);
|
|
|
|
for (nX = stEdgeIni->X; nX <= stEdgeEnd->X; nX++) {
|
|
drawPixelZ(nX, nY, ( nR & 0xff0000) |
|
|
((nG & 0xff0000) >> 8) |
|
|
((nB & 0xff0000) >> 16) |
|
|
((nA & 0xff0000) << 8), (u32)(nZ >> 16));
|
|
nZ += nZInc;
|
|
nR += nRInc; nG += nGInc; nB += nBInc; nA += nAInc;
|
|
}
|
|
}
|
|
|
|
void drawTriangleG_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleG_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, v[0].rgba);
|
|
#endif
|
|
|
|
SETdrawPixelZ();
|
|
|
|
drawTriangle(scanEdgeGZ, drawHLineGZ);
|
|
}
|
|
|
|
|
|
void scanEdgeFT(tagPolyEdge* pastEdge, Vertex *v1, Vertex *v2) {
|
|
int nX, nY, nU, nV;
|
|
int nXInc, nUInc, nVInc;
|
|
|
|
if (v1->y == v2->y)
|
|
return;
|
|
|
|
nX = v1->x << 16;
|
|
nU = v1->u << 16;
|
|
nV = v1->v << 16;
|
|
|
|
nXInc = ((v2->x - v1->x) << 16) / (v2->y - v1->y);
|
|
nUInc = ((v2->u - v1->u) << 16) / (v2->y - v1->y);
|
|
nVInc = ((v2->v - v1->v) << 16) / (v2->y - v1->y);
|
|
|
|
for (nY = v1->y; nY < 0; nY++) {
|
|
nX += nXInc;
|
|
nU += nUInc;
|
|
nV += nVInc;
|
|
}
|
|
for (; nY < v2->y; nY++) {
|
|
pastEdge[nY].X = nX >> 16; nX += nXInc;
|
|
pastEdge[nY].U = nU; nU += nUInc;
|
|
pastEdge[nY].V = nV; nV += nVInc;
|
|
}
|
|
}
|
|
|
|
|
|
#define _drawHLineFT(name, ftx) \
|
|
void drawHLineFT##name(int nY, tagPolyEdge *stEdgeIni, tagPolyEdge *stEdgeEnd) { \
|
|
int nX, nU, nV; \
|
|
int nUInc, nVInc; \
|
|
\
|
|
if (stEdgeEnd->X <= stEdgeIni->X) { \
|
|
return; \
|
|
} \
|
|
\
|
|
nX = stEdgeIni->X; \
|
|
nU = stEdgeIni->U; \
|
|
nV = stEdgeIni->V; \
|
|
nUInc = (stEdgeEnd->U - stEdgeIni->U) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nVInc = (stEdgeEnd->V - stEdgeIni->V) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
\
|
|
for (nX = stEdgeIni->X; nX <= stEdgeEnd->X; nX++) { \
|
|
drawPixel(nX, nY, ftx); \
|
|
nU += nUInc; nV += nVInc; \
|
|
} \
|
|
}
|
|
|
|
_drawHLineFT(Decal,
|
|
GetTexturePixel32(nU >> 16, nV >> 16)
|
|
);
|
|
_drawHLineFT(Modulate,
|
|
colModulate(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
_drawHLineFT(Highlight,
|
|
colHighlight(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
_drawHLineFT(Highlight2,
|
|
colHighlight2(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
|
|
void drawTriangleFTDecal(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleFTDecal %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixel();
|
|
|
|
drawTriangle(scanEdgeFT, drawHLineFTDecal);
|
|
}
|
|
|
|
void drawTriangleFTModulate(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleFTModulate %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixel();
|
|
colSetCol(gs.rgba);
|
|
|
|
drawTriangle(scanEdgeFT, drawHLineFTModulate);
|
|
}
|
|
|
|
void drawTriangleFTHighlight(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleFTHighlight %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixel();
|
|
colSetCol(gs.rgba);
|
|
|
|
drawTriangle(scanEdgeFT, drawHLineFTHighlight);
|
|
}
|
|
|
|
void drawTriangleFTHighlight2(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleFTHighlight2 %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixel();
|
|
colSetCol(gs.rgba);
|
|
|
|
drawTriangle(scanEdgeFT, drawHLineFTHighlight2);
|
|
}
|
|
|
|
void scanEdgeFTZ(tagPolyEdge* pastEdge, Vertex *v1, Vertex *v2) {
|
|
int nX, nY, nU, nV;
|
|
int nXInc, nUInc, nVInc;
|
|
s64 nZ;
|
|
s64 nZInc;
|
|
|
|
if (v1->y == v2->y)
|
|
return;
|
|
|
|
nX = v1->x << 16;
|
|
nZ = (u64)v1->z << 16;
|
|
nU = v1->u << 16;
|
|
nV = v1->v << 16;
|
|
|
|
nXInc = ((v2->x - v1->x) << 16) / (v2->y - v1->y);
|
|
nZInc = ((s64)((s64)v2->z - v1->z) << 16) / (v2->y - v1->y);
|
|
nUInc = ((v2->u - v1->u) << 16) / (v2->y - v1->y);
|
|
nVInc = ((v2->v - v1->v) << 16) / (v2->y - v1->y);
|
|
|
|
for (nY = v1->y; nY < 0; nY++) {
|
|
nX += nXInc;
|
|
nZ += nZInc;
|
|
nU += nUInc;
|
|
nV += nVInc;
|
|
}
|
|
for (; nY < v2->y; nY++) {
|
|
pastEdge[nY].X = nX >> 16; nX += nXInc;
|
|
pastEdge[nY].Z = nZ; nZ += nZInc;
|
|
pastEdge[nY].U = nU; nU += nUInc;
|
|
pastEdge[nY].V = nV; nV += nVInc;
|
|
}
|
|
}
|
|
|
|
|
|
#define _drawHLineFTZ(name, ftx) \
|
|
void drawHLineFTZ##name(int nY, tagPolyEdge *stEdgeIni, tagPolyEdge *stEdgeEnd) { \
|
|
int nX, nU, nV; \
|
|
int nUInc, nVInc; \
|
|
s64 nZ; \
|
|
s64 nZInc; \
|
|
\
|
|
if (stEdgeEnd->X <= stEdgeIni->X) { \
|
|
return; \
|
|
} \
|
|
\
|
|
nX = stEdgeIni->X; \
|
|
nZ = stEdgeIni->Z; \
|
|
nU = stEdgeIni->U; \
|
|
nV = stEdgeIni->V; \
|
|
nZInc = (s64)((s64)stEdgeEnd->Z - stEdgeIni->Z) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nUInc = (stEdgeEnd->U - stEdgeIni->U) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nVInc = (stEdgeEnd->V - stEdgeIni->V) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
\
|
|
for (nX = stEdgeIni->X; nX <= stEdgeEnd->X; nX++) { \
|
|
drawPixelZ(nX, nY, ftx, (u32)(nZ >> 16)); \
|
|
nZ += nZInc; \
|
|
nU += nUInc; nV += nVInc; \
|
|
} \
|
|
}
|
|
|
|
_drawHLineFTZ(Decal,
|
|
GetTexturePixel32(nU >> 16, nV >> 16)
|
|
);
|
|
_drawHLineFTZ(Modulate,
|
|
colModulate(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
_drawHLineFTZ(Highlight,
|
|
colHighlight(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
_drawHLineFTZ(Highlight2,
|
|
colHighlight2(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
|
|
void drawTriangleFTDecal_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleFTDecal_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixelZ();
|
|
|
|
drawTriangle(scanEdgeFTZ, drawHLineFTZDecal);
|
|
}
|
|
|
|
void drawTriangleFTModulate_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleFTModulate_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixelZ();
|
|
colSetCol(gs.rgba);
|
|
|
|
drawTriangle(scanEdgeFTZ, drawHLineFTZModulate);
|
|
}
|
|
|
|
void drawTriangleFTHighlight_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleFTHighlight_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixelZ();
|
|
colSetCol(gs.rgba);
|
|
|
|
drawTriangle(scanEdgeFTZ, drawHLineFTZHighlight);
|
|
}
|
|
|
|
void drawTriangleFTHighlight2_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleFTHighlight2_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixelZ();
|
|
colSetCol(gs.rgba);
|
|
|
|
drawTriangle(scanEdgeFTZ, drawHLineFTZHighlight2);
|
|
}
|
|
|
|
/**************************/
|
|
/* Gouraud Shaded/Textued */
|
|
|
|
void scanEdgeGT(tagPolyEdge* pastEdge, Vertex *v1, Vertex *v2) {
|
|
s32 nX, nU, nV, nY, nR, nG, nB, nA;
|
|
s32 nXInc, nUInc, nVInc, nRInc, nGInc, nBInc, nAInc;
|
|
s32 r1, g1, b1, a1;
|
|
s32 r2, g2, b2, a2;
|
|
|
|
if (v1->y == v2->y)
|
|
return;
|
|
|
|
b1 = (v1->rgba & 0x000000FF);
|
|
g1 = (v1->rgba & 0x0000FF00) >> 8;
|
|
r1 = (v1->rgba & 0x00FF0000) >> 16;
|
|
a1 = (v1->rgba & 0xFF000000) >> 24;
|
|
b2 = (v2->rgba & 0x000000FF);
|
|
g2 = (v2->rgba & 0x0000FF00) >> 8;
|
|
r2 = (v2->rgba & 0x00FF0000) >> 16;
|
|
a2 = (v2->rgba & 0xFF000000) >> 24;
|
|
|
|
nX = v1->x << 16;
|
|
nR = r1 << 16;
|
|
nG = g1 << 16;
|
|
nB = b1 << 16;
|
|
nA = a1 << 16;
|
|
nU = v1->u << 16;
|
|
nV = v1->v << 16;
|
|
|
|
nXInc = ((v2->x - v1->x) << 16) / (v2->y - v1->y);
|
|
nRInc = (( r2 - r1) << 16) / (v2->y - v1->y);
|
|
nGInc = (( g2 - g1) << 16) / (v2->y - v1->y);
|
|
nBInc = (( b2 - b1) << 16) / (v2->y - v1->y);
|
|
nAInc = (( a2 - a1) << 16) / (v2->y - v1->y);
|
|
nUInc = ((v2->u - v1->u) << 16) / (v2->y - v1->y);
|
|
nVInc = ((v2->v - v1->v) << 16) / (v2->y - v1->y);
|
|
|
|
for (nY = v1->y; nY < 0; nY++) {
|
|
nX += nXInc;
|
|
nU += nUInc;
|
|
nV += nVInc;
|
|
nR += nRInc;
|
|
nG += nGInc;
|
|
nB += nBInc;
|
|
nA += nAInc;
|
|
}
|
|
for (; nY < v2->y; nY++) {
|
|
pastEdge[nY].X = nX >> 16; nX += nXInc;
|
|
pastEdge[nY].U = nU; nU += nUInc;
|
|
pastEdge[nY].V = nV; nV += nVInc;
|
|
pastEdge[nY].R = nR; nR += nRInc;
|
|
pastEdge[nY].G = nG; nG += nGInc;
|
|
pastEdge[nY].B = nB; nB += nBInc;
|
|
pastEdge[nY].A = nA; nA += nAInc;
|
|
}
|
|
}
|
|
|
|
#define _drawHLineGT(name, ftx) \
|
|
void drawHLineGT##name(int nY, tagPolyEdge *stEdgeIni, tagPolyEdge *stEdgeEnd) { \
|
|
s32 nX, nU, nV, nR, nG, nB, nA; \
|
|
s32 nUInc, nVInc, nRInc, nGInc, nBInc, nAInc; \
|
|
\
|
|
if (stEdgeEnd->X <= stEdgeIni->X) { \
|
|
return; \
|
|
} \
|
|
\
|
|
nR = stEdgeIni->R; \
|
|
nG = stEdgeIni->G; \
|
|
nB = stEdgeIni->B; \
|
|
nA = stEdgeIni->A; \
|
|
nU = stEdgeIni->U; \
|
|
nV = stEdgeIni->V; \
|
|
nRInc = (stEdgeEnd->R - stEdgeIni->R) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nGInc = (stEdgeEnd->G - stEdgeIni->G) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nBInc = (stEdgeEnd->B - stEdgeIni->B) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nAInc = (stEdgeEnd->A - stEdgeIni->A) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nUInc = (stEdgeEnd->U - stEdgeIni->U) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nVInc = (stEdgeEnd->V - stEdgeIni->V) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
\
|
|
for (nX = stEdgeIni->X; nX <= stEdgeEnd->X; nX++) { \
|
|
colSetCol(( nR & 0xff0000) | \
|
|
((nG & 0xff0000) >> 8) | \
|
|
((nB & 0xff0000) >> 16) | \
|
|
((nA & 0xff0000) << 8)); \
|
|
drawPixel(nX, nY, ftx); \
|
|
nU += nUInc; nV += nVInc; \
|
|
nR += nRInc; nG += nGInc; nB += nBInc; nA += nAInc; \
|
|
} \
|
|
}
|
|
|
|
_drawHLineGT(Modulate,
|
|
colModulate(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
_drawHLineGT(Highlight,
|
|
colHighlight(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
_drawHLineGT(Highlight2,
|
|
colHighlight2(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
|
|
|
|
void drawTriangleGTDecal(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleGTDecal %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
drawTriangleFTDecal(v);
|
|
}
|
|
|
|
void drawTriangleGTModulate(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleGTModulate %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixel();
|
|
|
|
drawTriangle(scanEdgeGT, drawHLineGTModulate);
|
|
}
|
|
|
|
void drawTriangleGTHighlight(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleGTHighlight %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixel();
|
|
|
|
drawTriangle(scanEdgeGT, drawHLineGTHighlight);
|
|
}
|
|
|
|
void drawTriangleGTHighlight2(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleGTHighlight2 %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixel();
|
|
|
|
drawTriangle(scanEdgeGT, drawHLineGTHighlight2);
|
|
}
|
|
|
|
void scanEdgeGTZ(tagPolyEdge* pastEdge, Vertex *v1, Vertex *v2) {
|
|
s32 nX, nU, nV, nY, nR, nG, nB, nA;
|
|
s32 nXInc, nUInc, nVInc, nRInc, nGInc, nBInc, nAInc;
|
|
s64 nZ;
|
|
s64 nZInc;
|
|
s32 r1, g1, b1, a1;
|
|
s32 r2, g2, b2, a2;
|
|
|
|
if (v1->y == v2->y)
|
|
return;
|
|
|
|
b1 = (v1->rgba & 0x000000FF);
|
|
g1 = (v1->rgba & 0x0000FF00) >> 8;
|
|
r1 = (v1->rgba & 0x00FF0000) >> 16;
|
|
a1 = (v1->rgba & 0xFF000000) >> 24;
|
|
b2 = (v2->rgba & 0x000000FF);
|
|
g2 = (v2->rgba & 0x0000FF00) >> 8;
|
|
r2 = (v2->rgba & 0x00FF0000) >> 16;
|
|
a2 = (v2->rgba & 0xFF000000) >> 24;
|
|
|
|
nX = v1->x << 16;
|
|
nZ = (u64)v1->z << 16;
|
|
nR = r1 << 16;
|
|
nG = g1 << 16;
|
|
nB = b1 << 16;
|
|
nA = a1 << 16;
|
|
nU = v1->u << 16;
|
|
nV = v1->v << 16;
|
|
|
|
nXInc = ((v2->x - v1->x) << 16) / (v2->y - v1->y);
|
|
nZInc = ((s64)((s64)v2->z - v1->z) << 16) / (v2->y - v1->y);
|
|
nRInc = (( r2 - r1) << 16) / (v2->y - v1->y);
|
|
nGInc = (( g2 - g1) << 16) / (v2->y - v1->y);
|
|
nBInc = (( b2 - b1) << 16) / (v2->y - v1->y);
|
|
nAInc = (( a2 - a1) << 16) / (v2->y - v1->y);
|
|
nUInc = ((v2->u - v1->u) << 16) / (v2->y - v1->y);
|
|
nVInc = ((v2->v - v1->v) << 16) / (v2->y - v1->y);
|
|
|
|
for (nY = v1->y; nY < 0; nY++) {
|
|
nX += nXInc;
|
|
nZ += nZInc;
|
|
nU += nUInc;
|
|
nV += nVInc;
|
|
nR += nRInc;
|
|
nG += nGInc;
|
|
nB += nBInc;
|
|
nA += nAInc;
|
|
}
|
|
for (; nY < v2->y; nY++) {
|
|
pastEdge[nY].X = nX >> 16; nX += nXInc;
|
|
pastEdge[nY].Z = nZ; nZ += nZInc;
|
|
pastEdge[nY].U = nU; nU += nUInc;
|
|
pastEdge[nY].V = nV; nV += nVInc;
|
|
pastEdge[nY].R = nR; nR += nRInc;
|
|
pastEdge[nY].G = nG; nG += nGInc;
|
|
pastEdge[nY].B = nB; nB += nBInc;
|
|
pastEdge[nY].A = nA; nA += nAInc;
|
|
}
|
|
}
|
|
|
|
#define _drawHLineGTZ(name, ftx) \
|
|
void drawHLineGTZ##name(int nY, tagPolyEdge *stEdgeIni, tagPolyEdge *stEdgeEnd) { \
|
|
s32 nX, nU, nV, nR, nG, nB, nA; \
|
|
s32 nUInc, nVInc, nRInc, nGInc, nBInc, nAInc; \
|
|
s64 nZ; \
|
|
s64 nZInc; \
|
|
\
|
|
if (stEdgeEnd->X <= stEdgeIni->X) { \
|
|
return; \
|
|
} \
|
|
\
|
|
nZ = stEdgeIni->Z; \
|
|
nR = stEdgeIni->R; \
|
|
nG = stEdgeIni->G; \
|
|
nB = stEdgeIni->B; \
|
|
nA = stEdgeIni->A; \
|
|
nU = stEdgeIni->U; \
|
|
nV = stEdgeIni->V; \
|
|
nZInc = (s64)((s64)stEdgeEnd->Z - stEdgeIni->Z) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nRInc = (stEdgeEnd->R - stEdgeIni->R) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nGInc = (stEdgeEnd->G - stEdgeIni->G) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nBInc = (stEdgeEnd->B - stEdgeIni->B) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nAInc = (stEdgeEnd->A - stEdgeIni->A) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nUInc = (stEdgeEnd->U - stEdgeIni->U) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
nVInc = (stEdgeEnd->V - stEdgeIni->V) / (stEdgeEnd->X - stEdgeIni->X); \
|
|
\
|
|
for (nX = stEdgeIni->X; nX <= stEdgeEnd->X; nX++) { \
|
|
colSetCol(( nR & 0xff0000) | \
|
|
((nG & 0xff0000) >> 8) | \
|
|
((nB & 0xff0000) >> 16) | \
|
|
((nA & 0xff0000) << 8)); \
|
|
drawPixelZ(nX, nY, ftx, (u32)(nZ >> 16)); \
|
|
nZ += nZInc; \
|
|
nU += nUInc; nV += nVInc; \
|
|
nR += nRInc; nG += nGInc; nB += nBInc; nA += nAInc; \
|
|
} \
|
|
}
|
|
|
|
_drawHLineGTZ(Modulate,
|
|
colModulate(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
_drawHLineGTZ(Highlight,
|
|
colHighlight(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
_drawHLineGTZ(Highlight2,
|
|
colHighlight2(GetTexturePixel32(nU >> 16, nV >> 16))
|
|
);
|
|
|
|
void drawTriangleGTDecal_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleGTDecal_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
drawTriangleFTDecal_Z(v);
|
|
}
|
|
|
|
void drawTriangleGTModulate_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleGTModulate_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixelZ();
|
|
|
|
drawTriangle(scanEdgeGTZ, drawHLineGTZModulate);
|
|
}
|
|
|
|
void drawTriangleGTHighlight_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleGTHighlight_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixelZ();
|
|
|
|
drawTriangle(scanEdgeGTZ, drawHLineGTZHighlight);
|
|
}
|
|
|
|
void drawTriangleGTHighlight2_Z(Vertex * v) {
|
|
#ifdef GS_LOG
|
|
GS_LOG("drawTriangleGTHighlight2_Z %dx%d - %dx%d - %dx%d rgba=%x\n",
|
|
v[0].x, v[0].y, v[1].x, v[1].y, v[2].x, v[2].y, gs.rgba);
|
|
GS_LOG("uv: %xx%x - %xx%x - %xx%x\n",
|
|
v[0].u, v[0].v, v[1].u, v[1].v, v[2].u, v[2].v);
|
|
#endif
|
|
|
|
SetTexture();
|
|
SETdrawPixelZ();
|
|
|
|
drawTriangle(scanEdgeGTZ, drawHLineGTZHighlight2);
|
|
}
|
|
|
|
|
|
/*
|
|
3DFC
|
|
http://www.geocities.com/SiliconValley/Bay/1704
|
|
|
|
*/
|
|
|