diff --git a/src/core/Streaming.cpp b/src/core/Streaming.cpp index 1411ba6..8097c5d 100644 --- a/src/core/Streaming.cpp +++ b/src/core/Streaming.cpp @@ -270,7 +270,7 @@ CStreaming::Init2(void) void CStreaming::Init(void) { -/*#ifdef USE_TXD_CDIMAGE +#ifdef USE_TXD_CDIMAGE int txdHandle = CFileMgr::OpenFile("MODELS\\TXD.IMG", "r"); if (txdHandle) CFileMgr::CloseFile(txdHandle); @@ -285,9 +285,9 @@ CStreaming::Init(void) CStreaming::Init2(); } } -#else*/ +#else CStreaming::Init2(); -//#endif +#endif } void diff --git a/src/rw/TexRead.cpp b/src/rw/TexRead.cpp index bbfee01..ed78919 100644 --- a/src/rw/TexRead.cpp +++ b/src/rw/TexRead.cpp @@ -93,36 +93,106 @@ static int clamp(int size, int targetSize) return size; } -static void downscaleTexture(RwTexture *texture) -{ - RwRaster *oldRaster = RwTextureGetRaster(texture); - if (oldRaster == nil) - return; +void debugRaster(RwRaster *r){ + if(!r){ + debug("Raster NULL"); + return; + } - extern bool moreVram; - int targetSize = moreVram ? 64 : 32; - - int oldWidth = RwRasterGetWidth(oldRaster); - int oldHeight = RwRasterGetHeight(oldRaster); - if (oldWidth <= targetSize && oldHeight <= targetSize) return; + debug("Raster: %dx%d | depth: %d | format: 0x%X | stride: %d | platform: %d | pixels: %p", + r->width, + r->height, + r->depth, + r->format, + r->stride, + r->platform, + r->pixels); +} - int newWidth = clamp(oldWidth, targetSize); - int newHeight = clamp(oldHeight, targetSize); - if (newWidth == oldWidth && newHeight == oldHeight) return; +static void downscaleTexture(RwTexture *texture){ + #ifdef RW_GLES1 + if(texture == nil) + return; - RwImage *image = oldRaster->toImage(); - if (image == nil) return; + RwRaster *oldRaster = RwTextureGetRaster(texture); + if(oldRaster == nil) + return; - RwImage *resized = resizeImage(image, newWidth, newHeight); - RwImageDestroy(image); - if (resized == nil) return; + int oldWidth = RwRasterGetWidth(oldRaster); + int oldHeight = RwRasterGetHeight(oldRaster); - RwRaster *newRaster = rw::Raster::createFromImage(resized); - RwImageDestroy(resized); - if (newRaster == nil) return; + // dividir a la mitad, mínimo 16x16 + int newWidth = oldWidth > 16 ? oldWidth / 2 : oldWidth; + int newHeight = oldHeight > 16 ? oldHeight / 2 : oldHeight; - RwTextureSetRaster(texture, newRaster); - RwRasterDestroy(oldRaster); + // si ya es suficientemente chica, no hacer nada + if(newWidth == oldWidth && newHeight == oldHeight) + return; + + // toImage() funciona porque el backingStore está populado + RwImage *image = oldRaster->toImage(); + if(image == nil){ + debug("downscaleTexture: toImage FAILED for %dx%d", oldWidth, oldHeight); + return; + } + + RwImage *resized = resizeImage(image, newWidth, newHeight); + RwImageDestroy(image); + if(resized == nil){ + debug("downscaleTexture: resizeImage FAILED"); + return; + } + + // crear nuevo raster en formato compatible con GLES1 + int32 w, h, d, f; + rw::Raster::imageFindRasterFormat(resized, rw::Raster::TEXTURE, &w, &h, &d, &f); + RwRaster *newRaster = rw::Raster::create(w, h, d, f | rw::Raster::TEXTURE, rw::PLATFORM_GLES1); + if(newRaster == nil){ + debug("downscaleTexture: raster create FAILED"); + RwImageDestroy(resized); + return; + } + + if(newRaster->setFromImage(resized) == nil){ + debug("downscaleTexture: setFromImage FAILED"); + RwRasterDestroy(newRaster); + RwImageDestroy(resized); + return; + } + + RwImageDestroy(resized); + RwTextureSetRaster(texture, newRaster); + RwRasterDestroy(oldRaster); + #else + RwRaster *oldRaster = RwTextureGetRaster(texture); + if (oldRaster == nil) + return; + + extern bool moreVram; + int targetSize = moreVram ? 64 : 32; + + int oldWidth = RwRasterGetWidth(oldRaster); + int oldHeight = RwRasterGetHeight(oldRaster); + if (oldWidth <= targetSize && oldHeight <= targetSize) return; + + int newWidth = clamp(oldWidth, targetSize); + int newHeight = clamp(oldHeight, targetSize); + if (newWidth == oldWidth && newHeight == oldHeight) return; + + RwImage *image = oldRaster->toImage(); + if (image == nil) return; + + RwImage *resized = resizeImage(image, newWidth, newHeight); + RwImageDestroy(image); + if (resized == nil) return; + + RwRaster *newRaster = rw::Raster::createFromImage(resized); + RwImageDestroy(resized); + if (newRaster == nil) return; + + RwTextureSetRaster(texture, newRaster); + RwRasterDestroy(oldRaster); + #endif } #endif diff --git a/vendor/librw/src/gles1/gl1device.cpp b/vendor/librw/src/gles1/gl1device.cpp index a30be35..1dd9b6f 100644 --- a/vendor/librw/src/gles1/gl1device.cpp +++ b/vendor/librw/src/gles1/gl1device.cpp @@ -308,9 +308,7 @@ flushGlRenderState(void) -void -setAlphaBlend(bool32 enable) -{ +void setAlphaBlend(bool32 enable){ if(rwStateCache.blendEnable != enable){ rwStateCache.blendEnable = enable; setGlRenderState(RWGL_BLEND, enable); diff --git a/vendor/librw/src/gles1/gl1raster.cpp b/vendor/librw/src/gles1/gl1raster.cpp index 51d1eed..bca261a 100644 --- a/vendor/librw/src/gles1/gl1raster.cpp +++ b/vendor/librw/src/gles1/gl1raster.cpp @@ -416,86 +416,96 @@ rasterLock(Raster *raster, int32 level, int32 lockMode) #endif } -void -rasterUnlock(Raster *raster, int32 level) -{ +void rasterUnlock(Raster *raster, int32 level){ #ifdef RW_GLES1 - Gl1Raster *natras = GETGL1RASTEREXT(raster); + Gl1Raster *natras = GETGL1RASTEREXT(raster); - assert(raster->pixels); + assert(raster->pixels); - switch(raster->type){ - case Raster::NORMAL: - case Raster::TEXTURE: - case Raster::CAMERATEXTURE: - if(raster->privateFlags & Raster::LOCKWRITE){ - if (level != 0) break; - uint32 prev = bindTexture(natras->texid); - if(natras->isCompressed){ - glCompressedTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat, - raster->width, raster->height, 0, - getLevelSize(raster, level), - raster->pixels); - }else{ - int stride = raster->width * natras->bpp; - uint8_t* tmp = (uint8_t*)malloc(stride); - for (int y = 0; y < raster->height / 2; y++) { - uint8_t* a = (uint8_t*)raster->pixels + y * stride; - uint8_t* b = (uint8_t*)raster->pixels + (raster->height - 1 - y) * stride; - - memcpy(tmp, a, stride); - memcpy(a, b, stride); - memcpy(b, tmp, stride); - } - free(tmp); - - if (raster->pixels != nil && natras->format == GL_RGBA && natras->type == GL_UNSIGNED_BYTE) { - // convert to 16-bit - uint16_t* pixels16 = (uint16_t*)malloc(raster->width * raster->height * sizeof(uint16_t)); - uint8_t* pixels8 = (uint8_t*)raster->pixels; - - for (int i = 0; i < raster->width * raster->height; i++) { - uint8_t r = pixels8[i * 4 + 0]; - uint8_t g = pixels8[i * 4 + 1]; - uint8_t b = pixels8[i * 4 + 2]; - uint8_t a = pixels8[i * 4 + 3]; - - pixels16[i] = ((r >> 4) << 12) | ((g >> 4) << 8) | ((b >> 4) << 4) | (a >> 4); - } - glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, raster->width, raster->height, 0, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels16); - free(pixels16); - } else - { -// glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat, - raster->width, raster->height, - 0, natras->format, natras->type, raster->pixels); - } - } + switch(raster->type){ + case Raster::NORMAL: + case Raster::TEXTURE: + case Raster::CAMERATEXTURE: + if(raster->privateFlags & Raster::LOCKWRITE){ + if(level != 0) break; - if(natras->backingStore){ - assert(level < natras->backingStore->numlevels); - memcpy(natras->backingStore->levels[level].data, raster->pixels, - natras->backingStore->levels[level].size); - } + // === GUARDAR EN BACKING STORE ANTES DE SUBIR A GPU === + if(natras->backingStore == nil){ + int numLevels = natras->numLevels; + // RasterLevels tiene: int numlevels; struct { uint32 size; uint8 *data; } levels[]; + natras->backingStore = (RasterLevels*)malloc( + sizeof(RasterLevels) + sizeof(natras->backingStore->levels[0]) * numLevels); + natras->backingStore->numlevels = numLevels; + for(int i = 0; i < numLevels; i++){ + uint32 sz = getLevelSize(raster, i); + natras->backingStore->levels[i].size = sz; + natras->backingStore->levels[i].data = (uint8*)malloc(sz); + memset(natras->backingStore->levels[i].data, 0, sz); + } + } + // copiar píxeles actuales al backing store + { + uint32 sz = getLevelSize(raster, level); + assert(level < natras->backingStore->numlevels); + memcpy(natras->backingStore->levels[level].data, raster->pixels, sz); + } + // === FIN BACKING STORE === - bindTexture(prev); - } - break; + uint32 prev = bindTexture(natras->texid); - case Raster::CAMERA: - // TODO: write? - break; - } + // flip vertical (igual que antes) + { + int stride = raster->width * natras->bpp; + uint8_t *tmp = (uint8_t*)malloc(stride); + for(int y = 0; y < raster->height / 2; y++){ + uint8_t *a = (uint8_t*)raster->pixels + y * stride; + uint8_t *b = (uint8_t*)raster->pixels + (raster->height - 1 - y) * stride; + memcpy(tmp, a, stride); + memcpy(a, b, stride); + memcpy(b, tmp, stride); + } + free(tmp); + } - rwFree(raster->pixels); - raster->pixels = nil; + if(!natras->isCompressed){ + if(natras->format == GL_RGBA && natras->type == GL_UNSIGNED_BYTE){ + // convertir RGBA8888 → RGBA4444 + uint16_t *pixels16 = (uint16_t*)malloc(raster->width * raster->height * 2); + uint8_t *pixels8 = (uint8_t*)raster->pixels; + for(int i = 0; i < raster->width * raster->height; i++){ + uint8_t r = pixels8[i*4+0]; + uint8_t g = pixels8[i*4+1]; + uint8_t b = pixels8[i*4+2]; + uint8_t a = pixels8[i*4+3]; + pixels16[i] = ((r>>4)<<12)|((g>>4)<<8)|((b>>4)<<4)|(a>>4); + } + glTexImage2D(GL_TEXTURE_2D, level, GL_RGBA, + raster->width, raster->height, 0, + GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4, pixels16); + free(pixels16); + } else { + glTexImage2D(GL_TEXTURE_2D, level, natras->internalFormat, + raster->width, raster->height, 0, + natras->format, natras->type, raster->pixels); + } + } + + bindTexture(prev); + } + break; + + case Raster::CAMERA: + break; + } + + rwFree(raster->pixels); + raster->pixels = nil; #endif - raster->width = raster->originalWidth; - raster->height = raster->originalHeight; - raster->stride = raster->originalStride; - raster->pixels = raster->originalPixels; - raster->privateFlags = 0; + raster->width = raster->originalWidth; + raster->height = raster->originalHeight; + raster->stride = raster->originalStride; + raster->pixels = raster->originalPixels; + raster->privateFlags = 0; } int32 @@ -741,8 +751,8 @@ void evictRaster(Raster *raster); static void* destroyNativeRaster(void *object, int32 offset, int32) { - Raster *raster = (Raster*)object; - Gl1Raster *natras = PLUGINOFFSET(Gl1Raster, object, offset); + Raster *raster = (Raster*)object; + Gl1Raster *natras = PLUGINOFFSET(Gl1Raster, object, offset); #ifdef RW_GLES1 evictRaster(raster); switch(raster->type){ @@ -769,10 +779,14 @@ destroyNativeRaster(void *object, int32 offset, int32) natras->texid = 0; natras->fbo = 0; - free(natras->backingStore); - + if(natras->backingStore){ + for(int i = 0; i < natras->backingStore->numlevels; i++) + free(natras->backingStore->levels[i].data); + free(natras->backingStore); + natras->backingStore = nil; + } #endif - return object; + return object; } static void*