Support for showing % on Darwin platforms and some other changes

This commit is contained in:
Serena 2023-01-27 11:19:29 +03:00
parent 422883726e
commit f250a54958
7 changed files with 173 additions and 21 deletions

View file

@ -256,6 +256,7 @@ include(FindThreads)
if(APPLE)
find_library(COCOA_LIBRARY Cocoa)
find_library(IOKIT_LIBRARY IOKit)
find_library(QUARTZ_CORE_LIBRARY QuartzCore)
endif()
@ -775,6 +776,7 @@ add_library(Common STATIC
Common/SysError.cpp
Common/TimeUtil.cpp
Common/TimeUtil.h
Common/Battery/Battery.h
)
include_directories(Common)
@ -1150,6 +1152,7 @@ elseif(IOS)
ios/iCade/iCadeState.h
UI/DarwinMemoryStickManager.mm
UI/DarwinMemoryStickManager.h
Common/Battery/AppleBatteryClient.m
)
set(nativeExtraLibs ${nativeExtraLibs} "-framework Foundation -framework MediaPlayer -framework AudioToolbox -framework CoreGraphics -framework QuartzCore -framework UIKit -framework GLKit -framework OpenAL -framework AVFoundation -framework CoreLocation -framework CoreVideo -framework CoreMedia -framework CoreServices" )
@ -1170,6 +1173,7 @@ elseif(IOS)
set_source_files_properties(ios/CameraHelper.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
set_source_files_properties(ios/LocationHelper.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
set_source_files_properties(UI/DarwinMemoryStickManager.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
set_source_files_properties(Common/Battery/AppleBatteryClient.m PROPERTIES COMPILE_FLAGS -fobjc-arc)
set(TargetBin PPSSPP)
elseif(USING_QT_UI)
set(CMAKE_AUTOMOC ON)
@ -1227,9 +1231,10 @@ elseif(TARGET SDL2::SDL2)
endif()
set(nativeExtraLibs ${nativeExtraLibs} SDL2::SDL2)
if(APPLE)
set(nativeExtra ${nativeExtra} SDL/SDLMain.h SDL/SDLMain.mm SDL/SDLCocoaMetalLayer.h SDL/SDLCocoaMetalLayer.mm UI/DarwinMemoryStickManager.mm)
set(nativeExtra ${nativeExtra} SDL/SDLMain.h SDL/SDLMain.mm SDL/SDLCocoaMetalLayer.h SDL/SDLCocoaMetalLayer.mm UI/DarwinMemoryStickManager.mm Common/Battery/AppleBatteryClient.m)
set_source_files_properties(UI/DarwinMemoryStickManager.mm PROPERTIES COMPILE_FLAGS -fobjc-arc)
set(nativeExtraLibs ${nativeExtraLibs} ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY})
set_source_files_properties(Common/Battery/AppleBatteryClient.m PROPERTIES COMPILE_FLAGS -fobjc-arc)
set(nativeExtraLibs ${nativeExtraLibs} ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${IOKIT_LIBRARY})
elseif(USING_EGL)
set(nativeExtraLibs ${nativeExtraLibs} pthread)
endif()
@ -2378,7 +2383,7 @@ if(HEADLESS)
)
endif()
add_executable(PPSSPPHeadless ${HeadlessSource})
target_link_libraries(PPSSPPHeadless ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${LinkCommon})
target_link_libraries(PPSSPPHeadless ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${IOKIT_LIBRARY} ${LinkCommon})
setup_target_project(PPSSPPHeadless headless)
endif()
@ -2398,7 +2403,7 @@ if(UNITTEST)
Core/MIPS/ARM/ArmRegCache.cpp
Core/MIPS/ARM/ArmRegCacheFPU.cpp
)
target_link_libraries(PPSSPPUnitTest ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${LinkCommon} Common)
target_link_libraries(PPSSPPUnitTest ${COCOA_LIBRARY} ${QUARTZ_CORE_LIBRARY} ${IOKIT_LIBRARY} ${LinkCommon} Common)
setup_target_project(PPSSPPUnitTest unittest)
add_test(arm64_emitter PPSSPPUnitTest Arm64Emitter)
add_test(arm_emitter PPSSPPUnitTest ArmEmitter)

View file

