El Baul del Programador


Bienvenidos al Baul del Programador,en este hilo encontraras todo lo necesario para iniciarte en la Programacion para PSP y lograr crear tus propios Programas de PSP de la manera mas facil y sencilla.El objetivo de este Hilo,es que un usuario sin ningun conocimiento en programacion,consiga crear su propio Homebrew como pueden ser el XmbFlasherGui,DeadFlasher,Recovery Translator o nuestro propio Ultra Recovery.





Antes de todo,Agradecer a Dark_Alex,Mathieulh,Harleyg,Booster,Fanjita,Team280,Team C+D, noobTeam,Ookm,xTrusion y todos los Desarrolladores, que hacen que el mundo de la scene sea posible...a todos ellos,,,!!Gracias¡¡,por todos los esfuerzos realizados en la SCENE de la PSP para que todo esto fuera posible.




Archivos Adjuntos:


1º- KIT de programación para TORPES 2
2º- Libreria Personalizada Astaroth
3º- Libreria Grafica PNG
4º- Libreria Power
5º- Main.C (Mi 1º Programa)
6º- Makefile (Mi 1º Programa)
7º- Libreria Opciones (Mi 1º Programa)
8º- Main.C (Mi 1º Programa Modificado)

Web Site Oficial






Indice


    Tema I: Preparando el PC para empezar a Programar (Entorno a usar,Pspdev,Pspsdk,etc,etc)
    Tema II: Tengo el PC Listo,¿Ahora qué? (El Main y el Make,Estructura del Codigo)
    Tema III: Las Librerias (1º Parte)
    Tema IV: Definiciones mas Comunes y Utiles (Definiciones mas Usadas en Programacion)
    Tema V: Mi Primer Homebrew para PSP (La Compilacion)
    Tema VI: Las Librerias (2º Parte)
    Tema VII: Definiciones (2º Parte)
    Tema VIII: Mi Segundo Homebrew para PSP







Tema I: Preparando el PC



Bueno Amigos,antes de comenzar a programar,lo primero que debemos tener en cuenta,es que nuestro PC este preparado para programar y compilar el software que desarrollemos.Como seguramente no este preparado el entorno,aqui os dejo como hacerlo de la manera mas rapida y sencilla.

Lo primero que debereis hacer es Descargar este Pack creado por mi,el cual incluye todo lo necesario para preparar el entorno de nuestro PC.Si quereis que todo salga a la primera,seguir las instrucciones de Instalacion al pie de la letra.

Cita:





Proceso de Instalacion


Lo primero que debemos hacer antes de nada,es cambiar las variables de entorno de nuestro PC (hablo de windows xd). Para ello seguir estos pasos.

Hay que añadir el path en windows: en MiPc con el botón derecho, Opciones avanzadas, Variables de entorno, en la varible PATH (si no existe, aunque es raro, la creas en nuevo) y añades al final ";C:/PSPDev/bin" (Sin las Comillas xd). Ahora creas dos variables nuevas,una con el nombre PSPSDK con valor "C:/PSPDev/psp/sdk" y otra con nombre PSPDEV con valor "C:/PSPDev".



Una vez tengamos las variables de entorno de windows creadas, procedemos a instalar el Pack.

    *Podéis descargar Kit de Programacion PSP para Torpes 2 pulsando un de estos links ArrowLink1,Link2

Ejecuta el pack e instalalo en la ruta que te pide, usease,C:/Pspdev (Si cambiais la letra de la unidad del disco duro, debereis cambiarla tambien en las variables de entorno)



Una vez finalize la instalacion del pack,ya esta todo listo y preparado para programar y compilar.


Proceso de Compilacion


A la hora de compilar un codigo, simplemtente debemos copiar el archivo llamado Compilador.cmd que esta en C:/Pspdev al lado de nuestro main y make. (Ver la imagen xd)



Una vez compiado el archivo Compilador.cmd al lado del main y makefile a copilar, solo debemos clickear encima de el y automaticamente saldra una ventana de ms-dos mostrando la copilacion y los archivos copilados al lado de nuestro main.

    * Recordad el archivo Compilador.cmd esta dentro de la carpeta C:/Pspdev

Y ya esta compis asi de facil, cada vez que queramos copilar un src, sea cual sea, copiamos el archivo Compilador.cmd al lado del main y make y pinchamos encima de el y voila, programa compilado y listo para usar.


Software que incluye el pack


En el pack e incluido lo siguiente:

- Pspdev Win32 + SDK
- Libreria devKitARm Revision 20 + SDK(La ultima xd)
- Librerias SDL,SDL_MIXER,JPEG,LIBpsp2d,libmikmod,PSPGL,LibbulletML,Lib Tremor,LibPng,Zlib y LibMad
- Source Codecs variados en los cuales encontraremos diversos ejemplos para nuestra iniciacion en la programacion y Src complejos como el PsarDumper330,Donwgrader 3.50,etc,etc



Ahora vamos a realizar una pequeña prueba de comprobacion del entorno que hemos instalado en nuestro PC,de este modo comprobaremos que todo este correctamente preparado para la compilacion de nuestro programa de PSP.


Realizando Prueba de Entorno


En la carpeta c:/Pspdev encontrara un archivo llamado Compilador.cmd,copie este archivo dentro de la carpeta c:/Pspdev/Source Codec PSP/PsarDump330,(podeis copiar el archivo Compilador.cmd dentro de cualquira de los src,yo he seleccionado el psardump como ejemplo simple)


