Merge pull request #511 from roeming/master

tiny progress on the last nes file
This commit is contained in:
Cuyler36
2025-07-12 15:31:04 -04:00
committed by GitHub
5 changed files with 414 additions and 73 deletions
+16 -2
View File
@@ -30,12 +30,26 @@ extern "C" {
#define KS_NES_BYTES_PER_KB (1024)
#define KS_NES_TO_KB(b) ((f32)b * (1.0f / (f32)KS_NES_BYTES_PER_KB))
typedef struct _0B40_struct {
u8* _00;
u8* _04;
u8* _08;
u32 _0C;
u32 _10;
u32 _14;
u8 _18;
u8 _19;
u8 pad2[0x6];
} B40_struct; // size == 0x20
typedef struct ksNesCommonWorkPriv {
/* 0x0000 */ u8 wram[KS_NES_WRAM_SIZE];
/* 0x0800 */ u8 _0800[0x340];
/* 0x0B40 */ u8* _0B40[0x7c0];
/* 0x0B40 */ B40_struct _0B40[0xf0];
/* 0x2940 */ u8 _2940[0x100];
/* 0x2A40 */ u8 _2A40[0x800];
/* 0x3240 */ u8 _3240[0x5c00];
/* 0x3240 */ u8 _3240[0x4800];
/* 0x7840 */ u8 _7840[0x1400];
/* 0x8E40 */ u8 _8E40[0x80];
/* 0x8EC0 */ u8 _8EC0[0x28];
/* 0x8EE8 */ Mtx34 draw_mtx;
+1 -1
View File
@@ -3,7 +3,7 @@
#include "MSL_C/MSL_Common/float.h"
#ifndef BUGFIXES
#if !defined(BUGFIXES) && !defined(FIX_SQRT_LINKAGE)
#define SQRTF_LINKAGE extern
#else
// making the function static instead of extern resolves the bug
+13 -12
View File
@@ -9,27 +9,28 @@ extern "C" {
#endif
typedef GXTexRegion* (*GXTexRegionCallback)(const GXTexObj* obj, GXTexMapID id);
typedef GXTlutRegion *(*GXTlutRegionCallback)(u32 idx);
typedef GXTlutRegion* (*GXTlutRegionCallback)(u32 idx);
void GXInitTexObj(GXTexObj *obj, void *image_ptr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, u8 mipmap);
void GXInitTexObjCI(GXTexObj *obj, void *image_ptr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrap_s, GXTexWrapMode wrap_t, u8 mipmap, u32 tlut_name);
void GXInitTexObjData(GXTexObj *obj, void *image_ptr);
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt, f32 min_lod,
f32 max_lod, f32 lod_bias, GXBool bias_clamp, GXBool do_edge_lod,
GXAnisotropy max_aniso);
void GXInitTexObj(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXTexFmt format, GXTexWrapMode wrap_s,
GXTexWrapMode wrap_t, u8 mipmap);
void GXInitTexObjCI(GXTexObj* obj, void* image_ptr, u16 width, u16 height, GXCITexFmt format, GXTexWrapMode wrap_s,
GXTexWrapMode wrap_t, u8 mipmap, u32 tlut_name);
void GXInitTexObjData(GXTexObj* obj, void* image_ptr);
void GXInitTexObjLOD(GXTexObj* obj, GXTexFilter min_filt, GXTexFilter mag_filt, f32 min_lod, f32 max_lod, f32 lod_bias,
GXBool bias_clamp, GXBool do_edge_lod, GXAnisotropy max_aniso);
void GXLoadTexObj(GXTexObj* obj, GXTexMapID id);
u32 GXGetTexBufferSize(u16 width, u16 height, u32 format, GXBool mipmap, u8 max_lod);
void GXInvalidateTexAll();
void GXInitTexObjWrapMode(GXTexObj* obj, GXTexWrapMode s, GXTexWrapMode t);
void GXInitTlutObj(GXTlutObj *tlut_obj, void *lut, GXTlutFmt fmt, u16 n_entries);
void GXInitTlutObj(GXTlutObj* tlut_obj, void* lut, GXTlutFmt fmt, u16 n_entries);
void GXLoadTlut(GXTlutObj* obj, u32 idx);
void GXSetTexCoordScaleManually(GXTexCoordID coord, GXBool enable, u16 ss, u16 ts);
void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even,
GXTexCacheSize size_even, u32 tmem_odd, GXTexCacheSize size_odd);
void GXInitTexCacheRegion(GXTexRegion* region, GXBool is_32b_mipmap, u32 tmem_even, GXTexCacheSize size_even,
u32 tmem_odd, GXTexCacheSize size_odd);
GXTexRegionCallback GXSetTexRegionCallback(GXTexRegionCallback callback);
void GXInvalidateTexRegion(GXTexRegion* region);
void GXInitTlutRegion(GXTlutRegion *region, u32 tmem_addr, GXTlutSize tlut_size);
void GXInitTlutRegion(GXTlutRegion* region, u32 tmem_addr, GXTlutSize tlut_size);
void GXSetTexCoordBias(GXTexCoordID coord, u8 s_enable, u8 t_enable);
#ifdef __cplusplus
}
#endif
+32 -57
View File
@@ -2354,16 +2354,15 @@ void ksNesConvertChrToI8(ksNesCommonWorkObj* wp, const u8* data, u32 flags) {
u32 j;
u32 d;
u32 mask;
bufSize = (wp->chr_to_i8_buf_size > CHR_TO_I8_BUF_SIZE ? 0x100 : wp->chr_to_i8_buf_size >> 12);
idx = (flags >> 9) & 0x1f;
a = (flags & 0x40) << 5;
b = (flags >> 4) & 0x18;
c = (flags & 0x3f) << 5;
abc = c + a + b;
for (i = 0; i < 8; i++) {
if (i & 1) {
d = (data[7 - (i >> 1)]) | (data[0xf - (i >> 1)] << 8);
@@ -2373,7 +2372,8 @@ void ksNesConvertChrToI8(ksNesCommonWorkObj* wp, const u8* data, u32 flags) {
mask = 0x8080;
for (j = 0; j < 8; j++) {
wp->chr_to_u8_bufp[abc + (flags & 0x3e00) * 8 + (i * (bufSize >> 3)) * 0x1000 + j] = (((d & mask) & 0xff00) != 0 ? 2 : 0) | (((u16)(d & mask) & 0x00FF) != 0 ? 1 : 0);
wp->chr_to_u8_bufp[abc + (flags & 0x3e00) * 8 + (i * (bufSize >> 3)) * 0x1000 + j] =
(((d & mask) & 0xff00) != 0 ? 2 : 0) | (((u16)(d & mask) & 0x00FF) != 0 ? 1 : 0);
mask >>= 1;
}
DCStoreRangeNoSync(wp->chr_to_u8_bufp + (((idx) + (i * (bufSize >> 3))) * 0x1000 + b + a + c), 0x20);
@@ -2405,7 +2405,8 @@ void ksNesConvertChrToI8MMC5(ksNesCommonWorkObj* wp, const u8* ptr, u32 flag) {
mask = 0x8080;
for (j = 0; j < 8; j++) {
wp->chr_to_u8_bufp[abc + (flag & (0x3F << 9)) * 8 + (i * (adj >> 3)) * 0x1000 + j] = (((v & mask) & 0xFF00) != 0 ? 2 : 0) | ((((u16)(v & mask)) & 0x00FF) != 0 ? 1 : 0);
wp->chr_to_u8_bufp[abc + (flag & (0x3F << 9)) * 8 + (i * (adj >> 3)) * 0x1000 + j] =
(((v & mask) & 0xFF00) != 0 ? 2 : 0) | ((((u16)(v & mask)) & 0x00FF) != 0 ? 1 : 0);
mask >>= 1;
}
@@ -2477,8 +2478,8 @@ int ksNesQDFastLoad(ksNesCommonWorkObj* wp, ksNesStateObj* sp) {
}
memset(sp->wram + 0x200, 0, 0x600);
boot_file_no = search_p[25]; // boot file number
file_count = search_p[QD_BLOCK_DISKINFO_SZ + 1]; // amount->file_amount
boot_file_no = search_p[25]; // boot file number
file_count = search_p[QD_BLOCK_DISKINFO_SZ + 1]; // amount->file_amount
search_p += QD_BLOCK_DISKINFO_SZ + QD_BLOCK_AMOUNT_SZ; // skip immediately to first file info block
while (file_count != 0 && search_p < disk_end_p) {
@@ -2496,7 +2497,9 @@ int ksNesQDFastLoad(ksNesCommonWorkObj* wp, ksNesStateObj* sp) {
if (load_ofs < KS_NES_CHRRAM_SIZE && size <= KS_NES_CHRRAM_SIZE) {
memcpy(sp->chrramp + load_ofs, &search_p[QD_BLOCK_FILEHEADER_SZ + 1], size);
}
} else if (((load_ofs < KS_NES_WRAM_SIZE || load_ofs > (0x6000-1)) && (load_ofs < 0xE000 && ((load_ofs + size) <= KS_NES_WRAM_SIZE || (load_ofs + size) > 0x6000))) && (load_ofs + size) <= 0xE000 && (size <= KS_NES_BBRAM_SIZE && size != 0)) {
} else if (((load_ofs < KS_NES_WRAM_SIZE || load_ofs > (0x6000 - 1)) &&
(load_ofs < 0xE000 && ((load_ofs + size) <= KS_NES_WRAM_SIZE || (load_ofs + size) > 0x6000))) &&
(load_ofs + size) <= 0xE000 && (size <= KS_NES_BBRAM_SIZE && size != 0)) {
if (load_ofs < KS_NES_WRAM_SIZE) {
memcpy(sp->wram + load_ofs, &search_p[QD_BLOCK_FILEHEADER_SZ + 1], size);
} else {
@@ -2562,7 +2565,7 @@ search_start:
return -1;
}
search_p[0] = 3; // write file header block code? (3)
search_p[0] = 3; // write file header block code? (3)
search_p[1] = sp->wram[14]; // write file number?
memcpy(search_p + 2, sp->_176E + 10, 14);
@@ -2571,7 +2574,7 @@ search_start:
search_p += 19;
// write data
j = 0;
for (j = 0; j < save_len; j++) {
u8* read_p = (&sp->cpu_0000_1fff)[ksNes_ADDR2BANK(read_ofs + j)] + j;
@@ -2635,9 +2638,9 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
u8* nesromp;
OSTick os_tick;
uint uVar4;
int iVar4;
size_t count;
u8 bVar1;
int i;
// 0x40XX values appear to be NES APU addresses
// 0x5015 could be the address of the MMC5's audio status register
@@ -2659,23 +2662,17 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
if ((flags & 0x40) == 0) {
Sound_SetC000(sp->wram);
Sound_SetE000(sp->wram);
count = 0;
uVar4 = 0;
do {
if (!(count & 7) && 0x40 <= count && count < 0x90) {
for (u32 i = 0; i < 0x106; i++) {
if (!(i & 7) && 0x40 <= i && i < 0x90) {
uVar1 = count - 0x40 >> 3 & 0x3fffffff;
uVar1 = i - 0x40 >> 3 & 0x3fffffff;
Sound_Write((u16)sound_init_data[uVar1], (u8)sound_init_data[uVar1 + 1], uVar4);
Sound_Write((u16)sound_init_data[uVar1], (u8)sound_init_data[uVar1 + 1], i * 0x72);
}
Sound_Write(0, 0, uVar4);
count++;
uVar4 += 0x72;
} while (count < 0x106);
Sound_Write(0, 0, i * 0x72);
}
}
if (flags & 1) {
@@ -2692,32 +2689,23 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
} else {
// fill ram with a predetermined pattern.
iVar2 = 0;
for (count = 0x200; count; count--) {
for (i = 0, iVar2 = 0; i < 0x200; iVar2 += 4, i++) {
wramp = &sp->wram[iVar2];
wramp[0] = 0x0f;
wramp[1] = 0xef;
wramp[2] = 0xfe;
wramp[3] = 0x7d;
iVar2 += 4;
}
}
// zero out the private work struct
memset(&wp->work_priv, 0, sizeof(ksNesCommonWorkPriv));
iVar4 = 0;
iVar2 = 0;
// the state struct is (mostly) zeroed out.
// this sets up some self referential pointer in the state struct for an unknown reason.
for (count = 0x18; count; count--) {
sp->_186C[iVar2] = &sp->_0800[table[iVar4 & 0xf] * 0x100];
iVar4++;
iVar2++;
for (i = 0; i < 0x18; i++) {
sp->_186C[i] = &sp->_0800[table[i & 0xf] * 0x100];
}
sp->nesromp = wp->nesromp;
@@ -2775,34 +2763,21 @@ int ksNesReset(ksNesCommonWorkObj* wp, ksNesStateObj* sp, u32 flags, u8* chrramp
memcpy(sp->palette_normal, &ksNesPaletteNormal, 0x80);
}
iVar2 = 0;
for (count = 0x80; count; count--) {
sp->_16CC[iVar2] = 0x0f;
iVar2++;
for (i = 0; i < 0x80; i++) {
sp->_16CC[i] = 0x0f;
}
iVar2 = 0;
for (count = 8; count; count--) {
sp->_16A0[iVar2] = 0x20;
iVar2++;
for (i = 0; i < 8; i++) {
sp->_16A0[i] = 0x20;
}
iVar2 = 0;
// i think we're dealing a new type of struct here.
for (count = 0xf0; count; count--) {
wp->work_priv._0B40[iVar2] = sp->_1810[0];
wp->work_priv._0B40[iVar2 + 1] = sp->_1810[1];
iVar2 += 8;
for (i = 0; i < 0xf0; i++) {
wp->work_priv._0B40[i]._00 = sp->_1810[0];
wp->work_priv._0B40[i]._04 = sp->_1810[1];
}
iVar2 = 0;
for (count = 8; count; count--) {
sp->_17FC[iVar2] = (u8)iVar2;
iVar2++;
for (i = 0; i < 8; i++) {
sp->_17FC[i] = (u8)i;
}
memset(wp->chr_to_u8_bufp, 0, wp->chr_to_i8_buf_size);
+352 -1
View File
@@ -1,5 +1,8 @@
#define FIX_SQRT_LINKAGE
#include "Famicom/ks_nes_draw.h"
#include "dolphin/gx.h"
#include "dolphin/PPCArch.h"
#include "_mem.h"
u8 ksNesPaletteNormal[] = {
0xc2, 0x10, 0x80, 0x17, 0x98, 0x17, 0xc0, 0x14, 0xdc, 0x0d, 0xd8, 0x03, 0xd8, 0x00, 0xc8, 0x80, 0xbc, 0xa0, 0x80,
@@ -10,3 +13,351 @@ u8 ksNesPaletteNormal[] = {
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(0x80, -0x80);
GXColor1u32(0x00ff0000);
GXPosition2s16(0x180, -0x80);
GXColor1u32(0x00000000);
GXPosition2s16(0x180, -0x180);
GXColor1u32(0x0000ff00);
GXPosition2s16(0x80, -0x180);
GXColor1u32(0x00000000);
}
GXEnd();
}
void ksNesDrawMakeBGIndTex(ksNesCommonWorkObj* wp, u32 ind) {
u32 myInd = 0x7fff;
u8 myInd2 = 0x80;
if (ind) {
myInd = 9;
}
if (wp->chr_to_i8_buf_size <= 0x1000000) {
myInd2 = wp->chr_to_i8_buf_size >> 0xd;
}
DCFlushRangeNoSync(wp->work_priv._3240, sizeof(wp->work_priv._3240));
DCFlushRangeNoSync(wp->work_priv._7840, sizeof(wp->work_priv._7840));
}
void ksNesDrawMakeBGIndTexMMC5(ksNesCommonWorkObj*, ksNesStateObj*) {
}
void ksNesDrawMakeBGIndTexMMC2(ksNesCommonWorkObj*, u32) {
}
void ksNesDrawOBJSetupMMC2(ksNesCommonWorkObj*) {
}
void ksNesDrawBG(ksNesCommonWorkObj*, ksNesStateObj*) {
}
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.wram[ret] = i - wp->_004C[ret + 0x13];
ret++;
}
if ((comparison_mask == 20) || (wp->work_priv._0B40[i]._19 & 0x10) == 0) {
wp->work_priv.wram[ret++] = i;
}
comparison_mask = wp->work_priv._0B40[i]._19 & 0x14;
}
}
if (ret & 1) {
wp->work_priv.wram[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.wram[ret] = i - wp->_004C[ret + 0x13];
ret++;
}
if ((wp->work_priv._0B40[i]._19 & 0x10)) {
wp->work_priv.wram[ret++] = i;
}
comparison_mask = wp->work_priv._0B40[i]._19 & 0x14;
}
}
if (ret & 1) {
wp->work_priv.wram[ret] = i - wp->_004C[ret + 0x13];
ret++;
}
return ret;
}
void ksNesDrawOBJ(ksNesCommonWorkObj* wp, ksNesStateObj* state, u32 c) {
u32 size = 0x100000;
int i;
GXTexObj GStack_7c;
GXTexObj GStack_9c;
GXTexObj GStack_bc;
if (wp->chr_to_i8_buf_size <= 0x100000) {
size = wp->chr_to_i8_buf_size;
}
if (c == 0) {
for (u32 i = 0; i < 0x110; i++) {
u32 v;
if (i < 0xf0) {
v = 8;
if (state->frame_flags & 0x2000) {
v = 255;
}
} else {
v = 0;
}
wp->work_priv.wram[i] = v;
if ((wp->work_priv._0B40[i]._19 & 0x10) == 0) {
wp->work_priv.wram[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.wram[i] = 0;
}
}
}
memset(&wp->work_priv.wram[0x340], 0, 0x800);
u8* uVar6 = &wp->work_priv.wram[0x340];
int a;
for (u32 i = 0; i < 0x100; i++) {
int _j = 8;
if (wp->work_priv._0B40[wp->work_priv._2940[i]]._18 & 0x20) {
_j = 0x10;
}
a = 0;
int b, _c;
if (wp->work_priv._2940[i + 2] & 0x80) {
b = _j << 2;
_c = -4;
} else {
b = 0;
_c = 4;
}
u32 j, val;
for (j = 0; j < _j; j++) {
int ind = j + wp->work_priv._2940[i];
val = wp->work_priv.wram[ind];
if (val) {
wp->work_priv.wram[ind]--;
if ((a & 2) == 0) {
uVar6[a] = wp->work_priv._2940[i] + j;
uVar6[a + 1] = b;
a += 2;
}
} else if ((a & 2) != 0) {
uVar6[a] = wp->work_priv._2940[i] + j;
uVar6[a + 1] = b;
a += 2;
}
b += _c;
val = b;
}
if ((a & 2) != 0) {
uVar6[a] = wp->work_priv._2940[i] + j;
uVar6[a + 1] = val;
a += 2;
}
wp->work_priv.wram[0x300 + (i / 4)] = a;
}
}
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);
}
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) {
}
void ksNesDrawEmuResult(ksNesCommonWorkObj*) {
}
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();
}