From ecd0f4f7d8d14cd6fbbb4ce531e0b038bb83e87b Mon Sep 17 00:00:00 2001 From: sonique6784 Date: Tue, 11 Jun 2019 18:21:47 +1000 Subject: [PATCH 1/2] added higher resolution for PPSSPP Core --- PPSSPP.xcodeproj/project.pbxproj | 66 ++++++++++++++++++++++++++++++++ PPSSPPGameCore.mm | 19 ++++++--- 2 files changed, 80 insertions(+), 5 deletions(-) diff --git a/PPSSPP.xcodeproj/project.pbxproj b/PPSSPP.xcodeproj/project.pbxproj index d80b406..5872dcc 100644 --- a/PPSSPP.xcodeproj/project.pbxproj +++ b/PPSSPP.xcodeproj/project.pbxproj @@ -590,6 +590,27 @@ remoteGlobalIDString = 8CAFC10E1785B63900647A96; remoteInfo = PPSSPP; }; + CB9A552822AE2F4200F858F5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB9A552222AE2F4200F858F5 /* OpenEmu-SDK.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = C6772A261710A4BA00ED580A; + remoteInfo = OpenEmuBase; + }; + CB9A552A22AE2F4200F858F5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB9A552222AE2F4200F858F5 /* OpenEmu-SDK.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = C6772A8C1710CD7E00ED580A; + remoteInfo = OpenEmuSystem; + }; + CB9A552C22AE2F4200F858F5 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CB9A552222AE2F4200F858F5 /* OpenEmu-SDK.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 0109BBA2209F25EB002419C1; + remoteInfo = OpenEmuBaseTests; + }; EE76801E20C83100006470A2 /* PBXContainerItemProxy */ = { isa = PBXContainerItemProxy; containerPortal = 8CAFA78F1785AA9900647A96 /* Project object */; @@ -1532,6 +1553,7 @@ 8CD63AFA178DCEC60039164C /* sceCcc.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = sceCcc.cpp; sourceTree = ""; }; 8CD63B05178DD0700039164C /* HDRemaster.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = HDRemaster.cpp; sourceTree = ""; }; 8CD63B06178DD0700039164C /* HDRemaster.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HDRemaster.h; sourceTree = ""; }; + CB9A552222AE2F4200F858F5 /* OpenEmu-SDK.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = "OpenEmu-SDK.xcodeproj"; path = "../OpenEmu-SDK/OpenEmu-SDK.xcodeproj"; sourceTree = ""; }; EE081249218CA633007FD1AB /* attribute.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = attribute.h; sourceTree = ""; }; EE08124A218CA633007FD1AB /* attribute.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = attribute.cpp; sourceTree = ""; }; EE081276218CA90A007FD1AB /* Debugger.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = Debugger.h; sourceTree = ""; }; @@ -4837,6 +4859,16 @@ path = assets; sourceTree = ""; }; + CB9A552322AE2F4200F858F5 /* Products */ = { + isa = PBXGroup; + children = ( + CB9A552922AE2F4200F858F5 /* OpenEmuBase.framework */, + CB9A552B22AE2F4200F858F5 /* OpenEmuSystem.framework */, + CB9A552D22AE2F4200F858F5 /* OpenEmuBaseTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; EE081280218CAD91007FD1AB /* gason */ = { isa = PBXGroup; children = ( @@ -6715,6 +6747,7 @@ EE76806C20C9DF7C006470A2 /* Frameworks */ = { isa = PBXGroup; children = ( + CB9A552222AE2F4200F858F5 /* OpenEmu-SDK.xcodeproj */, ); name = Frameworks; sourceTree = ""; @@ -7027,11 +7060,18 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, ); mainGroup = 8CAFA78E1785AA9900647A96; productRefGroup = 8CAFA79B1785AE2A00647A96 /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = CB9A552322AE2F4200F858F5 /* Products */; + ProjectRef = CB9A552222AE2F4200F858F5 /* OpenEmu-SDK.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 8CAFA7D11785B06F00647A96 /* Common */, @@ -7057,6 +7097,30 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + CB9A552922AE2F4200F858F5 /* OpenEmuBase.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = OpenEmuBase.framework; + remoteRef = CB9A552822AE2F4200F858F5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CB9A552B22AE2F4200F858F5 /* OpenEmuSystem.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = OpenEmuSystem.framework; + remoteRef = CB9A552A22AE2F4200F858F5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CB9A552D22AE2F4200F858F5 /* OpenEmuBaseTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = OpenEmuBaseTests.xctest; + remoteRef = CB9A552C22AE2F4200F858F5 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 8CAFC10D1785B63900647A96 /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -8366,6 +8430,7 @@ "\"$(SRCROOT)/ppsspp/ext/native/ext\"", "\"$(SRCROOT)/ppsspp/ext/glew\"", "\"$(SRCROOT)/ppsspp/ffmpeg/macosx/x86_64/include\"", + "\"$(SRCROOT)/OpenEmuBase\"", ); PRODUCT_NAME = "$(TARGET_NAME)"; }; @@ -8384,6 +8449,7 @@ "\"$(SRCROOT)/ppsspp/ext/native/ext\"", "\"$(SRCROOT)/ppsspp/ext/glew\"", "\"$(SRCROOT)/ppsspp/ffmpeg/macosx/x86_64/include\"", + "\"$(SRCROOT)/OpenEmuBase\"", ); PRODUCT_NAME = "$(TARGET_NAME)"; }; diff --git a/PPSSPPGameCore.mm b/PPSSPPGameCore.mm index da2e103..71220b7 100644 --- a/PPSSPPGameCore.mm +++ b/PPSSPPGameCore.mm @@ -54,6 +54,15 @@ #define AUDIO_CHANNELS 2 #define AUDIO_SAMPLESIZE sizeof(int16_t) +#define GRAPHIC_ORIG_W 480 +#define GRAPHIC_ORIG_H 272 +#define GRAPHIC_DOUBLE_W 960 +#define GRAPHIC_DOUBLE_H 544 +#define GRAPHIC_TRIPLE_W 1440 +#define GRAPHIC_TRIPLE_H 816 +#define GRAPHIC_FULLHD_W 1920 +#define GRAPHIC_FULLHD_H 1088 + namespace SaveState { @@ -144,10 +153,10 @@ - (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error _coreParam.printfEmuLog = false; _coreParam.headLess = false; - _coreParam.renderWidth = 480; - _coreParam.renderHeight = 272; - _coreParam.pixelWidth = 480; - _coreParam.pixelHeight = 272; + _coreParam.renderWidth = GRAPHIC_FULLHD_W; + _coreParam.renderHeight = GRAPHIC_FULLHD_H; + _coreParam.pixelWidth = GRAPHIC_FULLHD_W; + _coreParam.pixelHeight = GRAPHIC_FULLHD_H; coreState = CORE_POWERUP; @@ -228,7 +237,7 @@ - (OEGameCoreRendering)gameCoreRendering - (OEIntSize)bufferSize { - return OEIntSizeMake(480, 272); + return OEIntSizeMake(GRAPHIC_FULLHD_W, GRAPHIC_FULLHD_H); } - (OEIntSize)aspectSize From ea365b38bc878d34f4b289b52989eeacb41690e8 Mon Sep 17 00:00:00 2001 From: sonique6784 Date: Sun, 16 Jun 2019 11:21:08 +1000 Subject: [PATCH 2/2] added Display Mode menu allowing selecting resolution --- Info.plist | 10 +- PPSSPPGameCore.mm | 282 +++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 285 insertions(+), 7 deletions(-) diff --git a/Info.plist b/Info.plist index 5bea80d..fd58640 100644 --- a/Info.plist +++ b/Info.plist @@ -35,6 +35,14 @@ SUEnableAutomaticChecks 1 SUFeedURL - https://raw.github.com/OpenEmu/OpenEmu-Update/master/ppsspp_appcast.xml + https://raw.github.com/OpenEmu/OpenEmu-Update/master/ppsspp_appcast.xml + OEGameCoreOptions + + openemu.system.psp + + OEGameCoreSupportsDisplayModeChange + + + diff --git a/PPSSPPGameCore.mm b/PPSSPPGameCore.mm index 71220b7..7b97401 100644 --- a/PPSSPPGameCore.mm +++ b/PPSSPPGameCore.mm @@ -50,6 +50,13 @@ #include "thin3d/GLRenderManager.h" #include "thin3d/DataFormatGL.h" + +#define Option(_NAME_, _PREFKEY_) @{ OEGameCoreDisplayModeNameKey : _NAME_, OEGameCoreDisplayModePrefKeyNameKey : _PREFKEY_, OEGameCoreDisplayModeStateKey : @NO, } +#define OptionIndented(_NAME_, _PREFKEY_) @{ OEGameCoreDisplayModeNameKey : _NAME_, OEGameCoreDisplayModePrefKeyNameKey : _PREFKEY_, OEGameCoreDisplayModeStateKey : @NO, OEGameCoreDisplayModeIndentationLevelKey : @(1), } +#define OptionToggleable(_NAME_, _PREFKEY_) @{ OEGameCoreDisplayModeNameKey : _NAME_, OEGameCoreDisplayModePrefKeyNameKey : _PREFKEY_, OEGameCoreDisplayModeStateKey : @NO, OEGameCoreDisplayModeAllowsToggleKey : @YES, } +#define Label(_NAME_) @{ OEGameCoreDisplayModeLabelKey : _NAME_, } +#define SeparatorItem() @{ OEGameCoreDisplayModeSeparatorItemKey : [NSNull null],} + #define AUDIO_FREQ 44100 #define AUDIO_CHANNELS 2 #define AUDIO_SAMPLESIZE sizeof(int16_t) @@ -90,9 +97,20 @@ @interface PPSSPPGameCore () CoreParameter _coreParam; bool _isInitialized; bool _shouldReset; + + int displayMode; + NSArray *_availableDisplayModes; OpenEmuGLContext *OEgraphicsContext; } + +- (NSString *)gameInternalName; + +- (void)loadResolution; +- (void)loadResolutionDefault; +- (void)changeResolution:(NSString *)resolution; + + @end PPSSPPGameCore *_current = 0; @@ -108,6 +126,260 @@ - (instancetype)init return self; } + +# pragma mark - Display Mode + +/** + * + * return the list of Display Mode + */ +- (NSArray *> *)displayModes +{ + if(_availableDisplayModes == nil || _availableDisplayModes.count == 0) { + _availableDisplayModes = [NSArray array]; + + NSArray *> *availableModesWithDefault = + @[ + Option(@"Original", @"resolution"), + Option(@"2x", @"resolution"), + Option(@"HD", @"resolution"), + Option(@"Full HD", @"resolution") + ]; + + +// if (![self gameHasInternalResolution]) +// availableModesWithDefault = [availableModesWithDefault subarrayWithRange:NSMakeRange(1, availableModesWithDefault.count - 1)]; + + _availableDisplayModes = availableModesWithDefault; + } + + return _availableDisplayModes; +} + + +/** + * + * set the display Mode for the current game + */ +- (void)changeDisplayWithMode:(NSString *)displayMode +{ + + // NOTE: This is a more complex implementation to serve as an example for handling submenus, + // toggleable options and multiple groups of mutually exclusive options. + + if (_availableDisplayModes.count == 0) + [self displayModes]; + + // First check if 'displayMode' is toggleable and grab its preference key + BOOL isDisplayModeToggleable, isValidDisplayMode; + NSString *displayModePrefKey; + for (NSDictionary *modeDict in _availableDisplayModes) + { + NSString *mode = modeDict[OEGameCoreDisplayModeNameKey]; + if ([mode isEqualToString:displayMode]) + { + displayModePrefKey = modeDict[OEGameCoreDisplayModePrefKeyNameKey]; + isDisplayModeToggleable = [modeDict[OEGameCoreDisplayModeAllowsToggleKey] boolValue]; + isValidDisplayMode = YES; + break; + } + // Submenu Items + for (NSDictionary *subModeDict in modeDict[OEGameCoreDisplayModeGroupItemsKey]) + { + NSString *subMode = subModeDict[OEGameCoreDisplayModeNameKey]; + if ([subMode isEqualToString:displayMode]) + { + displayModePrefKey = subModeDict[OEGameCoreDisplayModePrefKeyNameKey]; + isDisplayModeToggleable = [subModeDict[OEGameCoreDisplayModeAllowsToggleKey] boolValue]; + isValidDisplayMode = YES; + break; + } + } + } + + // Disallow a 'displayMode' not found in _availableDisplayModes + if (!isValidDisplayMode) + return; + + + NSMutableArray *tempOptionsArray = [NSMutableArray array]; + NSMutableArray *tempSubOptionsArray = [NSMutableArray array]; + NSString *mode, *pref, *label; + BOOL isToggleable, isSelected; + NSInteger indentationLevel; + + + // Handle option state changes + for (NSDictionary *optionDict in _availableDisplayModes) + { + mode = optionDict[OEGameCoreDisplayModeNameKey]; + pref = optionDict[OEGameCoreDisplayModePrefKeyNameKey]; + isToggleable = [optionDict[OEGameCoreDisplayModeAllowsToggleKey] boolValue]; + isSelected = [optionDict[OEGameCoreDisplayModeStateKey] boolValue]; + indentationLevel = [optionDict[OEGameCoreDisplayModeIndentationLevelKey] integerValue] ?: 0; + + if (optionDict[OEGameCoreDisplayModeSeparatorItemKey]) + { + [tempOptionsArray addObject:SeparatorItem()]; + continue; + } + else if (optionDict[OEGameCoreDisplayModeLabelKey]) + { + label = optionDict[OEGameCoreDisplayModeLabelKey]; + [tempOptionsArray addObject:Label(label)]; + continue; + } + // Mutually exclusive option state change + else if ([mode isEqualToString:displayMode] && !isToggleable) + isSelected = YES; + // Reset mutually exclusive options that are the same prefs group as 'displayMode' + else if (!isDisplayModeToggleable && [pref isEqualToString:displayModePrefKey]) + isSelected = NO; + // Toggleable option state change + else if ([mode isEqualToString:displayMode] && isToggleable) + isSelected = !isSelected; + // Submenu group + else if (optionDict[OEGameCoreDisplayModeGroupNameKey]) + { + NSString *submenuTitle = optionDict[OEGameCoreDisplayModeGroupNameKey]; + // Submenu items + for (NSDictionary *subOptionDict in optionDict[OEGameCoreDisplayModeGroupItemsKey]) + { + mode = subOptionDict[OEGameCoreDisplayModeNameKey]; + pref = subOptionDict[OEGameCoreDisplayModePrefKeyNameKey]; + isToggleable = [subOptionDict[OEGameCoreDisplayModeAllowsToggleKey] boolValue]; + isSelected = [subOptionDict[OEGameCoreDisplayModeStateKey] boolValue]; + indentationLevel = [subOptionDict[OEGameCoreDisplayModeIndentationLevelKey] integerValue] ?: 0; + + if (subOptionDict[OEGameCoreDisplayModeSeparatorItemKey]) + { + [tempSubOptionsArray addObject:SeparatorItem()]; + continue; + } + else if (subOptionDict[OEGameCoreDisplayModeLabelKey]) + { + label = subOptionDict[OEGameCoreDisplayModeLabelKey]; + [tempSubOptionsArray addObject:Label(label)]; + continue; + } + // Mutually exclusive option state change + else if ([mode isEqualToString:displayMode] && !isToggleable) + isSelected = YES; + // Reset mutually exclusive options that are the same prefs group as 'displayMode' + else if (!isDisplayModeToggleable && [pref isEqualToString:displayModePrefKey]) + isSelected = NO; + // Toggleable option state change + else if ([mode isEqualToString:displayMode] && isToggleable) + isSelected = !isSelected; + + // Add the submenu option + [tempSubOptionsArray addObject:@{ OEGameCoreDisplayModeNameKey : mode, + OEGameCoreDisplayModePrefKeyNameKey : pref, + OEGameCoreDisplayModeStateKey : @(isSelected), + OEGameCoreDisplayModeIndentationLevelKey : @(indentationLevel), + OEGameCoreDisplayModeAllowsToggleKey : @(isToggleable) }]; + } + + // Add the submenu group + [tempOptionsArray addObject:@{ OEGameCoreDisplayModeGroupNameKey : submenuTitle, + OEGameCoreDisplayModeGroupItemsKey : [tempSubOptionsArray copy] }]; + [tempSubOptionsArray removeAllObjects]; + continue; + } + + // Add the option + [tempOptionsArray addObject:@{ OEGameCoreDisplayModeNameKey : mode, + OEGameCoreDisplayModePrefKeyNameKey : pref, + OEGameCoreDisplayModeStateKey : @(isSelected), + OEGameCoreDisplayModeIndentationLevelKey : @(indentationLevel), + OEGameCoreDisplayModeAllowsToggleKey : @(isToggleable) }]; + } + + // Set the new Resolution + if ([displayModePrefKey isEqualToString:@"resolution"]) + [self changeResolution:displayMode]; + + _availableDisplayModes = tempOptionsArray; + +} + +- (NSString *)gameInternalName +{ + NSString *title = [NSString stringWithUTF8String:_coreParam.fileToStart.c_str()]; + return title; +} + +- (void)loadResolution +{ + // Only temporary, so core doesn't crash on an older OpenEmu version + if (![self respondsToSelector:@selector(displayModeInfo)]) + { + [self loadResolutionDefault]; + } + // No previous Resolution saved, set a default + else if (self.displayModeInfo[@"resolution"] == nil) + { + [self loadResolutionDefault]; + } + else + { + NSString *lastResolution = self.displayModeInfo[@"resolution"]; + + [self changeDisplayWithMode:lastResolution]; + } +} + +- (void)loadResolutionDefault +{ + [self changeDisplayWithMode:@"Original"]; +} + +- (void)changeResolution:(NSString *)resolution +{ + NSDictionary *ResolutionNames = + @{ + @"Original" : @"Original", + @"2x" : @"2x", + @"HD" : @"HD", + @"Full HD" : @"Full HD", + }; + + resolution = ResolutionNames[resolution]; + + if ([resolution isEqualToString:@"2x"]) + { + _coreParam.renderWidth = GRAPHIC_DOUBLE_W; + _coreParam.renderHeight = GRAPHIC_DOUBLE_H; + _coreParam.pixelWidth = GRAPHIC_DOUBLE_W; + _coreParam.pixelHeight = GRAPHIC_DOUBLE_H; + } + else if ([resolution isEqualToString:@"HD"]) + { + _coreParam.renderWidth = GRAPHIC_TRIPLE_W; + _coreParam.renderHeight = GRAPHIC_TRIPLE_H; + _coreParam.pixelWidth = GRAPHIC_TRIPLE_W; + _coreParam.pixelHeight = GRAPHIC_TRIPLE_H; + } + else if ([resolution isEqualToString:@"Full HD"]) + { + _coreParam.renderWidth = GRAPHIC_FULLHD_W; + _coreParam.renderHeight = GRAPHIC_FULLHD_H; + _coreParam.pixelWidth = GRAPHIC_FULLHD_W; + _coreParam.pixelHeight = GRAPHIC_FULLHD_H; + + } + else + _coreParam.renderWidth = GRAPHIC_ORIG_W; + _coreParam.renderHeight = GRAPHIC_ORIG_H; + _coreParam.pixelWidth = GRAPHIC_ORIG_W; + _coreParam.pixelHeight = GRAPHIC_ORIG_H; + + [self resetEmulation]; + return; + +} + + # pragma mark - Execution - (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error @@ -143,6 +415,7 @@ - (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error g_Config.internalDataDirectory = directoryString.fileSystemRepresentation; g_Config.iGPUBackend = (int)GPUBackend::OPENGL; g_Config.bHideStateWarnings = false; + _coreParam.cpuCore = CPUCore::JIT; _coreParam.gpuCore = GPUCORE_GLES; @@ -153,11 +426,8 @@ - (BOOL)loadFileAtPath:(NSString *)path error:(NSError **)error _coreParam.printfEmuLog = false; _coreParam.headLess = false; - _coreParam.renderWidth = GRAPHIC_FULLHD_W; - _coreParam.renderHeight = GRAPHIC_FULLHD_H; - _coreParam.pixelWidth = GRAPHIC_FULLHD_W; - _coreParam.pixelHeight = GRAPHIC_FULLHD_H; - + [self loadResolution]; + coreState = CORE_POWERUP; return true; @@ -237,7 +507,7 @@ - (OEGameCoreRendering)gameCoreRendering - (OEIntSize)bufferSize { - return OEIntSizeMake(GRAPHIC_FULLHD_W, GRAPHIC_FULLHD_H); + return OEIntSizeMake(_coreParam.pixelWidth, _coreParam.pixelHeight); } - (OEIntSize)aspectSize