Codigo PsarDump330 Antes de ser Compilado

Hidden:


Una vez copiado el archivo Compilador.cmd al lado del main y makefile a compilar,solo debemos clickear encima de el y automaticamente saldra una ventana de Ms-Dos mostrando la compilacion y los archivos compilados al lado de nuestro main.

Imagen Ventana Ms.dos

Hidden:


PsarDump330 Compilado Correctamente

Hidden:



* Recordad el archivo Compilador.cmd esta dentro de la carpeta C:/Pspdev






Tema II: ¿Ahora qué?



Bueno una vez que ya tenemos preparado el PC con el entorno adecuado para poder comenzar a compilar nuestro software,empezamos a estudiar la estructura que forma un codigo.

El Codigo o Source Codec (SRC) se divide de tres partes.

    1º - El Main.c
    - El Makefile
    - Las Librerias

Aqui os dejo una imagen,de la estructura del codigo del PsarDump,una aplicacion bastante buena de PSP.


Estructura del Codigo Original PsarDump330

Hidden:


Hablemos del Main.c.El archivo Main.c es el archivo donde escribiremos los comandos de programacion,dicese formaremos la estructura del programa mediantes definiciones en C+.
El archivo Main.c,es obligatorio en todos los Source Codecs,es el archivo principal del programa por asi decirlo. "No tiene por que llamarse Main Obligatoriamente"

El Makefile.El make es el archivo que especifica que formato de salida le damos a nuestro programa (Eboot.pbp,Prx,etc,etc),dicese,este archivo es obligatorio al igual que el Main.c,(En todo codigo de aver un Main.c y un Makefile).La funcion exacta del makefile,es definir la salida del formato del programa a ser compilado.Me explico si en el archivo make,lo configuramos para ELF,cuando compilemos el programa se creara en formato ELF,si el make lo configuramos para una salida en Eboot.pbp,cuando copilemos el archivo creado sera un Eboot.pbp.Tambien en el make se puede añadir las rutas del Icono,Fondo,Musica y tal para el Eboot


Archivo Makefile para dar salida en .ELF

Hidden:
Cita:

release: all

psp-strip MiPrograma.elf

TARGET = Mi Programa
OBJS = main.o

INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBDIR =
LIBS =
LDFLAGS =

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak




En este ejemplo del Makefile,vemos com esta preparado para Compilar el codigo en .ELF

Los archivos ELF son los PRX,solo debemos Renombralos,Ejemplo: si compilamos con este make,el archivo creado seria,MiPrograma.elf el cual renombramos como MiPrograma.prx


Archivo Makefile para dar salida en Eboot.PBP

Hidden:
Cita:

TARGET = MiPrograma
OBJS = main.o

INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS) -c

LIBDIR =
LDFLAGS =

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Mi Programa

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak




Aqui podemos observar como el Makefile esta preparado para crear el Programa en Eboot.pbp

Si quereis que al crear el Eboot,en el cual ya se incluya la imagen de Fondo e Icono,añadir estas lineas al Makefile


Lineas Adicionales para el Makefile (Solo salida en Eboot.PBP)

Hidden:
Cita:

PSP_EBOOT_ICON = ICON0.png
PSP_EBOOT_PIC1 = PIC1.png




Añadir estas lineas debajo de la linea que pone PSP_EBOOT_TITLE = MiPrograma.y cuando compileis el Eboot se incluira el Fondo e Icono del Eboot.

Bueno es muy sencillo,recordad,todo codigo lleva el Main.c que es archivo donde vamos a escribir el codigo del programa y el Makefile que es el archivo que le da el formato de salida a nuestro codigo.

* No todos los Makes sirven para todos los Main,dependiendo de las librerias que usemos,deberos usar un Makefile ó otro.


Las librerias,son archivos adicionales que llevan funciones,las librerias se usan para tener el codigo mas ordenado,me explico mejor,las librerias son llamadas por el Main.c,nosotros podemos definir funciones en una libreria y cuando el Main lo requiera la llamara para cojer el codigo que necesite.De todos modos todo sera explicado poco a poco y a su tiempo.






Tema III: Las Librerias (1º Parte)



En este apartado haremos especial incapie en las Librerias,Como hemos dicho antes las Librerias son archivos adicionales,requeridos por el Main.c,de esta manera ahorramos escribir codigo en el Main y asi tenerlo mas ordenado,limpio y depurado.


Libreria adicional para tus Proyectos

Hidden:
Cita:
     
// Libreria personalizada , by Astaroth//

#include "psppower.h"

#include < pspdisplay >
#include < pspgu >
#include < png >
#include < stdio >
#include "graphics.h"

#include < pspiofilemgr >
#include < pspdebug >
#include < pspusb >
#include < pspusbstor >
#include < pspctrl >
#include < pspumd >
#include < pspkernel >
#include < pspkerneltypes >
#include < psploadexec >
#include < pspthreadman >
#include < pspmodulemgr >
#include < string >



// ______________________________________ PSP POWER ______________________________________ //

// NOTA: Al añadir funciones encendido ay que añadir las siguientes librerias en el make: -lpsppower_2 //
// NOTA1: Aseguraros de tener estos archivos junto a esta libreria: psppower.h, libpsppower_2.a //

// Velocidad CPU //
// Ejemplo: scePowerSetClockFrequency(333, 333, 166) //
int scePowerSetCpuClockFrequency(int cpufreq);

