emu64 work and misc improvements

This commit is contained in:
Cuyler36
2023-08-28 21:01:23 -04:00
parent 1d9045ad10
commit 595e2a92df
35 changed files with 2746 additions and 6 deletions
+296
View File
@@ -0,0 +1,296 @@
#include "libforest/emu64/emu64.hpp"
static aflags_c aflags;
static u8 texture_buffer_data[TEX_BUFFER_DATA_SIZE];
static u8 texture_buffer_bss[TEX_BUFFER_BSS_SIZE];
static u32 texture_cache_num;
static texture_cache_entry_t texture_cache_list[TEXTURE_CACHE_LIST_SIZE];
/* These are set externally during emu64 initialization */
static texture_cache_data_entry_t texture_cache_data_entry_tbl[NUM_TEXTURE_CACHE_DATA];
static int texture_cache_data_entry_num;
static texture_cache_funcs texture_cache_data_func = {
&texture_cache_data_search,
&texture_cache_data_entry,
&texture_cache_alloc
};
static texture_cache_t texture_cache_data = {
&texture_cache_data_func,
&texture_buffer_data[0],
&texture_buffer_data[TEX_BUFFER_DATA_SIZE],
&texture_buffer_data[0],
nullptr,
nullptr,
FALSE,
0
};
/* .bss cache functions */
void* texture_cache_bss_search(void* addr);
int texture_cache_bss_entry(void* original, void* converted);
static texture_cache_funcs texture_cache_bss_func = {
&texture_cache_bss_search,
&texture_cache_bss_entry,
&texture_cache_alloc
};
static texture_cache_t texture_cache_bss = {
&texture_cache_bss_func,
&texture_buffer_bss[0],
&texture_buffer_bss[TEX_BUFFER_BSS_SIZE],
&texture_buffer_bss[0],
nullptr,
nullptr,
FALSE,
0
};
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_num++;
}
static texture_cache_t* texture_cache_select(void* addr) {
int i;
if (aflags[5] < 1 && (addr < _f_rodata || addr > _e_data)) {
for (i = 0; i < texture_cache_data_entry_num; i++) {
if (addr >= texture_cache_data_entry_tbl[i].start && addr < texture_cache_data_entry_tbl[i].end) {
return &texture_cache_data;
}
}
return &texture_cache_bss;
}
return &texture_cache_data;
}
static bool texture_cache_is_overflow(texture_cache_t* cache) {
return cache->is_overflow;
}
static void texture_cache_clear(texture_cache_t* cache) {
cache->is_overflow = false;
cache->buffer_current = cache->buffer_start;
}
/* @fabricated */
MATCH_FORCESTRIP static u32 texture_cache_get_max_alloc_size(texture_cache_t* cache) {
return cache->buffer_current - cache->buffer_start;
}
/* @fabricated */
MATCH_FORCESTRIP static u32 texture_cache_get_alloc_size(texture_cache_t* cache) {
return cache->buffer_current - cache->last_alloc_start;
}
/* @fabricated */
MATCH_FORCESTRIP static u32 texture_cache_get_free_size(texture_cache_t* cache) {
return cache->buffer_end - cache->buffer_current;
}
/* @fabricated */
MATCH_FORCESTRIP static u32 texture_cache_get_heap_size(texture_cache_t* cache) {
return cache->buffer_end - cache->buffer_start;
}
static void* texture_cache_alloc(texture_cache_t* cache, size_t size) {
u32 new_pos;
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_end < cache->last_alloc_end) {
cache->is_overflow = true;
return nullptr;
}
cache->buffer_current = cache->last_alloc_end;
return cache->last_alloc_start;
}
static void* texture_cache_data_search(void* original_addr) {
int i;
for (i = 0; i < texture_cache_num; i++) {
if (original_addr == texture_cache_list[i].original) {
return texture_cache_list[i].converted;
}
}
return nullptr;
}
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;
return 0;
}
texture_cache_data.is_overflow = true;
return -1;
}
static void* texture_cache_bss_search(void* original_addr) {
return nullptr;
}
static int texture_cache_bss_entry(void* original_addr, void* converted_addr) {
return -1;
}
static void texture_cache_list_clear() {
texture_cache_clear(&texture_cache_data);
texture_cache_num = 0;
}
extern void emu64_refresh() {
texture_cache_list_clear();
}
/* Helper function to convert N64 texture format to Dolphin format */
u16 emu64::fmtxtbl[8][4] = {
{ GX_TF_CMPR, -1, GX_TF_RGB5A3, GX_TF_RGBA8 }, /* G_IM_FMT_RGBA */
{ -1, -1, -1, -1 }, /* G_IM_FMT_YUV */
{ GX_TF_C4, GX_TF_C8, 0xA, -1 }, /* G_IM_FMT_CI */
{ -1, GX_TF_IA4, GX_TF_IA8, -1 }, /* G_IM_FMT_IA */
{ GX_TF_I4, GX_TF_I8, GX_TF_RGB565, -1 }, /* G_IM_FMT_I */
{ GX_TF_CMPR, GX_CTF_A8, GX_TF_RGB5A3, -1 }, /* ?? */
{ -1, GX_TF_Z8, GX_TF_Z16, GX_TF_Z24X8 }, /* ?? */
{ -1, -1, -1, -1 } /* ?? */
};
static u16 cvtN64ToDol(int n64_fmt, int n64_bpp) {
u16 dol = emu64::fmtxtbl[n64_fmt][n64_bpp];
if (dol != 0xFFFF) {
return dol;
}
return GX_TF_I4;
}
MATCH_FORCESTRIP static f32 PsendoArcSinConvert(f32 arcsin) {
f32 g = 2.0f * (arcsin - 0.5f);
g = g * 0.4623f * g * g + g * 0.5377f;
return 0.5f + g * 0.5f;
}
MATCH_FORCESTRIP static void TextureLinearConvert1(Texture* src, Texture* dst) {
int y;
int x;
for (y = 0; y < dst->height; y++) {
for (x = 0; x < dst->width; x++) {
f32 arcsin_x = (f32)x / (f32)(dst->width - 1);
f32 arcsin_y = (f32)y / (f32)(dst->height - 1);
f32 sin_x = PsendoArcSinConvert(arcsin_x);
f32 sin_y = PsendoArcSinConvert(arcsin_y);
dst->putTexel(x, y, src->getTexel(sin_x * (src->width - 1), sin_y * (src->height - 1)));
}
}
}
MATCH_FORCESTRIP static void* TextureLinearConvert(void* img_p, unsigned int width, unsigned int height, unsigned int fmt, unsigned int bpp) {
texture_cache_t* tex_cache = texture_cache_select(NULL);
void* conv_img_p = tex_cache->funcs->alloc(tex_cache, 0x1000);
Texture src(img_p, width, height, fmt, bpp);
Texture dst(conv_img_p, width, height, fmt, bpp);
TextureLinearConvert1(&src, &dst);
return conv_img_p;
}
static GXColor black_color = { 0, 0, 0, 0 };
static GXColor white_color = { 255, 255, 255, 255 };
static void emu64_init2(GXRenderModeObj* render_mode) {
Mtx m;
__GXSetIndirectMask(0);
GXSetTexCoordGen(GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD1, GX_TG_MTX2x4, GX_TG_TEX1, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD2, GX_TG_MTX2x4, GX_TG_TEX2, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD3, GX_TG_MTX2x4, GX_TG_TEX3, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD4, GX_TG_MTX2x4, GX_TG_TEX4, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD5, GX_TG_MTX2x4, GX_TG_TEX5, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD6, GX_TG_MTX2x4, GX_TG_TEX6, GX_IDENTITY);
GXSetTexCoordGen(GX_TEXCOORD7, GX_TG_MTX2x4, GX_TG_TEX7, GX_IDENTITY);
GXSetNumTexGens(1);
GXClearVtxDesc();
GXInvalidateVtxCache();
GXSetLineWidth(6, GX_TO_ZERO);
GXSetPointSize(6, GX_TO_ZERO);
GXEnableTexOffsets(GX_TEXCOORD0, GX_FALSE, GX_FALSE);
GXEnableTexOffsets(GX_TEXCOORD1, GX_FALSE, GX_FALSE);
GXEnableTexOffsets(GX_TEXCOORD2, GX_FALSE, GX_FALSE);
GXEnableTexOffsets(GX_TEXCOORD3, GX_FALSE, GX_FALSE);
GXEnableTexOffsets(GX_TEXCOORD4, GX_FALSE, GX_FALSE);
GXEnableTexOffsets(GX_TEXCOORD5, GX_FALSE, GX_FALSE);
GXEnableTexOffsets(GX_TEXCOORD6, GX_FALSE, GX_FALSE);
GXEnableTexOffsets(GX_TEXCOORD7, GX_FALSE, GX_FALSE);
PSMTXIdentity(m);
GXLoadPosMtxImm(m, GX_PNMTX0);
GXLoadNrmMtxImm(m, GX_PNMTX0);
GXSetCurrentMtx(GX_PNMTX0);
GXLoadTexMtxImm(m, GX_IDENTITY, GX_MTX3x4);
GXSetViewport(0.0f, 0.0f, render_mode->fbWidth, render_mode->xfbHeight, 0.0f, 1.0f);
GXSetCoPlanar(GX_FALSE);
GXSetCullMode(GX_CULL_BACK);
GXSetClipMode(GX_CLIP_ENABLE);
GXSetScissor(0, 0, render_mode->fbWidth, render_mode->efbHeight);
GXSetScissorBoxOffset(0, 0);
GXSetNumChans(0);
GXSetChanCtrl(GX_COLOR0A0, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetChanAmbColor(GX_COLOR0A0, black_color);
GXSetChanMatColor(GX_COLOR0A0, white_color);
GXSetChanCtrl(GX_COLOR1A1, GX_FALSE, GX_SRC_REG, GX_SRC_VTX, GX_LIGHT_NULL, GX_DF_NONE, GX_AF_NONE);
GXSetChanAmbColor(GX_COLOR1A1, black_color);
GXSetChanMatColor(GX_COLOR1A1, white_color);
GXInvalidateTexAll();
GXSetTevOrder(GX_TEVSTAGE0, GX_TEXCOORD0, GX_TEXMAP0, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE1, GX_TEXCOORD1, GX_TEXMAP1, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE2, GX_TEXCOORD2, GX_TEXMAP2, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE3, GX_TEXCOORD3, GX_TEXMAP3, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE4, GX_TEXCOORD4, GX_TEXMAP4, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE5, GX_TEXCOORD5, GX_TEXMAP5, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE6, GX_TEXCOORD6, GX_TEXMAP6, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE7, GX_TEXCOORD7, GX_TEXMAP7, GX_COLOR0A0);
GXSetTevOrder(GX_TEVSTAGE8, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE9, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE10, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE11, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
GXSetTevOrder(GX_TEVSTAGE12, GX_TEXCOORD_NULL, GX_TEXMAP_NULL, GX_COLOR_NULL);
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);
}