diff --git a/src/camera.h b/src/camera.h index ad8cf122..4faaa56b 100644 --- a/src/camera.h +++ b/src/camera.h @@ -532,6 +532,10 @@ struct Camera : ICamera { fov = firstPerson ? 90.0f : 65.0f; znear = firstPerson ? 8.0f : 32.0f; zfar = 45.0f * 1024.0f; + + #ifdef _OS_PSP + znear = 256.0f; + #endif } }; diff --git a/src/core.h b/src/core.h index 60426e13..c5d39202 100644 --- a/src/core.h +++ b/src/core.h @@ -246,17 +246,29 @@ namespace Core { } void setLighting(Quality value) { + #ifdef _OS_PSP + lighting = LOW; + #else lighting = value; + #endif } void setShadows(Quality value) { + #ifdef _OS_PSP + shadows = LOW; + #else shadows = value; + #endif } void setWater(Quality value) { + #ifdef _OS_PSP + water = LOW; + #else if (value > LOW && !(support.texFloat || support.texHalf)) value = LOW; water = value; + #endif } } detail; diff --git a/src/gapi_gu.h b/src/gapi_gu.h index ac955dea..890fc24d 100644 --- a/src/gapi_gu.h +++ b/src/gapi_gu.h @@ -6,10 +6,9 @@ #include #include -#define FFP -#define TEX_SWIZZLE -//#define EDRAM_MESH -#define EDRAM_TEX +#define PROFILE_MARKER(title) +#define PROFILE_LABEL(id, name, label) +#define PROFILE_TIMING(time) namespace GAPI { @@ -22,6 +21,16 @@ namespace GAPI { short3 coord; }; +// Shader + struct Shader { + void init(Core::Pass pass, int type, int *def, int defCount) {} + void deinit() {} + void bind() {} + void setParam(UniformType uType, const vec4 &value, int count = 1) {} + void setParam(UniformType uType, const mat4 &value, int count = 1) {} + void setParam(UniformType uType, const Basis &value, int count = 1) {} + }; + // Texture struct Texture { uint8 *memory; @@ -100,9 +109,9 @@ namespace GAPI { void setFilterQuality(int value) { if (value > Core::Settings::LOW) - opt &= ~NEAREST; + opt &= ~OPT_NEAREST; else - opt |= NEAREST; + opt |= OPT_NEAREST; } }; @@ -117,17 +126,16 @@ namespace GAPI { Mesh(bool dynamic) : iBuffer(NULL), vBuffer(NULL), dynamic(dynamic) {} - void init(Index *indices, int iCount, ::Vertex *vertices, int vCount, int aCount, bool dynamic) { + void init(Index *indices, int iCount, ::Vertex *vertices, int vCount, int aCount) { this->iCount = iCount; this->vCount = vCount; - this->dynamic = dynamic; if (dynamic) return; #ifdef EDRAM_MESH - iBuffer = (Index*)Core::allocEDRAM(iCount * sizeof(Index)); - vBuffer = (Vertex*)Core::allocEDRAM(vCount * sizeof(Vertex)); + iBuffer = (Index*)allocEDRAM(iCount * sizeof(Index)); + vBuffer = (Vertex*)allocEDRAM(vCount * sizeof(Vertex)); #else iBuffer = new Index[iCount]; vBuffer = new Vertex[vCount]; @@ -171,12 +179,7 @@ namespace GAPI { } } - void bind(const MeshRange &range) const { - ASSERT(iBuffer != NULL); - ASSERT(vBuffer != NULL); - Core::active.iBuffer = iBuffer; - Core::active.vBuffer = vBuffer + range.vStart; - } + void bind(const MeshRange &range) const {} void initNextRange(MeshRange &range, int &aIndex) const { range.aIndex = -1; @@ -193,8 +196,8 @@ namespace GAPI { static int EDRAM_SIZE; void* allocEDRAM(int size) { - LOG("EDRAM ALLOC: offset: %d size %d (free %d)\n", Core::EDRAM_OFFSET, size, EDRAM_SIZE - (Core::EDRAM_OFFSET + size)); - if (Core::EDRAM_OFFSET + size > EDRAM_SIZE) + LOG("EDRAM ALLOC: offset: %d size %d (free %d)\n", EDRAM_OFFSET, size, EDRAM_SIZE - (EDRAM_OFFSET + size)); + if (EDRAM_OFFSET + size > EDRAM_SIZE) LOG("! EDRAM overflow !\n"); void *ptr = ((char*)sceGeEdramGetAddr()) + EDRAM_OFFSET; @@ -290,11 +293,11 @@ namespace GAPI { } mat4 ortho(float l, float r, float b, float t, float znear, float zfar) { - return mat4(mat4::PROJ_ZERO_POS, l, r, b, t, znear, zfar); + return mat4(mat4::PROJ_NEG_POS, l, r, b, t, znear, zfar); } mat4 perspective(float fov, float aspect, float znear, float zfar) { - return mat4(mat4::PROJ_ZERO_POS, fov, aspect, znear, zfar); + return mat4(mat4::PROJ_NEG_POS, fov, aspect, znear, zfar); } bool beginFrame() { @@ -397,12 +400,28 @@ namespace GAPI { sceGumMatrixMode(GU_MODEL); sceGumLoadMatrix((ScePspFMatrix4*)&m); - sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_16BIT | GU_COLOR_8888 | GU_NORMAL_16BIT | GU_VERTEX_16BIT | GU_INDEX_16BIT | GU_TRANSFORM_3D, range.iCount, mesh->iBuffer + range.iStart, mesh->vBuffer); + sceGumDrawArray(GU_TRIANGLES, GU_TEXTURE_16BIT | GU_COLOR_8888 | GU_NORMAL_16BIT | GU_VERTEX_16BIT | GU_INDEX_16BIT | GU_TRANSFORM_3D, range.iCount, mesh->iBuffer + range.iStart, mesh->vBuffer + range.vStart); } vec4 copyPixel(int x, int y) { return vec4(0.0f); // TODO: read from framebuffer } + + void initPSO(PSO *pso) { + ASSERT(pso); + ASSERT(pso && pso->data == NULL); + pso->data = &pso; + } + + void deinitPSO(PSO *pso) { + ASSERT(pso); + ASSERT(pso->data != NULL); + pso->data = NULL; + } + + void bindPSO(const PSO *pso) { + // + } } #endif \ No newline at end of file diff --git a/src/inventory.h b/src/inventory.h index 971c5a1e..03596413 100644 --- a/src/inventory.h +++ b/src/inventory.h @@ -1417,9 +1417,6 @@ struct Inventory { } void renderGameBG() { - #ifdef _OS_PSP - return; - #endif Index indices[6] = { 0, 1, 2, 0, 2, 3 }; Vertex vertices[4]; vertices[0].coord = short4(-32767, 32767, 0, 0); @@ -1437,9 +1434,7 @@ struct Inventory { game->setShader(Core::passFilter, Shader::DEFAULT, false, false); if (Core::settings.detail.stereo == Core::Settings::STEREO_VR || !background[0]) { - for (int i = 0; i < 4; i++) - vertices[i].light.x = vertices[i].light.y = vertices[i].light.z = 0; - Core::whiteTex->bind(sDiffuse); // black background + Core::blackTex->bind(sDiffuse); // black background } else background[0]->bind(sDiffuse); // blured grayscale image diff --git a/src/level.h b/src/level.h index 2a12ace4..705dfd44 100644 --- a/src/level.h +++ b/src/level.h @@ -417,6 +417,10 @@ struct Level : IGame { Core::active.shader->setParam(uParam, Core::params); Core::setMaterial(diffuse, ambient, specular, alpha); + #ifdef FFP + updateLighting(type); + #endif + if (Core::settings.detail.shadows > Core::Settings::MEDIUM) Core::active.shader->setParam(uContacts, Core::contacts[0], MAX_CONTACTS); } @@ -659,7 +663,7 @@ struct Level : IGame { flags |= Sound::LOOP; waitTrack = true; - getGameTrack(level.version, track, playAsync, new TrackRequest(this, flags)); + TR::getGameTrack(level.version, track, playAsync, new TrackRequest(this, flags)); } virtual void stopTrack() { @@ -669,7 +673,7 @@ struct Level : IGame { Level(Stream &stream) : level(stream), inventory(this), waitTrack(false), isEnded(false), cutsceneWaitTimer(0.0f), animTexTimer(0.0f) { #ifdef _OS_PSP - Core::freeEDRAM(); + GAPI::freeEDRAM(); #endif params = (Params*)&Core::params; params->time = 0.0f; @@ -1158,43 +1162,54 @@ struct Level : IGame { #ifdef _OS_PSP atlas = new Texture(level.tiles4, level.tilesCount, level.cluts, level.clutsCount); #else - level.initTiles(); + TR::Tile32 *tiles = new TR::Tile32[level.tilesCount]; - atlas = new Texture(level.tiles, level.tilesCount); - - delete[] level.tiles; - level.tiles = NULL; + for (int i = 0; i < level.objectTexturesCount; i++) { + TR::ObjectTexture &t = level.objectTextures[i]; + short4 uv = t.getMinMax(); + level.fillObjectTexture(&tiles[t.tile.index], uv, t.tile.index, t.clut); + } + + for (int i = 0; i < level.spriteTexturesCount; i++) { + TR::SpriteTexture &t = level.spriteTextures[i]; + short4 uv = t.getMinMax(); + level.fillObjectTexture(&tiles[t.tile], uv, t.tile, t.clut); + } + + atlas = new Texture(tiles, level.tilesCount); + + delete[] tiles; #endif for (int i = 0; i < level.objectTexturesCount; i++) { TR::ObjectTexture &t = level.objectTextures[i]; - t.texCoord[0].x <<= 7; - t.texCoord[0].y <<= 7; - t.texCoord[1].x <<= 7; - t.texCoord[1].y <<= 7; - t.texCoord[2].x <<= 7; - t.texCoord[2].y <<= 7; - t.texCoord[3].x <<= 7; - t.texCoord[3].y <<= 7; - - t.texCoord[0].x += 64; - t.texCoord[0].y += 64; - t.texCoord[1].x += 64; - t.texCoord[1].y += 64; - t.texCoord[2].x += 64; - t.texCoord[2].y += 64; - t.texCoord[3].x += 64; - t.texCoord[3].y += 64; + t.texCoordAtlas[0].x <<= 7; + t.texCoordAtlas[0].y <<= 7; + t.texCoordAtlas[1].x <<= 7; + t.texCoordAtlas[1].y <<= 7; + t.texCoordAtlas[2].x <<= 7; + t.texCoordAtlas[2].y <<= 7; + t.texCoordAtlas[3].x <<= 7; + t.texCoordAtlas[3].y <<= 7; + + t.texCoordAtlas[0].x += 64; + t.texCoordAtlas[0].y += 64; + t.texCoordAtlas[1].x += 64; + t.texCoordAtlas[1].y += 64; + t.texCoordAtlas[2].x += 64; + t.texCoordAtlas[2].y += 64; + t.texCoordAtlas[3].x += 64; + t.texCoordAtlas[3].y += 64; } for (int i = 0; i < level.spriteTexturesCount; i++) { TR::SpriteTexture &t = level.spriteTextures[i]; - t.texCoord[0].x <<= 7; - t.texCoord[0].y <<= 7; - t.texCoord[1].x <<= 7; - t.texCoord[1].y <<= 7; + t.texCoordAtlas[0].x <<= 7; + t.texCoordAtlas[0].y <<= 7; + t.texCoordAtlas[1].x <<= 7; + t.texCoordAtlas[1].y <<= 7; /* t.texCoord[0].x += 16; t.texCoord[0].y += 16; @@ -1351,9 +1366,6 @@ struct Level : IGame { dir = -1; } - beginLighting(true); - updateLighting(); - while (i != end) { int roomIndex = roomsList[i]; MeshBuilder::RoomRange &range = mesh->rooms[roomIndex]; @@ -1412,7 +1424,6 @@ struct Level : IGame { mesh->renderRoomSprites(roomIndex); } } - endLighting(); Core::setBlendMode(bmNone); } @@ -1445,6 +1456,13 @@ struct Level : IGame { if (entity.type == TR::Entity::CRYSTAL) type = Shader::MIRROR; + if (isModel) { // model + setMainLight(controller); + } else { // sprite + Core::lightPos[0] = vec4(0, 0, 0, 0); + Core::lightColor[0] = vec4(0, 0, 0, 1); + } + if (type == Shader::SPRITE) { float alpha = (entity.type == TR::Entity::SMOKE || entity.type == TR::Entity::WATER_SPLASH || entity.type == TR::Entity::SPARKLES) ? 0.75f : 1.0f; float diffuse = entity.isPickup() ? 1.0f : 0.5f; @@ -1452,8 +1470,6 @@ struct Level : IGame { } else setRoomParams(roomIndex, type, 1.0f, intensity, controller->specular, 1.0f, mesh->transparent == 1); - updateLighting(); - if (isModel) { // model vec3 pos = controller->getPos(); if (ambientCache) { @@ -1463,13 +1479,8 @@ struct Level : IGame { memcpy(controller->ambient, cube.colors, sizeof(cube.colors)); // store last calculated ambient into controller Core::active.shader->setParam(uAmbient, controller->ambient[0], 6); } + } - setMainLight(controller); - } else { // sprite - Core::lightPos[0] = vec4(0, 0, 0, 0); - Core::lightColor[0] = vec4(0, 0, 0, 1); - } - Core::active.shader->setParam(uLightPos, Core::lightPos[0], MAX_LIGHTS); Core::active.shader->setParam(uLightColor, Core::lightColor[0], MAX_LIGHTS); @@ -1602,13 +1613,41 @@ struct Level : IGame { } } - void updateLighting() { - #ifdef FFP +#ifdef FFP + void updateLighting(Shader::Type type) { + float ambient = Core::active.material.y; + int lightMask = 0; + switch (type) { + case Shader::SPRITE : + case Shader::ROOM : + ambient = 1.0f; + lightMask = 2; + break; + case Shader::ENTITY : + lightMask = 1 | 2; + break; + case Shader::FLASH : + case Shader::MIRROR : + ambient = 1.0f; + break; + default : ; + } + #ifdef _OS_PSP - ubyte4 ambient; - ambient.x = ambient.y = ambient.z = clamp(int(Core::active.material.y * 255), 0, 255); - ambient.w = 255; - sceGuAmbient(*(uint32*)&ambient); + if (lightMask & 1) + sceGuEnable(GU_LIGHT0); + else + sceGuDisable(GU_LIGHT0); + + if (lightMask & 2) + sceGuEnable(GU_LIGHT1); + else + sceGuDisable(GU_LIGHT1); + + ubyte4 amb; + amb.x = amb.y = amb.z = clamp(int(ambient * 255), 0, 255); + amb.w = 255; + sceGuAmbient(*(uint32*)&amb); for (int i = 0; i < 2 /*MAX_LIGHTS*/; i++) { ScePspFVector3 pos; @@ -1628,8 +1667,18 @@ struct Level : IGame { sceGuLightAtt(i, 1.0f, 0.0f, Core::lightColor[i].w * Core::lightColor[i].w); } #else - vec4 ambient(vec3(Core::active.material.y), 1.0f); - glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (GLfloat*)&ambient); + if (lightMask & 1) + glDisable(GL_LIGHT0); + else + glEnable(GL_LIGHT0); + + if (lightMask & 2) + glDisable(GL_LIGHT1); + else + glEnable(GL_LIGHT1); + + vec4 amb(vec3(ambient), 1.0f); + glLightModelfv(GL_LIGHT_MODEL_AMBIENT, (GLfloat*)&amb); for (int i = 0; i < 2 /*MAX_LIGHTS*/; i++) { vec4 pos(Core::lightPos[i].xyz(), 1.0f); @@ -1642,41 +1691,27 @@ struct Level : IGame { glLightfv(GL_LIGHT0 + i, GL_QUADRATIC_ATTENUATION, (GLfloat*)&att); } #endif - #endif } - void beginLighting(bool room) { - #ifdef FFP + void beginLighting() { Core::mModel.identity(); #ifdef _OS_PSP sceGuEnable(GU_LIGHTING); - if (room) - sceGuDisable(GU_LIGHT0); - else - sceGuEnable(GU_LIGHT0); - sceGuEnable(GU_LIGHT1); #else glEnable(GL_COLOR_MATERIAL); glEnable(GL_LIGHTING); - if (room) - glDisable(GL_LIGHT0); - else - glEnable(GL_LIGHT0); - glEnable(GL_LIGHT1); #endif - #endif } void endLighting() { - #ifdef FFP #ifdef _OS_PSP sceGuDisable(GU_LIGHTING); #else glDisable(GL_COLOR_MATERIAL); glDisable(GL_LIGHTING); #endif - #endif } +#endif void setup() { camera->setup(Core::pass == Core::passCompose); @@ -1698,8 +1733,6 @@ struct Level : IGame { PROFILE_MARKER("ENTITIES"); - beginLighting(false); - if (transp == 0) { Core::setBlendMode(bmNone); renderEntitiesTransp(transp); @@ -1733,8 +1766,6 @@ struct Level : IGame { renderEntitiesTransp(transp); Core::setDepthWrite(true); } - - endLighting(); } bool checkPortal(const TR::Room &room, const TR::Room::Portal &portal, const vec4 &viewPort, vec4 &clipPort) { @@ -1921,11 +1952,17 @@ struct Level : IGame { prepareRooms(roomsList, roomsCount); - updateLighting(); + #ifdef FFP + beginLighting(); + #endif renderOpaque(roomsList, roomsCount); renderTransparent(roomsList, roomsCount); + #ifdef FFP + endLighting(); + #endif + if (camera->isUnderwater()) renderAdditive(roomsList, roomsCount); @@ -2097,7 +2134,7 @@ struct Level : IGame { void renderShadows(int roomIndex) { PROFILE_MARKER("PASS_SHADOW"); - if (Core::settings.detail.shadows == Core::Settings::Quality::LOW) + if (Core::settings.detail.shadows == Core::Settings::LOW) return; ASSERT(shadow); @@ -2422,7 +2459,7 @@ struct Level : IGame { params->waterHeight = params->clipHeight; if (shadow) { - if (view > 0 && Core::settings.detail.shadows < Core::Settings::Quality::HIGH) + if (view > 0 && Core::settings.detail.shadows < Core::Settings::HIGH) renderShadows(player->getRoomIndex()); // render shadows for player2 for all-in-one shadow technique shadow->bind(sShadow); } diff --git a/src/mesh.h b/src/mesh.h index 5ac78fff..0ffdd2dd 100644 --- a/src/mesh.h +++ b/src/mesh.h @@ -352,14 +352,13 @@ struct MeshBuilder { #endif int index = level.meshOffsets[model.mStart + j]; - if (!index && model.mStart + j > 0) - continue; - - TR::Mesh &mesh = level.meshes[index]; - #ifndef MERGE_MODELS - geom.getNextRange(vStartModel, iCount, 0xFFFF, 0xFFFF); - #endif - buildMesh(geom, blendMask, mesh, level, indices, vertices, iCount, vCount, vStartModel, j, 0, 0, 0, 0, COLOR_WHITE); + if (index || model.mStart + j <= 0) { + TR::Mesh &mesh = level.meshes[index]; + #ifndef MERGE_MODELS + geom.getNextRange(vStartModel, iCount, 0xFFFF, 0xFFFF); + #endif + buildMesh(geom, blendMask, mesh, level, indices, vertices, iCount, vCount, vStartModel, j, 0, 0, 0, 0, COLOR_WHITE); + } #ifndef MERGE_MODELS geom.finish(iCount); diff --git a/src/platform/psp/main.cpp b/src/platform/psp/main.cpp index 1548e62d..c9856033 100644 --- a/src/platform/psp/main.cpp +++ b/src/platform/psp/main.cpp @@ -170,7 +170,7 @@ int main() { sceDisplayWaitVblankStart(); sceGuDisplay(GU_TRUE); - Core::curBackBuffer = 0; + GAPI::curBackBuffer = 0; while (!Core::isQuit) { GAPI::beginCmdBuf(); @@ -180,7 +180,7 @@ int main() { Game::render(); GAPI::submitCmdBuf(); Core::waitVBlank(); - Core::curBackBuffer = sceGuSwapBuffers(); + GAPI::curBackBuffer = sceGuSwapBuffers(); } Game::deinit(); diff --git a/src/texture.h b/src/texture.h index 51fae447..55bf68c8 100644 --- a/src/texture.h +++ b/src/texture.h @@ -14,8 +14,8 @@ struct Texture : GAPI::Texture { Texture(TR::Tile4 *tiles, int tilesCount, TR::CLUT *cluts, int clutsCount) : GAPI::Texture(256, 256, OPT_PROXY) { #ifdef EDRAM_TEX - this->tiles = (TR::Tile4*)Core::allocEDRAM(tilesCount * sizeof(tiles[0])); - this->cluts = (TR::CLUT*)Core::allocEDRAM(clutsCount * sizeof(cluts[0])); + this->tiles = (TR::Tile4*)GAPI::allocEDRAM(tilesCount * sizeof(tiles[0])); + this->cluts = (TR::CLUT*)GAPI::allocEDRAM(clutsCount * sizeof(cluts[0])); memcpy(this->cluts, cluts, clutsCount * sizeof(cluts[0])); #ifdef TEX_SWIZZLE for (int i = 0; i < tilesCount; i++) @@ -102,9 +102,11 @@ struct Texture : GAPI::Texture { } virtual ~Texture() { - #ifdef SPLIT_BY_TILE - for (int i = 0; i < COUNT(tiles); i++) - delete tiles[i]; + #ifndef _OS_PSP + #ifdef SPLIT_BY_TILE + for (int i = 0; i < COUNT(tiles); i++) + delete tiles[i]; + #endif #endif deinit(); }