// Porciento de Bateria //
// Ejemplo: scePowerGetBatteryLifePercent(); //
int scePowerGetBatteryLifePercent(void);


// ______________________________________ GRAFRICOS & IMAGENES PNG ______________________________________ //

// NOTA: Al añadir funciones graficas ay que añadir las siguientes librerias en el make: -lpspgu -lpng -lz -lm //
// NOTA2: Y los siguientes archivos en los objetos del make: graphics.o framebuffer.o //
// NOTA3: Aseguraros de tener estos archivos junto a esta libreria: graphics.h, graphics.c, framebuffer.h, framebuffer.c //



// Carga de la imagen //
// Ejemplo: Image* ourImage;
// ourImage = loadImage("ms0:/background.png");
extern Image* loadImage(const char* filename);



// Inicia Graficos //
// Ejemplo: initGraphics() //
extern void initGraphics();

// Desactiva los Graficos //
// Ejemplo: disableGraphics() //
extern void disableGraphics();

// Muestra la pantalla //
// Ejemplo: flipScreen() //
extern void flipScreen();

// Fallo de carga de la imagen //
// Ejemplo: if (!ourImage)
// {
// printf("Image load failed!\n");
// }

// Borra la pantalla //
// Ejemplo: sceDisplayWaitVblankStart(); //

// Imprime Imagen //
// Ejemplo: blitAlphaImageToScreen(0,0,SCREEN_WIDTH,SCREEN_HEIGHT, ourImage, 0, 0); //
extern void blitAlphaImageToScreen(int sx, int sy, int width, int height, Image* source, int dx, int dy);


// ______________________________________ WRITE IN FLASH ______________________________________ //

// Escribe un archivo desde la ms a la flash1 //
// Ejemplo: writetoflash1("ms0:/file.txt","flash1:/file.txt") //

