From 1d8860ab1d574bdf9065bb1b016af7dde2650e8b Mon Sep 17 00:00:00 2001 From: Cuyler36 Date: Tue, 8 Apr 2025 11:07:06 -0400 Subject: [PATCH] More work on emu64 --- config/GAFE01_00/splits.txt | 2 +- configure.py | 2 +- include/libforest/emu64/emu64.hpp | 12 +- include/libforest/emu64/emu64_wrapper.h | 2 +- include/libforest/emu64/texture_cache.h | 10 +- include/libforest/gbi_extensions.h | 9 + include/types.h | 4 + .../libforest/emu64/{emu64.cc => emu64.c} | 204 +++++++++++------- .../{emu64_utility.cc => emu64_utility.c} | 0 9 files changed, 156 insertions(+), 89 deletions(-) rename src/static/libforest/emu64/{emu64.cc => emu64.c} (97%) rename src/static/libforest/emu64/{emu64_utility.cc => emu64_utility.c} (100%) diff --git a/config/GAFE01_00/splits.txt b/config/GAFE01_00/splits.txt index f7726212..51d0e921 100644 --- a/config/GAFE01_00/splits.txt +++ b/config/GAFE01_00/splits.txt @@ -440,7 +440,7 @@ GBA2/JoyBoot.c: .data start:0x800DAA08 end:0x800DAAA0 .bss start:0x801F7180 end:0x801F71C0 -libforest/emu64/emu64.cc: +libforest/emu64/emu64.c: .text start:0x8004AE00 end:0x800595CC .text start:0x800595CC end:0x800595CC .text start:0x800595CC end:0x8005A654 diff --git a/configure.py b/configure.py index 09e1cb04..7cab7b31 100644 --- a/configure.py +++ b/configure.py @@ -345,7 +345,7 @@ config.libs = [ "progress_category": "library", "src_dir": "src/static", "objects": [ - Object(NonMatching, "libforest/emu64/emu64.cc", extra_cflags=["-lang=c++", "-O4,p", "-inline auto"]), + Object(NonMatching, "libforest/emu64/emu64.c", extra_cflags=["-lang=c++", "-O4,p", "-inline auto"]), Object(Matching, "libforest/osreport.c"), Object(Matching, "libforest/fault.c"), Object(Matching, "libforest/ReconfigBATs.c"), diff --git a/include/libforest/emu64/emu64.hpp b/include/libforest/emu64/emu64.hpp index 453e5b44..3f027f3e 100644 --- a/include/libforest/emu64/emu64.hpp +++ b/include/libforest/emu64/emu64.hpp @@ -250,7 +250,7 @@ typedef union GXTexFmts { u32 raw; } GXTexFmts; -static inline void get_blk_wd_ht(unsigned int siz, unsigned int* blk_wd, unsigned int* blk_ht) { +inline void get_blk_wd_ht(unsigned int siz, unsigned int* blk_wd, unsigned int* blk_ht) { static u8 blk_tbl[4][2] = { { 8, 8 }, // G_IM_SIZ_4b { 8, 4 }, // G_IM_SIZ_8b @@ -264,7 +264,7 @@ static inline void get_blk_wd_ht(unsigned int siz, unsigned int* blk_wd, unsigne extern void get_dol_wd_ht(unsigned int siz, unsigned int in_wd, unsigned int in_ht, unsigned int* wd, unsigned int* ht); -static inline unsigned int rgba5551_to_rgb5a3(unsigned int rgba5551) { +inline unsigned int rgba5551_to_rgb5a3(unsigned int rgba5551) { unsigned int rgb5a3; switch (rgba5551 & 1) { @@ -279,7 +279,7 @@ static inline unsigned int rgba5551_to_rgb5a3(unsigned int rgba5551) { return rgb5a3; } -static inline unsigned int get_dol_tex_siz(unsigned int siz, unsigned int in_wd, unsigned int in_ht) { +inline unsigned int get_dol_tex_siz(unsigned int siz, unsigned int in_wd, unsigned int in_ht) { unsigned int wd; unsigned int ht; @@ -287,7 +287,7 @@ static inline unsigned int get_dol_tex_siz(unsigned int siz, unsigned int in_wd, return ((wd * ht) << siz) / 2; } -static inline unsigned int get_dol_tlut_siz(unsigned int count) { +inline unsigned int get_dol_tlut_siz(unsigned int count) { unsigned int siz = count * sizeof(u16); return ALIGN_NEXT(siz, 32); } @@ -489,7 +489,7 @@ class emu64_print { }; #define EMU64_ASSERTLINE(cond, line) \ - if (!cond) { \ + if (!(cond)) { \ this->panic(#cond, __FILE__, line); \ } @@ -579,7 +579,7 @@ class emu64 : public emu64_print { unsigned int start_wd, unsigned int start_ht, unsigned int end_wd, unsigned int end_ht, unsigned int line_siz); unsigned int tmem_swap(unsigned int ofs, unsigned int blk_siz) { - return ofs ^ ((ofs / blk_siz) & 4); + return ofs ^ (((ofs / blk_siz) >> 1) & 4); } void tlutconv_rgba5551(u16* rgba5551_p, u16* rgb5a3_p, unsigned int count); void tlutconv_ia16(u16* src_ia16_p, u16* dst_ia16_p, unsigned int count); diff --git a/include/libforest/emu64/emu64_wrapper.h b/include/libforest/emu64/emu64_wrapper.h index c24db954..4b503c2c 100644 --- a/include/libforest/emu64/emu64_wrapper.h +++ b/include/libforest/emu64/emu64_wrapper.h @@ -17,7 +17,7 @@ extern void emu64_init(); extern void emu64_refresh(); extern void emu64_cleanup(); -extern void emu64_texture_cache_data_entry_set(u8* cache_start, u8* cache_end); +extern void emu64_texture_cache_data_entry_set(void* begin, void* end); #ifdef __cplusplus } diff --git a/include/libforest/emu64/texture_cache.h b/include/libforest/emu64/texture_cache.h index 4c1aee8d..ba7e2758 100644 --- a/include/libforest/emu64/texture_cache.h +++ b/include/libforest/emu64/texture_cache.h @@ -6,6 +6,7 @@ #ifdef __cplusplus extern "C" { +#endif #define TEX_CACHE_ALIGNMENT (32 - 1) /* 32 byte alignment */ #define NUM_TEXTURE_CACHE_DATA 10 @@ -61,17 +62,10 @@ typedef struct texture_cache_s { /* TMEM map */ // static tmem_t tmem_map[TMEM_ENTRIES]; -/* Shared alloc function */ -void* texture_cache_alloc(texture_cache_t* cache, u32 size); - -/* .data cache functions */ -void* texture_cache_data_search(void* addr); -int texture_cache_data_entry(void* original, void* converted); - #define TEX_BUFFER_DATA_SIZE 0xC000 #define TEX_BUFFER_BSS_SIZE 0x1000 -extern texture_cache_t* texture_cache_select(void* address); +#ifdef __cplusplus } #endif diff --git a/include/libforest/gbi_extensions.h b/include/libforest/gbi_extensions.h index 248f969c..1368456d 100644 --- a/include/libforest/gbi_extensions.h +++ b/include/libforest/gbi_extensions.h @@ -262,6 +262,15 @@ typedef struct { unsigned int d1:4; } Gsetcombine_tev; +typedef struct { + int cmd:8; + unsigned int upper0:8; + unsigned int lower0:16; + + unsigned int upper1:16; + unsigned int lower1:16; +} Gsetcombine_raw; + typedef struct { unsigned int cmd:8; unsigned int xl:12; /* Top-left x coord */ diff --git a/include/types.h b/include/types.h index af1f2aed..49b8f19d 100644 --- a/include/types.h +++ b/include/types.h @@ -43,7 +43,11 @@ typedef u32 unknown; #define FALSE 0 #ifndef NULL +#ifndef __cplusplus #define NULL ((void*)0) +#else +#define NULL 0 +#endif #endif #define nullptr 0 diff --git a/src/static/libforest/emu64/emu64.cc b/src/static/libforest/emu64/emu64.c similarity index 97% rename from src/static/libforest/emu64/emu64.cc rename to src/static/libforest/emu64/emu64.c index b1f699a5..49319fde 100644 --- a/src/static/libforest/emu64/emu64.cc +++ b/src/static/libforest/emu64/emu64.c @@ -14,7 +14,7 @@ #pragma inline_depth(smart) #pragma inline_max_size(1000) -#include "../src/static/libforest/emu64/emu64_utility.cc" +#include "../src/static/libforest/emu64/emu64_utility.c" extern void OSInitFastCast(void); @@ -32,6 +32,11 @@ static texture_cache_entry_t texture_cache_list[TEXTURE_CACHE_LIST_SIZE]; static texture_cache_data_entry_t texture_cache_data_entry_tbl[NUM_TEXTURE_CACHE_DATA]; static int texture_cache_data_entry_num = 0; +static void* texture_cache_alloc(texture_cache_t* cache, u32 size); +static void* texture_cache_data_search(void* addr); +static int texture_cache_data_entry(void* original, void* converted); +static texture_cache_t* texture_cache_select(void* address); + static texture_cache_funcs texture_cache_data_func = { &texture_cache_data_search, &texture_cache_data_entry, @@ -50,8 +55,8 @@ static texture_cache_t texture_cache_data = { }; /* .bss cache functions */ -void* texture_cache_bss_search(void* addr); -int texture_cache_bss_entry(void* original, void* converted); +static void* texture_cache_bss_search(void* addr); +static int texture_cache_bss_entry(void* original, void* converted); static texture_cache_funcs texture_cache_bss_func = { &texture_cache_bss_search, @@ -71,14 +76,12 @@ static texture_cache_t texture_cache_bss = { }; extern void emu64_texture_cache_data_entry_set(void* begin, void* end) { - texture_cache_data_entry_t* entry = &texture_cache_data_entry_tbl[texture_cache_data_entry_num]; - - entry->start = begin; - entry->end = end; + texture_cache_data_entry_tbl[texture_cache_data_entry_num].start = begin; + texture_cache_data_entry_tbl[texture_cache_data_entry_num].end = end; texture_cache_data_entry_num++; } -extern texture_cache_t* texture_cache_select(void* addr) { +static texture_cache_t* texture_cache_select(void* addr) { int i; if (aflags[AFLAGS_SKIP_TEXTURE_CONV] >= 1 || (addr >= _f_rodata && addr <= _e_data)) { @@ -123,18 +126,15 @@ MATCH_FORCESTRIP static u32 texture_cache_get_heap_size(texture_cache_t* cache) return cache->buffer_end - cache->buffer_start; } -extern void* texture_cache_alloc(texture_cache_t* cache, size_t size) { - u32 new_pos; - +static void* texture_cache_alloc(texture_cache_t* cache, u32 size) { cache->last_alloc_start = cache->buffer_current; cache->last_alloc_end = (u8*)ALIGN_NEXT((u32)cache->buffer_current + size, 32); - new_pos = cache->last_alloc_end - cache->buffer_start; - if (cache->buffer_pos < new_pos) { - cache->buffer_pos = new_pos; + if (cache->buffer_pos < cache->last_alloc_end - cache->buffer_start) { + cache->buffer_pos = cache->last_alloc_end - cache->buffer_start; } - if (cache->buffer_end < cache->last_alloc_end) { + if (cache->last_alloc_end > cache->buffer_end) { cache->is_overflow = true; return nullptr; } @@ -143,7 +143,7 @@ extern void* texture_cache_alloc(texture_cache_t* cache, size_t size) { return cache->last_alloc_start; } -extern void* texture_cache_data_search(void* original_addr) { +static void* texture_cache_data_search(void* original_addr) { int i; for (i = 0; i < texture_cache_num; i++) { @@ -155,12 +155,11 @@ extern void* texture_cache_data_search(void* original_addr) { return nullptr; } -extern int texture_cache_data_entry(void* original_addr, void* converted_addr) { +static int texture_cache_data_entry(void* original_addr, void* converted_addr) { if (texture_cache_num < TEXTURE_CACHE_LIST_SIZE && original_addr != nullptr && converted_addr != nullptr) { - texture_cache_entry_t* entry = &texture_cache_list[texture_cache_num++]; - - entry->original = original_addr; - entry->converted = converted_addr; + texture_cache_list[texture_cache_num].original = original_addr; + texture_cache_list[texture_cache_num].converted = converted_addr; + texture_cache_num++; return 0; } @@ -168,11 +167,11 @@ extern int texture_cache_data_entry(void* original_addr, void* converted_addr) { return -1; } -extern void* texture_cache_bss_search(void* original_addr) { +static void* texture_cache_bss_search(void* original_addr) { return nullptr; } -extern int texture_cache_bss_entry(void* original_addr, void* converted_addr) { +static int texture_cache_bss_entry(void* original_addr, void* converted_addr) { return -1; } @@ -247,8 +246,9 @@ static GXColor white_color = { 255, 255, 255, 255 }; static void emu64_init2(GXRenderModeObj* render_mode) { GC_Mtx m; + int i; - __GXSetIndirectMask(0); + // __GXSetIndirectMask(0); GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY); @@ -314,6 +314,44 @@ static void emu64_init2(GXRenderModeObj* render_mode) { GXSetTevOrder(GX_TEVSTAGE13, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); GXSetTevOrder(GX_TEVSTAGE14, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); GXSetTevOrder(GX_TEVSTAGE15, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + + GXSetNumTevStages(1); + GXSetTevOp(GX_TEVSTAGE0, GX_REPLACE); + GXSetAlphaCompare(GX_ALWAYS, 0, GX_AOP_AND, GX_ALWAYS, 0); + GXSetZTexture(GX_ZT_DISABLE, GX_TF_Z8, 0); + + for (i = 0; i < GX_MAX_TEVSTAGE; i++) { + GXSetTevKColorSel((GXTevStageID)i, GX_TEV_KCSEL_1_4); + GXSetTevKAlphaSel((GXTevStageID)i, GX_TEV_KASEL_1); + GXSetTevSwapMode((GXTevStageID)i, GX_TEV_SWAP0, GX_TEV_SWAP0); + } + + GXSetTevSwapModeTable(GX_TEV_SWAP0, GX_CH_RED, GX_CH_GREEN, GX_CH_BLUE, GX_CH_ALPHA); + 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); + + for (i = 0; i < GX_MAX_TEVSTAGE; i++) { + GXSetTevDirect((GXTevStageID)i); + } + + GXSetNumIndStages(0); + GXSetIndTexCoordScale(GX_INDTEXSTAGE0, GX_ITS_1, GX_ITS_1); + GXSetIndTexCoordScale(GX_INDTEXSTAGE1, GX_ITS_1, GX_ITS_1); + GXSetIndTexCoordScale(GX_INDTEXSTAGE2, GX_ITS_1, GX_ITS_1); + GXSetIndTexCoordScale(GX_INDTEXSTAGE3, GX_ITS_1, GX_ITS_1); + + GXSetFog(GX_FOG_NONE, 0.0f, 1.0f, 0.1f, 1.0f, black_color); + GXSetFogRangeAdj(GX_FALSE, 0, 0); + GXSetBlendMode(GX_BM_NONE, GX_BL_SRCALPHA, GX_BL_INVSRCALPHA, GX_LO_CLEAR); + GXSetColorUpdate(GX_TRUE); + GXSetAlphaUpdate(GX_TRUE); + GXSetZMode(GX_TRUE, GX_LEQUAL, GX_TRUE); + GXSetZCompLoc(GX_TRUE); + GXSetDither(GX_FALSE); + GXSetDstAlpha(GX_FALSE, 0); + GXSetFieldMask(GX_TRUE, GX_TRUE); + GXSetFieldMode(render_mode->field_rendering, (render_mode->xfbHeight * 2 - render_mode->viHeight) == 0 ? GX_TRUE : GX_FALSE); } void emu64::emu64_init() { @@ -333,6 +371,7 @@ void emu64::emu64_init() { PSMTXIdentity(this->perspective_mtx); PSMTXIdentity(this->projection_mtx); PSMTXIdentity(this->original_projection_mtx); + PSMTXIdentity(this->position_mtx); PSMTXIdentity(this->model_view_mtx_stack[0]); PSMTXIdentity(this->position_mtx_stack[0]); GXSetProjection(this->ortho_mtx, GX_ORTHOGRAPHIC); @@ -374,7 +413,7 @@ void emu64::emu64_init() { 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88 }; - for (int i = GX_TEXMAP0; i < GX_MAX_TEXMAP; i++) { + for (u32 i = GX_TEXMAP0; i < GX_MAX_TEXMAP; i++) { GXInitTexObj(&this->tex_objs[i], black_texture, 8, 4, GX_TF_I8, GX_CLAMP, GX_CLAMP, GX_FALSE); GXLoadTexObj(&this->tex_objs[i], (GXTexMapID)i); } @@ -382,7 +421,8 @@ void emu64::emu64_init() { texture_cache_bss.is_overflow = false; texture_cache_bss.buffer_current = texture_cache_bss.buffer_start; - if (texture_cache_data.is_overflow) { + int overflow = texture_cache_data.is_overflow; + if (overflow) { texture_cache_data.is_overflow = false; texture_cache_data.buffer_current = texture_cache_data.buffer_start; texture_cache_num = 0; @@ -444,8 +484,15 @@ void emu64::printInfo() { } void emu64::panic(char* msg, char* file, int line) { - this->Printf0(VT_COL(RED, WHITE) "emu64 PANIC!! in %s line %d" VT_RST "\n", file, line); - this->Printf0("%s", msg); + if (file) { + this->Printf0(VT_COL(RED, WHITE) "emu64 PANIC!! in %s line %d" VT_RST "\n", file, line); + } else { + this->Printf0(VT_COL(RED, WHITE) "emu64 PANIC!!" VT_RST "\n", file, line); + } + + if (msg) { + this->Printf0("%s", msg); + } this->printInfo(); } @@ -481,47 +528,53 @@ extern void get_dol_wd_ht(unsigned int siz, unsigned int in_wd, unsigned int in_ } void emu64::texconv_tile(u8* addr, u8* converted_addr, unsigned int wd, unsigned int fmt, unsigned int siz, - unsigned int start_wd, unsigned int start_ht, unsigned int end_wd, unsigned int end_ht, - unsigned int line_siz) { - unsigned int blk_wd; + unsigned int start_wd, unsigned int start_ht, unsigned int end_wd, unsigned int end_ht, + unsigned int line_siz) { unsigned int blk_ht; + unsigned int blk_wd; + unsigned int blk_y; + unsigned int blk_x; + unsigned int y; + unsigned int y_ofs; get_blk_wd_ht(siz, &blk_wd, &blk_ht); - for (unsigned int blk_y = start_ht; blk_y < end_ht; blk_y += blk_ht) { - for (unsigned int blk_x = start_wd; blk_x < end_wd; blk_x += blk_wd) { - for (unsigned int y = 0; y < blk_ht; y++) { - unsigned int y_ofs = start_ht + y; + for (blk_y = start_ht; blk_y < end_ht; blk_y += blk_ht) { + for (blk_x = start_wd; blk_x < end_wd; blk_x += blk_wd) { + for (y = 0; y < blk_ht; y++) { + y_ofs = blk_y + y; if (siz == G_IM_SIZ_16b) { if (fmt == G_IM_FMT_RGBA) { unsigned int x_ofs = (blk_x + y_ofs * wd) * sizeof(u16); unsigned int ofs = this->tmem_swap(x_ofs, line_siz); + u16* src = (u16*)(addr + ofs); - *(u16*)(converted_addr + 0) = rgba5551_to_rgb5a3(*(u16*)(addr + ofs + 0)); - *(u16*)(converted_addr + 2) = rgba5551_to_rgb5a3(*(u16*)(addr + ofs + 2)); + *(u16*)(converted_addr + 0) = rgba5551_to_rgb5a3(src[0]); + *(u16*)(converted_addr + 2) = rgba5551_to_rgb5a3(src[1]); ofs = this->tmem_swap(x_ofs + 4, line_siz); - - *(u16*)(converted_addr + 4) = rgba5551_to_rgb5a3(*(u16*)(addr + ofs + 0)); - *(u16*)(converted_addr + 6) = rgba5551_to_rgb5a3(*(u16*)(addr + ofs + 2)); + src = (u16*)(addr + ofs); + *(u16*)(converted_addr + 4) = rgba5551_to_rgb5a3(src[0]); + *(u16*)(converted_addr + 6) = rgba5551_to_rgb5a3(src[1]); } else if (fmt == G_IM_FMT_IA) { unsigned int x_ofs = (blk_x + y_ofs * wd) * sizeof(u16); unsigned int ofs = this->tmem_swap(x_ofs, line_siz); u8* src = addr + ofs; - *(converted_addr + 0) = *(src + 1); - *(converted_addr + 1) = *(src + 0); - *(converted_addr + 2) = *(src + 3); - *(converted_addr + 3) = *(src + 2); + converted_addr[0] = src[1]; + converted_addr[1] = src[0]; + converted_addr[2] = src[3]; + converted_addr[3] = src[2]; - ofs = this->tmem_swap(x_ofs + 4, line_siz); + x_ofs += 4; + ofs = this->tmem_swap(x_ofs, line_siz); src = addr + ofs; - *(converted_addr + 4) = *(src + 1); - *(converted_addr + 5) = *(src + 0); - *(converted_addr + 6) = *(src + 3); - *(converted_addr + 7) = *(src + 2); + converted_addr[4] = src[1]; + converted_addr[5] = src[0]; + converted_addr[6] = src[3]; + converted_addr[7] = src[2]; } converted_addr += 8; @@ -529,12 +582,18 @@ void emu64::texconv_tile(u8* addr, u8* converted_addr, unsigned int wd, unsigned if (fmt == G_IM_FMT_IA) { unsigned int x_ofs = blk_x + y_ofs * wd; unsigned int ofs = this->tmem_swap(x_ofs, line_siz); + u32* dst = (u32*)converted_addr; + u32* src = (u32*)(addr + ofs); + u32 part0 = (src[0] << 4) & 0xF0F0F0F0; + u32 part1 = (src[0] >> 4) & 0x0F0F0F0F; + + dst[0] = part0 + part1; - *(u32*)(converted_addr + 0) = - (((*(u32*)(addr + ofs)) & 0x0F0F0F0F) << 4) | (((*(u32*)(addr + ofs)) & 0xF0F0F0F0) >> 4); ofs = this->tmem_swap(x_ofs + 4, line_siz); - *(u32*)(converted_addr + 4) = - (((*(u32*)(addr + ofs)) & 0x0F0F0F0F) << 4) | (((*(u32*)(addr + ofs)) & 0xF0F0F0F0) >> 4); + src = (u32*)(addr + ofs); + u32 part02 = (src[0] << 4) & 0xF0F0F0F0; + u32 part12 = (src[0] >> 4) & 0x0F0F0F0F; + dst[1] = part02 + part12; } else { unsigned int x_ofs = blk_x + y_ofs * wd; unsigned int ofs = this->tmem_swap(x_ofs, line_siz); @@ -986,9 +1045,11 @@ int emu64::combine_auto() { } int emu64::combine_tev() { - Gsetcombine_tev combine_tev = *((Gsetcombine_tev*)&this->combine_gfx); + + if ((u8)this->combine_gfx.setcombine.cmd == G_SETCOMBINE_TEV) { + int two_cycle = (this->othermode_high & G_CYC_2CYCLE) >> G_MDSFT_CYCLETYPE; + Gsetcombine_tev combine_tev = *((Gsetcombine_tev*)&this->combine_gfx); - if (((this->combine_gfx.words.w0 >> 24) & 0xFF) == G_SETCOMBINE_TEV) { if (aflags[AFLAGS_FORCE_TEV_COMBINE_MODE] != 0) { if (aflags[AFLAGS_FORCE_TEV_COMBINE_MODE] == 1) { static u32 c = TEV_SHADE; @@ -1076,23 +1137,7 @@ int emu64::combine_tev() { GXSetTevAlphaIn(GX_TEVSTAGE0, (GXTevAlphaArg)combine_tev.Aa0, (GXTevAlphaArg)combine_tev.Ab0, (GXTevAlphaArg)combine_tev.Ac0, (GXTevAlphaArg)combine_tev.Ad0); - if ((this->othermode_high & G_CYC_2CYCLE) == 0 || - ((this->combine_gfx.words.w1 & 0xFFFF) == 0xFFF0 && ((this->combine_gfx.words.w0 & 0xFFF) == 0xFF8))) { - GXSetNumTexGens(1); - GXSetNumTevStages(1); - - GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); - GXSetTevColorOp(GX_TEVSTAGE1, 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); - GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ONE); - GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); - - GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); - GXSetTevColorOp(GX_TEVSTAGE2, 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); - GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ONE); - GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); - } else { + if (two_cycle && ((((Gsetcombine_raw*)&combine_tev)->lower1) != 0xFFF0 || ((((Gsetcombine_raw*)&combine_tev)->lower0) & 0xFFF) != 0x0FF8)) { GXSetNumTexGens(2); GXSetNumTevStages(2); @@ -1104,6 +1149,21 @@ int emu64::combine_tev() { GXSetTevAlphaIn(GX_TEVSTAGE1, (GXTevAlphaArg)combine_tev.Aa1, (GXTevAlphaArg)combine_tev.Ab1, (GXTevAlphaArg)combine_tev.Ac1, (GXTevAlphaArg)combine_tev.Ad1); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorOp(GX_TEVSTAGE2, 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); + GXSetTevColorIn(GX_TEVSTAGE2, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ONE); + GXSetTevAlphaIn(GX_TEVSTAGE2, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + } else { + GXSetNumTexGens(1); + GXSetNumTevStages(1); + + GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); + GXSetTevColorOp(GX_TEVSTAGE1, 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); + GXSetTevColorIn(GX_TEVSTAGE1, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ZERO, GX_CC_ONE); + GXSetTevAlphaIn(GX_TEVSTAGE1, GX_CA_ZERO, GX_CA_ZERO, GX_CA_ZERO, GX_CA_KONST); + GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL); GXSetTevColorOp(GX_TEVSTAGE2, 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); diff --git a/src/static/libforest/emu64/emu64_utility.cc b/src/static/libforest/emu64/emu64_utility.c similarity index 100% rename from src/static/libforest/emu64/emu64_utility.cc rename to src/static/libforest/emu64/emu64_utility.c