diff --git a/desmume/src/frontend/windows/main.cpp b/desmume/src/frontend/windows/main.cpp index 9a8738487..c2c7d0e75 100755 --- a/desmume/src/frontend/windows/main.cpp +++ b/desmume/src/frontend/windows/main.cpp @@ -4477,6 +4477,9 @@ void FilterUpdate(HWND hwnd, bool user) SetRotate(hwnd, video.rotation, false); if(user && windowSize==0) {} else ScaleScreen(windowSize, false); + if (romloaded) + Display(); + WritePrivateProfileInt("Video", "Filter", video.currentfilter, IniName); WritePrivateProfileInt("Video", "Width", video.width, IniName); WritePrivateProfileInt("Video", "Height", video.height, IniName); diff --git a/desmume/src/frontend/windows/video.h b/desmume/src/frontend/windows/video.h index 448122db1..c45517d1a 100644 --- a/desmume/src/frontend/windows/video.h +++ b/desmume/src/frontend/windows/video.h @@ -1,18 +1,18 @@ /* - Copyright (C) 2009-2015 DeSmuME team +Copyright (C) 2009-2015 DeSmuME team - This file is free software: you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation, either version 2 of the License, or - (at your option) any later version. +This file is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 2 of the License, or +(at your option) any later version. - This file is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. +This file is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. - You should have received a copy of the GNU General Public License - along with the this software. If not, see . +You should have received a copy of the GNU General Public License +along with the this software. If not, see . */ #include "filter/filter.h" @@ -44,6 +44,7 @@ public: int prescaleTotal; size_t scratchBufferSize; + size_t rawBufferSize; u8* srcBuffer; size_t srcBufferSize; u32 *buffer, *buffer_raw; @@ -51,33 +52,46 @@ public: void SetPrescale(int prescaleHD, int prescalePost) { - free_aligned(buffer_raw); - free_aligned(filteredbuffer); + if (this->prescaleHD != prescaleHD || this->prescalePost != prescalePost) + { + free_aligned(buffer_raw); + free_aligned(filteredbuffer); - this->prescaleHD = prescaleHD; - this->prescalePost = prescalePost; + this->prescaleHD = prescaleHD; + this->prescalePost = prescalePost; - prescaleTotal = prescaleHD; - - const int kInflationFactor = 5; //the largest filter is going up 5x in each dimension + prescaleTotal = prescaleHD; - //all these stupid video filters read outside of their buffer. let's allocate too much and hope it stays filled with black. geeze + ResizeBuffers(); + + setfilter(currentfilter); + } + } + + void ResizeBuffers() + { + // all these stupid video filters read outside of their buffer. let's allocate too much and hope it stays filled with black. geeze const int kPadSize = 4; - - size_t scratchBufferWidth = 256*kInflationFactor*prescaleHD + (kPadSize*2); - size_t scratchBufferHeight = 192*2*prescaleHD*kInflationFactor + (kPadSize*2); - scratchBufferSize = scratchBufferWidth * scratchBufferHeight * 4; - //why are these the same size, anyway? - buffer_raw = buffer = (u32*)malloc_alignedCacheLine(scratchBufferSize); + // raw buffer + size_t rawBufferWidth = 256 * prescaleHD + (kPadSize * 2); + size_t rawBufferHeight = 192 * 2 * prescaleHD + (kPadSize * 2); + rawBufferSize = rawBufferWidth * rawBufferHeight * 4; + buffer_raw = buffer = (u32*)malloc_alignedCacheLine(rawBufferSize); + + // display buffer + size_t scratchBufferWidth = width + (kPadSize * 2); + size_t scratchBufferHeight = height + (kPadSize * 2); + scratchBufferSize = scratchBufferWidth * scratchBufferHeight * 4; filteredbuffer = (u32*)malloc_alignedCacheLine(scratchBufferSize); - clear(); - //move the buffer pointer inside it's padded area so that earlier reads won't go out of the buffer we allocated - buffer += (kPadSize*scratchBufferWidth + kPadSize)*4; + buffer += (kPadSize*rawBufferWidth + kPadSize) * 4; - setfilter(currentfilter); + // clean the new buffers + clear(); + // prevent crashing when reducing the scaling + srcBufferSize = 0; } enum { @@ -114,62 +128,63 @@ public: //{ // memset(srcBuffer, 0xFF, size() * 2); //} - memset(buffer_raw, 0, scratchBufferSize); + memset(buffer_raw, 0, rawBufferSize); memset(filteredbuffer, 0, scratchBufferSize); } void reset() { - SetPrescale(1,1); //should i do this here? + SetPrescale(1, 1); //should i do this here? width = 256; height = 384; } void setfilter(int filter) { - if(filter < 0 || filter >= NUM_FILTERS) + if (filter < 0 || filter >= NUM_FILTERS) filter = NONE; currentfilter = filter; - switch(filter) { + switch (filter) { - case NONE: - width = 256; - height = 384; - break; - case EPX1POINT5: - case EPXPLUS1POINT5: - case NEAREST1POINT5: - case NEARESTPLUS1POINT5: - width = 256*3/2; - height = 384*3/2; - break; + case NONE: + width = 256; + height = 384; + break; + case EPX1POINT5: + case EPXPLUS1POINT5: + case NEAREST1POINT5: + case NEARESTPLUS1POINT5: + width = 256 * 3 / 2; + height = 384 * 3 / 2; + break; - case _5XBRZ: - width = 256*5; - height = 384*5; - break; + case _5XBRZ: + width = 256 * 5; + height = 384 * 5; + break; - case HQ4X: - case _4XBRZ: - width = 256*4; - height = 384*4; - break; + case HQ4X: + case _4XBRZ: + width = 256 * 4; + height = 384 * 4; + break; - case _3XBRZ: - width = 256*3; - height = 384*3; - break; + case _3XBRZ: + width = 256 * 3; + height = 384 * 3; + break; - case _2XBRZ: - default: - width = 256*2; - height = 384*2; - break; + case _2XBRZ: + default: + width = 256 * 2; + height = 384 * 2; + break; } width *= prescaleHD; height *= prescaleHD; + ResizeBuffers(); } SSurface src; @@ -177,7 +192,7 @@ public: u16* finalBuffer() const { - if(currentfilter == NONE) + if (currentfilter == NONE) return (u16*)buffer; else return (u16*)filteredbuffer; } @@ -191,81 +206,81 @@ public: dst.Height = height * prescaleHD; dst.Width = width * prescaleHD; - dst.Pitch = width*2; + dst.Pitch = width * 2; dst.Surface = (u8*)filteredbuffer; - switch(currentfilter) + switch (currentfilter) { - case NONE: - break; - case LQ2X: - RenderLQ2X(src, dst); - break; - case LQ2XS: - RenderLQ2XS(src, dst); - break; - case HQ2X: - RenderHQ2X(src, dst); - break; - case HQ4X: - RenderHQ4X(src, dst); - break; - case HQ2XS: - RenderHQ2XS(src, dst); - break; - case _2XSAI: - Render2xSaI (src, dst); - break; - case SUPER2XSAI: - RenderSuper2xSaI (src, dst); - break; - case SUPEREAGLE: - RenderSuperEagle (src, dst); - break; - case SCANLINE: - RenderScanline(src, dst); - break; - case BILINEAR: - RenderBilinear(src, dst); - break; - case NEAREST2X: - RenderNearest2X(src,dst); - break; - case EPX: - RenderEPX(src,dst); - break; - case EPXPLUS: - RenderEPXPlus(src,dst); - break; - case EPX1POINT5: - RenderEPX_1Point5x(src,dst); - break; - case EPXPLUS1POINT5: - RenderEPXPlus_1Point5x(src,dst); - break; - case NEAREST1POINT5: - RenderNearest_1Point5x(src,dst); - break; - case NEARESTPLUS1POINT5: - RenderNearestPlus_1Point5x(src,dst); - break; - case _2XBRZ: - Render2xBRZ(src,dst); - break; - case _3XBRZ: - Render3xBRZ(src,dst); - break; - case _4XBRZ: - Render4xBRZ(src,dst); - break; - case _5XBRZ: - Render5xBRZ(src,dst); - break; + case NONE: + break; + case LQ2X: + RenderLQ2X(src, dst); + break; + case LQ2XS: + RenderLQ2XS(src, dst); + break; + case HQ2X: + RenderHQ2X(src, dst); + break; + case HQ4X: + RenderHQ4X(src, dst); + break; + case HQ2XS: + RenderHQ2XS(src, dst); + break; + case _2XSAI: + Render2xSaI(src, dst); + break; + case SUPER2XSAI: + RenderSuper2xSaI(src, dst); + break; + case SUPEREAGLE: + RenderSuperEagle(src, dst); + break; + case SCANLINE: + RenderScanline(src, dst); + break; + case BILINEAR: + RenderBilinear(src, dst); + break; + case NEAREST2X: + RenderNearest2X(src, dst); + break; + case EPX: + RenderEPX(src, dst); + break; + case EPXPLUS: + RenderEPXPlus(src, dst); + break; + case EPX1POINT5: + RenderEPX_1Point5x(src, dst); + break; + case EPXPLUS1POINT5: + RenderEPXPlus_1Point5x(src, dst); + break; + case NEAREST1POINT5: + RenderNearest_1Point5x(src, dst); + break; + case NEARESTPLUS1POINT5: + RenderNearestPlus_1Point5x(src, dst); + break; + case _2XBRZ: + Render2xBRZ(src, dst); + break; + case _3XBRZ: + Render3xBRZ(src, dst); + break; + case _4XBRZ: + Render4xBRZ(src, dst); + break; + case _5XBRZ: + Render5xBRZ(src, dst); + break; } } int size() { - return width*height; + return width * height; } int dividebyratio(int x) { @@ -273,62 +288,62 @@ public: } int rotatedwidth() { - switch(rotation) { - case 0: - return width; - case 90: - return height; - case 180: - return width; - case 270: - return height; - default: - return 0; + switch (rotation) { + case 0: + return width; + case 90: + return height; + case 180: + return width; + case 270: + return height; + default: + return 0; } } int rotatedheight() { - switch(rotation) { - case 0: - return height; - case 90: - return width; - case 180: - return height; - case 270: - return width; - default: - return 0; + switch (rotation) { + case 0: + return height; + case 90: + return width; + case 180: + return height; + case 270: + return width; + default: + return 0; } } int rotatedwidthgap() { - switch(rotation) { - case 0: - return width; - case 90: - return height + ((layout == 0) ? scaledscreengap() : 0); - case 180: - return width; - case 270: - return height + ((layout == 0) ? scaledscreengap() : 0); - default: - return 0; + switch (rotation) { + case 0: + return width; + case 90: + return height + ((layout == 0) ? scaledscreengap() : 0); + case 180: + return width; + case 270: + return height + ((layout == 0) ? scaledscreengap() : 0); + default: + return 0; } } int rotatedheightgap() { - switch(rotation) { - case 0: - return height + ((layout == 0) ? scaledscreengap() : 0); - case 90: - return width; - case 180: - return height + ((layout == 0) ? scaledscreengap() : 0); - case 270: - return width; - default: - return 0; + switch (rotation) { + case 0: + return height + ((layout == 0) ? scaledscreengap() : 0); + case 90: + return width; + case 180: + return height + ((layout == 0) ? scaledscreengap() : 0); + case 270: + return width; + default: + return 0; } }