void writetoflashone(const char *origen, const char *destino) {
char write_buffer[128*1024];
sceIoUnassign("flash1:");
sceIoAssign("flash1:", "lflash0:0,1", "flashfat1:", IOASSIGN_RDWR, NULL, 0);
int primero;
int segundo;

primero = open(origen, PSP_O_RDONLY, 0777);
if(primero <0>= 0)
{

int bytesleidos = 1;
segundo = open(destino, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
bytesleidos = read(primero, write_buffer, sizeof(write_buffer));
while((bytesleidos > 0) && (segundo >= 0))
{
write(segundo, write_buffer, bytesleidos);
bytesleidos = read(primero, write_buffer, sizeof(write_buffer));

}

if(segundo >= 0)
{
close(segundo);
}

if(primero >= 0)
{
close(primero);
}

}

}

// Escribe un archivo desde la ms a la flash0 //
// Ejemplo: writetoflash0("ms0:/file.txt","flash0:/file.txt") //

void writetoflash0(const char *origen, const char *destino) {

char write_buffer[128*1024];
sceIoUnassign("flash0:");
sceIoAssign("flash0:", "lflash0:0,0", "flashfat0:", IOASSIGN_RDWR, NULL, 0);
int primero;
int segundo;

primero = open(origen, PSP_O_RDONLY, 0777);
if(primero <0>= 0)
{

int bytesleidos = 1;
segundo = open(destino, PSP_O_WRONLY | PSP_O_CREAT | PSP_O_TRUNC, 0777);
bytesleidos = read(primero, write_buffer, sizeof(write_buffer));
while((bytesleidos > 0) && (segundo >= 0))
{
write(segundo, write_buffer, bytesleidos);
bytesleidos = read(primero, write_buffer, sizeof(write_buffer));

}

if(segundo >= 0)
{
close(segundo);
}

if(primero >= 0)
{
close(primero);
}

}

}


// ______________________________________ PSP IO FILE ______________________________________ //

#define open sceIoOpen
#define close sceIoClose
#define write sceIoWrite
#define remove sceIoRemove
#define rename sceIoRename
#define read sceIoRead
#define mkdir sceIoMkdir
#define rmdir sceIoRmdir

// Abre un archivo //
// Nueva función : open //
SceUID sceIoOpen(const char *file, int flags, SceMode mode);

// Cierra el archivo //
// Cúando abres un archivo , es muy importante después usar esta función!!...
// si no lo haces la consola se puede bloquear! //
// Nueva función : close //
int sceIoClose(SceUID fd);

// Escribe un archivo //
// Nueva función : write //
int sceIoWrite(SceUID fd, const void *data, SceSize size);

// Elimina un archivo
// Ejemplo : remove("ms0:/xxx.txt"); //
// Nueva función : remove //
int sceIoRemove(const char *file);

// Lee un archivo //
// Nueva función : read //
int sceIoRead(SceUID fd, void *data, SceSize size);

// Cambia el nombre a un archivo //
// Ejemplo : rename("ms0:/oldname.txt", "ms0:/newname.txt"); //
// Nueva Funcion : rename //
int sceIoRename(const char *oldname, const char *newname);

// Crea un nuevo directorio //
// Ejemplo : mkdir("ms0:/nuevodirectorio", 0777); //
// Nueva Funcion : mkdir //
int sceIoMkdir(const char *dir, SceMode mode);

// Elimina un directorio //
// Ejemplo : rmdir("ms0:/directorio"); //
// Nueva Funcion : rmdir //
int sceIoRmdir(const char *path);


// ______________________________________ PSP DEBUG ______________________________________ //

#define screeninit pspDebugScreenInit
#define printf pspDebugScreenPrintf
#define clearscreen pspDebugScreenClear
#define backcolor pspDebugScreenSetBackColor
#define textcolor pspDebugScreenSetTextColor
#define setxy pspDebugScreenSetXY

// Inicializa la pantalla para poder escribir en ella //
// Ejemplo : screeninit(); //
void pspDebugScreenInit(void);

// Imprime texto en pantalla
// Ejemplo : printf("Hola Mundo"); //
void pspDebugScreenPrintf(const char *fmt, ...) __attribute__((format(printf,1,2)));

// Limpia la pantalla //
// Ejemplo : clearscreen; //
void pspDebugScreenClear(void);

// Permite cambiar el color de fondo //
// Ejemplo 1 : backcolor(0xFFFF0000);
// Ejemplo 2 : backcolor(RED);
void pspDebugScreenSetBackColor(u32 color);

// Permite cambiar el color del texto //
// Ejemplo 1 : textcolor(0xFFFF0000);
// Ejemplo 2 : textcolor(GREEN);
void pspDebugScreenSetTextColor(u32 color);

// Permite específicar en coordenadas donde se mostrará el texto //
// Ejemplo: setxy(20,10); //
void pspDebugScreenSetXY(int x, int y);


// ______________________________________ PSP USB & USB STOR ______________________________________ //

// NOTA: Al añadir funciones usb ay que añadir las siguientes librerias en el make: -lpspusb -lpspusbstor //

#define USBBusDriver PSP_USBBUS_DRIVERNAME
#define USBStorDriver PSP_USBSTOR_DRIVERNAME


#define PSP_USB_ACTIVATED 0x200
#define PSP_USB_CABLE_CONNECTED 0x020
#define PSP_USB_CONNECTION_ESTABLISHED 0x002

#define startusb sceUsbStart
#define stopusb sceUsbStop
#define ausb sceUsbActivate
#define dusb sceUsbDeactivate
#define stateusb sceUsbGetState

// Inicializa el USB
// Ejemplo : startusb(USBStorDriver, 0, 0); //
// startusb(USBBusDriver, 0, 0); //
int sceUsbStart(const char* driverName, int size, void *args);

// Detiene el USB
// Ejemplo: stopusb(USBStorDriver, 0, 0); //
// stopusb(USBBusDriver, 0, 0); //
int sceUsbStop(const char* driverName, int size, void *args);

// Activa el USB
// Ejemplo : ausb(0x1c8); //
int sceUsbActivate(u32 pid);

// Desactiva el USB
// Ejemplo : dusb(0x1c8); //
int sceUsbDeactivate(u32 pid);

// Devuelve un valor y indica el estado del USB //
// Ejemplo : stateusb(); //
int sceUsbGetState(void);

// Añadir esta funcion antes de activar el usb //
void loadusb()
{
pspSdkLoadStartModule("flash0:/kd/semawm.prx", PSP_MEMORY_PARTITION_KERNEL);
pspSdkLoadStartModule("flash0:/kd/usbstor.prx", PSP_MEMORY_PARTITION_KERNEL);
pspSdkLoadStartModule("flash0:/kd/usbstormgr.prx", PSP_MEMORY_PARTITION_KERNEL);
pspSdkLoadStartModule("flash0:/kd/usbstorms.prx", PSP_MEMORY_PARTITION_KERNEL);
pspSdkLoadStartModule("flash0:/kd/usbstorboot.prx", PSP_MEMORY_PARTITION_KERNEL);
}


// ______________________________________ PSP CTRL ______________________________________ //

#define CtrlData SceCtrlData
#define CtrlCycle sceCtrlSetSamplingCycle
#define CtrlMode sceCtrlSetSamplingMode
#define digital PSP_CTRL_MODE_DIGITAL
#define analog PSP_CTRL_MODE_ANALOG
#define CtrlBuffer sceCtrlReadBufferPositive

#define cross PSP_CTRL_CROSS
#define square PSP_CTRL_SQUARE
#define circle PSP_CTRL_CIRCLE
#define triangle PSP_CTRL_TRIANGLE
#define rtrigger PSP_CTRL_RTRIGGER
#define ltrigger PSP_CTRL_LTRIGGER
#define start PSP_CTRL_START
#define select PSP_CTRL_SELECT
#define left PSP_CTRL_LEFT
#define right PSP_CTRL_RIGHT
#define down PSP_CTRL_DOWN
#define up PSP_CTRL_UP

// Ejemplo de activación de controles usando esta libreria //

// CtrlData pad;
// CtrlCycle(0);
// CtrlMode(analog);
//
// while(1){
// CtrlBuffer(&pad, 1);
// if (pad.Buttons & cross)
// {
// printf("Prueva de botones con la libreria Astaroth");
// }
// }


// ______________________________________ PSP UMD ______________________________________ //

#define aumd sceUmdActivate


// Activa el UMD
// Ejemplo : aumd(1, "disc0:");
// sceUmdWaitDriveStat(UMD_WAITFORINIT); //
int sceUmdActivate(int unit, const char *drive);


// ______________________________________ PSP KERNEL DEBUG ______________________________________ //

#define kprintf Kprintf

// Imprime el texto en modo kernel //
// Ejemplo : kprintf("Hola mundo ,imprimido en modo kernel");
// NOTA: Esta función requiere modo kernel, sino no será ejecutada ni el texto será imprimido en pantalla! //
void Kprintf(const char *format, ...) __attribute__((format(printf, 1, 2)));


// ______________________________________ PSP LOADEXEC ______________________________________ //

#define exit sceKernelExitGame
#define loadexec sceKernelLoadExec

// Finaliza el programa o el juego
// Ejemplo : exit();
void sceKernelExitGame(void);

// Ejecuta un nuevo programa //
// Ejemplo : loadexec("ms0:/eboot.pbp", NULL); //
int sceKernelLoadExec(const char *file, struct SceKernelLoadExecParam *param);


// ______________________________________ PSP THREADMAN ______________________________________ //

#define delay sceKernelDelayThread
#define exitthread sceKernelExitDeleteThread
#define screensleep sceKernelSleepThread
#define screensleepcb sceKernelSleepThreadCB


// Retardo de tiempo //
// Contador en microsegundos 1000000 = 1 seg //
// Ejemplo : delay(1*1000*1000); //
int sceKernelDelayThread(SceUInt delay);

// Pausa la pantalla
// Esta función es necesaria siempre para imprimir información en pantalla !!! //
// Ejemplo : screensleep(); //
int sceKernelSleepThread(void);

// También pausa la pantalla pero permite usar los callbacks
// Ejemplo : screensleepcb();
int sceKernelSleepThreadCB(void);


// ______________________________________ PSP MODULE MGR ______________________________________ //

#define loadmodule sceKernelLoadModule
#define loadmodulems sceKernelLoadModuleMs
#define stopmodule sceKernelStopModule
#define unloadmodule sceKernelUnloadModule

// Carga un módulo (prx,elf,pbp, etc...)
// Ejemplo : loadmodule("ms0:/mymodule.prx", 0, NULL); //
SceUID sceKernelLoadModule(const char *path, int flags, SceKernelLMOption *option);

// Carga un módulo desde la Memory Stick
// Ejemplo : loadmodulems("ms0:/mymodule.prx", 0, NULL); //
SceUID sceKernelLoadModuleMs(const char *path, int flags, SceKernelLMOption *option);

// Detiene un módulo
// Ejemplo : mymodule = stopmodule(modid, 0, NULL, &status, NULL);
int sceKernelStopModule(SceUID modid, SceSize argsize, void *argp, int *status, SceKernelSMOption *option);

// Carga un módulo ya cargado anteriormente
// Ejemplo : SceModule *mymodule;
// unloadmodule(mymodule->modid); //
int sceKernelUnloadModule(SceUID modid);


// ______________________________________ PSP SETUPCALLBACKS ______________________________________ //

// NOTA: introduce SetupCallbacks(); en la función main NOTA2: No hace falta incluir todo el código de los SetupCallbacks en tu proyecto. //

void dump_threadstatus(void);

int done = 0;

/* Exit callback */
int exit_callback(int arg1, int arg2, void *common)
{
done = 1;
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;
}


// _________ SystemCtrl.h from Custom firmware 3.0X OE-X by Dark_AleX _______________//
// NOTA: Estas funciones estan sacadas de la libreria SystemCTRL.h de Dark_AleX //
/**
* All of these functions can be accessed in both, SE-C (or later) and
* HEN-D (or later) in both, normal and devhook
*
* All of the functions can be used in both, user or kernel mode.
*/

/**
* Restart the vsh.
*
* @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL
*
* @returns < 0 on some errors.
*
*/
int sctrlKernelExitVSH(struct SceKernelLoadExecVSHParam *param);

/**
* Executes a new executable from a disc.
* It is the function used by the firmware to execute the EBOOT.BIN from a disc.
*
* @param file - The file to execute.
* @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL.
*
* @returns < 0 on some errors.
*/
int sctrlKernelLoadExecVSHDisc(const char *file, struct SceKernelLoadExecVSHParam *param);

/**
* Executes a new executable from a disc.
* It is the function used by the firmware to execute an updater from a disc.
*
* @param file - The file to execute.
* @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL.
*
* @returns < 0 on some errors.
*/
int sctrlKernelLoadExecVSHDiscUpdater(const char *file, struct SceKernelLoadExecVSHParam *param);

/**
* Executes a new executable from a memory stick.
* It is the function used by the firmware to execute an updater from a memory stick.
*
* @param file - The file to execute.
* @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL.
*
* @returns < 0 on some errors.
*/
int sctrlKernelLoadExecVSHMs1(const char *file, struct SceKernelLoadExecVSHParam *param);

/**
* Executes a new executable from a memory stick.
* It is the function used by the firmware to execute games (and homebrew Razz) from a memory stick.
*
* @param file - The file to execute.
* @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL.
*
* @returns < 0 on some errors.
*/
int sctrlKernelLoadExecVSHMs2(const char *file, struct SceKernelLoadExecVSHParam *param);

/**
* Executes a new executable from a memory stick.
* It is the function used by the firmware to execute ... ?
*
* @param file - The file to execute.
* @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL.
*
* @returns < 0 on some errors.
*/
int sctrlKernelLoadExecVSHMs3(const char *file, struct SceKernelLoadExecVSHParam *param);

/**
* Executes a new executable with the specified apitype
*
* @param apitype - The apitype
* @param file - The file to execute.
* @param param - Pointer to a ::SceKernelLoadExecVSHParam structure, or NULL.
*
* @returns < 0 on some errors.
*/
int sctrlKernelLoadExecVSHWithApitype(int apitype, const char *file, struct SceKernelLoadExecVSHParam *param);

/**
* Sets the api type
*
* @param apitype - The apitype to set
* @returns 0 on success
*
* @Note - this will modify also the value of sceKernelBootFrom, since the value of
* bootfrom is calculated from the apitype
*/
int sctrlKernelSetInitApitype(int apitype);

/**
* Sets the filename of the launched executable.
*
* @param filename - The filename to set
* @returns 0 on success
*/
int sctrlKernelSetInitFileName(char *filename);

/**
* Sets the user level of the current thread
*
* @param level - The user level
* @return the previous user level on success
*/
int sctrlKernelSetUserLevel(int level);

/**
* Sets the devkit version
*
* @param version - The devkit version to set
* @return 0 on success
*
*/
int sctrlKernelSetDevkitVersion(int version);

/**
* Checks if we are in SE.
*
* @returns 1 if we are in SE-C or later, 0 if we are in HEN-D or later,
* and < 0 (a kernel error code) in any other case
*/
int sctrlHENIsSE();

/**
* Checks if we are in Devhook.
*
* @returns 1 if we are in SE-C/HEN-D for devhook or later, 0 if we are in normal SE-C/HEN-D or later,
* and < 0 (a kernel error code) in any other case
*/
int sctrlHENIsDevhook();

/**
* Gets the HEN version
*
* @returns - The HEN version
*
* HEN D / SE-C : 0x00000400
*/
int sctrlHENGetVersion();

/**
* Finds a driver
*
* @param drvname - The name of the driver (without ":" or numbers)
*
* @returns the driver if found, NULL otherwise
*
*/
PspIoDrv *sctrlHENFindDriver(char *drvname);

/**
* Finds a function.
*
* @param modname - The module where to search the function
* @param libname - The library name
* @nid - The nid of the function
*
* @returns - The function address or 0 if not found
*
*/
u32 sctrlHENFindFunction(char *modname, char *libname, u32 nid);





Como podemos observar en la libreria arriba expuesta,la libreria contiene diverso codigo,como las funciones de flasheo,botones,bateria,etc,etc.Solo debemos escribir la funcion en el Main.c. y el se encargara de buscar el resto del codigo en las librerias,de este modo ahorramos tiempo tambien,puesto que no hay que estar definiendo completamente la funcion nuevamente.

Para incluir una libreria en la Main.c debemos escribir esto en las primeras lineas del Main.c

#include "Nombre de la Libreria a Incluir" Buscara la libreria al lado del Main.c
#include < Nombre de la Libreria a Incluir > Buscara la libreria en el sdk del Pc

bueno de momento aqui vamos a dejar el tema de las librerias,mas adelante seguiremos explicando mas,ahora es mejor ver unas definiciones y empezar a practicar.






TemaIV: Definiciones (1º Parte)



Respecto a las definiciones,vamos a ver pocas,puesto que la mejor manera de conocerlas es empezar a crear nuestro 1º Programa ya.


SceUID sceIoOpen(const char *file, int flags, SceMode mode);
Abre un archivo

int sceIoClose(SceUID fd);
Cierra el archivo

int sceIoWrite(SceUID fd, const void *data, SceSize size);
Escribe un archivo

int sceIoRemove(const char *file);
Elimina un archivo

int sceIoRead(SceUID fd, void *data, SceSize size);
Lee un archivo

int sceIoRename(const char *oldname, const char *newname);
Cambia el nombre a un archivo

int sceIoMkdir(const char *dir, SceMode mode);
Crea un nuevo directorio

int sceIoRmdir(const char *path);
Elimina un directorio

void pspDebugScreenInit(void);
Inicializa la pantalla para poder escribir en ella

void pspDebugScreenPrintf(const char *fmt, ...) __attribute__((format(printf,1,2)));
Imprime texto en pantalla

void pspDebugScreenClear(void);
Limpia la pantalla

void pspDebugScreenSetBackColor(u32 color);
Permite cambiar el color de fondo

void pspDebugScreenSetTextColor(u32 color);
Permite cambiar el color del texto

void pspDebugScreenSetXY(int x, int y);
Permite específicar en coordenadas donde se mostrará el texto

void Kprintf(const char *format, ...) __attribute__((format(printf, 1, 2)));
Imprime el texto en modo kernel

void sceKernelExitGame(void);
Finaliza el programa o el juego

int sceKernelLoadExec(const char *file, struct SceKernelLoadExecParam *param);
Ejecuta un nuevo programa

int sceKernelDelayThread(SceUInt delay);
Retardo de tiempo


* Para mas dudas y ejemplos de definiciones,mirar la libreria de Astaroth.h






Tema V: Compilando mi 1º Programa



Bien,llegado a este punto del tutorial deberiamos tener el Entorno del PC preparado para compilar cualquier programa,no vamos hacer mas incapie en definiciones y mas teoria,puesto que lo mejor para aprender es ponerse a practicar,de este modo lo entenderemos mejor todo.Por eso vamos a empezar a crear nuestro 1º Programa para PSP desde cero

* Os recuerdo que las Definiciones y Librerias espuestas anteriormente,son para crear aplicaciones en MODO USER (Validas para todos los firmwares) y en MODO KERNEL (Validas para firmwares con kernel 1.50 solamente)

Vamos a comenzar a crear nuestra primera aplicacion de PSP,la aplicacion que vamos a crear es muy simple,se trata de una aplicacion cuya funcion sera ocultar y mostrar una carpetas.Esta aplicacion la crearemos en modo user para que funcione en todos los custom firmwares.

Empezamos:

Lo primero que debemos hacer es crear una carpeta,la la podeis llamar como querais,ejemplo: "Mi Programa"

Ahora descargais la libreria Astaroth y las libreria graficas y power (Encontrareis las descargas en Archivos Adjuntos).Una vez tengamos las librerias las incluimos dentro de nuestra carpeta anteriormente creada. (ver imagen)

Preparando la Carpeta

Hidden:


Una vez tengamos la carpeta preparada con las librerias,al igual que se muestra en la imagen,creamos un nuevo txt y le llamamos MAIN.C,cambiando la extension del archivo .TXT por .C. y le metemos dentro nuestra carpeta con las librerias.

Ahora abrimos el archivo MAIN.C con el wordpad,ultraedit,etc,etc (sirve cualquier editor de texto) y escribimos en el lo siguiente:
Cita:


// Ejemplo creado por Marce82 //





#include "Astaroth.h" // Incluimos la libreria Astaroth //








PSP_MODULE_INFO("Mi Programa", 0, 1, 0); // Definimos el nombre del modulo //


PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); // Definimos el MODO de la aplicacion en este caso es MODO USER //








