2020-12-11 16:41:37 +01:00
# include "main.h"
# include "retain_vars.hpp"
2023-01-22 14:45:20 +01:00
# include "thread.h"
2022-09-24 17:57:29 +02:00
# include "utils/WUPSConfigItemButtonCombo.h"
2020-12-11 16:41:37 +01:00
# include "utils/logger.h"
# include <coreinit/cache.h>
# include <coreinit/title.h>
2018-07-01 19:12:35 +02:00
# include <malloc.h>
2020-12-11 16:41:37 +01:00
# include <nn/acp.h>
2018-07-01 19:12:35 +02:00
# include <string>
2020-12-11 16:41:37 +01:00
# include <wups.h>
# include <wups/config/WUPSConfigItemBoolean.h>
# include <wups/config/WUPSConfigItemIntegerRange.h>
# include <wups/config/WUPSConfigItemMultipleValues.h>
2018-07-01 19:12:35 +02:00
// Mandatory plugin information.
2020-12-11 16:41:37 +01:00
WUPS_PLUGIN_NAME ( " Screenshot plugin " ) ;
2018-07-01 19:12:35 +02:00
WUPS_PLUGIN_DESCRIPTION ( " This plugin allows you to make screenshots that will be saved to the sd card " ) ;
2020-12-11 16:41:37 +01:00
WUPS_PLUGIN_VERSION ( VERSION_FULL ) ;
2018-07-01 19:12:35 +02:00
WUPS_PLUGIN_AUTHOR ( " Maschell " ) ;
WUPS_PLUGIN_LICENSE ( " GPL " ) ;
// FS Access
2020-12-11 16:41:37 +01:00
WUPS_USE_WUT_DEVOPTAB ( ) ;
WUPS_USE_STORAGE ( " screenshot_plugin " ) ;
2018-07-01 19:12:35 +02:00
2023-01-22 16:36:40 +01:00
# define ENABLED_CONFIG_STRING "enabled"
# define BUTTON_COMBO_CONFIG_STRING "buttonCombo"
# define FORMAT_CONFIG_STRING "format"
# define QUALITY_CONFIG_STRING "quality"
# define SCREEN_CONFIG_STRING "screen"
# define RESERVED_BIT_USAGE_CONFIG_STRING "reservedBitUsage"
2018-07-01 19:12:35 +02:00
// Gets called once the loader exists.
INITIALIZE_PLUGIN ( ) {
2020-12-11 16:41:37 +01:00
initLogging ( ) ;
2023-01-22 14:09:57 +01:00
gButtonCombo = VPAD_BUTTON_TV ;
2020-12-11 16:41:37 +01:00
OSMemoryBarrier ( ) ;
// Open storage to read values
WUPSStorageError storageRes = WUPS_OpenStorage ( ) ;
if ( storageRes ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to open storage %s (%d) " , WUPS_GetStorageStatusStr ( storageRes ) , storageRes ) ;
} else {
// Try to get value from storage
2022-09-24 17:57:29 +02:00
if ( ( storageRes = WUPS_GetBool ( nullptr , ENABLED_CONFIG_STRING , & gEnabled ) ) = = WUPS_STORAGE_ERROR_NOT_FOUND ) {
2020-12-11 16:41:37 +01:00
// Add the value to the storage if it's missing.
if ( WUPS_StoreBool ( nullptr , ENABLED_CONFIG_STRING , gEnabled ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to store value " ) ;
}
} else if ( storageRes ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to get value %s (%d) " , WUPS_GetStorageStatusStr ( storageRes ) , storageRes ) ;
}
// Try to get value from storage
if ( ( storageRes = WUPS_GetInt ( nullptr , FORMAT_CONFIG_STRING , reinterpret_cast < int32_t * > ( & gOutputFormat ) ) ) = = WUPS_STORAGE_ERROR_NOT_FOUND ) {
// Add the value to the storage if it's missing.
2022-09-24 17:57:29 +02:00
if ( WUPS_StoreInt ( nullptr , FORMAT_CONFIG_STRING , gOutputFormat ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
2020-12-11 16:41:37 +01:00
DEBUG_FUNCTION_LINE_ERR ( " Failed to store value " ) ;
}
} else if ( storageRes ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to get value %s (%d) " , WUPS_GetStorageStatusStr ( storageRes ) , storageRes ) ;
}
2018-07-01 19:12:35 +02:00
2020-12-11 16:41:37 +01:00
// Try to get value from storage
if ( ( storageRes = WUPS_GetInt ( nullptr , QUALITY_CONFIG_STRING , reinterpret_cast < int32_t * > ( & gQuality ) ) ) = = WUPS_STORAGE_ERROR_NOT_FOUND ) {
// Add the value to the storage if it's missing.
if ( WUPS_StoreInt ( nullptr , QUALITY_CONFIG_STRING , ( int32_t ) gQuality ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to store value " ) ;
}
} else if ( storageRes ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to get value %s (%d) " , WUPS_GetStorageStatusStr ( storageRes ) , storageRes ) ;
}
2018-07-01 19:12:35 +02:00
2020-12-11 16:41:37 +01:00
// Try to get value from storage
if ( ( storageRes = WUPS_GetInt ( nullptr , SCREEN_CONFIG_STRING , reinterpret_cast < int32_t * > ( & gImageSource ) ) ) = = WUPS_STORAGE_ERROR_NOT_FOUND ) {
// Add the value to the storage if it's missing.
if ( WUPS_StoreInt ( nullptr , SCREEN_CONFIG_STRING , ( int32_t ) gImageSource ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to store value " ) ;
}
} else if ( storageRes ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to get value %s (%d) " , WUPS_GetStorageStatusStr ( storageRes ) , storageRes ) ;
}
2018-07-01 19:12:35 +02:00
2022-09-24 17:57:29 +02:00
// Try to get value from storage
if ( ( storageRes = WUPS_GetInt ( nullptr , BUTTON_COMBO_CONFIG_STRING , reinterpret_cast < int32_t * > ( & gButtonCombo ) ) ) = = WUPS_STORAGE_ERROR_NOT_FOUND ) {
// Add the value to the storage if it's missing.
if ( WUPS_StoreInt ( nullptr , BUTTON_COMBO_CONFIG_STRING , ( int32_t ) gButtonCombo ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to store value " ) ;
}
} else if ( storageRes ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to get value %s (%d) " , WUPS_GetStorageStatusStr ( storageRes ) , storageRes ) ;
}
2023-01-22 16:36:40 +01:00
// Try to get value from storage
if ( ( storageRes = WUPS_GetBool ( nullptr , RESERVED_BIT_USAGE_CONFIG_STRING , & gReservedBitUsage ) ) = = WUPS_STORAGE_ERROR_NOT_FOUND ) {
// Add the value to the storage if it's missing.
if ( WUPS_StoreBool ( nullptr , RESERVED_BIT_USAGE_CONFIG_STRING , gReservedBitUsage ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to store value " ) ;
}
} else if ( storageRes ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to get value %s (%d) " , WUPS_GetStorageStatusStr ( storageRes ) , storageRes ) ;
}
2020-12-11 16:41:37 +01:00
// Close storage
if ( WUPS_CloseStorage ( ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to close storage " ) ;
}
}
if ( gOutputFormat > = 3 ) {
gOutputFormat = IMAGE_OUTPUT_FORMAT_JPEG ;
}
if ( gQuality < 10 ) {
gQuality = 10 ;
} else if ( gQuality > 100 ) {
gQuality = 100 ;
}
2018-07-01 19:12:35 +02:00
}
2022-09-24 18:00:12 +02:00
void multipleValueItemCallback ( ConfigItemMultipleValues * item , uint32_t newValue ) {
if ( item & & item - > configId ) {
DEBUG_FUNCTION_LINE ( " New value in %s changed: %d " , item - > configId , newValue ) ;
if ( std : : string_view ( item - > configId ) = = FORMAT_CONFIG_STRING ) {
gOutputFormat = ( ImageOutputFormatEnum ) newValue ;
if ( gOutputFormat > = 3 ) {
gOutputFormat = IMAGE_OUTPUT_FORMAT_JPEG ;
}
2018-07-01 19:12:35 +02:00
2022-09-24 18:00:12 +02:00
WUPS_StoreInt ( nullptr , item - > configId , ( int32_t ) newValue ) ;
} else if ( std : : string_view ( item - > configId ) = = SCREEN_CONFIG_STRING ) {
gImageSource = ( ImageSourceEnum ) newValue ;
2018-07-01 19:12:35 +02:00
2022-09-24 18:00:12 +02:00
if ( gImageSource > = 3 ) {
gImageSource = IMAGE_SOURCE_TV_AND_DRC ;
}
2020-12-11 16:41:37 +01:00
2022-09-24 18:00:12 +02:00
WUPS_StoreInt ( nullptr , item - > configId , ( int32_t ) newValue ) ;
}
2020-12-11 16:41:37 +01:00
}
2018-07-01 19:12:35 +02:00
}
2022-09-24 18:00:12 +02:00
void integerRangeItemCallback ( ConfigItemIntegerRange * item , int32_t newValue ) {
if ( item & & item - > configId ) {
DEBUG_FUNCTION_LINE ( " New value in %s changed: %d " , item - > configId , newValue ) ;
if ( std : : string_view ( item - > configId ) = = QUALITY_CONFIG_STRING ) {
gQuality = ( ImageOutputFormatEnum ) newValue ;
2018-07-01 19:12:35 +02:00
2022-09-24 18:00:12 +02:00
if ( gQuality < 10 ) {
gQuality = 10 ;
} else if ( gQuality > 100 ) {
gQuality = 100 ;
}
2018-07-01 19:12:35 +02:00
2022-09-24 18:00:12 +02:00
WUPS_StoreInt ( nullptr , item - > configId , ( int32_t ) gQuality ) ;
}
}
2020-12-11 16:41:37 +01:00
}
2018-07-01 19:12:35 +02:00
2022-09-24 18:00:12 +02:00
void boolItemCallback ( ConfigItemBoolean * item , bool newValue ) {
if ( item & & item - > configId ) {
DEBUG_FUNCTION_LINE ( " New value in %s changed: %d " , item - > configId , newValue ) ;
if ( std : : string_view ( item - > configId ) = = ENABLED_CONFIG_STRING ) {
2023-01-22 16:36:40 +01:00
gEnabled = newValue ;
2022-09-24 18:00:12 +02:00
WUPS_StoreBool ( nullptr , item - > configId , gEnabled ) ;
2023-01-22 16:36:40 +01:00
} else if ( std : : string_view ( item - > configId ) = = RESERVED_BIT_USAGE_CONFIG_STRING ) {
gReservedBitUsage = newValue ;
WUPS_StoreBool ( nullptr , item - > configId , gReservedBitUsage ) ;
2022-09-24 18:00:12 +02:00
}
}
2020-12-11 16:41:37 +01:00
}
2018-07-01 19:12:35 +02:00
2022-09-24 17:57:29 +02:00
void buttonComboItemChanged ( ConfigItemButtonCombo * item , uint32_t newValue ) {
if ( item & & item - > configId ) {
DEBUG_FUNCTION_LINE ( " New value in %s changed: %d " , item - > configId , newValue ) ;
if ( std : : string_view ( item - > configId ) = = BUTTON_COMBO_CONFIG_STRING ) {
gButtonCombo = newValue ;
WUPS_StoreInt ( nullptr , item - > configId , ( int32_t ) gButtonCombo ) ;
}
}
}
2020-12-11 16:41:37 +01:00
WUPS_GET_CONFIG ( ) {
// We open the storage, so we can persist the configuration the user did.
if ( WUPS_OpenStorage ( ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to open storage " ) ;
return 0 ;
2018-07-01 19:12:35 +02:00
}
2020-12-11 16:41:37 +01:00
WUPSConfigHandle config ;
WUPSConfig_CreateHandled ( & config , " Screenshot plugin " ) ;
2018-07-01 19:12:35 +02:00
2020-12-11 16:41:37 +01:00
WUPSConfigCategoryHandle setting ;
WUPSConfig_AddCategoryByNameHandled ( config , " Settings " , & setting ) ;
2018-07-01 19:12:35 +02:00
2022-09-24 18:00:12 +02:00
WUPSConfigItemBoolean_AddToCategoryHandled ( config , setting , ENABLED_CONFIG_STRING , " Enabled " , gEnabled , & boolItemCallback ) ;
2020-12-11 16:41:37 +01:00
2022-09-24 17:57:29 +02:00
WUPSConfigItemButtonCombo_AddToCategoryHandled ( config , setting , BUTTON_COMBO_CONFIG_STRING , " Button combo " , gButtonCombo , & buttonComboItemChanged ) ;
2022-09-23 17:00:53 +02:00
ConfigItemMultipleValuesPair source [ 3 ] ;
source [ 0 ] . value = IMAGE_SOURCE_TV_AND_DRC ;
source [ 0 ] . valueName = ( char * ) " TV & GamePad " ;
2020-12-11 16:41:37 +01:00
2022-09-23 17:00:53 +02:00
source [ 1 ] . value = IMAGE_SOURCE_TV ;
source [ 1 ] . valueName = ( char * ) " TV only " ;
source [ 2 ] . value = IMAGE_SOURCE_DRC ;
source [ 2 ] . valueName = ( char * ) " GamePad only " ;
2020-12-11 16:41:37 +01:00
uint32_t defaultIndex = 0 ;
uint32_t curIndex = 0 ;
2022-09-23 17:00:53 +02:00
for ( auto & cur : source ) {
if ( cur . value = = gImageSource ) {
2020-12-11 16:41:37 +01:00
defaultIndex = curIndex ;
2018-07-01 19:12:35 +02:00
break ;
}
2020-12-11 16:41:37 +01:00
curIndex + + ;
}
2022-09-23 17:00:53 +02:00
WUPSConfigItemMultipleValues_AddToCategoryHandled ( config , setting , SCREEN_CONFIG_STRING , " Screen " , defaultIndex , source ,
2022-09-24 18:00:12 +02:00
sizeof ( source ) / sizeof ( source [ 0 ] ) , & multipleValueItemCallback ) ;
2020-12-11 16:41:37 +01:00
2022-09-23 17:00:53 +02:00
ConfigItemMultipleValuesPair fileFormat [ 3 ] ;
fileFormat [ 0 ] . value = IMAGE_OUTPUT_FORMAT_JPEG ;
fileFormat [ 0 ] . valueName = ( char * ) " JPEG " ;
2020-12-11 16:41:37 +01:00
2022-09-23 17:00:53 +02:00
fileFormat [ 1 ] . value = IMAGE_OUTPUT_FORMAT_PNG ;
fileFormat [ 1 ] . valueName = ( char * ) " PNG " ;
2020-12-11 16:41:37 +01:00
2022-09-23 17:00:53 +02:00
fileFormat [ 2 ] . value = IMAGE_OUTPUT_FORMAT_BMP ;
fileFormat [ 2 ] . valueName = ( char * ) " BMP " ;
2020-12-11 16:41:37 +01:00
defaultIndex = 0 ;
curIndex = 0 ;
2022-09-23 17:00:53 +02:00
for ( auto & cur : fileFormat ) {
if ( cur . value = = gOutputFormat ) {
2020-12-11 16:41:37 +01:00
defaultIndex = curIndex ;
2018-07-01 19:12:35 +02:00
break ;
}
2020-12-11 16:41:37 +01:00
curIndex + + ;
2018-07-01 19:12:35 +02:00
}
2022-09-23 17:00:53 +02:00
WUPSConfigItemMultipleValues_AddToCategoryHandled ( config , setting , FORMAT_CONFIG_STRING , " Output format " , defaultIndex , fileFormat ,
2022-09-24 18:00:12 +02:00
sizeof ( fileFormat ) / sizeof ( fileFormat [ 0 ] ) , & multipleValueItemCallback ) ;
2020-12-11 16:41:37 +01:00
2022-09-24 18:00:12 +02:00
WUPSConfigItemIntegerRange_AddToCategoryHandled ( config , setting , QUALITY_CONFIG_STRING , " JPEG quality " , gQuality , 10 , 100 , & integerRangeItemCallback ) ;
2020-12-11 16:41:37 +01:00
2023-01-22 16:36:40 +01:00
WUPSConfigItemBoolean_AddToCategoryHandled ( config , setting , RESERVED_BIT_USAGE_CONFIG_STRING , " Check ReservedBit for taking Screenshots " , gReservedBitUsage , & boolItemCallback ) ;
2020-12-11 16:41:37 +01:00
return config ;
}
WUPS_CONFIG_CLOSED ( ) {
// Save all changes
if ( WUPS_CloseStorage ( ) ! = WUPS_STORAGE_ERROR_SUCCESS ) {
DEBUG_FUNCTION_LINE_ERR ( " Failed to close storage " ) ;
2018-07-01 19:12:35 +02:00
}
2020-12-11 16:41:37 +01:00
}
// Called whenever an application was started.
ON_APPLICATION_START ( ) {
initLogging ( ) ;
ACPInitialize ( ) ;
auto * metaXml = ( ACPMetaXml * ) memalign ( 0x40 , sizeof ( ACPMetaXml ) ) ;
if ( ACPGetTitleMetaXml ( OSGetTitleID ( ) , metaXml ) = = ACP_RESULT_SUCCESS ) {
gShortNameEn = metaXml - > shortname_en ;
std : : string illegalChars = " \\ /:? \" <>|@=;`_^][ " ;
for ( auto it = gShortNameEn . begin ( ) ; it < gShortNameEn . end ( ) ; + + it ) {
if ( * it < ' 0 ' | | * it > ' z ' ) {
* it = ' ' ;
}
}
for ( auto it = gShortNameEn . begin ( ) ; it < gShortNameEn . end ( ) ; + + it ) {
bool found = illegalChars . find ( * it ) ! = std : : string : : npos ;
if ( found ) {
* it = ' ' ;
}
}
uint32_t length = gShortNameEn . length ( ) ;
for ( uint32_t i = 1 ; i < length ; + + i ) {
if ( gShortNameEn [ i - 1 ] = = ' ' & & gShortNameEn [ i ] = = ' ' ) {
gShortNameEn . erase ( i , 1 ) ;
i - - ;
length - - ;
}
}
if ( gShortNameEn . size ( ) = = 1 & & gShortNameEn [ 0 ] = = ' ' ) {
gShortNameEn . clear ( ) ;
} else {
DEBUG_FUNCTION_LINE ( " Detected name as \" %s \" " , gShortNameEn . c_str ( ) ) ;
}
} else {
gShortNameEn . clear ( ) ;
2018-07-01 19:12:35 +02:00
}
2023-01-22 14:45:20 +01:00
startFSIOThreads ( ) ;
2023-01-22 14:09:57 +01:00
VPADSetTVMenuInvalid ( VPAD_CHAN_0 , true ) ;
2020-12-11 16:41:37 +01:00
}
2018-07-01 19:12:35 +02:00
2023-01-22 14:45:20 +01:00
2020-12-11 16:41:37 +01:00
ON_APPLICATION_REQUESTS_EXIT ( ) {
2023-01-22 14:45:20 +01:00
stopFSIOThreads ( ) ;
2020-12-11 16:41:37 +01:00
deinitLogging ( ) ;
2018-07-01 19:12:35 +02:00
}