1
0
mirror of https://github.com/XProger/OpenLara.git synced 2025-08-17 10:30:47 +02:00

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

This commit is contained in:
Timur Gagiev
2020-11-25 02:06:40 +03:00
parent a94937ae40
commit 23cf124c2b
7 changed files with 76 additions and 34 deletions

View File

@@ -706,7 +706,7 @@ namespace Core {
void stop() { void stop() {
if (fpsTime < Core::getTime()) { 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 #ifdef PROFILE
LOG("frame time: %d mcs\n", tFrame / 1000); 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); 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 &params) { void setFog(const vec4 &params) {
#if defined(_GAPI_D3D8) || defined(_GAPI_C3D) #if defined(_GAPI_D3D8) || defined(_GAPI_C3D) || defined(_GAPI_SW) || defined(FFP)
GAPI::setFog(params); GAPI::setFog(params);
#else #else
ASSERT(Core::active.shader); ASSERT(Core::active.shader);

View File

@@ -27,7 +27,7 @@ namespace GAPI {
struct Vertex { struct Vertex {
short4 coord; short4 coord;
ubyte4 normal; ubyte4 normal;
short2 texCoord; short4 texCoord;
ubyte4 color; ubyte4 color;
ubyte4 light; ubyte4 light;
}; };
@@ -461,17 +461,28 @@ namespace GAPI {
FormatDesc desc = formats[fmt]; FormatDesc desc = formats[fmt];
if (width < 8 || height < 8) { 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; width = 8;
height = 8; height = 8;
data = NULL; data = NULL;
} }
void* tmpData = NULL;
if (width > 1024 || height > 1024) { if (width > 1024 || height > 1024) {
LOG("texture too large %dx%d [%d %d]!\n", width, height, fmt, opt); LOG("\ntexture too large %dx%d [%d %d]!\n", width, height, fmt, opt);
width = 8;
height = 8; origWidth >>= 1;
data = NULL; 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; bool isCube = (opt & OPT_CUBEMAP) != 0;
@@ -508,6 +519,10 @@ namespace GAPI {
update(data); update(data);
} }
if (tmpData) {
linearFree(tmpData);
}
GPU_TEXTURE_FILTER_PARAM filter = (opt & OPT_NEAREST) ? GPU_NEAREST : GPU_LINEAR; GPU_TEXTURE_FILTER_PARAM filter = (opt & OPT_NEAREST) ? GPU_NEAREST : GPU_LINEAR;
C3D_TexSetFilter(&tex, filter, filter); C3D_TexSetFilter(&tex, filter, filter);
C3D_TexSetFilterMipmap(&tex, filter); C3D_TexSetFilterMipmap(&tex, filter);
@@ -824,7 +839,7 @@ namespace GAPI {
AttrInfo_Init(&vertexAttribs); AttrInfo_Init(&vertexAttribs);
AttrInfo_AddLoader(&vertexAttribs, aCoord , GPU_SHORT , 4); AttrInfo_AddLoader(&vertexAttribs, aCoord , GPU_SHORT , 4);
AttrInfo_AddLoader(&vertexAttribs, aNormal , GPU_UNSIGNED_BYTE , 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, aColor , GPU_UNSIGNED_BYTE , 4);
AttrInfo_AddLoader(&vertexAttribs, aLight , GPU_UNSIGNED_BYTE , 4); AttrInfo_AddLoader(&vertexAttribs, aLight , GPU_UNSIGNED_BYTE , 4);

View File

@@ -1697,6 +1697,10 @@ namespace GAPI {
#endif #endif
} }
void setFog(const vec4 &params) {
// FFP TODO
}
void DIP(Mesh *mesh, const MeshRange &range) { void DIP(Mesh *mesh, const MeshRange &range) {
#ifdef FFP #ifdef FFP
mat4 m = mView * mModel; mat4 m = mView * mModel;

View File

@@ -335,6 +335,8 @@ namespace GAPI {
} }
} }
void setFog(const vec4 &params) {}
bool checkBackface(const VertexSW *a, const VertexSW *b, const VertexSW *c) { bool checkBackface(const VertexSW *a, const VertexSW *b, const VertexSW *c) {
return ((b->x - a->x) >> 16) * (c->y - a->y) - return ((b->x - a->x) >> 16) * (c->y - a->y) -
((c->x - a->x) >> 16) * (b->y - a->y) <= 0; ((c->x - a->x) >> 16) * (b->y - a->y) <= 0;
@@ -474,9 +476,9 @@ namespace GAPI {
b b
*/ */
VertexSW _n; VertexSW _n;
VertexSW *t = swVertices + indices[0]; VertexSW *t = swVertices.items + indices[0];
VertexSW *m = swVertices + indices[1]; VertexSW *m = swVertices.items + indices[1];
VertexSW *b = swVertices + indices[2]; VertexSW *b = swVertices.items + indices[2];
VertexSW *n = &_n; VertexSW *n = &_n;
if (checkBackface(t, m, b)) if (checkBackface(t, m, b))
@@ -521,10 +523,10 @@ namespace GAPI {
*/ */
VertexSW _n; VertexSW _n;
VertexSW _p; VertexSW _p;
VertexSW *t = swVertices + indices[0]; VertexSW *t = swVertices.items + indices[0];
VertexSW *m = swVertices + indices[1]; VertexSW *m = swVertices.items + indices[1];
VertexSW *b = swVertices + indices[2]; VertexSW *b = swVertices.items + indices[2];
VertexSW *o = swVertices + indices[3]; VertexSW *o = swVertices.items + indices[3];
VertexSW *n = &_n; VertexSW *n = &_n;
VertexSW *p = &_p; VertexSW *p = &_p;

View File

@@ -3625,6 +3625,11 @@ struct Lara : Character {
return false; 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() { void move() {
vec3 vel = (velocity + flowVelocity) * Core::deltaTime * 30.0f + collisionOffset; vec3 vel = (velocity + flowVelocity) * Core::deltaTime * 30.0f + collisionOffset;
vec3 opos(pos), offset(0.0f); vec3 opos(pos), offset(0.0f);
@@ -3775,6 +3780,10 @@ struct Lara : Character {
if (dozy) stand = STAND_UNDERWATER; if (dozy) stand = STAND_UNDERWATER;
} }
#ifdef _OS_3DS
#pragma GCC pop_options
#endif
virtual void applyFlow(TR::Camera &sink) { virtual void applyFlow(TR::Camera &sink) {
if (stand != STAND_UNDERWATER && stand != STAND_ONWATER) return; if (stand != STAND_UNDERWATER && stand != STAND_ONWATER) return;

View File

@@ -48,7 +48,7 @@ APP_DESCRIPTION := Classic Tomb Raider open-source engine
#--------------------------------------------------------------------------------- #---------------------------------------------------------------------------------
ARCH := -march=armv6k -mtune=mpcore -mfloat-abi=hard -mtp=soft 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 CFLAGS += $(INCLUDE) -DARM11 -D_3DS
CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11 CXXFLAGS := $(CFLAGS) -fno-rtti -fno-exceptions -std=gnu++11

View File

@@ -33,7 +33,7 @@ int osGetTimeMS() {
} }
// backlight // backlight
bool bottomScreenOn = true; bool bottomScreenOn = false;
void setBottomScreen(bool enable) { void setBottomScreen(bool enable) {
gspLcdInit(); gspLcdInit();
@@ -46,10 +46,10 @@ aptHookCookie(cookie);
void checkAptHook(APT_HookType hook, void *param) { void checkAptHook(APT_HookType hook, void *param) {
if (!bottomScreenOn) { if (!bottomScreenOn) {
switch(hook) { switch(hook) {
case APTHOOK_ONSUSPEND : setBottomScreen(1); case APTHOOK_ONSUSPEND : setBottomScreen(true);
break; break;
case APTHOOK_ONRESTORE : case APTHOOK_ONRESTORE :
case APTHOOK_ONWAKEUP : setBottomScreen(0); case APTHOOK_ONWAKEUP : setBottomScreen(false);
break; break;
default: default:
break; break;
@@ -97,13 +97,13 @@ void inputUpdate() {
if (down & KEY_TOUCH) { if (down & KEY_TOUCH) {
bottomScreenOn = !bottomScreenOn; bottomScreenOn = !bottomScreenOn;
bottomScreenOn ? setBottomScreen(1) : setBottomScreen(0); bottomScreenOn ? setBottomScreen(true) : setBottomScreen(false);
} }
} }
void inputFree() { void inputFree() {
if (!bottomScreenOn) if (!bottomScreenOn)
setBottomScreen(1); setBottomScreen(true);
hidExit(); hidExit();
} }
@@ -117,7 +117,6 @@ int sndBufIndex;
bool sndReady; bool sndReady;
void sndFill(void *arg) { void sndFill(void *arg) {
LOG("thread start\n");
memset(sndWaveBuf, 0, sizeof(sndWaveBuf)); memset(sndWaveBuf, 0, sizeof(sndWaveBuf));
sndWaveBuf[0].data_vaddr = sndBuffer + 0; sndWaveBuf[0].data_vaddr = sndBuffer + 0;
sndWaveBuf[0].nsamples = SND_FRAMES; sndWaveBuf[0].nsamples = SND_FRAMES;
@@ -177,6 +176,8 @@ void sndFree() {
} }
int main() { int main() {
setBottomScreen(false);
{ {
bool isNew3DS; bool isNew3DS;
APT_CheckNew3DS(&isNew3DS); APT_CheckNew3DS(&isNew3DS);
@@ -189,10 +190,6 @@ int main() {
strcpy(saveDir, "sdmc:/3ds/OpenLara/"); strcpy(saveDir, "sdmc:/3ds/OpenLara/");
strcpy(contentDir, "sdmc:/3ds/OpenLara/"); strcpy(contentDir, "sdmc:/3ds/OpenLara/");
if(chdir(contentDir) != 0) {
return 0;
}
Stream::init(); Stream::init();
sndInit(); sndInit();
@@ -202,16 +199,31 @@ int main() {
Game::init(); Game::init();
while (aptMainLoop() && !Core::isQuit) { if (Core::isQuit) {
inputUpdate(); 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]) gfxFlushBuffers();
Core::quit(); gfxSwapBuffers();
gspWaitForVBlank();
}
} else {
while (aptMainLoop() && !Core::isQuit) {
inputUpdate();
Game::update(); Game::update();
Game::render(); Game::render();
GAPI::present(); GAPI::present();
}
} }
inputFree(); inputFree();