void menu() // Definimos nuestro Menu (Esto es un ejemplo de como crear una funcion propia) //


{


clearscreen(); // Limpia la Pantalla //





printf(" Pulse X para Ocultar la Carpeta PHOTO\n"); // Imprime texto en Pantalla //


printf(" Pulse O para Mostrar la Carpeta PHOTO\n\n"); // Imprime texto en Pantalla //


printf(" Pulse Triangulo para Salir de la Aplicacion"); // Imprime texto en Pantalla //





CtrlData pad; // Define el control del pad //





while (1) // Comenzamos la definicion de botones //


{


CtrlBuffer(&pad, 1); // Lectura del Buffer de los botones definidos anteriormente //





if (pad.Buttons & cross) // Definimos al pulsar el Boton Equis //


{


clearscreen(); // Limpia la Pantalla //


printf("Ocultando Carpeta... Espere..."); // Imprime texto en Pantalla //


rename("ms0:/PSP/PHOTO","ms0:/PSP/TOPSECRET"); // Renombra el Archivo o Carpeta //


delay(1*1000*1000); // Retardo de Tiempo (1 Segundo) //


menu(); // Regresa al menu //


}


if (pad.Buttons & circle) // Definimos al pulsar el Boton Circulo //


{


clearscreen(); // Limpia la Pantalla //


printf("Mostrando Carpeta... Espere..."); // Imprime texto en Pantalla //


rename("ms0:/PSP/TOPSECRET","ms0:/PSP/PHOTO" ); // Renombra el Archivo o Carpeta //


delay(1*1000*1000); // Retardo de Tiempo (1 Segundo) //


menu(); // Regresa al menu //


}


if (pad.Buttons & triangle) // Definimos al pulsar el Boton Triagulo //


{


clearscreen(); // Limpia la Pantalla //


printf("Saliendo... Espere..."); // Imprime texto en Pantalla //


delay(2*1000*1000); // Retardo de Tiempo (2 Segundo) //


exit(); // Sale de la Aplicacion //


}


} // Siempre que vamos a definir un comando,se abre el "{" recordad que luego ahy que cerrarlos todos "}"


}





