mirror of
https://github.com/ACreTeam/ac-decomp
synced 2026-05-22 22:24:16 -04:00
762b74fcf0
Ks nes draw emu result
848 lines
32 KiB
C++
848 lines
32 KiB
C++
#define FIX_SQRT_LINKAGE
|
|
#include "Famicom/ks_nes_draw.h"
|
|
#include "dolphin/gx.h"
|
|
#include "dolphin/PPCArch.h"
|
|
#include "_mem.h"
|
|
#include "dolphin/os.h"
|
|
|
|
u8 ksNesPaletteNormal[] = {
|
|
0xc2, 0x10, 0x80, 0x17, 0x98, 0x17, 0xc0, 0x14, 0xdc, 0x0d, 0xd8, 0x03, 0xd8, 0x00, 0xc8, 0x80, 0xbc, 0xa0, 0x80,
|
|
0xe0, 0x81, 0x21, 0x80, 0xe4, 0x80, 0xac, 0x80, 0x00, 0x80, 0x00, 0x80, 0x00, 0xe7, 0x39, 0x81, 0x7f, 0xa0, 0xff,
|
|
0xd8, 0xd9, 0xfc, 0xd5, 0xfc, 0xcb, 0xfc, 0xc3, 0xe9, 0x20, 0xe1, 0x80, 0x9d, 0xe0, 0x8e, 0x02, 0x82, 0x4c, 0x82,
|
|
0x18, 0x88, 0x42, 0x80, 0x00, 0x80, 0x00, 0xff, 0xff, 0x82, 0x5f, 0xb6, 0x1f, 0xe9, 0xbf, 0xfd, 0xd9, 0xfd, 0xb3,
|
|
0xfd, 0xeb, 0xfe, 0x4b, 0xfe, 0x86, 0xd2, 0xe0, 0xab, 0x6d, 0xa7, 0x55, 0x83, 0x7f, 0xb1, 0x8c, 0x80, 0x00, 0x80,
|
|
0x00, 0xff, 0xff, 0xc2, 0xff, 0xde, 0xff, 0xea, 0xff, 0xfe, 0xfd, 0xfe, 0xf9, 0xff, 0x16, 0xff, 0x35, 0xff, 0x74,
|
|
0xe7, 0x93, 0xd7, 0xb6, 0xd7, 0xdd, 0xdb, 0xbf, 0xef, 0x7b, 0x80, 0x00, 0x80, 0x00,
|
|
};
|
|
|
|
void ksNesDrawInit(ksNesCommonWorkObj* wp) {
|
|
Mtx44 mtx;
|
|
Vec v1 = { 0.f, 0.f, 800.f };
|
|
Vec v3 = { 0.f, 0.f, -100.f };
|
|
Vec v2 = { 0.f, 1.f, 0.f };
|
|
GXInvalidateTexAll();
|
|
GXInvalidateVtxCache();
|
|
GXSetClipMode(GX_CLIP_DISABLE);
|
|
GXSetPixelFmt(GX_PF_RGB8_Z24, GX_ZC_LINEAR);
|
|
GXSetCopyFilter(GX_FALSE, NULL, GX_FALSE, NULL);
|
|
GXSetZMode(GX_FALSE, GX_ALWAYS, GX_FALSE);
|
|
GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0);
|
|
GXSetZCompLoc(GX_FALSE);
|
|
GXSetColorUpdate(GX_TRUE);
|
|
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
|
|
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
C_MTXOrtho(mtx, 0, -480.f, 0.f, 640.f, 0.f, 2000.f);
|
|
GXSetProjection(mtx, GX_ORTHOGRAPHIC);
|
|
C_MTXLookAt(wp->work_priv.draw_mtx, &v1, &v2, &v3);
|
|
}
|
|
|
|
void ksNesDrawEnd() {
|
|
GXSetClipMode(GX_CLIP_ENABLE);
|
|
GXSetZCompLoc(GX_TRUE);
|
|
GXSetNumIndStages(0);
|
|
GXSetTevDirect(GX_TEVSTAGE0);
|
|
GXSetTevDirect(GX_TEVSTAGE1);
|
|
GXSetTevDirect(GX_TEVSTAGE2);
|
|
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
|
GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA);
|
|
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
GXSetTexCoordScaleManually(GX_TEXCOORD0, GX_FALSE, 0, 0);
|
|
GXSetTexCoordScaleManually(GX_TEXCOORD1, GX_FALSE, 0, 0);
|
|
}
|
|
|
|
void ksNesDrawClearEFBFirst(ksNesCommonWorkObj* wp) {
|
|
DCFlushRange(&wp->work_priv._2A40, sizeof(wp->work_priv._2A40));
|
|
GXSetNumChans(1);
|
|
GXSetNumTexGens(0);
|
|
GXSetNumTevStages(1);
|
|
GXSetNumIndStages(0);
|
|
GXSetTevDirect(GX_TEVSTAGE0);
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
|
|
GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
|
|
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE);
|
|
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
|
GXSetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY);
|
|
GXClearVtxDesc();
|
|
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGBA4, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
|
GXSetCurrentMtx(0);
|
|
GXLoadPosMtxImm(wp->work_priv.draw_mtx, 0);
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, 4);
|
|
{
|
|
GXPosition2s16(128, -128);
|
|
GXColor1u32(0x00ff0000);
|
|
|
|
GXPosition2s16(384, -128);
|
|
GXColor1u32(0x00000000);
|
|
|
|
GXPosition2s16(384, -384);
|
|
GXColor1u32(0x0000ff00);
|
|
|
|
GXPosition2s16(128, -384);
|
|
GXColor1u32(0x00000000);
|
|
}
|
|
GXEnd();
|
|
}
|
|
|
|
// TODO: this function needs help
|
|
void ksNesDrawMakeBGIndTex(ksNesCommonWorkObj* wp, u32 mapper4) {
|
|
u32 trigger_col = 0x7fff;
|
|
u8 CHR_flag_xor = 0x80;
|
|
u32 row;
|
|
u32 col;
|
|
|
|
if (mapper4) {
|
|
trigger_col = 9;
|
|
}
|
|
|
|
if (wp->chr_to_i8_buf_size <= CHR_TO_I8_BUF_SIZE * 16) {
|
|
CHR_flag_xor = wp->chr_to_i8_buf_size >> 13;
|
|
}
|
|
|
|
for (row = 8; row < 236; row++) {
|
|
u8 scanline_ctrl0 = wp->work_priv._0B40[row]._1C;
|
|
u8 scanline_ctrl1 = wp->work_priv._0B40[row]._1B;
|
|
u32* patternPtrBase = &wp->work_priv._0B40[row]._10;
|
|
u8* nametable_p;
|
|
u8 tile_byte;
|
|
u8 palette_bits;
|
|
u8 nibble_acc; // @bug - uninitialized
|
|
u32 dst_idx;
|
|
|
|
for (col = 0; col < 34; col++) {
|
|
|
|
if (col == trigger_col) {
|
|
patternPtrBase -= 2;
|
|
}
|
|
|
|
// _00 and _04 are pointers to ppu_nametable_pointers[0/1]?
|
|
nametable_p = &(wp->work_priv._0B40[row]._00)[((scanline_ctrl0 >> 7) & 1)];
|
|
if (((u32)nametable_p) & OS_BASE_CACHED) {
|
|
tile_byte = nametable_p[((scanline_ctrl0 & 0xF8) << 2) + ((scanline_ctrl1 & 0xF8) >> 3)];
|
|
nibble_acc = ((nametable_p[0x3C0 + ((scanline_ctrl0 & 0xE0) >> 2) + ((scanline_ctrl1 & 0xE0) >> 7)] >> (((scanline_ctrl0 & 0x10) >> 2) | ((scanline_ctrl1 & 0x10) >> 3))) & 3) | (nibble_acc << 4);
|
|
} else {
|
|
tile_byte = ((u32)nametable_p) >> 8;
|
|
nibble_acc = (((u32)nametable_p) & 3) | (nibble_acc << 4);
|
|
}
|
|
|
|
palette_bits = patternPtrBase[((wp->work_priv._0B40[row]._18 & 0x10) >> 2) | (tile_byte >> 6)];
|
|
dst_idx = ((col & 3) * 2) + ((col & 0x3C) * 8) + ((row & 3) * 8) + ((row >> 2) * 288);
|
|
|
|
wp->work_priv._3240[dst_idx + 0] = (((palette_bits & 1) << 6) | (tile_byte & 0x3F)) - (col & 1);
|
|
wp->work_priv._3240[dst_idx + 1] = (palette_bits >> 1) ^ (CHR_flag_xor & -((scanline_ctrl0 & 0x04) >> 2));
|
|
|
|
if ((col & 1) != 0) {
|
|
wp->work_priv._7840[((col >> 1) & 3) + (col & 0x38) * 4 + (row & 7) * 4 + (row >> 3) * 160] = nibble_acc;
|
|
}
|
|
|
|
scanline_ctrl1 += 8;
|
|
}
|
|
}
|
|
|
|
DCFlushRangeNoSync(wp->work_priv._3240, sizeof(wp->work_priv._3240));
|
|
DCFlushRangeNoSync(wp->work_priv._7840, sizeof(wp->work_priv._7840));
|
|
}
|
|
|
|
void ksNesDrawMakeBGIndTexMMC5(ksNesCommonWorkObj*, ksNesStateObj*) {
|
|
}
|
|
|
|
#define ksNes_MMC2_LATCH_LO 0xFD // select chr bank 0/2
|
|
#define ksNes_MMC2_LATCH_HI 0xFE // select chr bank 1/3
|
|
|
|
void ksNesDrawMakeBGIndTexMMC2(ksNesCommonWorkObj* wp, u32 mode) {
|
|
}
|
|
|
|
void ksNesDrawOBJSetupMMC2(ksNesCommonWorkObj* wp) {
|
|
u32 i;
|
|
u32 j;
|
|
u32 max;
|
|
u32 chr_bank;
|
|
|
|
memset(&wp->work_priv._0200, 0, sizeof(wp->work_priv._0200));
|
|
for (i = 0; i < 64; i++) {
|
|
// _0B40 is the scanline state, _2940 is list of scanline triggers?
|
|
if (wp->work_priv._2940[i]._00 >= 236 || (wp->work_priv._2940[i]._01 != ksNes_MMC2_LATCH_HI && wp->work_priv._2940[i]._01 != ksNes_MMC2_LATCH_LO)) {
|
|
continue;
|
|
}
|
|
|
|
j = wp->work_priv._2940[i]._00;
|
|
max = (((wp->work_priv._0B40[j]._18 >> 2) & 0x08) + 8) + j;
|
|
do {
|
|
wp->work_priv._0200[j] = wp->work_priv._2940[i]._01;
|
|
j++;
|
|
} while(j < max);
|
|
}
|
|
|
|
// _0200 is the scanline marker entries
|
|
for (i = 0, chr_bank = 0; i < ARRAY_COUNT(wp->work_priv._0200); i++) {
|
|
if (wp->work_priv._0200[i] == ksNes_MMC2_LATCH_HI) {
|
|
chr_bank = 0;
|
|
} else if (wp->work_priv._0200[i] == ksNes_MMC2_LATCH_LO) {
|
|
chr_bank = 1;
|
|
}
|
|
|
|
if (chr_bank) {
|
|
wp->work_priv._0B40[i]._08[0] = wp->work_priv._0B40[i]._08[1] - 1;
|
|
wp->work_priv._0B40[i]._08[2] = wp->work_priv._0B40[i]._08[1] + 1;
|
|
wp->work_priv._0B40[i]._08[3] = wp->work_priv._0B40[i]._08[1] + 2;
|
|
} else {
|
|
wp->work_priv._0B40[i]._08[1] = wp->work_priv._0B40[i]._08[0] + 1;
|
|
wp->work_priv._0B40[i]._08[2] = wp->work_priv._0B40[i]._08[0] + 2;
|
|
wp->work_priv._0B40[i]._08[3] = wp->work_priv._0B40[i]._08[0] + 3;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ksNesDrawBG(ksNesCommonWorkObj*, ksNesStateObj*) {
|
|
const static GXColor color_r_0xf0 = { 240, 0, 0, 0 };
|
|
// GXSetIndTexMtx(GX_ITM_0, );
|
|
}
|
|
|
|
u32 ksNesDrawMakeOBJBlankVtxList(ksNesCommonWorkObj* wp) {
|
|
u32 ret = 0;
|
|
u32 comparison_mask = 20;
|
|
int i;
|
|
|
|
for (i = 8; i < 0xf0; i++) {
|
|
int bMask = wp->work_priv._0B40[i]._19 & 0x14;
|
|
if (bMask != comparison_mask && ((bMask != 0) || (comparison_mask != 4)) &&
|
|
(bMask != 4 || comparison_mask != 0)) {
|
|
if (ret & 1 != 0) {
|
|
wp->work_priv._0000[ret] = i - wp->_004C[ret + 0x13];
|
|
ret++;
|
|
}
|
|
if ((comparison_mask == 20) || (wp->work_priv._0B40[i]._19 & 0x10) == 0) {
|
|
wp->work_priv._0000[ret++] = i;
|
|
}
|
|
comparison_mask = wp->work_priv._0B40[i]._19 & 0x14;
|
|
}
|
|
}
|
|
|
|
if (ret & 1) {
|
|
wp->work_priv._0000[ret] = i - wp->_004C[ret + 0x13];
|
|
ret++;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
u32 ksNesDrawMakeOBJAppearVtxList(ksNesCommonWorkObj* wp) {
|
|
u32 ret = 0;
|
|
u32 comparison_mask = 0;
|
|
int i;
|
|
|
|
for (i = 8; i < 0xf0; i++) {
|
|
int bMask = wp->work_priv._0B40[i]._19 & 0x14;
|
|
if (bMask != comparison_mask && ((bMask != 0) || (comparison_mask != 4)) &&
|
|
(bMask != 4 || comparison_mask != 0)) {
|
|
if (ret & 1 != 0) {
|
|
wp->work_priv._0000[ret] = i - wp->_004C[ret + 0x13];
|
|
ret++;
|
|
}
|
|
if ((wp->work_priv._0B40[i]._19 & 0x10)) {
|
|
wp->work_priv._0000[ret++] = i;
|
|
}
|
|
comparison_mask = wp->work_priv._0B40[i]._19 & 0x14;
|
|
}
|
|
}
|
|
|
|
if (ret & 1) {
|
|
wp->work_priv._0000[ret] = i - wp->_004C[ret + 0x13];
|
|
ret++;
|
|
}
|
|
return ret;
|
|
}
|
|
|
|
void ksNesDrawOBJ(ksNesCommonWorkObj* wp, ksNesStateObj* state, u32 c) {
|
|
u32 size = wp->chr_to_i8_buf_size <= CHR_TO_I8_BUF_SIZE ? wp->chr_to_i8_buf_size : CHR_TO_I8_BUF_SIZE;
|
|
// int i;
|
|
GXTexObj GStack_7c;
|
|
GXTexObj GStack_9c;
|
|
GXTexObj GStack_bc;
|
|
u32 i;
|
|
u32 j;
|
|
|
|
if (c == 0) {
|
|
for (i = 0; i < 0x110; i++) {
|
|
wp->work_priv._0000[i] = i < 0xF0 ? ((state->frame_flags & 0x2000) ? 255 : 8) : 0;
|
|
if ((wp->work_priv._0B40[i]._19 & 0x10) == 0) {
|
|
wp->work_priv._0000[i] = 0;
|
|
}
|
|
}
|
|
if (state->prg_size == 0x40000 && memcmp(state->prgromp + 0x3ffe9, "MARIO 3", 7) == 0) {
|
|
for (i = 0; i < 0xf0; i++) {
|
|
if (wp->work_priv._0B40[i]._0C == 0x7e7e7e7e) {
|
|
wp->work_priv._0000[i] = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
memset(&wp->work_priv._0340, 0, sizeof(wp->work_priv._0340));
|
|
int b;
|
|
int _c;
|
|
int a;
|
|
int _j;
|
|
_0340_struct* _340_p = wp->work_priv._0340;
|
|
|
|
for (i = 0; i < 0x100; i += 4) {
|
|
_j = 8;
|
|
if (wp->work_priv._0B40[wp->work_priv._2940[i]._00]._18 & 0x20) {
|
|
_j = 0x10;
|
|
}
|
|
a = 0;
|
|
if (wp->work_priv._2940[i]._02 & 0x80) {
|
|
b = _j << 2;
|
|
_c = -4;
|
|
} else {
|
|
b = 0;
|
|
_c = 4;
|
|
}
|
|
for (j = 0; j < _j; j++) {
|
|
if (wp->work_priv._0000[wp->work_priv._2940[i]._00 + j] != 0) {
|
|
wp->work_priv._0000[wp->work_priv._2940[i]._00 + j]--;
|
|
if ((a & 2) == 0) {
|
|
_340_p->_00[a] = j + wp->work_priv._2940[i]._00;
|
|
_340_p->_00[a + 1] = b;
|
|
a += 2;
|
|
}
|
|
} else if ((a & 2) != 0) {
|
|
_340_p->_00[a] = j + wp->work_priv._2940[i]._00;
|
|
_340_p->_00[a + 1] = b;
|
|
a += 2;
|
|
}
|
|
b += _c;
|
|
}
|
|
if ((a & 2) != 0) {
|
|
_340_p->_00[a] = j + wp->work_priv._2940[i]._00;
|
|
_340_p->_00[a + 1] = b;
|
|
a += 2;
|
|
}
|
|
wp->work_priv._0300[i >> 2] = a;
|
|
_340_p++;
|
|
}
|
|
}
|
|
GXSetNumChans(1);
|
|
GXSetNumTexGens(2);
|
|
GXSetNumTevStages(3);
|
|
GXSetNumIndStages(2);
|
|
GXSetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY);
|
|
GXClearVtxDesc();
|
|
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_TEX1, GX_DIRECT);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_CLR_RGB, GX_RGBA4, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_CLR_RGBA, GX_RGBX8, 10);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX1, GX_CLR_RGBA, GX_RGBX8, 10);
|
|
GXInitTexObj(&GStack_7c, wp->chr_to_u8_bufp, 0x400, (u16)(size >> 10), GX_TF_I8, GX_MIRROR, GX_CLAMP, 0);
|
|
GXInitTexObjLOD(&GStack_7c, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
|
GXLoadTexObj(&GStack_7c, GX_TEXMAP0);
|
|
GXInitTexObj(&GStack_9c, wp->work_priv._8EC0, 8, 4, GX_TF_IA8, GX_CLAMP, GX_CLAMP, 0);
|
|
GXInitTexObjLOD(&GStack_9c, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
|
GXLoadTexObj(&GStack_9c, GX_TEXMAP1);
|
|
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 0x3c);
|
|
GXSetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, 0x100, 0x101);
|
|
GXSetTexCoordBias(GX_TEXCOORD0, 0, 0);
|
|
GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP1);
|
|
GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_8, GX_ITS_1);
|
|
GXSetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_OFF, GX_ITW_OFF, GX_ITW_OFF, GX_FALSE,
|
|
GX_FALSE, GX_ITBA_OFF);
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEX_DISABLE, GX_COLOR0A0);
|
|
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_VTX, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE);
|
|
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_RASC, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO);
|
|
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVREG2);
|
|
GXInitTexObj(&GStack_bc, wp->work_priv._8E40, 4, 0x10, GX_TF_IA8, GX_CLAMP, GX_CLAMP, 0);
|
|
GXInitTexObjLOD(&GStack_bc, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, 0, 0, GX_ANISO_1);
|
|
GXLoadTexObj(&GStack_bc, GX_TEXMAP2);
|
|
GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, 0x3c);
|
|
GXSetTexCoordScaleManually(GX_TEXCOORD1, GX_TRUE, 0x100, 0x101);
|
|
GXSetTexCoordBias(GX_TEXCOORD1, 0, 0);
|
|
GXSetIndTexOrder(GX_INDTEXSTAGE1, GX_TEXCOORD1, GX_TEXMAP2);
|
|
GXSetIndTexCoordScale(GX_INDTEXSTAGE1, GX_ITS_8, GX_ITS_1);
|
|
{
|
|
// u32 i;
|
|
for (i = 0; size > (0x8000 << i); i++) {}
|
|
|
|
static f32 indtexmtx_obj[2][3] = { { 0.5f, 0.f, 0.f }, { 0.f, 0.0625f, 0.f } };
|
|
indtexmtx_obj[0][0] = 0.5f / (i >= 4 ? (1 << i - 3) : 1);
|
|
indtexmtx_obj[1][1] = 0.5f / (i <= 2 ? (1 << 3 - i) : 1);
|
|
GXSetIndTexMtx(GX_ITM_0, indtexmtx_obj, 36 + (i < 4 ? 0 : i - 3));
|
|
}
|
|
GXSetTevIndirect(GX_TEVSTAGE1, GX_INDTEXSTAGE1, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_OFF, GX_ITW_0, GX_TRUE,
|
|
GX_FALSE, GX_ITBA_OFF);
|
|
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP0, GX_COLOR_NULL);
|
|
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_C2, GX_CC_ZERO, GX_CC_ZERO, GX_CC_TEXC);
|
|
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_TEXA);
|
|
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevDirect(GX_TEVSTAGE2);
|
|
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
|
|
const static GXColor color_thres = { 0xff, 1, 0, 0 };
|
|
GXSetTevColor(GX_TEVREG0, color_thres);
|
|
GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_C0, GX_CC_C2, GX_CC_CPREV, GX_CC_ZERO);
|
|
GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_COMP_GR16_GT, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_APREV, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
|
GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
|
|
|
u32 n_verts = 0;
|
|
for (i = 0; i < 0x100; i += 4) {
|
|
if (c == 0 || (wp->work_priv._2940[i]._02 & 0x20) != 0) {
|
|
n_verts += wp->work_priv._0300[i >> 2];
|
|
}
|
|
}
|
|
|
|
u32 idx = 0x100-4;
|
|
u32 idx2 = 0x40-1;
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, n_verts);
|
|
while (TRUE) {
|
|
_0340_struct* _0340_thing = &wp->work_priv._0340[idx2];
|
|
u8* bruh = _0340_thing->_00;
|
|
// u32 scanline_idx = wp->work_priv._2940[idx];
|
|
u32 flags = wp->work_priv._2940[idx]._01;
|
|
u32 flags2;
|
|
|
|
if (wp->work_priv._0B40[wp->work_priv._2940[idx]._00]._18 & 0x20) {
|
|
flags2 = wp->work_priv._0B40[wp->work_priv._2940[idx]._00]._08[(flags >> 6) | ((flags & 1) << 2)];
|
|
flags &= (u8)~0x01;
|
|
} else {
|
|
flags2 = wp->work_priv._0B40[wp->work_priv._2940[idx]._00]._08[(flags >> 6) | ((wp->work_priv._0B40[wp->work_priv._2940[idx]._00]._18 >> 1) & 4)];
|
|
}
|
|
|
|
// u32 flags3 = wp->work_priv._2940[idx + 2];
|
|
u32 x0 = wp->work_priv._2940[idx]._03 + 128;
|
|
u32 x1 = wp->work_priv._2940[idx]._03 + 136;
|
|
u32 color = ((wp->work_priv._2940[idx]._02 & 3) * 0x10 + 4) * 0x01000000;
|
|
|
|
if (c != 0) {
|
|
if ((flags & 0x20) == 0) {
|
|
goto loop_condition;
|
|
}
|
|
} else {
|
|
if ((flags & 0x20) != 0) {
|
|
color |= 0xFF010000;
|
|
}
|
|
}
|
|
|
|
u32 s0;
|
|
u32 t0;
|
|
u32 s1;
|
|
u32 s1_2;
|
|
u32 t1;
|
|
u32 t1_2;
|
|
u32 temp;
|
|
// u32 j;
|
|
|
|
s0 = 0;
|
|
t0 = (flags2 & (u8)~0x01) * 2;
|
|
temp = ((flags & 0x3F) * 0x20) | ((flags2 & 0x01) * 0x800);
|
|
|
|
if (wp->work_priv._2940[idx]._02 & 0x40) {
|
|
s1 = temp + 32;
|
|
s1_2 = temp;
|
|
} else {
|
|
s1 = temp;
|
|
s1_2 = temp + 32;
|
|
}
|
|
|
|
for (j = 0; j < wp->work_priv._0300[idx >> 2]; j += 4) {
|
|
u32 y0 = -129 - bruh[0];
|
|
t1 = bruh[1];
|
|
u32 y1 = -129 - bruh[2];
|
|
t1_2 = bruh[3];
|
|
|
|
bruh += 4;
|
|
GXPosition2s16(x0, y0);
|
|
GXColor1u32(color);
|
|
GXTexCoord2u16(s0, t0);
|
|
GXTexCoord2u16(s1, t1);
|
|
|
|
GXPosition2s16(x1, y0);
|
|
GXColor1u32(color);
|
|
GXTexCoord2u16(s0, t0);
|
|
GXTexCoord2u16(s1_2, t1);
|
|
|
|
GXPosition2s16(x1, y1);
|
|
GXColor1u32(color);
|
|
GXTexCoord2u16(s0, t0);
|
|
GXTexCoord2u16(s1_2, t1_2);
|
|
|
|
GXPosition2s16(x0, y1);
|
|
GXColor1u32(color);
|
|
GXTexCoord2u16(s0, t0);
|
|
GXTexCoord2u16(s1, t1_2);
|
|
}
|
|
|
|
|
|
loop_condition:
|
|
if (idx == 0) {
|
|
break;
|
|
}
|
|
|
|
idx -= 4;
|
|
idx2--;
|
|
}
|
|
|
|
GXEnd();
|
|
|
|
if (c != 0) {
|
|
u32 n = ksNesDrawMakeOBJBlankVtxList(wp);
|
|
|
|
if (n != 0) {
|
|
GXSetNumChans(1);
|
|
GXSetNumTexGens(0);
|
|
GXSetNumTevStages(1);
|
|
GXSetNumIndStages(0);
|
|
GXSetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY);
|
|
GXClearVtxDesc();
|
|
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
|
GXSetTevDirect(GX_TEVSTAGE0);
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
|
|
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_VTX, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
|
|
GXSetTevOp(GX_TEVSTAGE0, GX_PASSCLR);
|
|
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
|
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, n * 2);
|
|
for (u32 i = 0; i < n; i += 2) {
|
|
s16 x1 = (wp->work_priv._0B40[wp->work_priv._0000[i]]._19 & 0x14) == 0x10 ? 136 : 384;
|
|
|
|
GXPosition2s16(128, -128 - wp->work_priv._0000[i]);
|
|
GXColor1u32(0x00000000);
|
|
GXPosition2s16(x1, -128 - wp->work_priv._0000[i]);
|
|
GXColor1u32(0x00000000);
|
|
GXPosition2s16(x1, -128 - wp->work_priv._0000[i] - wp->work_priv._0000[i + 1]);
|
|
GXColor1u32(0x00000000);
|
|
GXPosition2s16(128, -128 - wp->work_priv._0000[i] - wp->work_priv._0000[i + 1]);
|
|
GXColor1u32(0x00000000);
|
|
}
|
|
GXEnd();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ksNesDrawOBJMMC5(ksNesCommonWorkObj*, ksNesStateObj*, u32) {
|
|
}
|
|
|
|
void ksNesDrawFlushEFBToRed8(u8* buf) {
|
|
static const GXColor black = { 0, 0, 0, 0 };
|
|
GXSetTexCopySrc(0x80, 0x88, 0x100, 0xe4);
|
|
GXSetTexCopyDst(0x100, 0xe4, GX_CTF_R8, GX_FALSE);
|
|
GXSetCopyClear(black, 0xffffff);
|
|
GXCopyTex(buf, GX_FALSE);
|
|
GXPixModeSync();
|
|
GXInvalidateTexAll();
|
|
}
|
|
|
|
void ksNesDrawOBJI8ToEFB(ksNesCommonWorkObj* wp, u8* buf) {
|
|
GXTexObj obj;
|
|
u32 i;
|
|
s32 u;
|
|
u8* work;
|
|
u32 cnt;
|
|
|
|
GXSetNumChans(0);
|
|
GXSetNumTexGens(1);
|
|
GXSetNumTevStages(1);
|
|
GXSetNumIndStages(0);
|
|
GXSetBlendMode(GX_BM_LOGIC, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_COPY);
|
|
|
|
GXClearVtxDesc();
|
|
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U16, 8);
|
|
|
|
GXInitTexObj(&obj, (void*)buf, 256, 228, GX_TF_I8, GX_CLAMP, GX_CLAMP, 0);
|
|
GXInitTexObjLOD(&obj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
|
|
GXLoadTexObj(&obj, GX_TEXMAP0);
|
|
|
|
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 60);
|
|
GXSetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, 0x100, 0x100);
|
|
GXSetTexCoordBias(GX_TEXCOORD0, 0, 0);
|
|
|
|
GXSetTevDirect(GX_TEVSTAGE0);
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
|
GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
|
|
|
|
GXSetAlphaCompare(GX_GREATER, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
|
|
|
cnt = ksNesDrawMakeOBJAppearVtxList(wp);
|
|
if (cnt == 0) return;
|
|
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, cnt * 2);
|
|
|
|
for (i = 0; i < cnt; i += 2) {
|
|
work = (u8*)wp + i; // if it works...
|
|
u = (wp->work_priv._0B40[(u8)((u8*)wp)[i + 0x60]]._19 & 0x14) == 0x10 ? 8 : 0;
|
|
|
|
GXPosition2s16(u + 0x80, -128 - work[0x60]);
|
|
GXTexCoord2u16(u, work[0x60] - 8);
|
|
|
|
GXPosition2s16(0x180, -128 - work[0x60]);
|
|
GXTexCoord2u16(0x100, work[0x60] - 8);
|
|
|
|
GXPosition2s16(0x180, -128 - work[0x60] - work[0x61]);
|
|
GXTexCoord2u16(0x100, work[0x60] + work[0x61] - 8);
|
|
|
|
GXPosition2s16(u + 0x80, -128 - work[0x60] - work[0x61]);
|
|
GXTexCoord2u16(u, work[0x60] + work[0x61] - 8);
|
|
}
|
|
|
|
GXEnd();
|
|
}
|
|
|
|
void ksNesDrawEmuResult(ksNesCommonWorkObj* wp) {
|
|
static f32 indtexmtx[2][3] = {
|
|
{ 1.0f, 0.0f, 0.0f },
|
|
{ 0.0f, 0.0f, 0.0f }
|
|
};
|
|
static const GXColor black2 = { 0, 0, 0, 0 }; // unused, corrects stack
|
|
static const GXColor black = { 0, 0, 0, 0 };
|
|
static const GXColor color0 = { 0x3A, 0x3A, 0x3A, 0x00 };
|
|
static const GXColor color1 = { 0x71, 0x71, 0x71, 0x00 };
|
|
static const GXColor color2 = { 0x15, 0x15, 0x15, 0x00 };
|
|
|
|
u32 cnt;
|
|
u32 i;
|
|
u32 unk_r7;
|
|
u8 y;
|
|
u32 val;
|
|
u32 clr;
|
|
u8 *work;
|
|
GXTexObj obj;
|
|
GXTexObj obj2;
|
|
|
|
cnt = 0;
|
|
i = 8;
|
|
unk_r7 = 0xFF;
|
|
for (; i < 228 + 8; i++) {
|
|
val = wp->work_priv._0B40[i]._19 & 0xE1;
|
|
if (val != unk_r7) {
|
|
unk_r7 = val;
|
|
if ((cnt & 1) != 0) {
|
|
wp->work_priv._0000[cnt++] = i - 8;
|
|
}
|
|
wp->work_priv._0000[cnt++] = i - 8;
|
|
}
|
|
}
|
|
|
|
if ((cnt & 1) != 0) {
|
|
wp->work_priv._0000[cnt++] = i - 8;
|
|
}
|
|
wp->work_priv._0000[cnt] = 0xFF;
|
|
|
|
GXInitTexObj(&obj2, wp->result_bufp, 256, 228, GX_TF_I8, GX_CLAMP, GX_CLAMP, 0);
|
|
GXInitTexObjLOD(&obj2, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
|
|
GXLoadTexObj(&obj2, GX_TEXMAP1);
|
|
|
|
GXInitTexObj(&obj, wp->work_priv._2A40, 256, 4, GX_TF_RGB5A3, GX_CLAMP, GX_CLAMP, 0);
|
|
GXInitTexObjLOD(&obj, GX_NEAR, GX_NEAR, 0.0f, 0.0f, 0.0f, GX_FALSE, GX_FALSE, GX_ANISO_1);
|
|
GXLoadTexObj(&obj, GX_TEXMAP0);
|
|
|
|
GXSetTexCoordGen2(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, 60, GX_FALSE, 125);
|
|
GXSetTexCoordScaleManually(GX_TEXCOORD0, GX_TRUE, 256, 256);
|
|
GXSetTexCoordBias(GX_TEXCOORD0, 0, 0);
|
|
|
|
GXSetIndTexOrder(GX_INDTEXSTAGE0, GX_TEXCOORD0, GX_TEXMAP1);
|
|
GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1);
|
|
GXSetIndTexMtx(GX_ITM_0, indtexmtx, 1);
|
|
|
|
GXSetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
|
|
|
GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0);
|
|
|
|
cnt = 0;
|
|
for (i = 0; wp->work_priv._0000[i] != 0xFF; i += 2) {
|
|
val = wp->work_priv._0B40[wp->work_priv._0000[i]]._19;
|
|
if ((val & 0xE1) == 0) {
|
|
cnt += 4;
|
|
}
|
|
}
|
|
|
|
if (cnt != 0) {
|
|
GXSetNumChans(0);
|
|
GXSetNumTexGens(1);
|
|
GXSetNumTevStages(1);
|
|
GXSetNumIndStages(1);
|
|
|
|
GXClearVtxDesc();
|
|
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U16, 8);
|
|
GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE);
|
|
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, cnt);
|
|
|
|
do {
|
|
i -= 2;
|
|
work = ((u8*)wp + i);
|
|
val = wp->work_priv._0B40[work[0x60]]._19 & 0xE1;
|
|
if (val == 0) {
|
|
GXPosition2s16(0x180, -136 - work[0x60]);
|
|
GXTexCoord2u16(0x100, work[0x60]);
|
|
|
|
GXPosition2s16(0x180, -136 - work[0x61]);
|
|
GXTexCoord2u16(0x100, work[0x61]);
|
|
|
|
GXPosition2s16(0x080, -136 - work[0x61]);
|
|
GXTexCoord2u16(0x000, work[0x61]);
|
|
|
|
GXPosition2s16(0x080, -136 - work[0x60]);
|
|
GXTexCoord2u16(0x000, work[0x60]);
|
|
}
|
|
} while (i != 0);
|
|
}
|
|
|
|
cnt = 0;
|
|
for (i = 0; wp->work_priv._0000[i] != 0xFF; i += 2) {
|
|
val = wp->work_priv._0B40[wp->work_priv._0000[i]]._19;
|
|
if ((val & 0xE1) != 0) {
|
|
cnt += 4;
|
|
}
|
|
}
|
|
|
|
if (cnt != 0) {
|
|
GXSetNumChans(1);
|
|
GXSetNumTexGens(1);
|
|
GXSetNumTevStages(4);
|
|
GXSetNumIndStages(1);
|
|
|
|
GXClearVtxDesc();
|
|
GXSetVtxDesc(GX_VA_POS, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_CLR0, GX_DIRECT);
|
|
GXSetVtxDesc(GX_VA_TEX0, GX_DIRECT);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_POS, GX_POS_XY, GX_S16, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0);
|
|
GXSetVtxAttrFmt(GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_U16, 8);
|
|
|
|
GXSetTevIndirect(GX_TEVSTAGE0, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
|
|
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
|
GXSetTevIndirect(GX_TEVSTAGE1, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
|
|
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
|
GXSetTevIndirect(GX_TEVSTAGE2, GX_INDTEXSTAGE0, GX_ITF_8, GX_ITB_NONE, GX_ITM_0, GX_ITW_0, GX_ITW_0, GX_FALSE, GX_FALSE, GX_ITBA_OFF);
|
|
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR_NULL);
|
|
|
|
GXSetTevDirect(GX_TEVSTAGE3);
|
|
GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR0A0);
|
|
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_VTX, GX_SRC_VTX, 0, GX_DF_NONE, GX_AF_NONE);
|
|
|
|
GXSetTevSwapModeTable(GX_TEV_SWAP1, GX_CH_RED, GX_CH_RED, GX_CH_RED, GX_CH_ALPHA);
|
|
GXSetTevSwapModeTable(GX_TEV_SWAP2, GX_CH_GREEN, GX_CH_GREEN, GX_CH_GREEN, GX_CH_ALPHA);
|
|
GXSetTevSwapModeTable(GX_TEV_SWAP3, GX_CH_BLUE, GX_CH_BLUE, GX_CH_BLUE, GX_CH_ALPHA);
|
|
|
|
GXSetTevSwapMode(GX_TEVSTAGE0, GX_TEV_SWAP0, GX_TEV_SWAP1);
|
|
GXSetTevSwapMode(GX_TEVSTAGE1, GX_TEV_SWAP0, GX_TEV_SWAP2);
|
|
GXSetTevSwapMode(GX_TEVSTAGE2, GX_TEV_SWAP0, GX_TEV_SWAP3);
|
|
GXSetTevSwapMode(GX_TEVSTAGE3, GX_TEV_SWAP0, GX_TEV_SWAP0);
|
|
|
|
GXSetTevColorIn(GX_TEVSTAGE0, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C0, GX_CC_ZERO);
|
|
GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C1, GX_CC_CPREV);
|
|
GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_TEXC, GX_CC_C2, GX_CC_CPREV);
|
|
GXSetTevColorIn(GX_TEVSTAGE3, GX_CC_RASC, GX_CC_ZERO, GX_CC_ZERO, GX_CC_CPREV);
|
|
|
|
GXSetTevColorOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevColorOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevColorOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevColorOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
|
|
GXSetTevAlphaIn(GX_TEVSTAGE0, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
|
GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
|
GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
|
GXSetTevAlphaIn(GX_TEVSTAGE3, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO);
|
|
|
|
GXSetTevAlphaOp(GX_TEVSTAGE0, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevAlphaOp(GX_TEVSTAGE1, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevAlphaOp(GX_TEVSTAGE2, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
GXSetTevAlphaOp(GX_TEVSTAGE3, GX_TEV_ADD, GX_TB_ZERO, GX_CS_SCALE_1, GX_TRUE, GX_TEVPREV);
|
|
|
|
GXSetTevColor(GX_TEVREG0, color0);
|
|
GXSetTevColor(GX_TEVREG1, color1);
|
|
GXSetTevColor(GX_TEVREG2, color2);
|
|
|
|
GXBegin(GX_QUADS, GX_VTXFMT0, cnt);
|
|
|
|
do {
|
|
i -= 2;
|
|
work = (u8*)wp + i;
|
|
if ((wp->work_priv._0B40[work[0x60]]._19 & 0xE1) != 0) {
|
|
clr = 0x2F2F2F00;
|
|
if ((wp->work_priv._0B40[work[0x60]]._19 & 0x20) != 0) {
|
|
clr += 0x10000000;
|
|
}
|
|
if ((wp->work_priv._0B40[work[0x60]]._19 & 0x40) != 0) {
|
|
clr += 0x00100000;
|
|
}
|
|
if ((wp->work_priv._0B40[work[0x60]]._19 & 0x80) != 0) {
|
|
clr += 0x00001000;
|
|
}
|
|
|
|
GXPosition2s16(0x180, -136 - work[0x60]);
|
|
GXColor1u32(clr);
|
|
GXTexCoord2u16(0x100, work[0x60]);
|
|
|
|
GXPosition2s16(0x180, -136 - work[0x61]);
|
|
GXColor1u32(clr);
|
|
GXTexCoord2u16(0x100, work[0x61]);
|
|
|
|
GXPosition2s16(0x080, -136 - work[0x61]);
|
|
GXColor1u32(clr);
|
|
GXTexCoord2u16(0x000, work[0x61]);
|
|
|
|
GXPosition2s16(0x080, -136 - work[0x60]);
|
|
GXColor1u32(clr);
|
|
GXTexCoord2u16(0x000, work[0x60]);
|
|
}
|
|
} while (i != 0);
|
|
}
|
|
|
|
GXSetTexCopySrc(128, 136, 256, 228);
|
|
GXSetTexCopyDst(256, 228, GX_TF_RGB565, GX_FALSE);
|
|
GXSetCopyClear(black, 0xFFFFFF);
|
|
GXCopyTex(wp->result_bufp, GX_FALSE);
|
|
GXPixModeSync();
|
|
}
|
|
|
|
void ksNesDraw(ksNesCommonWorkObj* wp, ksNesStateObj* state) {
|
|
ksNesDrawInit(wp);
|
|
ksNesDrawClearEFBFirst(wp);
|
|
if (state->mapper == 9 || state->mapper == 10) {
|
|
ksNesDrawMakeBGIndTexMMC2(wp, state->mapper == 9 ? TRUE : FALSE);
|
|
ksNesDrawOBJSetupMMC2(wp);
|
|
} else if (state->mapper == 5) {
|
|
ksNesDrawMakeBGIndTexMMC5(wp, state);
|
|
} else {
|
|
ksNesDrawMakeBGIndTex(wp, state->mapper == 4 ? TRUE : FALSE);
|
|
}
|
|
PPCSync();
|
|
if (state->mapper == 5) {
|
|
ksNesDrawOBJMMC5(wp, state, 0);
|
|
} else {
|
|
ksNesDrawOBJ(wp, state, 0);
|
|
}
|
|
ksNesDrawFlushEFBToRed8(wp->result_bufp);
|
|
if (state->mapper == 5) {
|
|
ksNesDrawOBJMMC5(wp, state, 1);
|
|
} else {
|
|
ksNesDrawOBJ(wp, state, 1);
|
|
}
|
|
|
|
ksNesDrawBG(wp, state);
|
|
ksNesDrawOBJI8ToEFB(wp, wp->result_bufp);
|
|
ksNesDrawFlushEFBToRed8(wp->result_bufp);
|
|
ksNesDrawEmuResult(wp);
|
|
ksNesDrawEnd();
|
|
}
|