The loader stuff:
// This is taken from the PSPRadio PRXLoader
PRXLoader.h
Code: Select all
#include <pspkernel.h>
#include <psptypes.h>
#define _PRXLOADER_
class CPRXLoader
{
public:
CPRXLoader();
~CPRXLoader();
int Load(const char *filename);
int Unload();
int Start(int argc = 0, char * const argv[] = NULL);
bool IsLoaded() { return m_IsLoaded; }
bool IsStarted() { return m_IsStarted; }
int GetError() { return m_error; }
char *GetFilename() { return m_FileName; }
/** Helpers */
void SetName(const char *strName);
char *GetName();
private:
SceUID StartModuleWithArgs(char *filename, int modid, int argc, char * const argv[]);
SceUID m_ModId;
int m_error;
char *m_FileName;
char *m_Name;
bool m_IsStarted, m_IsLoaded;
};
Code: Select all
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <pspsdk.h>
#include "PRXLoader.h"
#define MAX_ARGS 2048
#define printf pspDebugScreenPrintf
CPRXLoader::CPRXLoader()
{
m_ModId = -1;
m_FileName = NULL;
m_error = 0;
m_IsStarted = false;
m_IsLoaded = false;
m_Name = strdup("Off");
}
CPRXLoader::~CPRXLoader()
{
Unload();
if (m_FileName)
{
free(m_FileName), m_FileName = NULL;
}
if (m_Name)
{
free(m_Name), m_Name = NULL;
}
}
void CPRXLoader::SetName(const char *strName)
{
if (m_Name)
{
free(m_Name);
}
m_Name = strdup(strName);
}
char *CPRXLoader::GetName()
{
if (m_Name)
{
return m_Name;
}
else
{
return "Off";
}
}
int CPRXLoader::Load(const char *filename)
{
SceKernelLMOption option;
SceUID mpid = PSP_MEMORY_PARTITION_USER;
memset(&option, 0, sizeof(option));
option.size = sizeof(option);
option.mpidtext = mpid;
option.mpiddata = mpid;
option.position = 0;
option.access = 1;
SceSize am = sceKernelTotalFreeMemSize();
printf( "CPRXLoader::Load('%s') - Available memory before loading: %dbytes (%dKB or %dMB)\n", filename, am, am/1024, am/1024/1024 );
am = sceKernelMaxFreeMemSize();
printf( "CPRXLoader::Load('%s') - Max(continguos) memory before loading: %dbytes (%dKB or %dMB)\n", filename, am, am/1024, am/1024/1024 );
m_ModId = sceKernelLoadModule(filename, 0, &option);
printf( "CPRXLoader::Load('%s') - Module Id = %d\n", filename, m_ModId );
sleep(1);
if (m_ModId > 0)
{
if (m_FileName)
{
free(m_FileName), m_FileName = NULL;
}
m_FileName = strdup(filename);
m_error = 0;
m_IsLoaded = true;
}
else
{
m_error = m_ModId;
m_IsLoaded = false;
}
return m_ModId;
}
int CPRXLoader::Unload()
{
int ret = 0;
int status = 0;
if (IsLoaded() == true)
{
printf( "CPRXLoader::Unload - Stopping Module %d\n", m_ModId );
if (IsStarted() == true)
{
// Stop
printf( "CPRXLoader::Unload - Module was started, so stopping first.\n" );
ret = sceKernelStopModule(m_ModId, 0, NULL, &status, NULL);
m_IsStarted = false;
}
printf( "StopModule returned 0x%x\n", ret );
// Unload
///if(ret >= 0)
{
printf( "Unload(): Unloading Module\n" );
ret = sceKernelUnloadModule(m_ModId);
printf( "UnloadModule returned 0x%x\n" );
}
sleep(1);
m_ModId = 0;
m_IsLoaded = false;
}
return 0;
}
int CPRXLoader::Start(int argc, char *const argv[])
{
return StartModuleWithArgs(m_FileName, m_ModId, argc, argv);
}
SceUID CPRXLoader::StartModuleWithArgs(char *filename, int modid, int argc, char * const argv[])
{
int retVal = 0, mresult = 0;
char args[MAX_ARGS];
int argpos = 0;
int i = 0;
memset(args, 0, MAX_ARGS);
strcpy(args, filename);
argpos += strlen(args) + 1;
for(i = 0; (i < argc) && (argpos < MAX_ARGS); i++)
{
int len;
snprintf(&args[argpos], MAX_ARGS-argpos, "%s", argv[i]);
len = strlen(&args[argpos]);
argpos += len + 1;
}
retVal = sceKernelStartModule(modid, argpos, args, &mresult, NULL);
if(retVal < 0)
{
m_IsStarted = false;
return retVal;
}
m_IsStarted = true;
return modid;
}
Code: Select all
#include <pspkernel.h>
#include <pspsdk.h>
#include <stdio.h>
#include <stdlib.h>
#include <SDL/SDL.h>
#include "PRXLoader.h"
#include "plugin.h"
PSP_MODULE_INFO("LOADER", 0x0, 1, 1);
/* Define the main thread's attribute value (optional) */
PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_VFPU);
#define printf pspDebugScreenPrintf
#define usleep(x) sceKernelDelayThread( x * 1000000 )
Plugin *plugin;
/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
sceKernelExitGame();
return 0;
}
/* Callback thread */
int CallbackThread(SceSize args, void *argp)
{
int cbid;
cbid = sceKernelCreateCallback("Exit Callback", exit_callback, NULL);
sceKernelRegisterExitCallback(cbid);
sceKernelSleepThreadCB();
return 0;
}
/* Sets up the callback thread and returns its thread id */
int SetupCallbacks(void)
{
int thid = 0;
thid = sceKernelCreateThread("update_thread", CallbackThread,
0x11, 0xFA0, 0, 0);
if(thid >= 0)
{
sceKernelStartThread(thid, 0, 0);
}
return thid;
}
int main( int argc, char *argv[] )
{
CPRXLoader *loader;
pspDebugScreenInit();
SetupCallbacks();
loader = new CPRXLoader;
if( loader->Load( "ms0:/PSP/GAME150/PRXTest/plugin.prx" ) <= 0 ) {
printf( "Cannot load plugin prx!\n" );
usleep( 1 );
goto out;
}
if( loader->IsLoaded( ) == true ) {
printf( "Load OK\n" );
usleep( 1 );
loader->Start( );
}
if( loader->IsStarted( ) == true ) {
printf( "Module Started\n" );
plugin = get_plugin_info();
printf( "Description: %s\n", plugin->description );
plugin->init();
}
sceKernelDelayThread( 5 * 1000000 );
loader->Unload( );
out:
sceKernelDelayThread( 0 );
sceKernelExitGame( );
return 0;
}
Code: Select all
TARGET = PluginTest
EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Plugin Test
EXPORTS_OBJS = PluginStub.o
OBJS = Main.o PRXLoader.o \
$(EXPORTS_OBJS)
CFLAGS = -O2 -Wall -g -DPSP
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS =
LIBS = -lstdc++ \
-lSDLmain -lSDL -lGL \
-lpspvfpu -L/usr/local/pspdev/psp/sdk/lib -lpspdebug -lpspgu \
-lpspctrl -lpspge -lpspdisplay -lpsphprm -lpspsdk -lpsprtc \
-lpspaudio -lc -lpspuser -lpsputility -lpspkernel -lpspnet_inet
all: $(EXTRA_TARGETS)
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
plugin.h
Code: Select all
typedef struct
{
char *description; /* The description of the plugin */
void (*init) (void); /* Called when the plugin is loaded */
}
Plugin;
/* The plugin exports this function */
extern "C" Plugin *get_plugin_info();
Code: Select all
* Default headers */
#include <pspkernel.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#include <malloc.h>
#include <stdarg.h>
#include <ctype.h>
#include <string>
using namespace std;
#include "plugin.h"
PSP_MODULE_INFO("PLUGIN", 0, 1, 1);
PSP_HEAP_SIZE_KB( 0 );
/* Prototypes */
static void init(void);
/* End Prototypes */
/** START of Plugin definitions setup */
Plugin table =
{
/* Populated by Plugin */
"Plugin Test", /* The description of the plugin */
init /* Called when the plugin is loaded */
};
/** END of Plugin definitions setup */
/** Single Plugin Export */
Plugin *get_plugin_info()
{
return &table;
}
static void init(void)
{
char *text;
text = new char[100];
}
#ifdef __cplusplus
extern "C" {
#endif
/** START Plugin Boilerplate -- shouldn't need to change **/
PSP_NO_CREATE_MAIN_THREAD();
int module_start(SceSize argc, void* argp)
{
return 0;
}
int module_stop(int args, void *argp)
{
return 0;
}
/** END Plugin Boilerplate -- shouldn't need to change **/
#ifdef __cplusplus
}
#endif
Code: Select all
TARGET = plugin
OBJS = plugin.o
# Define to build this as a prx (instead of a static elf)
BUILD_PRX = 1
# Define the name of our custom exports (minus the .exp extension)
PRX_EXPORTS = PluginExports.exp
CFLAGS = -G0 -mno-explicit-relocs -fno-strict-aliasing -O2 -g -Wall -DPSP
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LDFLAGS = -mno-crt0 -nostartfiles
LIBS = -lstdc++
all: exports $(TARGET).prx
exports:
psp-build-exports -s PluginExports.exp
PSPSDK = $(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
Code: Select all
# Define the exports for Plugin
PSP_BEGIN_EXPORTS
# These four lines are mandatory (although you can add other functions like module_stop)
# syslib is a psynonym for the single mandatory export.
PSP_EXPORT_START(syslib, 0, 0x8000)
PSP_EXPORT_FUNC_HASH(module_start)
PSP_EXPORT_VAR_HASH(module_info)
PSP_EXPORT_FUNC_HASH(module_stop)
PSP_EXPORT_END
# Export our function
PSP_EXPORT_START(PluginStub, 0, 0x0001)
PSP_EXPORT_FUNC_HASH(get_plugin_info)
PSP_EXPORT_END
PSP_END_EXPORTS
Code: Select all
plugin->init();
Code: Select all
text = new char[100];
I don't know a lot about prx so Maybe i'm missing something?
Hope someone can help. Thanks in advance.