From c77f686f6b8e31977f856d78d956bb2a0410510a Mon Sep 17 00:00:00 2001 From: rogerman Date: Fri, 28 Dec 2012 03:36:57 +0000 Subject: [PATCH] Cocoa Port: - Add new static method to run a video filter without needed to instantiate a new video filter object. - When changing filters, do not reinitialize the destination buffers if the video filter ID is the same. - Do some other cleanup of the video filter code. - Add new HQ4XS video filter. --- desmume/src/cocoa/cocoa_videofilter.h | 1 + desmume/src/cocoa/cocoa_videofilter.mm | 13 +- .../English.lproj/MainMenu.strings | Bin 271872 -> 272232 bytes .../translations/English.lproj/MainMenu.xib | 209 ++++++------ desmume/src/cocoa/videofilter.cpp | 305 ++++++------------ desmume/src/cocoa/videofilter.h | 68 ++-- 6 files changed, 270 insertions(+), 326 deletions(-) diff --git a/desmume/src/cocoa/cocoa_videofilter.h b/desmume/src/cocoa/cocoa_videofilter.h index 47d7e801f..5079b8d09 100644 --- a/desmume/src/cocoa/cocoa_videofilter.h +++ b/desmume/src/cocoa/cocoa_videofilter.h @@ -31,6 +31,7 @@ @interface CocoaVideoFilter : NSObject { VideoFilter *vf; + VideoFilterTypeID currentFilterType; } - (id) initWithSize:(NSSize)theSize; diff --git a/desmume/src/cocoa/cocoa_videofilter.mm b/desmume/src/cocoa/cocoa_videofilter.mm index f33652175..85c5403fd 100644 --- a/desmume/src/cocoa/cocoa_videofilter.mm +++ b/desmume/src/cocoa/cocoa_videofilter.mm @@ -46,6 +46,7 @@ } vf = new VideoFilter((unsigned int)theSize.width, (unsigned int)theSize.height, typeID, numThreads); + currentFilterType = typeID; return self; } @@ -73,11 +74,19 @@ { BOOL result = NO; - bool cResult = vf->ChangeFilter(typeID); - if (cResult) + if (typeID == currentFilterType) { result = YES; } + else + { + bool cResult = vf->ChangeFilterByID(typeID); + if (cResult) + { + result = YES; + currentFilterType = typeID; + } + } return result; } diff --git a/desmume/src/cocoa/translations/English.lproj/MainMenu.strings b/desmume/src/cocoa/translations/English.lproj/MainMenu.strings index 84ea3275e99aa7d7ad55d46020e6280f907c5081..23cb61e1220274c9115bc88458a288fedea5a336 100644 GIT binary patch delta 337 zcmXYsJxIe~5Qg)%A%aNxMkx;Qk9H_ALXc8_25}HK(V-|v5pi%R866xtsfdGck^^yY zbaW70Q`3J+aZte~G*05!(MkLoJKS)0?>!G!YK!lVC_UoKB|S_~;3rv>k&}(#EW@C& z-i%X$#@#Y35^ zKAf>#MV7l2tdQ-eqtsH@h&=aI7>*lL`L2d5F4m-JuZ|lw>o6(!$a0~9L;k5F=QMH3 zl?F`SX+omkBOQwtG~{`{jTE0ZVT`ORn~J66sr;H6n9gKCR_sZ%;{9Ddx{Pn|rz@nJ+QVqE;wkCiQDN?BA!l|R+~g&hC@ delta 293 zcmaEHPN3n8K*JWsX9uP`sIh2G=R3$~HTl7PgK4&mdXr`D3r$xz%&0K^+(AZ@$qM)N zz@j|&RHpMCVPu9)L7Ui@4KrqxxheY@`2lY z(*+JQ8cY{C!e|3x2~7TQUjZs*1~Kc=5k|Yo7jE+)$p}m?xXm#+t5^!6V#QIQxdKNS zXH3sJ24sEM&%`qQ)=|a@laKTZOb<8=bdSezMyctujxo-db^_>$x|@8{tBy0aO;4$2 zgetgkf>C06!f{5P$#FOI!1lLY)0p0O8mPD8B*@GYj0w{dPBF5z^PFM?Vy5jpr {1.79769e+308, 1.79769e+308} {256, 408} - + 256 YES @@ -5122,7 +5122,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{0, 24}, {256, 384}} - YES @@ -5136,7 +5135,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{2, 3}, {16, 16}} - 28938 100 @@ -5145,7 +5143,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 289 {{180, 3}, {56, 15}} - YES -2079981824 @@ -5179,7 +5176,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{160, 1}, {20, 20}} - YES 130560 @@ -5200,7 +5196,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 294 {{17, 5}, {137, 14}} - YES 68288064 @@ -5219,8 +5214,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {256, 408} - - {{0, 0}, {1920, 1178}} {256, 476} @@ -8085,6 +8078,17 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 5 + + + HQ4xS + + 2147483647 + + + _popUpItemAction: + 18 + + 2xSaI @@ -8317,7 +8321,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES - -2080244224 + 67239424 0 Use Vertical Sync @@ -15439,7 +15443,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 279 2 - {{1651, 296}, {204, 501}} + {{1651, 276}, {204, 521}} -461896704 Video Output Settings NSPanel @@ -15453,7 +15457,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{25, 18}, {154, 19}} + {{20, 18}, {164, 19}} YES @@ -15483,16 +15487,16 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{18, 14}, {129, 358}} + {{18, 14}, {129, 378}} YES - 18 + 19 1 YES -2080244224 - 139264 + 131072 None @@ -15510,7 +15514,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 67239424 - 139264 + 131072 LQ2x @@ -15616,7 +15620,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 1140981248 - 139264 + 131072 LQ2xS @@ -15663,7 +15667,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 1140981248 - 139264 + 131072 HQ2x @@ -15677,7 +15681,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 1140981248 - 139264 + 131072 HQ2xS @@ -15691,7 +15695,7 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 67239424 - 139264 + 131072 HQ4x @@ -15705,7 +15709,21 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 1140981248 - 139264 + 131072 + HQ4XS + + + 18 + 1211912703 + 0 + + + 400 + 75 + + + 67239424 + 131072 2xSaI @@ -15717,9 +15735,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - - 67239424 - 139264 + + 1140981248 + 131072 Super 2xSaI @@ -15731,9 +15749,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - - 1140981248 - 139264 + + 67239424 + 131072 Super Eagle @@ -15745,9 +15763,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - + 67239424 - 139264 + 131072 Scanline @@ -15759,9 +15777,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - - 67239424 - 139264 + + 1140981248 + 131072 Bilinear @@ -15773,9 +15791,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - - 1140981248 - 139264 + + 67239424 + 131072 Nearest 2x @@ -15787,9 +15805,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - + 67239424 - 139264 + 131072 Nearest 1.5x @@ -15801,9 +15819,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - + 67239424 - 139264 + 131072 Nearest+ 1.5x @@ -15815,9 +15833,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - + 67239424 - 139264 + 131072 EPX @@ -15829,9 +15847,9 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - + 67239424 - 139264 + 131072 EPX+ @@ -15843,29 +15861,15 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 - + 67239424 - 139264 + 131072 EPX 1.5x 16 1211912703 0 - - - 400 - 75 - - - 67239424 - 131072 - EPX+ 1.5x - - - 17 - 1211912703 - 0 12779520 @@ -15904,6 +15908,19 @@ QXBwbGUgQ29tcHV0ZXIsIEluYy4sIDIwMDUAAAAAA 400 75 + + 67239424 + 131072 + EPX+ 1.5x + + + 17 + 1211912703 + 0 + + 400 + 75 + {129, 18} {4, 2} @@ -15967,11 +15984,11 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - {{1, 1}, {168, 382}} + {{1, 1}, {168, 402}} - {{17, 41}, {170, 398}} + {{17, 41}, {170, 418}} {0, 0} @@ -15994,7 +16011,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{17, 465}, {169, 18}} + {{17, 485}, {169, 18}} YES @@ -16016,11 +16033,11 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 - {{17, 445}, {135, 18}} + {{17, 465}, {135, 18}} YES - -2080244224 + 67239424 131072 Use Vertical Sync @@ -16036,7 +16053,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - {204, 501} + {204, 521} {{0, 0}, {1920, 1178}} {1.79769e+308, 1.79769e+308} @@ -16051,7 +16068,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {1.79769e+308, 1.79769e+308} - + 256 YES @@ -16070,7 +16087,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 77}, {206, 18}} - YES -2080244224 @@ -16093,7 +16109,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 57}, {134, 18}} - YES -2080244224 @@ -16116,7 +16131,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 37}, {80, 18}} - YES -2080244224 @@ -16139,7 +16153,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{185, 12}, {45, 19}} - YES -1804468671 @@ -16220,7 +16233,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 14}, {165, 14}} - YES 68288064 @@ -16235,12 +16247,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 103}} - {{17, 163}, {250, 119}} - {0, 0} 67239424 @@ -16264,7 +16274,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{65, 18}, {154, 19}} - YES -2080244224 @@ -16295,7 +16304,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{18, 14}, {107, 58}} - YES 3 1 @@ -16500,12 +16508,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 82}} - {{17, 364}, {250, 98}} - {0, 0} 67239424 @@ -16539,7 +16545,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{18, 14}, {120, 78}} - YES 4 1 @@ -16791,12 +16796,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 102}} - {{17, 41}, {250, 118}} - {0, 0} 67239424 @@ -16830,7 +16833,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 32}, {113, 18}} - YES -2080244224 @@ -16853,7 +16855,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 268 {{15, 12}, {108, 18}} - YES -2080244224 @@ -16874,12 +16875,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {{1, 1}, {248, 58}} - {{17, 286}, {250, 74}} - {0, 0} 67239424 @@ -16900,8 +16899,6 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA {284, 482} - - {{0, 0}, {1920, 1178}} {1.79769e+308, 1.79769e+308} @@ -28950,6 +28947,14 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 6235 + + + changeVideoFilter: + + + + 6237 + @@ -29558,10 +29563,10 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA YES - - + + @@ -31332,6 +31337,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA + @@ -33828,6 +33834,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA + @@ -39445,6 +39452,16 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA + + 6236 + + + + + 6238 + + + @@ -41368,6 +41385,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA 6233.IBAttributePlaceholdersKey 6233.IBPluginDependency 6234.IBAttributePlaceholdersKey + 6238.IBPluginDependency 627.IBEditorWindowLastContentRect 627.IBPluginDependency 627.IBWindowTemplateEditedContentRect @@ -42141,7 +42159,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - {{1004, 578}, {489, 425}} + {{872, 628}, {489, 425}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -42193,7 +42211,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA P4AAAL+AAABC6AAAw5QAAA com.apple.InterfaceBuilder.CocoaPlugin - {{531, 545}, {151, 363}} + {{1002, 572}, {151, 383}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -42975,7 +42993,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - P4AAAL+AAABCRAAAxHyAAA + P4AAAL+AAABBkAAAw9UAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -43003,7 +43021,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin - P4AAAL+AAABBiAAAw+aAAA + P4AAAL+AAABBiAAAxAbAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -45384,6 +45402,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA OpenGL-based 3D rendering engine. Some 3D objects may have better looking texturing, but the geometry may be less accurate. Extremely high CPU usage. + com.apple.InterfaceBuilder.CocoaPlugin {{609, 360}, {400, 100}} com.apple.InterfaceBuilder.CocoaPlugin {{609, 360}, {400, 100}} @@ -45447,9 +45466,9 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin - {{1422, 661}, {204, 501}} + {{1237, 473}, {204, 521}} com.apple.InterfaceBuilder.CocoaPlugin - {{1422, 661}, {204, 501}} + {{1237, 473}, {204, 521}} com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -45502,7 +45521,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin - P4AAAL+AAABByAAAwgwAAA + P4AAAL+AAABBoAAAwmQAAA com.apple.InterfaceBuilder.CocoaPlugin com.apple.InterfaceBuilder.CocoaPlugin @@ -45763,7 +45782,7 @@ AAMAAAABAAEAAAFTAAMAAAAEAAAFwgAAAAAACAAIAAgACAABAAEAAQABA - 6235 + 6238 diff --git a/desmume/src/cocoa/videofilter.cpp b/desmume/src/cocoa/videofilter.cpp index 3832115ff..91bacd0cf 100644 --- a/desmume/src/cocoa/videofilter.cpp +++ b/desmume/src/cocoa/videofilter.cpp @@ -572,7 +572,7 @@ VideoFilter::~VideoFilter() A bool that reports if the resizing was successful. A value of true means success, while a value of false means failure. ********************************************************************************************/ -bool VideoFilter::SetSourceSize(unsigned int width, unsigned int height) +bool VideoFilter::SetSourceSize(const unsigned int width, const unsigned int height) { bool result = false; @@ -612,15 +612,15 @@ bool VideoFilter::SetSourceSize(unsigned int width, unsigned int height) pthread_mutex_unlock(&this->_mutexSrc); - result = this->ChangeFilter(this->GetTypeID()); + result = this->ChangeFilterByID(this->GetTypeID()); return result; } /******************************************************************************************** - ChangeFilter() + ChangeFilterByID() - Changes the video filter type. + Changes the video filter type using a VideoFilterTypeID. Takes: typeID - The type ID of the video filter. See the VideoFilterTypeID @@ -630,143 +630,62 @@ bool VideoFilter::SetSourceSize(unsigned int width, unsigned int height) A bool that reports if the filter change was successful. A value of true means success, while a value of false means failure. ********************************************************************************************/ -bool VideoFilter::ChangeFilter(VideoFilterTypeID typeID) +bool VideoFilter::ChangeFilterByID(const VideoFilterTypeID typeID) { bool result = false; + if (typeID >= VideoFilterTypeIDCount) + { + return result; + } + + return this->ChangeFilterByAttributes(&VideoFilterAttributesList[typeID]); +} + +/******************************************************************************************** + ChangeFilterByAttributes() + + Changes the video filter type using video filter attributes. + + Takes: + vfAttr - The video filter's attributes. + + Returns: + A bool that reports if the filter change was successful. A value of true means + success, while a value of false means failure. + ********************************************************************************************/ +bool VideoFilter::ChangeFilterByAttributes(const VideoFilterAttributes *vfAttr) +{ + bool result = false; + + if (vfAttr == NULL) + { + return result; + } + pthread_mutex_lock(&this->_mutexSrc); const unsigned int srcWidth = this->_srcSurfaceMaster->Width; const unsigned int srcHeight = this->_srcSurfaceMaster->Height; pthread_mutex_unlock(&this->_mutexSrc); - unsigned int destWidth = srcWidth; - unsigned int destHeight = srcHeight; - const char *typeString = VideoFilter::GetTypeStringByID(typeID); - VideoFilterCallback filterCallback = NULL; - - switch (typeID) - { - case VideoFilterTypeID_None: - break; - - case VideoFilterTypeID_LQ2X: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderLQ2X; - break; - - case VideoFilterTypeID_LQ2XS: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderLQ2XS; - break; - - case VideoFilterTypeID_HQ2X: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderHQ2X; - break; - - case VideoFilterTypeID_HQ2XS: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderHQ2XS; - break; - - case VideoFilterTypeID_HQ4X: - destWidth = srcWidth * 4; - destHeight = srcHeight * 4; - filterCallback = &RenderHQ4X; - break; - - case VideoFilterTypeID_2xSaI: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &Render2xSaI; - break; - - case VideoFilterTypeID_Super2xSaI: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderSuper2xSaI; - break; - - case VideoFilterTypeID_SuperEagle: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderSuperEagle; - break; - - case VideoFilterTypeID_Scanline: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderScanline; - break; - - case VideoFilterTypeID_Bilinear: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderBilinear; - break; - - case VideoFilterTypeID_Nearest2X: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderNearest2X; - break; - - case VideoFilterTypeID_Nearest1_5X: - destWidth = srcWidth * 3 / 2; - destHeight = srcHeight * 3 / 2; - filterCallback = &RenderNearest_1Point5x; - break; - - case VideoFilterTypeID_NearestPlus1_5X: - destWidth = srcWidth * 3 / 2; - destHeight = srcHeight * 3 / 2; - filterCallback = &RenderNearestPlus_1Point5x; - break; - - case VideoFilterTypeID_EPX: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderEPX; - break; - - case VideoFilterTypeID_EPXPlus: - destWidth = srcWidth * 2; - destHeight = srcHeight * 2; - filterCallback = &RenderEPXPlus; - break; - - case VideoFilterTypeID_EPX1_5X: - destWidth = srcWidth * 3 / 2; - destHeight = srcHeight * 3 / 2; - filterCallback = &RenderEPX_1Point5x; - break; - - case VideoFilterTypeID_EPXPlus1_5X: - destWidth = srcWidth * 3 / 2; - destHeight = srcHeight * 3 / 2; - filterCallback = &RenderEPXPlus_1Point5x; - break; - - default: - break; - } + const VideoFilterTypeID typeID = vfAttr->typeID; + const unsigned int dstWidth = srcWidth * vfAttr->scaleMultiply / vfAttr->scaleDivide; + const unsigned int dstHeight = srcHeight * vfAttr->scaleMultiply / vfAttr->scaleDivide; + const char *typeString = vfAttr->typeString; + const VideoFilterCallback filterCallback = vfAttr->filterFunction; pthread_mutex_lock(&this->_mutexDest); - uint32_t *newSurfaceBuffer = (uint32_t *)calloc(destWidth * destHeight, sizeof(uint32_t)); + uint32_t *newSurfaceBuffer = (uint32_t *)calloc(dstWidth * dstHeight, sizeof(uint32_t)); if (newSurfaceBuffer == NULL) { return result; } this->_filterCallback = filterCallback; - this->_destSurfaceMaster->Width = destWidth; - this->_destSurfaceMaster->Height = destHeight; - this->_destSurfaceMaster->Pitch = destWidth * 2; + this->_destSurfaceMaster->Width = dstWidth; + this->_destSurfaceMaster->Height = dstHeight; + this->_destSurfaceMaster->Pitch = dstWidth * 2; free(this->_destSurfaceMaster->Surface); this->_destSurfaceMaster->Surface = (unsigned char*)newSurfaceBuffer; @@ -853,6 +772,59 @@ uint32_t* VideoFilter::RunFilter() return destBufPtr; } +/******************************************************************************************** + RunFilterCustom() - STATIC + + Runs the pixels from srcBuffer through the video filter, and then stores the + resulting pixels into dstBuffer. + + Takes: + srcBuffer - A pointer to the source pixel buffer. The caller is responsible + for ensuring that this buffer is valid. Also note that certain video filters + may do out-of-bounds reads, so the caller is responsible for overallocating + this buffer in order to avoid crashing on certain platforms. + + dstBuffer - A pointer to the destination pixel buffer. The caller is responsible + for ensuring that this buffer is valid and large enough to store all of the + destination pixels. + + srcWidth - The source surface width in pixels. + + srcHeight - The source surface height in pixels. + + typeID - The type ID of the video filter. See the VideoFilterTypeID + enumeration for possible values. + + Returns: + Nothing. + ********************************************************************************************/ +void VideoFilter::RunFilterCustom(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ dstBuffer, + const unsigned int srcWidth, const unsigned int srcHeight, + const VideoFilterTypeID typeID) +{ + if (typeID >= VideoFilterTypeIDCount) + { + return; + } + + const VideoFilterAttributes *vfAttr = &VideoFilterAttributesList[typeID]; + const unsigned int dstWidth = srcWidth * vfAttr->scaleMultiply / vfAttr->scaleDivide; + const unsigned int dstHeight = dstWidth * vfAttr->scaleMultiply / vfAttr->scaleDivide; + const VideoFilterCallback filterFunction = vfAttr->filterFunction; + + SSurface srcSurface = {(unsigned char *)srcBuffer, srcWidth*2, srcWidth, srcHeight}; + SSurface dstSurface = {(unsigned char *)dstBuffer, dstWidth*2, dstWidth, dstHeight}; + + if (filterFunction == NULL) + { + memcpy(dstBuffer, srcBuffer, dstWidth * dstHeight * sizeof(uint32_t)); + } + else + { + filterFunction(srcSurface, dstSurface); + } +} + /******************************************************************************************** GetTypeStringByID() - STATIC @@ -866,89 +838,14 @@ uint32_t* VideoFilter::RunFilter() A C-string that represents the video filter type. If typeID is invalid, this method returns the string "Unknown". ********************************************************************************************/ -const char* VideoFilter::GetTypeStringByID(VideoFilterTypeID typeID) +const char* VideoFilter::GetTypeStringByID(const VideoFilterTypeID typeID) { - const char *typeString = "Unknown"; - - switch (typeID) + if (typeID >= VideoFilterTypeIDCount) { - case VideoFilterTypeID_None: - typeString = VIDEOFILTERTYPE_NONE_STRING; - break; - - case VideoFilterTypeID_LQ2X: - typeString = VIDEOFILTERTYPE_LQ2X_STRING; - break; - - case VideoFilterTypeID_LQ2XS: - typeString = VIDEOFILTERTYPE_LQ2XS_STRING; - break; - - case VideoFilterTypeID_HQ2X: - typeString = VIDEOFILTERTYPE_HQ2X_STRING; - break; - - case VideoFilterTypeID_HQ2XS: - typeString = VIDEOFILTERTYPE_HQ2XS_STRING; - break; - - case VideoFilterTypeID_HQ4X: - typeString = VIDEOFILTERTYPE_HQ4X_STRING; - break; - - case VideoFilterTypeID_2xSaI: - typeString = VIDEOFILTERTYPE_2XSAI_STRING; - break; - - case VideoFilterTypeID_Super2xSaI: - typeString = VIDEOFILTERTYPE_SUPER_2XSAI_STRING; - break; - - case VideoFilterTypeID_SuperEagle: - typeString = VIDEOFILTERTYPE_SUPER_EAGLE_STRING; - break; - - case VideoFilterTypeID_Scanline: - typeString = VIDEOFILTERTYPE_SCANLINE_STRING; - break; - - case VideoFilterTypeID_Bilinear: - typeString = VIDEOFILTERTYPE_BILINEAR_STRING; - break; - - case VideoFilterTypeID_Nearest2X: - typeString = VIDEOFILTERTYPE_NEAREST_2X_STRING; - break; - - case VideoFilterTypeID_Nearest1_5X: - typeString = VIDEOFILTERTYPE_NEAREST_1_5X_STRING; - break; - - case VideoFilterTypeID_NearestPlus1_5X: - typeString = VIDEOFILTERTYPE_NEAREST_PLUS_1_5X_STRING; - break; - - case VideoFilterTypeID_EPX: - typeString = VIDEOFILTERTYPE_EPX_STRING; - break; - - case VideoFilterTypeID_EPXPlus: - typeString = VIDEOFILTERTYPE_EPX_PLUS_STRING; - break; - - case VideoFilterTypeID_EPX1_5X: - typeString = VIDEOFILTERTYPE_EPX_1_5X_STRING; - break; - - case VideoFilterTypeID_EPXPlus1_5X: - typeString = VIDEOFILTERTYPE_EPX_PLUS_1_5X_STRING; - break; - - default: - break; + return VIDEOFILTERTYPE_UNKNOWN_STRING; } - return typeString; + return VideoFilterAttributesList[typeID].typeString; } /******************************************************************************************** @@ -963,7 +860,7 @@ VideoFilterTypeID VideoFilter::GetTypeID() return typeID; } -void VideoFilter::SetTypeID(VideoFilterTypeID typeID) +void VideoFilter::SetTypeID(const VideoFilterTypeID typeID) { pthread_mutex_lock(&this->_mutexTypeID); this->_typeID = typeID; diff --git a/desmume/src/cocoa/videofilter.h b/desmume/src/cocoa/videofilter.h index e4681a85d..40edc9b84 100644 --- a/desmume/src/cocoa/videofilter.h +++ b/desmume/src/cocoa/videofilter.h @@ -22,7 +22,6 @@ #include #include #include -#include "types.h" #include "../filter/filter.h" @@ -46,32 +45,48 @@ enum VideoFilterTypeID VideoFilterTypeID_EPX, VideoFilterTypeID_EPXPlus, VideoFilterTypeID_EPX1_5X, - VideoFilterTypeID_EPXPlus1_5X + VideoFilterTypeID_EPXPlus1_5X, + VideoFilterTypeID_HQ4XS, + + VideoFilterTypeIDCount // Make sure this one is always last }; -// VIDEO FILTER TYPE STRINGS -#define VIDEOFILTERTYPE_NONE_STRING "None" -#define VIDEOFILTERTYPE_LQ2X_STRING "LQ2X" -#define VIDEOFILTERTYPE_LQ2XS_STRING "LQ2XS" -#define VIDEOFILTERTYPE_HQ2X_STRING "HQ2X" -#define VIDEOFILTERTYPE_HQ2XS_STRING "HQ2XS" -#define VIDEOFILTERTYPE_HQ4X_STRING "HQ4X" -#define VIDEOFILTERTYPE_2XSAI_STRING "2xSaI" -#define VIDEOFILTERTYPE_SUPER_2XSAI_STRING "Super 2xSaI" -#define VIDEOFILTERTYPE_SUPER_EAGLE_STRING "Super Eagle" -#define VIDEOFILTERTYPE_SCANLINE_STRING "Scanline" -#define VIDEOFILTERTYPE_BILINEAR_STRING "Bilinear" -#define VIDEOFILTERTYPE_NEAREST_2X_STRING "Nearest 2x" -#define VIDEOFILTERTYPE_NEAREST_1_5X_STRING "Nearest 1.5x" -#define VIDEOFILTERTYPE_NEAREST_PLUS_1_5X_STRING "Nearest+ 1.5x" -#define VIDEOFILTERTYPE_EPX_STRING "EPX" -#define VIDEOFILTERTYPE_EPX_PLUS_STRING "EPX+" -#define VIDEOFILTERTYPE_EPX_1_5X_STRING "EPX 1.5x" -#define VIDEOFILTERTYPE_EPX_PLUS_1_5X_STRING "EPX+ 1.5x" -#define VIDEOFILTERTYPE_UNKNOWN_STRING "Unknown" +#define VIDEOFILTERTYPE_UNKNOWN_STRING "Unknown" typedef void (*VideoFilterCallback)(SSurface Src, SSurface Dst); +typedef struct +{ + VideoFilterTypeID typeID; + const char *typeString; + VideoFilterCallback filterFunction; + unsigned int scaleMultiply; + unsigned int scaleDivide; +} VideoFilterAttributes; + +// Attributes list of known video filters, indexed using VideoFilterTypeID. +const VideoFilterAttributes VideoFilterAttributesList[] = { + {VideoFilterTypeID_None, "None", NULL, 1, 1}, + {VideoFilterTypeID_LQ2X, "LQ2X", &RenderLQ2X, 2, 1}, + {VideoFilterTypeID_LQ2XS, "LQ2XS", &RenderLQ2XS, 2, 1}, + {VideoFilterTypeID_HQ2X, "HQ2X", &RenderHQ2X, 2, 1}, + {VideoFilterTypeID_HQ2XS, "HQ2XS", &RenderHQ2XS, 2, 1}, + {VideoFilterTypeID_HQ4X, "HQ4X", &RenderHQ4X, 4, 1}, + {VideoFilterTypeID_2xSaI, "2xSaI", &Render2xSaI, 2, 1}, + {VideoFilterTypeID_Super2xSaI, "Super 2xSaI", &RenderSuper2xSaI, 2, 1}, + {VideoFilterTypeID_SuperEagle, "Super Eagle", &RenderSuperEagle, 2, 1}, + {VideoFilterTypeID_Scanline, "Scanline", &RenderScanline, 2, 1}, + {VideoFilterTypeID_Bilinear, "Bilinear", &RenderBilinear, 2, 1}, + {VideoFilterTypeID_Nearest2X, "Nearest 2x", &RenderNearest2X, 2, 1}, + {VideoFilterTypeID_Nearest1_5X, "Nearest 1.5x", &RenderNearest_1Point5x, 3, 2}, + {VideoFilterTypeID_NearestPlus1_5X, "Nearest+ 1.5x", &RenderNearestPlus_1Point5x, 3, 2}, + {VideoFilterTypeID_EPX, "EPX", &RenderEPX, 2, 1}, + {VideoFilterTypeID_EPXPlus, "EPX+", &RenderEPXPlus, 2, 1}, + {VideoFilterTypeID_EPX1_5X, "EPX 1.5x", &RenderEPX_1Point5x, 3, 2}, + {VideoFilterTypeID_EPXPlus1_5X, "EPX+ 1.5x", &RenderEPXPlus_1Point5x, 3, 2}, + {VideoFilterTypeID_HQ4XS, "HQ4XS", &RenderHQ4XS, 4, 1} }; + +// Parameters struct for IPC typedef struct { SSurface srcSurface; @@ -146,10 +161,13 @@ public: VideoFilter(unsigned int srcWidth, unsigned int srcHeight, VideoFilterTypeID typeID, unsigned int numberThreads); ~VideoFilter(); - bool SetSourceSize(unsigned int width, unsigned int height); - bool ChangeFilter(VideoFilterTypeID typeID); + bool SetSourceSize(const unsigned int width, const unsigned int height); + bool ChangeFilterByID(const VideoFilterTypeID typeID); + bool ChangeFilterByAttributes(const VideoFilterAttributes *vfAttr); uint32_t* RunFilter(); - static const char* GetTypeStringByID(VideoFilterTypeID typeID); + + static void RunFilterCustom(const uint32_t *__restrict__ srcBuffer, uint32_t *__restrict__ dstBuffer, const unsigned int srcWidth, const unsigned int srcHeight, const VideoFilterTypeID typeID); + static const char* GetTypeStringByID(const VideoFilterTypeID typeID); VideoFilterTypeID GetTypeID(); const char* GetTypeString();