@ -0,0 +1,96 @@
//
// AppleBatteryClient.m
// PPSSPP
//
// Created by Serena on 24/01/2023.
//
#include "Battery.h"
#import <Foundation/Foundation.h>
#if PPSSPP_PLATFORM(MAC)
#include <IOKit/ps/IOPSKeys.h>
#include <IOKit/ps/IOPowerSources.h>
#elif PPSSPP_PLATFORM(IOS)
#import <UIKit/UIKit.h>
#endif
@interface AppleBatteryClient : NSObject
+(instancetype)sharedClient;
-(void)setNeedsToUpdateLevel;
@property int batteryLevel;
@end
void _powerSourceRunLoopCallback(void * __unused ctx) {
// IOKit has told us that battery information has changed, now update the batteryLevel var
[[AppleBatteryClient sharedClient] setNeedsToUpdateLevel];
}
// You may ask,
// "Why an entire class?
// Why not just call the UIDevice/IOKitPowerSource functions every time getCurrentBatteryCapacity() is called?"
// Well, calling the UIDevice/IOKitPowerSource very frequently is expensive
// So, instead, I made a class with a cached batteryLevel property
// that only gets set when it needs to.
@implementation AppleBatteryClient
+ (instancetype)sharedClient {
static AppleBatteryClient *client;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
client = [AppleBatteryClient new];
[client initialSetup];
[client setNeedsToUpdateLevel];
});
return client;
}
-(void)initialSetup {
#if TARGET_OS_IOS
// on iOS, this needs to be true to get the battery level
// and it needs to be set just once, so do it here
UIDevice.currentDevice.batteryMonitoringEnabled = YES;
// Register for when the battery % changes
[[NSNotificationCenter defaultCenter] addObserver:self
selector:@selector(setNeedsToUpdateLevel)
name:UIDeviceBatteryLevelDidChangeNotification object:nil];
#elif TARGET_OS_MAC
CFRunLoopSourceRef loop = IOPSNotificationCreateRunLoopSource(_powerSourceRunLoopCallback, nil);
CFRunLoopAddSource(CFRunLoopGetMain(), loop, kCFRunLoopDefaultMode);
#endif
}
- (void)setNeedsToUpdateLevel {
#if TARGET_OS_IOS
// `-[UIDevice batteryLevel]` returns the % like '0.(actual %)' (ie, 0.28 when the battery is 28%)
// so multiply it by 100 to get a visually appropriate version
self.batteryLevel = [[UIDevice currentDevice] batteryLevel] * 100;
#elif TARGET_OS_MAC
CFTypeRef snapshot = IOPSCopyPowerSourcesInfo();
NSArray *sourceList = (__bridge NSArray *)IOPSCopyPowerSourcesList(snapshot);
if (!sourceList) {
if (snapshot) CFRelease(snapshot);
return;
}
for (NSDictionary *source in sourceList) {
// kIOPSCurrentCapacityKey = battery level
NSNumber *currentCapacity = [source objectForKey:@(kIOPSCurrentCapacityKey)];
if (currentCapacity) {
// we found what we want
self.batteryLevel = currentCapacity.intValue;
break;
}
}
CFRelease(snapshot);
#endif
}
@end
int getCurrentBatteryCapacity() {
return [[AppleBatteryClient sharedClient] batteryLevel];
}

32
Common/Battery/Battery.h Normal file
View file

@ -0,0 +1,32 @@
//
// Battery.h
// PPSSPP
//
// Created by Serena on 24/01/2023.
//
// NOTE: Though this is a general purpose header file,
// though the implementation right now is Darwin specific
// In case any future platform implementations are made for other platforms,
// define the function below in their own file
#ifndef BATTERY_H
#define BATTERY_H
#include "ppsspp_config.h"
//#include <Foundation/Foundation.h>
#ifdef __cplusplus
extern "C" {
#endif
#if PPSSPP_PLATFORM(IOS) || PPSSPP_PLATFORM(MAC)
#define CAN_DISPLAY_CURRENT_BATTERY_CAPACITY
/// Get the current battery %.
int getCurrentBatteryCapacity();
#endif /* PPSSPP_PLATFORM(IOS) || PPSSPP_PLATFORM(MAC) */
#ifdef __cplusplus
}
#endif
#endif /* BATTERY_H */

View file

@ -870,7 +870,11 @@ public:
BitCheckBox(uint32_t *bitfield, uint32_t bit, const std::string &text, const std::string &smallText = "", LayoutParams *layoutParams = nullptr)
: CheckBox(nullptr, text, smallText, layoutParams), bitfield_(bitfield), bit_(bit) {
}
BitCheckBox(int *bitfield, int bit, const std::string &text, const std::string &smallText = "", LayoutParams *layoutParams = nullptr) : BitCheckBox((uint32_t *)bitfield, (uint32_t)bit, text, smallText, layoutParams) {
}
void Toggle() override;
bool Toggled() const override;

View file