int main() // Definimos aqui el Programa //


{


CtrlData currentPad, lastPad; // Define el control del pad //


CtrlBuffer(&lastPad, 1); // Lectura del Buffer de los botones definidos anteriormente //





screeninit(); // Inicia Pantalla para poder Escribir en ella //


menu(); // Llama a nuestra Definicion (En este caso a nuestro menu) //


}




Ahora salimos del editor de texto guardando los cambios en MAIN.C

*Este es el programa,al lado de cada funcion podeis observar un pequeño cometario explicativo,echarle un vistazo.

Ahora vamos a crear el Makefile necesario para compilar nuestro programa,para ello creamos un nuevo archivo txt y le llamamos "Makefile" (Sin extension),lo abrimos con cualquier editor de texto y escribimos lo siguiente:


Cita:

TARGET = MiPrograma
OBJS = main.o

INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)

LIBDIR =
LDFLAGS =
LIBS =

EXTRA_TARGETS = EBOOT.PBP
PSP_EBOOT_TITLE = Mi Programa de PSP

PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak


Salimos del editor de texto y guardamos,ya tenemos nuestra primera aplicacion lista para ser Compilada.(Ver imagen)

Preparado para Compilar

Hidden:


Ya esta todo listo,ahora cojemos el Compilador.bat el cual ya deberiamos conocer y lo metemos dentro de nuestra carpeta.(Ver imagen)

