From 23cf124c2bd8f2daa8cfebcfa0042412c385ca7a Mon Sep 17 00:00:00 2001 From: Timur Gagiev Date: Wed, 25 Nov 2020 02:06:40 +0300 Subject: [PATCH] 3DS turn off bottom screen by default, downscale atlas to 1024x1024 if it's necessary (SAT version only), fix sprites rendering, add notification if no content data is available, fix floating point precision bugs --- src/core.h | 4 ++-- src/gapi/c3d.h | 29 ++++++++++++++++++------ src/gapi/gl.h | 4 ++++ src/gapi/sw.h | 16 ++++++++------ src/lara.h | 9 ++++++++ src/platform/3ds/Makefile | 2 +- src/platform/3ds/main.cpp | 46 ++++++++++++++++++++++++--------------- 7 files changed, 76 insertions(+), 34 deletions(-) diff --git a/src/core.h b/src/core.h index f10a930..f0d52fa 100644 --- a/src/core.h +++ b/src/core.h @@ -706,7 +706,7 @@ namespace Core { void stop() { if (fpsTime < Core::getTime()) { - LOG("FPS: %d DIP: %d TRI: %d RT: %d CB: %d\n", fps, dips, tris, rt, cb); + LOG("FPS: %d DIP: %d TRI: %d RT: %d\n", fps, dips, tris, rt); #ifdef PROFILE LOG("frame time: %d mcs\n", tFrame / 1000); LOG("sound: mix %d rev %d ren %d/%d ogg %d\n", Sound::stats.mixer, Sound::stats.reverb, Sound::stats.render[0], Sound::stats.render[1], Sound::stats.ogg); @@ -1221,7 +1221,7 @@ namespace Core { } void setFog(const vec4 ¶ms) { - #if defined(_GAPI_D3D8) || defined(_GAPI_C3D) + #if defined(_GAPI_D3D8) || defined(_GAPI_C3D) || defined(_GAPI_SW) || defined(FFP) GAPI::setFog(params); #else ASSERT(Core::active.shader); diff --git a/src/gapi/c3d.h b/src/gapi/c3d.h index 5f2c736..8f1be38 100644 --- a/src/gapi/c3d.h +++ b/src/gapi/c3d.h @@ -27,7 +27,7 @@ namespace GAPI { struct Vertex { short4 coord; ubyte4 normal; - short2 texCoord; + short4 texCoord; ubyte4 color; ubyte4 light; }; @@ -461,17 +461,28 @@ namespace GAPI { FormatDesc desc = formats[fmt]; if (width < 8 || height < 8) { - LOG("texture too small %dx%d [%d %d]!\n", width, height, fmt, opt); + LOG("\ntexture too small %dx%d [%d %d]!\n\n", width, height, fmt, opt); width = 8; height = 8; data = NULL; } + void* tmpData = NULL; + if (width > 1024 || height > 1024) { - LOG("texture too large %dx%d [%d %d]!\n", width, height, fmt, opt); - width = 8; - height = 8; - data = NULL; + LOG("\ntexture too large %dx%d [%d %d]!\n", width, height, fmt, opt); + + origWidth >>= 1; + origHeight >>= 1; + width >>= 1; + height >>= 1; + + LOG("downsample to %dx%d\n\n", width, height); + + tmpData = linearAlloc(width * height * desc.bpp / 8); + downsampleImage(tmpData, data, width << 1, height << 1); + + data = tmpData; } bool isCube = (opt & OPT_CUBEMAP) != 0; @@ -508,6 +519,10 @@ namespace GAPI { update(data); } + if (tmpData) { + linearFree(tmpData); + } + GPU_TEXTURE_FILTER_PARAM filter = (opt & OPT_NEAREST) ? GPU_NEAREST : GPU_LINEAR; C3D_TexSetFilter(&tex, filter, filter); C3D_TexSetFilterMipmap(&tex, filter); @@ -824,7 +839,7 @@ namespace GAPI { AttrInfo_Init(&vertexAttribs); AttrInfo_AddLoader(&vertexAttribs, aCoord , GPU_SHORT , 4); AttrInfo_AddLoader(&vertexAttribs, aNormal , GPU_UNSIGNED_BYTE , 4); - AttrInfo_AddLoader(&vertexAttribs, aTexCoord , GPU_SHORT , 2); + AttrInfo_AddLoader(&vertexAttribs, aTexCoord , GPU_SHORT , 4); AttrInfo_AddLoader(&vertexAttribs, aColor , GPU_UNSIGNED_BYTE , 4); AttrInfo_AddLoader(&vertexAttribs, aLight , GPU_UNSIGNED_BYTE , 4); diff --git a/src/gapi/gl.h b/src/gapi/gl.h index 360d316..f1afed3 100644 --- a/src/gapi/gl.h +++ b/src/gapi/gl.h @@ -1697,6 +1697,10 @@ namespace GAPI { #endif } + void setFog(const vec4 ¶ms) { + // FFP TODO + } + void DIP(Mesh *mesh, const MeshRange &range) { #ifdef FFP mat4 m = mView * mModel; diff --git a/src/gapi/sw.h b/src/gapi/sw.h index 4800313..b15c681 100644 --- a/src/gapi/sw.h +++ b/src/gapi/sw.h @@ -335,6 +335,8 @@ namespace GAPI { } } + void setFog(const vec4 ¶ms) {} + bool checkBackface(const VertexSW *a, const VertexSW *b, const VertexSW *c) { return ((b->x - a->x) >> 16) * (c->y - a->y) - ((c->x - a->x) >> 16) * (b->y - a->y) <= 0; @@ -474,9 +476,9 @@ namespace GAPI { b */ VertexSW _n; - VertexSW *t = swVertices + indices[0]; - VertexSW *m = swVertices + indices[1]; - VertexSW *b = swVertices + indices[2]; + VertexSW *t = swVertices.items + indices[0]; + VertexSW *m = swVertices.items + indices[1]; + VertexSW *b = swVertices.items + indices[2]; VertexSW *n = &_n; if (checkBackface(t, m, b)) @@ -521,10 +523,10 @@ namespace GAPI { */ VertexSW _n; VertexSW _p; - VertexSW *t = swVertices + indices[0]; - VertexSW *m = swVertices + indices[1]; - VertexSW *b = swVertices + indices[2]; - VertexSW *o = swVertices + indices[3]; + VertexSW *t = swVertices.items + indices[0]; + VertexSW *m = swVertices.items + indices[1]; + VertexSW *b = swVertices.items + indices[2]; + VertexSW *o = swVertices.items + indices[3]; VertexSW *n = &_n; VertexSW *p = &_p; diff --git a/src/lara.h b/src/lara.h index 1c0859c..34e3a12 100644 --- a/src/lara.h +++ b/src/lara.h @@ -3625,6 +3625,11 @@ struct Lara : Character { return false; } + #ifdef _OS_3DS // for some reason move() math works incorrect on 3DS + #pragma GCC push_options + #pragma GCC optimize ("O0") + #endif + void move() { vec3 vel = (velocity + flowVelocity) * Core::deltaTime * 30.0f + collisionOffset; vec3 opos(pos), offset(0.0f); @@ -3775,6 +3780,10 @@ struct Lara : Character { if (dozy) stand = STAND_UNDERWATER; } + #ifdef _OS_3DS + #pragma GCC pop_options + #endif + virtual void applyFlow(TR::Camera &sink) { if (stand != STAND_UNDERWATER && stand != STAND_ONWATER) return; diff --git a/src/platform/3ds/Makefile b/src/platform/3ds/Makefile index efec6dc..7eb7a4a 100644 --- a/src/platform/3ds/Makefile +++ b/src/platform/3ds/Makefile @@ -48,7 +48,7 @@ APP_DESCRIPTION := Classic Tomb Raider open-source engine #--------------------------------------------------------------------------------- ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft -CFLAGS := $(ARCH) -g0 -w -O3 -mword-relocations -fomit-frame-pointer -ffunction-sections +CFLAGS := $(ARCH) -g0 -w -Ofast -ffast-math -mword-relocations -fomit-frame-pointer -ffunction-sections CFLAGS += $(INCLUDE) -DARM11 -D_3DS CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 diff --git a/src/platform/3ds/main.cpp b/src/platform/3ds/main.cpp index 72af624..131c898 100644 --- a/src/platform/3ds/main.cpp +++ b/src/platform/3ds/main.cpp @@ -33,7 +33,7 @@ int osGetTimeMS() { } // backlight -bool bottomScreenOn = true; +bool bottomScreenOn = false; void setBottomScreen(bool enable) { gspLcdInit(); @@ -46,10 +46,10 @@ aptHookCookie(cookie); void checkAptHook(APT_HookType hook, void *param) { if (!bottomScreenOn) { switch(hook) { - case APTHOOK_ONSUSPEND : setBottomScreen(1); + case APTHOOK_ONSUSPEND : setBottomScreen(true); break; case APTHOOK_ONRESTORE : - case APTHOOK_ONWAKEUP : setBottomScreen(0); + case APTHOOK_ONWAKEUP : setBottomScreen(false); break; default: break; @@ -97,13 +97,13 @@ void inputUpdate() { if (down & KEY_TOUCH) { bottomScreenOn = !bottomScreenOn; - bottomScreenOn ? setBottomScreen(1) : setBottomScreen(0); + bottomScreenOn ? setBottomScreen(true) : setBottomScreen(false); } } void inputFree() { if (!bottomScreenOn) - setBottomScreen(1); + setBottomScreen(true); hidExit(); } @@ -117,7 +117,6 @@ int sndBufIndex; bool sndReady; void sndFill(void *arg) { - LOG("thread start\n"); memset(sndWaveBuf, 0, sizeof(sndWaveBuf)); sndWaveBuf[0].data_vaddr = sndBuffer + 0; sndWaveBuf[0].nsamples = SND_FRAMES; @@ -177,6 +176,8 @@ void sndFree() { } int main() { + setBottomScreen(false); + { bool isNew3DS; APT_CheckNew3DS(&isNew3DS); @@ -189,10 +190,6 @@ int main() { strcpy(saveDir, "sdmc:/3ds/OpenLara/"); strcpy(contentDir, "sdmc:/3ds/OpenLara/"); - if(chdir(contentDir) != 0) { - return 0; - } - Stream::init(); sndInit(); @@ -202,16 +199,31 @@ int main() { Game::init(); - while (aptMainLoop() && !Core::isQuit) { - inputUpdate(); + if (Core::isQuit) { + bottomScreenOn = true; + setBottomScreen(true); + consoleClear(); + LOG("\n\nCopy the original game content to:\n\n %s\n\nPress A to exit", contentDir); + while (aptMainLoop()) { + hidScanInput(); + u64 mask = hidKeysDown() | hidKeysHeld(); + if (mask & KEY_A) { + break; + } - if (Input::joy[0].down[jkStart]) - Core::quit(); + gfxFlushBuffers(); + gfxSwapBuffers(); + gspWaitForVBlank(); + } + } else { + while (aptMainLoop() && !Core::isQuit) { + inputUpdate(); - Game::update(); - Game::render(); + Game::update(); + Game::render(); - GAPI::present(); + GAPI::present(); + } } inputFree();