@ -31,6 +31,12 @@ extern const char *PPSSPP_GIT_VERSION;
extern bool jitForcedOff;
// should this be here?!
// for Config.iShowFPSCounter
#define SHOW_FPS_COUNTER 1 << 1
#define SHOW_SPEED_COUNTER 1 << 2
#define SHOW_BATTERY_PERCENT 1 << 3
enum ChatPositions {
BOTTOM_LEFT = 0,
BOTTOM_CENTER = 1,
@ -270,7 +276,7 @@ public:
// UI
bool bShowDebuggerOnLoad;
int iShowFPSCounter;
int iShowFPSCounter; // Should we rename this now?
bool bShowRegionOnGameIcon;
bool bShowIDOnGameIcon;
float fGameGridScale;

View file

@ -25,6 +25,7 @@ using namespace std::placeholders;
#include "Common/Render/TextureAtlas.h"
#include "Common/GPU/OpenGL/GLFeatures.h"
#include "Common/Render/Text/draw_text.h"
#include "Common/Battery/Battery.h"
#include "Common/UI/Root.h"
#include "Common/UI/UI.h"
@ -1294,23 +1295,26 @@ static void DrawFPS(UIContext *ctx, const Bounds &bounds) {
FontID ubuntu24("UBUNTU24");
float vps, fps, actual_fps;
__DisplayGetFPS(&vps, &fps, &actual_fps);
char fpsbuf[256];
switch (g_Config.iShowFPSCounter) {
case 1:
snprintf(fpsbuf, sizeof(fpsbuf), "Speed: %0.1f%%", vps / (59.94f / 100.0f)); break;
case 2:
snprintf(fpsbuf, sizeof(fpsbuf), "FPS: %0.1f", actual_fps); break;
case 3:
snprintf(fpsbuf, sizeof(fpsbuf), "%0.0f/%0.0f (%0.1f%%)", actual_fps, fps, vps / (59.94f / 100.0f)); break;
default:
return;
char fpsbuf[256] = {""};
if (g_Config.iShowFPSCounter & SHOW_FPS_COUNTER) {
snprintf(fpsbuf, sizeof(fpsbuf), "%s FPS: %0.1f", fpsbuf, actual_fps);
}
if (g_Config.iShowFPSCounter & SHOW_SPEED_COUNTER) {
snprintf(fpsbuf, sizeof(fpsbuf), "%s Speed: %0.1f%%", fpsbuf, vps / (59.94f / 100.0f));
}
#ifdef CAN_DISPLAY_CURRENT_BATTERY_CAPACITY
if (g_Config.iShowFPSCounter & SHOW_BATTERY_PERCENT) {
snprintf(fpsbuf, sizeof(fpsbuf), "%s Battery: %d%%", fpsbuf, getCurrentBatteryCapacity());
}
#endif
ctx->Flush();
ctx->BindFontTexture();
ctx->Draw()->SetFontScale(0.7f, 0.7f);
ctx->Draw()->DrawText(ubuntu24, fpsbuf, bounds.x2() - 8, 12, 0xc0000000, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII);
ctx->Draw()->DrawText(ubuntu24, fpsbuf, bounds.x2() - 10, 10, 0xFF3fFF3f, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII);
ctx->Draw()->DrawText(ubuntu24, fpsbuf, bounds.x2() - 8, 20, 0xc0000000, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII);
ctx->Draw()->DrawText(ubuntu24, fpsbuf, bounds.x2() - 10, 19, 0xFF3fFF3f, ALIGN_TOPRIGHT | FLAG_DYNAMIC_ASCII);
ctx->Draw()->SetFontScale(1.0f, 1.0f);
ctx->Flush();
ctx->RebindTexture();

View file

@ -31,6 +31,7 @@
#include "Common/System/Display.h" // Only to check screen aspect ratio with pixel_yres/pixel_xres
#include "Common/System/System.h"
#include "Common/Battery/Battery.h"
#include "Common/System/NativeApp.h"
#include "Common/Data/Color/RGBAUtil.h"
#include "Common/Math/curves.h"
@ -563,8 +564,12 @@ void GameSettingsScreen::CreateViews() {
});
graphicsSettings->Add(new ItemHeader(gr->T("Overlay Information")));
static const char *fpsChoices[] = { "None", "Speed", "FPS", "Both" };
graphicsSettings->Add(new PopupMultiChoice(&g_Config.iShowFPSCounter, gr->T("Show FPS Counter"), fpsChoices, 0, ARRAY_SIZE(fpsChoices), gr->GetName(), screenManager()));
graphicsSettings->Add(new BitCheckBox(&g_Config.iShowFPSCounter, SHOW_FPS_COUNTER, "Show FPS"));
graphicsSettings->Add(new BitCheckBox(&g_Config.iShowFPSCounter, SHOW_SPEED_COUNTER, "Show Speed"));
#ifdef CAN_DISPLAY_CURRENT_BATTERY_CAPACITY
graphicsSettings->Add(new BitCheckBox(&g_Config.iShowFPSCounter, SHOW_BATTERY_PERCENT, "Show Battery"));
#endif
graphicsSettings->Add(new CheckBox(&g_Config.bShowDebugStats, gr->T("Show Debug Statistics")))->OnClick.Handle(this, &GameSettingsScreen::OnJitAffectingSetting);
// Audio