Compilacion

Hidden:



Ahora solo debemos clickear 2 veces encima del Compilador.bat,se mostrara una pantalla de Ms.Dos mostrando el proceso de Compilacion y Listo!!! (Ver imagen)

Compilacion Finalizada con Exito

Hidden:


Como observareis,se ha creado un Eboot.pbp en nuestra carpeta,ese es el resultado que esperabamos,ahora a testearlo.

* Es importante que cada vez que abrais una nueva funcion,nose os olvide cerrarla,hablo de las sangrias.Ejemplo:

    Void menu();

    { <- Abrimos y comenzamos a definir

    Definimos funcion

    } <- Cerramos



** La Aplicacion que hemos creado esta en Modo User,esto significa que no requiere kernel 1.50,por lo cual debera ir en PSP/GAME y no GAME150

*** Realmente para crear esta aplicacion,no hace falta las librerias,con el main.c y el makefile sobraria,pero las añado para una futura actualizacion de la aplicacion,de este modo solo ahi que modificar el main.c en un futuro






Tema VI: Las Librerias (2º Parte)


En este tema vamos aprender a crear nuestra propia libreria en la cual incluiremos la definicion de nuestras propias funciones.Para ello editaremos nuestro 1º programa,dejando el main.c mejor estructurado y depurado.

