-
Notifications
You must be signed in to change notification settings - Fork 2.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support for loading game-specific plugins #13335
Conversation
Nice. Some people are motivated by also being able to run their stuff on a real PSP, so having support for PRX plugins is probably a good thing even if we also add support for other languages. Of course for uses like custom touch interfaces etc that can't run on a real PSP, lua or ecma might indeed be more appropriate - somewhat safer and easier than prx plugins (no need to install SDK etc). |
One comment on the post: You write
But in the example you use |
Right, and PRX plugins are - as long as we're not building out the whole internal kernel framework - easy to support. Far easier than any scripting language. But I think we'd probably need a scripting language if we wanted hooks like running code when you save state or something. That'd be annoying to do with a PRX plugin...
Oops, I'll amend. -[Unknown] |
My opinion about runtime game patches is that there should always be a way to place them in the same dir as the game for ease of movement and transfer. In other projects it pisses me off when i can't place (for instance) texture replacement projects in the same dir as the game, as a subdir or a zip. I understand that the psp already has conventions that ppsspp is reusing - for instance for the certificates to run certain games - but i wish it was possible to shadow files/folder structure the game dir, if the files thus shadowed are 'single game related'. |
This sounds really cool. Perhaps it could be used to add accessibility to games, like sounds for quick-time events, sound beacons to find the next objective, or speaking menu items, or even enhancing sound through audio filters and effects.
… On Aug 25, 2020, at 11:19 PM, Unknown W. Brackets ***@***.***> wrote:
This makes it possible to define plugins, as prx files, for specific games. An immediate example is fan translation.
Basic usage:
Create a plugin directory inside PSP/PLUGINS/, i.e. PSP/PLUGINS/mycrisiscoretranslation/.
Add an ini file, such as:
[options]
version = 1
type = prx
filename = patch.prx
[games]
ULJM05275 = true
Compile a prx plugin using the pspsdk, and it'll be loaded. However, you cannot use many kernel or HEN functions, since they don't work in PPSSPP. The internal architecture is different. You can however call the same functions games can call, update RAM, etc.
Other options:
You can use memory = 64 under [options] to allocate more RAM, up to 93 MB due to memory map limitations. Beware this gives the game overall more RAM, and may affect cheats and memory management in the game.
Under [games], you can use ULJM05275 = foo.ini to allow your plugin to use a different prx for different game IDs, i.e. multidisc games. ALL = true can also be used to apply to all games. seplugins won't work, because HEN/kernel funcs are not supported.
You can also add [lang] and put something like se_SE = swedish.ini. This allows you to load a prx just for a user's specific language. This can be in addition to, or instead of, a main plugin.
In theory, this could allow more things. If we wanted to allow lua or ecma or python, we could add it as a different type. We could also add an import to be able to call things like:
ppssppVibrate(type)
ppssppUseTouch(enable), ppssppGetTouches()
ppssppPreloadTexture(addr, bufw, w, h)
ppssppReplaceTexture(addr, hash0, hash1, hash2), ppssppForgetTexture(addr)
ppssppReplaceSound(atracID, "filename.mp3")
ppssppGetRenderResolution(), ppssppDownloadFramebuffer(fb_address, ram_address, bufw, w, h, bilinear) (coupled with memory = 93)
Though, not sure if a scripting language is more appropriate. I don't want PPSSPP itself to try to solve game bugs with game-specific hacks, but I'm all for allowing people to make game-specific enhancements. Not sure what people are interested in making, though, and in what language... cwcheat doesn't seem like enough.
-[Unknown]
You can view, comment on, or merge this pull request online at:
#13335 <#13335>
Commit Summary
Module: Split out module start to use externally.
Plugins: Support for loading game-specific plugins.
File Changes
M CMakeLists.txt <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-af3b638bc2a3e6c650974192a53c7291> (2)
M Core/Config.cpp <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-0319254777e353e315f24a35b7a8430a> (1)
M Core/Config.h <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-0a3b475c1f5cc8d1037beea30329fbe9> (1)
M Core/Core.vcxproj <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-4e25412ae65915bd6db11f8f22e3b899> (2)
M Core/Core.vcxproj.filters <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-551e90efd7c911715ef690cc9be3f512> (6)
A Core/HLE/Plugins.cpp <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-c95bf8da677ef22f01c4b7df5771b8e9> (210)
A Core/HLE/Plugins.h <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-7a73c09897d7e9ba5a2068afbb76b020> (34)
M Core/HLE/sceKernelModule.cpp <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-eb784c656c56255624635d18f7e2f057> (156)
M Core/HLE/sceKernelModule.h <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-ae5178682d2357944652be356eaae1aa> (3)
M Core/Reporting.cpp <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-cd4e126108155cbe08eef9155cabe67c> (3)
M Core/System.cpp <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-130401d995253e54392d8b71dbad2ece> (5)
M Core/System.h <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-9e3fedc3c9009c896bd4f2c4ff3c1605> (1)
M UI/NativeApp.cpp <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-1746de24333eafb8ba59254e484bc90a> (2)
M UWP/CoreUWP/CoreUWP.vcxproj <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-507d1a309feabc09360ce7574e55caa6> (2)
M UWP/CoreUWP/CoreUWP.vcxproj.filters <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-8b339be71ea005651b0f45cba17ac341> (2)
M android/jni/Android.mk <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-983cf7060ee7932325a5473d56993529> (1)
M libretro/Makefile.common <https://github.com/hrydgard/ppsspp/pull/13335/files#diff-691980c178164b2b1492e2ba21780987> (1)
Patch Links:
https://github.com/hrydgard/ppsspp/pull/13335.patch <https://github.com/hrydgard/ppsspp/pull/13335.patch>
https://github.com/hrydgard/ppsspp/pull/13335.diff <https://github.com/hrydgard/ppsspp/pull/13335.diff>
—
You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub <#13335>, or unsubscribe <https://github.com/notifications/unsubscribe-auth/ADUMTTSRSRVWPAERMVLMU73SCSEL5ANCNFSM4QLLUGHQ>.
|
To follow up, I think this is great except possibly for the ini configuration interface. i30817 has a point with the ability to easily copy patches around with the games, although it is also established in PPSSPP practice to have similar things separately (like cheats). As for the game id = parameter, anything that can be set to either a string or true, with different meaning in the latter case, feels quite odd to me.. I wonder if we can think of a more intuitive way. |
Well, I can just remove true. I just think it'll make a bunch of people confused and think they have to create a bunch of separate files, which seems annoying. Textures are also not grouped with the game. I think it gets tricky with different file formats, like PBP, PBP as folder, CSO, etc. -[Unknown] |
Yeah fair enough. I'll consider it. Anyway, can probably take this PR out of Draft mode... |
Yeah, at least one person has used it with some success. -[Unknown] |
7b56a12
to
ac7522b
Compare
Just as an example, this is a version of the Kingdom Hearts right analog plugin that doesn't use the HEN stuff we don't support. Makefile, exports, etc. unchanged. PSP/PLUGINS/khbbs_remastered/plugin.ini: [options]
type = prx
version = 1
filename = khbbs_remastered.prx
[games]
ULUS10505 = true
ULJM05600 = true
ULJM05775 = true
ULES01441 = true main.c: /*
Remastered Controls: Kingdom Hearts
Copyright (C) 2018, TheFloW
This program 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 3 of the License, or
(at your option) any later version.
This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pspsdk.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <stdio.h>
#include <string.h>
#include <systemctrl.h>
#define EMULATOR_DEVCTL__IS_EMULATOR 0x00000003
PSP_MODULE_INFO("KHBBSRemastered", 0x1007, 1, 0);
int sceKernelQuerySystemCall(void *function);
#define MAKE_SYSCALL(a, n) _sw(0x0000000C | ((n) << 6), a);
#define MAKE_JAL(a, n) _sw(0x0C000000 | ((n) >> 2), a);
static STMOD_HANDLER previous;
float leftAnalogX() {
SceCtrlData pad;
int k1 = pspSdkSetK1(0);
sceCtrlPeekBufferPositive(&pad, 1);
pspSdkSetK1(k1);
return (float)(pad.Rsrv[0] - 128) / 128.0f;
}
float leftAnalogY() {
SceCtrlData pad;
int k1 = pspSdkSetK1(0);
sceCtrlPeekBufferPositive(&pad, 1);
pspSdkSetK1(k1);
return (float)(pad.Rsrv[1] - 128) / 128.0f;
}
static void ApplyPatch(u32 text_addr, u32 text_size, int use_jal) {
u32 i;
for (i = 0; i < text_size; i += 4) {
u32 addr = text_addr + i;
// Fake L trigger as held
if (_lw(addr + 0x00) == 0x30840004 && _lw(addr + 0x04) == 0x508000BA) {
_sw(0, addr + 0x04);
continue;
}
if (_lw(addr + 0x00) == 0xAFBF0008 && _lw(addr + 0x04) == 0x1C80000B) {
// Fake control type B
_sw(0, addr + 0x04);
// Redirect left analog stick to right analog stick
if (_lw(addr + 0x08) == 0x46007506) {
if (use_jal) {
MAKE_JAL(addr + 0x14, (intptr_t)leftAnalogX);
MAKE_JAL(addr + 0x54, (intptr_t)leftAnalogX);
} else {
u32 syscall = sceKernelQuerySystemCall(leftAnalogX);
_sw(_lw(addr + 0x18), addr + 0x14);
_sw(_lw(addr + 0x58), addr + 0x54);
MAKE_SYSCALL(addr + 0x18, syscall);
MAKE_SYSCALL(addr + 0x58, syscall);
}
} else if (_lw(addr + 0x08) == 0x4480A000) {
if (use_jal) {
MAKE_JAL(addr + 0x14, (intptr_t)leftAnalogY);
MAKE_JAL(addr + 0x54, (intptr_t)leftAnalogY);
} else {
u32 syscall = sceKernelQuerySystemCall(leftAnalogY);
_sw(_lw(addr + 0x18), addr + 0x14);
_sw(_lw(addr + 0x58), addr + 0x54);
MAKE_SYSCALL(addr + 0x18, syscall);
MAKE_SYSCALL(addr + 0x58, syscall);
}
}
continue;
}
}
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
}
static int OnModuleStart(SceModule2 *mod) {
if (strcmp(mod->modname, "MainApp") == 0) {
ApplyPatch(mod->text_addr, mod->text_size, 0);
}
if (!previous)
return 0;
return previous(mod);
}
static void CheckModules() {
SceUID modules[10];
int count = 0;
if (sceKernelGetModuleIdList(modules, sizeof(modules), &count) >= 0) {
int i;
SceKernelModuleInfo info;
for (i = 0; i < count; ++i) {
info.size = sizeof(SceKernelModuleInfo);
if (sceKernelQueryModuleInfo(modules[i], &info) < 0) {
continue;
}
if (strcmp(info.name, "MainApp") == 0) {
ApplyPatch(info.text_addr, info.text_size, 1);
}
}
}
}
int module_start(SceSize args, void *argp) {
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
if (sceIoDevctl("kemulator:", EMULATOR_DEVCTL__IS_EMULATOR, NULL, 0, NULL, 0) == 0) {
// Just scan the modules using normal/official syscalls.
CheckModules();
} else {
previous = sctrlHENSetStartModuleHandler(OnModuleStart);
}
return 0;
} -[Unknown] |
OK, I see now how the "true" makes sense. Nice. |
I know that I am not a developer and I am not allowed to chat here but does that mean Cheat Device for the GTA PSP games works now? |
I don't know what Cheat Device is, but no - I would assume this does not mean this. PSP firmware plugins are unsupported, so if that's some plugin people used on real PSPs it does not work. -[Unknown] |
This might be a small detail/request but on real hardware argp in module_start contains the loaded prx's full path where currently with PPSSPP it is not used?! Some plugins use this to check where they are loaded from to dynamically load more files from the same location. Especially since PPSSPP uses a different folder for plugins compared to CFWs this would be great to have! Also thanks for the sample code @unknownbrackets , works great! :) |
This makes it possible to define plugins, as prx files, for specific games. An immediate example is fan translation.
IMPORTANT: This does not support original PSP firmware plugins which use hacks of PSP firmware internals to inject into games. The same internals do not exist in PPSSPP.
Basic usage:
Other options:
memory = 64
under[options]
to allocate more RAM, up to 93 MB due to memory map limitations. Beware this gives the game overall more RAM, and may affect cheats and memory management in the game.[games]
, you can useULJM05275 = foo.ini
to allow your plugin to use a different prx for different game IDs, i.e. multidisc games.true
is the same as usingplugin.ini
, in other words use[options]
in the same file.ALL = true
orALL = otherfile.ini
can also be used to apply to all games. seplugins won't work, because HEN/kernel funcs are not supported.[lang]
and put something likese_SE = swedish.ini
. This allows you to load a prx just for a user's specific language. This can be in addition to, or instead of, a main plugin.In theory, this could allow more things. If we wanted to allow lua or ecma or python, we could add it as a different type. We could also add an import to be able to call things like:
Though, not sure if a scripting language is more appropriate. I don't want PPSSPP itself to try to solve game bugs with game-specific hacks, but I'm all for allowing people to make game-specific enhancements. Not sure what people are interested in making, though, and in what language... cwcheat doesn't seem like enough.
-[Unknown]