Vamos a crear nuestra propia libreria,para ello lo primero q debemos hacer es crear un nuevo archivo de texto en la carpeta de nuestro 1º Programa y le llamamos con el nombre que queramos Ej: "Opciones" y lo guardamos con extension ".H",al igual que las librerias que hemos visto en los temas anteriores.debera quedar asi Ej: "Opciones.h" (Ver imagen)

Nuestra Libreria

Hidden:


En esta libreria que vamos a crear,vamos a definir nuestras funciones para nuestro 1º Programa,el cual deberiamos aver compilado exitosamente en el tema anterior.

Abrimos nuestra libreria la cual esta vacia y comenzamos a definir.Vamos a crear 4 funciones

Empezamos a definir:

Cita:


// Libreria de opciones por Marce82 //





void TextoMenu() // Funcion de Texto //


{


clearscreen(); // Limpia la Pantalla //





printf(" Pulse X para Ocultar la Carpeta PHOTO\n"); // Imprime texto en Pantalla //


printf(" Pulse O para Mostrar la Carpeta PHOTO\n\n"); // Imprime texto en Pantalla //


printf(" Pulse Triangulo para Salir de la Aplicacion"); // Imprime texto en Pantalla //


}





void Ocultar() // Funcion ocultar //


{


clearscreen(); // Limpia la Pantalla //


printf("Ocultando Carpeta... Espere..."); // Imprime texto en Pantalla //


rename("ms0:/PSP/PHOTO","ms0:/PSP/TOPSECRET"); // Renombra el Archivo o Carpeta //


delay(1*1000*1000); // Retardo de Tiempo (1 Segundo) //


menu(); // Regresa al menu //


}





void Mostrar() // Funcion Mostrar //


{


clearscreen(); // Limpia la Pantalla //


printf("Mostrando Carpeta... Espere..."); // Imprime texto en Pantalla //


rename("ms0:/PSP/TOPSECRET","ms0:/PSP/PHOTO" ); // Renombra el Archivo o Carpeta //


delay(1*1000*1000); // Retardo de Tiempo (1 Segundo) //


menu(); // Regresa al menu //


}





void Salir() // Funcion Salir //


{


clearscreen(); // Limpia la Pantalla //


printf("Saliendo... Espere..."); // Imprime texto en Pantalla //


delay(2*1000*1000); // Retardo de Tiempo (2 Segundo) //


exit(); // Sale de la Aplicacion //


}




como podeis observar,las definiciones que antes estaban en el main.c,ahora las hemos movido a nuestra libreria,ahora tenemos q editar el MAIN.C de la siguiente manera.

Cita:


// Ejemplo creado por Marce82 //





#include "Astaroth.h" // Incluimos la libreria Astaroth //


#include "Opciones.h" // Incluimos nuestra libreria //




PSP_MODULE_INFO("Mi Programa", 0, 1, 0); // Definimos el nombre del modulo //


PSP_MAIN_THREAD_ATTR(PSP_THREAD_ATTR_USER); // Definimos el MODO de la aplicacion en este caso es MODO USER //








void menu() // Definimos nuestro Menu (Esto es un ejemplo de como crear una funcion propia) //


{


TextoMenu(); // Llamamos a nuestra funcion de texto la cual esta definida en nuestra Libreria //




CtrlData pad; // Define el control del pad //





while (1) // Comenzamos la definicion de botones //


{


CtrlBuffer(&pad, 1); // Lectura del Buffer de los botones definidos anteriormente //





if (pad.Buttons & cross) // Definimos al pulsar el Boton Equis //


{


Ocultar(); // Llamamos a nuestra funcion de Ocultar,la cual esta definida en nuestra Libreria //

}


if (pad.Buttons & circle) // Definimos al pulsar el Boton Circulo //


{


Mostrar(); // Llamamos a nuestra funcion de Mostrar,la cual esta definida en nuestra Libreria //

}


if (pad.Buttons & triangle) // Definimos al pulsar el Boton Triagulo //


{


Salir(); // Llamamos a nuestra funcion de Salir,la cual esta definida en nuestra Libreria //

}


} // Siempre que vamos a definir un comando,se abre el "{" recordad que luego ahy que cerrarlos todos "}"


}





int main() // Definimos aqui el Programa //


{


CtrlData currentPad, lastPad; // Define el control del pad //


CtrlBuffer(&lastPad, 1); // Lectura del Buffer de los botones definidos anteriormente //





screeninit(); // Inicia Pantalla para poder Escribir en ella //


menu(); // Llama a nuestra Definicion (En este caso a nuestro menu) //


}




Si comparais los codigos,observareis las diferencias,ahora el main.c esta mas depurado y limpio que antes.
Ahora solo queda volverlo a compilar y testearlo

* Dejo remarcado en Rojo los cambios realizados en el Main.c






Tema VII: Definiciones (2º Parte)


Tema en Proceso




Tema VIII: Compilando mi 2º Programa


Tema en Proceso




Glosario de Terminos C+


Tema en Proceso




El Baul del Programador by Astaroth,Arkarian & Marce82





Bueno poco a poco ire ampliando el hilo, Wink
_________________