Anuncios Google

LuaDEV, el nacimiento

Hace mucho que no escribo por aquí, y hoy por una cosa o por otra recordé cómo y por que comenzé LuaDEV. Así que, por qué no? Voy a compartir ese pedacito de mi historia con vosotros... ahi va...

Corría el año.... nah, hace algún tiempo, no recuerdo exactamente cuanto, obtuve mi negrita, la pobre de segunda mano. La compré por que ví que se podía programar tranquilamente con distintas herramientas que había, y una de mis aficiones es programar, así que dije, por que no? Conocí Lua, aprendí con el "curso" de pipagerardo, y comenzé un homebrew, yo ahi todo animado y contento... a ver... por dónde estaba... ah sí, aquí: http://psp.scenebeta.com/node/38045 .

Es un motorcillo RPG tal y cual, amos, un muñecajo moviendose en pantalla, y tal. Weno, la velocidad no era su punto fuerte, yo por aquella época scripteaba en HM. Conseguí reorganizar todo para que anduviera a altas velocidades.... (weno, las que permite...) y... eeeeei, esto va por buen camino señores!

Mentira. Aquello no iba por buen camino ni mucho menos. Podréis comprobar en esa versión, ( si aún existiera por la red ), que tras moverse por los escenarios repetidas vecessss tu ahi to felizz, moviento tu personaje cutre... ouch! Al XMB. Te quedas... ¿?

Nada! Repetimos!
... XMB
Sh*t.
Otra...
... XMB.

Vale, what happens? (<- Esa pregunta sigo haciendomela hoy día, no crean...)

Pues yo ahi to contento de la vida, cabezón como ninguno, quería mi motor de RPG's, para hacer mis RPG's... Lua HM no cumplía mis requisitos, y por aquellos tiempos no conocía PGE, así que... me decidí a hacerlo en C!

Esto, lo entenderéis los que hayais programado un juego o aplicación en C...

Hace un dia soleado, te levantas, te pones a escribir...
... pasan las horas... sigues en tu interminable mundo de código...
... una pausa para comer siempre viene bien...
... un ratito más y merendamos va...
... va, sólo hasta la cena, luego descanso...
... uf, va, hasta que acabé... EL MENU.
Sh*t (2).

Bien, programar en C no era mi solución, me podría haber tirado largas semanas, para reproducir con exactitud lo que en LUA había conseguido en tan sólo unos ratos libres. Por aquellos momentos se me vino otra idea a la cabeza, estúpido de mí...
Y si hago un luaplayer para hacer el juego? <- Yo aquí con ansias de re-programación, hacer un luaplayer, para usarlo en un juego... en qué estaría yo pensando...

Desde entonces, y hasta el día de hoy, sigue el desarrollo de LuaDEV [Lua, for Developers] (And from Developers xD)

 


 

Hoy día, tenéis dónde elegir, Lua PGE, HM, LuaDEV...

Me veréis pregonando a diestro y siniestro, pero si LuaDEV es más rápido, pero si es más eficiente... Amos... que corre mas! (Jiaj), pues... Sí, a día de hoy sigo diciendolo a los cuatro vientos con total tranquilidad.

Aunque... hoy estaba en pleno desarrollo de un nuevo módulo para LuaDEV, el modulo savedata. Me permitirá utilizar los savedatas a placer, guardar, cargar, borrar, y esta vez, la configuración es total. Pues puesto en ello, me pasó un flash por la cabeza.... -oye dev... (sí, me hablo en tercera persona, y usando mi nick... ¬¬) -... y si le das una miradita a los sources de la competencia? Total, es competencia sana... muchos ya se retiraron... Bueno oye, por qué no? Voy a compartir con vosotros mi opinión global sobre los sources de la competencia, pero no todo el source, como hoy estaba trabajando en savedatas, pues miremos esta parte!

 


 

Revisión del código fuente de PGE (Phoenix Game Engine)

/* 
 Extracto del código fuente de pgeUtils.c
 http://svn.luaplayer.org/pge/pgeUtils.c
*/
 
static char pgeUtilsSavedataSaveName[20] = "0000";
SceUtilitySavedataParam pgeUtilsSavedataParams;
static void *pgeUtilsSaveDataData = NULL;
typedef struct
{
	char signature[4];
	int version;
	int offset[8];
 
} pgeUtilsEbootHeader;
 
char pgeUtilsSaveNameMultiple[][20] =
{
	"0000",
	"0001",
	"0002",
	"0003",
	"0004",
	""
};
 
/* Vale, por lo que puedo comprobar hasta aquí, es
que PGE nos deja hasta 5 espacios de guardado,
compartiendo el espacio "0000" con el autosave, como
veremos más adelante ... */
 
int pgeUtilsSavedataInit(int type, void *data, unsigned int datasize, const char *gamename, const char *key, const char *title, const char *subtitle, const char *detail) {
	pgeUtilsSaveDataData = data;
	PspUtilitySavedataListSaveNewData newData;
	memset(&newData, 0, sizeof(newData));
	memset(&pgeUtilsSavedataParams, 0, sizeof(pgeUtilsSavedataParams));
	pgeUtilsSavedataParams.base.size = sizeof(pgeUtilsSavedataParams);
	void *icon0data = NULL;
	int icon0datasize = 0;
	void *pic1data = NULL;
	int pic1datasize = 0;
	void *snd0data = NULL;
	int snd0datasize = 0;
	char *titleshow = "New Save";
 
	sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, &pgeUtilsSavedataParams.base.language);
	sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &pgeUtilsSavedataParams.base.buttonSwap);
	pgeUtilsSavedataParams.base.graphicsThread = 17;
	pgeUtilsSavedataParams.base.accessThread = 19;
	pgeUtilsSavedataParams.base.fontThread = 18;
	pgeUtilsSavedataParams.base.soundThread = 16;
	pgeUtilsSavedataParams.mode = type;
	pgeUtilsSavedataParams.overwrite = 1;
 
/* Inicializa las estructuras correctamente, bueno, me molesta que "New Save" sea en inglés y constante,
así como el overwrite activado por defecto... pero son minucias soportables */	
 
	if(type == PGE_UTILS_SAVEDATA_TYPE_LISTLOAD)
	{
		pgeUtilsSavedataParams.focus = PSP_UTILITY_SAVEDATA_FOCUS_LATEST;
	}
	else
	{
		pgeUtilsSavedataParams.focus = PSP_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY;
	}
 
	strncpy(pgeUtilsSavedataParams.key, key, 16);
	strncpy(pgeUtilsSavedataParams.gameName, gamename, 9);
	strcpy(pgeUtilsSavedataParams.saveName, "<>");
 
	if(type == PGE_UTILS_SAVEDATA_TYPE_AUTOLOAD || type == PGE_UTILS_SAVEDATA_TYPE_AUTOSAVE)
	{
		strcpy(pgeUtilsSavedataParams.saveName, pgeUtilsSavedataSaveName);
	}
	else
	{
		pgeUtilsSavedataParams.saveNameList = pgeUtilsSaveNameMultiple;
	}
 
	strcpy(pgeUtilsSavedataParams.fileName, "DATA.BIN");
 
/* 
	Hasta aquí todo correcto, bueno, para lo que ha sido diseñado claro.
	Un archivo estático, DATA.BIN, 5 ranuras de guardado, una con el autosave...
	Sigamos, esto tiene buena pinta!
*/
 
	pgeUtilsSavedataParams.dataBuf = pgeMalloc(datasize);
	pgeUtilsSavedataParams.dataBufSize = datasize;
	pgeUtilsSavedataParams.dataSize = datasize;
 
	if(type == PGE_UTILS_SAVEDATA_TYPE_AUTOSAVE || type == PGE_UTILS_SAVEDATA_TYPE_LISTSAVE)
	{
		memset(pgeUtilsSavedataParams.dataBuf, 0, datasize);
		strncpy(pgeUtilsSavedataParams.dataBuf, data, datasize);
 
		strcpy(pgeUtilsSavedataParams.sfoParam.title, title);
		strcpy(pgeUtilsSavedataParams.sfoParam.savedataTitle, subtitle);
		strcpy(pgeUtilsSavedataParams.sfoParam.detail, detail);
		pgeUtilsSavedataParams.sfoParam.parentalLevel = 0;
 
		if(type != PGE_UTILS_SAVEDATA_TYPE_AUTOSAVE)
		{
			pgeUtilsEbootHeader ebootpgeUtilsEbootHeader;
 
			int fd;
			int ebootlength;
			int filesize;
 
			fd = sceIoOpen("EBOOT.PBP", PSP_O_RDONLY, 0777);
 
			ebootlength = sceIoLseek32(fd, 0, PSP_SEEK_END);
 
			sceIoLseek32(fd, 0, PSP_SEEK_SET);
 
			sceIoRead(fd, &ebootpgeUtilsEbootHeader, sizeof(ebootpgeUtilsEbootHeader));
 
			filesize = ebootpgeUtilsEbootHeader.offset[1 + 1] - ebootpgeUtilsEbootHeader.offset[1];
 
			if(filesize > 0)
			{
				sceIoLseek32(fd, ebootpgeUtilsEbootHeader.offset[1], PSP_SEEK_SET);
				icon0data = pgeMalloc(filesize);
				sceIoRead(fd, icon0data, filesize);
				icon0datasize = filesize;
			}
 
			filesize = ebootpgeUtilsEbootHeader.offset[4 + 1] - ebootpgeUtilsEbootHeader.offset[4];
 
			if(filesize > 0)
			{
				sceIoLseek32(fd, ebootpgeUtilsEbootHeader.offset[4], PSP_SEEK_SET);
				pic1data = pgeMalloc(filesize);
				sceIoRead(fd, pic1data, filesize);
				pic1datasize = filesize;
			}
 
			filesize = ebootpgeUtilsEbootHeader.offset[5 + 1] - ebootpgeUtilsEbootHeader.offset[5];
 
			if(filesize > 0)
			{
				sceIoLseek32(fd, ebootpgeUtilsEbootHeader.offset[5], PSP_SEEK_SET);
				snd0data = pgeMalloc(filesize);
				sceIoRead(fd, snd0data, filesize);
				snd0datasize = filesize;
			}
 
			sceIoClose(fd);
		}
 
/* Genial, extrae PIC1,ICON0 y SND0 del EBOOT, y queda registrado en los saves,
   con esto, los saves tendrán la estética del homebrew final, muy cuidado. */
 
		pgeUtilsSavedataParams.icon1FileData.buf = NULL;
		pgeUtilsSavedataParams.icon1FileData.bufSize = 0;
		pgeUtilsSavedataParams.icon1FileData.size = 0;
 
		pgeUtilsSavedataParams.pic1FileData.buf = pic1data;
		pgeUtilsSavedataParams.pic1FileData.bufSize = pic1datasize;
		pgeUtilsSavedataParams.pic1FileData.size = pic1datasize;
 
		pgeUtilsSavedataParams.icon0FileData.buf = icon0data;
		pgeUtilsSavedataParams.icon0FileData.bufSize = icon0datasize;
		pgeUtilsSavedataParams.icon0FileData.size = icon0datasize;
 
		pgeUtilsSavedataParams.snd0FileData.buf = snd0data;
		pgeUtilsSavedataParams.snd0FileData.bufSize = snd0datasize;
		pgeUtilsSavedataParams.snd0FileData.size = snd0datasize;
 
		// Set title
		newData.title = titleshow;
 
		// Set new data
		pgeUtilsSavedataParams.newData = &newData;
	}
 
	int result = sceUtilitySavedataInitStart(&pgeUtilsSavedataParams);
 
	if(result == 0)
		return 1;
 
	return result;
}

Opinión personal, valoración: Notable. Si, este luaplayer, en este aspecto, se gana mi aprobado. Además, tiene separadas las funciones de inicialización y update, con lo que podremos ejecutar código mientras realizamos el save, hasta creo que se puede pintar debajo y encima, interesante. Ampliamente configurable, un buen trabajo. Lástima que no se puedan utilizar pic's y icon's y demás personalizables por save, pero oye, es lua...

 


 

Revisión del código fuente de Lua HM (Da igual la versión, los varios sources que he encontrado, todos tienen el mismo código en este apartado)

Nota: Así como del source del PGE he recortado lo que sobraba, éste no tiene desperdicio, así que viene entero, (no quería ser malo, pero... puFFF es que esto no hay por dónde cogerlo)

/*
	savedata.c, Source luaplayer HM,
	extraída de qj.net
*/
 
/*
 * PSP Software Development Kit - http://www.pspdev.org
 * -----------------------------------------------------------------------
 * Licensed under the BSD license, see LICENSE in PSPSDK root for details.
 *
 * main.c - Sample to demonstrate how to use savedata utility
 *
 * Copyright (c) 2005 weltall (weltall [at] consoleworld [dot] org)
 *			 (c) 2007 InsertWittyName (tias_dp [at] hotmail [dot] com)
 * Based on work by Shine
 *
 * $Id: main.c 2364 2008-02-16 22:07:09Z iwn $
 */
 
 /* Ehm, espera, lo que acabo de leer está bien? Me estás diciendo que esto ES
 el sample del sdk? Bueno, veremos ese tal "main" k pone ahi... sigamos leyendo */
 
#include <pspkernel.h>
#include <pspdisplay.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <pspmoduleinfo.h>
#include <pspdebug.h>
#include <pspgu.h>
#include <pspgum.h>
#include <psputility.h>
#include <pspctrl.h>
 
#include "data.h"
 
#define BUF_WIDTH (512)
#define SCR_WIDTH (480)
#define SCR_HEIGHT (272)
#define PIXEL_SIZE (4) /* change this if you change to another screenmode */
#define FRAME_SIZE (BUF_WIDTH * SCR_HEIGHT * PIXEL_SIZE)
#define ZBUF_SIZE (BUF_WIDTH SCR_HEIGHT * 2) /* zbuffer seems to be 16-bit? */
 
/* Ehm, que tendrá que ver los gráficos con los saves... */
 
#define DATABUFFLEN   0x20
 
/* Buffer len 0x20... Ah pera, 32 carácteres ok... para qué lo usará?... */
 
char* svdataret;
static int running = 1;
char string[128];
PspUtilitySavedataListSaveNewData newData;
char *titleShow = "New Save";
char nameMultiple[][20] =	// End list with ""
{
 "0000",
 "0001",
 "0002",
 "0003",
 "0004",
 ""
};
 
/* Bien, usando las mismas ranuras que PGE, de momento aceptamos el code */
 
PspGeContext __attribute__((aligned(16))) geContext4;
char key[] = "LuaPlayerHMRULES";	// Key to encrypt or decrypt savedata
 
/* Espera.. y esa key? y ese contexto... el cuarto por lo que veo.
 Una key estática que permitirá copiar los saves de una psp a otra, pueden
 ser ventajas o desventajas, pero esta key debería ser única de cada psp... */
 
void initSavedata(SceUtilitySavedataParam * savedata, int mode, char *TITLE1, char *TITLE2, char *DETAILS , char* SVDATA)
{
	memset(savedata, 0, sizeof(SceUtilitySavedataParam));
	savedata->base.size = sizeof(SceUtilitySavedataParam);
 
	savedata->base.language = PSP_SYSTEMPARAM_LANGUAGE_ENGLISH;
	savedata->base.buttonSwap = PSP_UTILITY_ACCEPT_CROSS;
	savedata->base.graphicsThread = 0x11;
	savedata->base.accessThread = 0x13;
	savedata->base.fontThread = 0x12;
	savedata->base.soundThread = 0x10;
 
/* 
 Bien, el dialogo, te lo comes en ingles, no en el idioma de la consola,
 y el boton de aceptar siempre será cruz, (lo siento japos, hm no piensa en vosotros!)
*/
 
	if (mode == PSP_UTILITY_SAVEDATA_LISTSAVE)
	{
	savedata->mode = PSP_UTILITY_SAVEDATA_LISTSAVE; //mode;
	}
	if (mode == PSP_UTILITY_SAVEDATA_LISTLOAD)
	{
	savedata->mode = PSP_UTILITY_SAVEDATA_LISTLOAD; //mode;
	}
 
/*
	La verdad, esto de aqui arriba yo lo hubiera solucionado con un...
	savedata->mode = mode; quizás?
*/
 
	savedata->overwrite = 1;
	savedata->focus = PSP_UTILITY_SAVEDATA_FOCUS_LATEST; // Set initial focus to the newest file (for loading)
 
#if _PSP_FW_VERSION >= 200
	strncpy(savedata->key, key, 16);
#endif
 
	strcpy(savedata->gameName, "DEMO11111");	// First part of the save name, game identifier name
	strcpy(savedata->saveName, "0000");	// Second part of the save name, save identifier name
 
/* 
	Ah no espera, la GAME ID es "DEMO1111" ???
	y el savename por defecto 0000, bueno, esto nos sigue dejando
	con el problema de las 5 ranuras que teniamos con PGE, pero al menos
	en PGE podiamos cambiar la GAMEID, y aunque crearamos mas carpetas, podriamos
	tener tantos saves como quisieramos, en HM, al tener esto estático,
	lo siento amigos, 5 saves para cualquier homebrew de HM.
	Pero.. atencion, mismo GAMEID implica que si yo hago un homebrew, y guardo algo
	y otra persona hace otro homebrew distinto, y guarda OTRA cosa, el podrá cargar la partida
	creada con mi juego, que le dará error pq no sabe que he guardado yo, y incluso podrá
	sobreescribir mis partidas, pq todas tienen el mismo juego de base...
 
	... grande hm, grande.
*/
 
	// List of multiple names
	savedata->saveNameList = nameMultiple;
	strcpy(savedata->fileName, "DATA.BIN");	// name of the data file
 
	// Allocate buffers used to store various parts of the save data
	savedata->dataBuf = malloc(DATABUFFLEN);
	savedata->dataBufSize = DATABUFFLEN;
	savedata->dataSize = DATABUFFLEN;
 
	// Set some data
	if (mode == PSP_UTILITY_SAVEDATA_LISTSAVE)
	{
	 memset(savedata->dataBuf, 0, DATABUFFLEN);
	 strcpy((char*)savedata->dataBuf, SVDATA);
 
	strcpy(savedata->sfoParam.title,TITLE1);
	strcpy(savedata->sfoParam.savedataTitle,TITLE2);
	strcpy(savedata->sfoParam.detail,DETAILS);
	savedata->sfoParam.parentalLevel = 1;
 
	// No icon1
	savedata->icon1FileData.buf = NULL;
	savedata->icon1FileData.bufSize = 0;
	savedata->icon1FileData.size = 0;
 
	savedata->pic1FileData.buf = pic1;
	savedata->pic1FileData.bufSize = size_pic1;
	savedata->pic1FileData.size = size_pic1;
 
	savedata->icon0FileData.buf = icon0;
	savedata->icon0FileData.bufSize = size_icon0;
	savedata->icon0FileData.size = size_icon0;
 
	// No snd0
	savedata->snd0FileData.buf = NULL;
	savedata->snd0FileData.bufSize = 0;
	savedata->snd0FileData.size = 0;
 
/* Por lo que veo seteas igual que PGE los icons, amos, clavao...
 empiezo a dudar si esto no es un remix sample-pge, pero con constantes,
 al menos se podría haber mejorado, copiar para empeorar no es copiar,
 eso debería ser antimoral xD
 
 P.D: no veo donde setea icon0, pic1 y resto de la prole, de donde saca
 las imagenes?
 */
 
	// Set title
	newData.title = titleShow;
 
	// Set new data
	savedata->newData = &newData;
 
	savedata->focus = PSP_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY; // If saving, set inital focus to the first empty slot
	}
}
 
 
 
/* Aqui para actualizar el dialogo, veamos... */
static void ShowSaveDialog (int mode, char *TITLE1, char *TITLE2, char *DETAILS, char* SVDATA)
{
	clearScreen(0);
	flipScreen();
	clearScreen(0);
	flipScreen();   /* no habia suficiente con perder un frame? */
	sceGeSaveContext(&geContext4); /* ahi ahi, gastando ram.. xD */
	SceUtilitySavedataParam dialog;
    initSavedata(&dialog, mode, TITLE1, TITLE2, DETAILS, SVDATA);
    sceUtilitySavedataInitStart(&dialog);
    while(running) { /* bucle cerrado.. */
	clearScreen(0);	/* clear? vale, ni pintar debajo, ni pintar encima... */
	switch(sceUtilitySavedataGetStatus()) {
	case PSP_UTILITY_DIALOG_VISIBLE :
	    sceUtilitySavedataUpdate(1);
	    break;
	case PSP_UTILITY_DIALOG_QUIT :
	    sceUtilitySavedataShutdownStart();
	    break;
	case PSP_UTILITY_DIALOG_FINISHED :
	    sceUtilitySavedataShutdownStart();
	    break;
	case PSP_UTILITY_DIALOG_NONE :
	    return;
	}
	sceDisplayWaitVblankStart(); /* <- el ralentizador por excelencia! */
	flipScreen();
    }
	sceDisplayWaitVblankStart(); /* repetimos multiples clears varios para perder el tiempo, ok? */
	clearScreen(0);
	flipScreen();
	clearScreen(0);
	flipScreen();				/* Ya me kedao a gusto.. xD */
	sceGuFinish();
	sceGuSync(0, 0);			
	sceGeRestoreContext(&geContext4);	
	int err;
	err = sceUtilitySavedataGetStatus();
	while(err != 4){				/* <- espero que no le de por colgarse... */
		err = sceUtilitySavedataGetStatus();
		sceUtilitySavedataShutdownStart();
	}
}
 
/* continua para abajo... pero es mas de lo mismo... */

Nah, mejor pongo lo que falta...

void ShowSaveDialogload (int mode, char *string )
{
	clearScreen(0);
	flipScreen();
	clearScreen(0);
	flipScreen();
	sceGeSaveContext(&geContext4);
 
	SceUtilitySavedataParam dialog;
 
    initSavedata(&dialog, mode, "NULL", "NULL", "NULL", "NULL");
 
    sceUtilitySavedataInitStart(&dialog);
 
    while(running) {
 
	clearScreen(0);
 
	switch(sceUtilitySavedataGetStatus()) {
 
	case PSP_UTILITY_DIALOG_VISIBLE :
 
	    sceUtilitySavedataUpdate(1);
	    break;
 
	case PSP_UTILITY_DIALOG_QUIT :
 
	    sceUtilitySavedataShutdownStart();
	    break;
 
	case PSP_UTILITY_DIALOG_FINISHED :
	string = ((char*)dialog.dataBuf); // The actual data in the savedata file that was saved previouslyg
	    sceUtilitySavedataShutdownStart();
	    break;
 
	case PSP_UTILITY_DIALOG_NONE :
	    return;
	}
 
	sceDisplayWaitVblankStart();
	flipScreen();
    }
	sceDisplayWaitVblankStart();
	clearScreen(0);
	flipScreen();
	clearScreen(0);
	flipScreen();
	sceGuFinish();
	sceGuSync(0, 0);
	sceGeRestoreContext(&geContext4);
	int err;
	err = sceUtilitySavedataGetStatus();
	while(err != 4){
		err = sceUtilitySavedataGetStatus();
		sceUtilitySavedataShutdownStart();
	}
}

Opinión personal, valoración: Ehm, no puedo. Colisión de nombres en los saves, y lo más divertido, un búffer de 0x20, es decir 32 bytes... si quiero guardar más de 32 letras, no puedo. Es más, si guardo más de 32 letras al cargarlo obtendré un bonito volcado de ram, que nada tiene que ver con lo que previamente guardé, directamente hace un string = ((char*)dialog.dataBuf); pero las cadenas de carácteres terminan en carácter nulo \0, pero si lo que yo guardé antes, es mayor a 32 letras, ese caracter nulo me lo comeré, y cosas bonitas y preciosas ocurrirán a nuestra consola. Nota final, suspendido con honores. xD


Revisión de LuaDEV:

/*************************************************
            MODULO         SAVEDATA
**************************************************/
 
/* 
GCREW CONFIDENTIAL, pero os dejo echar un vistazo a un trozo
del código va...
 */
 
#include "msavedata.h"								/* Este módulo */
#include "mimage.h"									/* Módulo de las imágenes */
#include "mpbp.h"									/* Módulo de los eboots */
 
static SceUtilitySavedataParam SavedataParams;		/* Config del diálogo */
static void *SaveDataData = NULL;					/* Puntero a los datos */
static int SaveDataDataSize = 0;					/* Longitud de los datos */
static PspUtilitySavedataListSaveNewData newData;	/* Formato nuevo save */
static char SavedataSaveName[20] = "0000";			/* Nombre del save */
char *SavedataTitle = NULL;							/* Aparece mientras guardas */
char *SavedataMultipleList = NULL;					/* Varios nombres */
 
 
/* Clave de encriptación propia: */
void getpspidentifier(char *psid) { 
	PspOpenPSID thepsid; 
	sceOpenPSIDGetOpenPSID(&thepsid); 
	memcpy(psid, &thepsid, 16);
}
 
/* 
 Posible configuración de cada save.
 Dentro de cada carpeta, puede haber 
 distintos archivos, savename puede
 ser numeros o letras:
 
    - CARPETA: "GAMEID"+"SAVENAME"
	- ARCHIVO: "FILENAME"
 
 Gracias a esta config, podemos mantener
 perfiles distintos, configuraciones,
 o lo que sea, agrupado, o separado.
Infinidad de combinaciones, ranuras, saves...
*/
 
 
/* Si, aquí me pasé con las variables, pero paso de hacer mil funciones */
int savedata_init_struct(int type, int overwrite, void *data, unsigned int datasize, char *savelist, int numlist, char *icon0, char *savetext, char *vshtitle, char *vshsubtitle, char *vshdetails, char *vshpic, char *vshicon0, char *vshsnd0, char *vshicon1, char *gameid, char *filename) {
/*	
	Parámetros:
	< vshtitle, vshsubtitle, vshdetails, vshpic1, vshicon0, vshsnd0, vshicon1 >,
	< gameid , savelist, numlist , filename >,
	< mode, icon0, savetext > 												
*/
	/* Unas variables.. */
	char psid[16];
	void *icon1data = NULL;
	int icon1datasize = 0;
	void *icon0data = NULL;
	int icon0datasize = 0;
	void *pic1data = NULL;
	int pic1datasize = 0;
	void *snd0data = NULL;
	int snd0datasize = 0;
	void *sicon0data = NULL;
	int sicon0datasize = 0;
 
	/* Resetear estructuras */
	SaveDataData = data;
	SaveDataDataSize = datasize;
	memset(&newData, 0, sizeof(newData));
	memset(&SavedataParams, 0, sizeof(SavedataParams));
	SavedataParams.base.size = sizeof(SceUtilitySavedataParam);	
 
	/* Inicializar diálogo */
	sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_LANGUAGE, &SavedataParams.base.language);
	sceUtilityGetSystemParamInt(PSP_SYSTEMPARAM_ID_INT_UNKNOWN, &SavedataParams.base.buttonSwap);
	SavedataParams.base.soundThread 	= 0x10;
	SavedataParams.base.graphicsThread 	= 0x11;
	SavedataParams.base.fontThread 		= 0x12;
	SavedataParams.base.accessThread 	= 0x13;
	SavedataParams.mode 				= type;
	SavedataParams.overwrite 			= 1;
 
	/* Focus */
	if(type == 0 || type == 2 || type == 4 ) { SavedataParams.focus = PSP_UTILITY_SAVEDATA_FOCUS_LATEST; }
	else { SavedataParams.focus = PSP_UTILITY_SAVEDATA_FOCUS_FIRSTEMPTY; }
 
	getpspidentifier(psid);	strncpy(SavedataParams.key,psid,0x10);
	strncpy(SavedataParams.gameName,gameid,0x09);
	strncpy(SavedataParams.fileName,filename,);
 
	/* Lista de archivos, o archivo */
	strcpy(SavedataParams.saveName, "NONAME");
	if (numlist < 2) { 
		strncpy(SavedataParams.saveName,savelist,0x14);
		SavedataMultipleList = NULL;
	}
	else {
		int i;
		SavedataMultipleList = malloc(sizeof(char) * 20 * numlist);
		for (i=0;i<numlist;i++) strncpy(SavedataMultipleList[i*20],savelist[i*20],0x14);
		strncpy(SavedataParams.saveName,SavedataMultipleList,0x14);
	}
	SavedataParams.saveNameList = SavedataMultipleList;
 
	/* Buffer de datos */
	SavedataParams.dataBuf = malloc(datasize);
	memset(SavedataParams.dataBuf,0,datasize);
	SavedataParams.dataBufSize = datasize;
	SavedataParams.dataSize = datasize;
 
	/* Guardar partida */
	if(type == 1  || type == 3 || type == 5 ) {
		int fsize = 0;
		PBPHEADER *cabecera = (PBPHEADER *)filetoarray("EBOOT.PBP",0,sizeof(PBPHEADER));
		//filetostruct(const char* fpath, void * pointer, SceSize offset, SceSize len) 
		strncpy(SavedataParams.dataBuf, data, datasize);
		strncat(SavedataParams.sfoParam.title,vshtitle,0x80);
		strncat(SavedataParams.sfoParam.savedataTitle,vshsubtitle,0x80);
		strncat(SavedataParams.sfoParam.detail,vshdetails,0x400);
		SavedataParams.sfoParam.parentalLevel = 1;
		/* LEER ICON0 */
		if (vshicon0 == NULL) {
			fsize = cabecera->icon1 - cabecera->icon0;
			if (fsize > 0) { 
				icon0data = (void *)filetoarray("EBOOT.PBP",cabecera->icon0,fsize); 
				icon0datasize = fsize;
			}
		} else { 
			icon0datasize = filesize(vshicon0);
			icon0data = (void *)filetoarray(vshicon0,0,icon0datasize);
		}
		/* LEER ICON1 */
		if (vshicon1 == NULL) {
			fsize = cabecera->apic - cabecera->icon1;
			if (fsize > 0) { 
				icon1data = (void *)filetoarray("EBOOT.PBP",cabecera->icon1,fsize);
				icon1datasize = fsize;
			}
		} else {
			icon1datasize = filesize(vshicon1);
			icon1data = (void *)filetoarray(vshicon1,0,icon1datasize);
		}
		/* LEER PIC1 */
		if (vshpic == NULL) {
			fsize = cabecera->sound - cabecera->background;
			if (fsize > 0) { 
				pic1data = (void *)filetoarray("EBOOT.PBP",cabecera->background,fsize);
				pic1datasize = fsize;
			}
		} else {
			pic1datasize = filesize(vshpic);
			pic1data = (void *)filetoarray(vshpic,0,pic1datasize);
		}
		/* LEER SND0 */
		if (vshsnd0 == NULL) {
			fsize = cabecera->datapsp - cabecera->sound;
			if (fsize > 0) { 
				snd0data = (void *)filetoarray("EBOOT.PBP",cabecera->sound,fsize);
				snd0datasize = fsize;
			}
		} else {
			snd0datasize = filesize(vshsnd0);
			snd0data = (void *)filetoarray(vshsnd0,0,snd0datasize);
		}
 
		/* ICONS, PICS */
		SavedataParams.icon1FileData.buf = icon1data;
		SavedataParams.icon1FileData.bufSize = icon1datasize;
		SavedataParams.icon1FileData.size = icon1datasize;
 
		SavedataParams.pic1FileData.buf = pic1data;
		SavedataParams.pic1FileData.bufSize = pic1datasize;
		SavedataParams.pic1FileData.size = pic1datasize;
 
		SavedataParams.icon0FileData.buf = icon0data;
		SavedataParams.icon0FileData.bufSize = icon0datasize;
		SavedataParams.icon0FileData.size = icon0datasize;
 
		SavedataParams.snd0FileData.buf = snd0data;
		SavedataParams.snd0FileData.bufSize = snd0datasize;
		SavedataParams.snd0FileData.size = snd0datasize;
 
		/* Extra icon, solo para diálogo saves */
		if (icon0 != NULL) {
			newData.icon0.bufSize = filesize(icon0);
			newData.icon0.size = newData.icon0.bufSize;
			newData.icon0.buf = (void *)filetoarray(icon0,0,newData.icon0.size);
		}
		SavedataTitle = strdup(savetext);
		newData.title = SavedataTitle;
		SavedataParams.newData = &newData;	
	}	
	return sceUtilitySavedataInitStart(&SavedataParams);
};
 
 
/* Ara falta aqui abajo, para mostrar el diálogo. */

Bien, no me voy a puntuar, pero es configurable al 200%, incluso los icon0 de la pantalla de guardando y el save final pueden ser distintos, y incluso distintos a los del eboot. Podremos pintar debajo y encima, e incluso cancelar el diálogo por código (esto lo estoy introduciendo ahora, que se puedan cancelar los diálogos por código, ya lo verán en próximas documentaciones...


Ahi les dejo las tres revisiones, y el nacimiento de esta pequeña bestia, próximamente multiplataforma... Así que, con sources en mano, juzguen ustedes.

Un saludo y hasta mi próxima entrada de aquí tiempo...

      DeV


Actualmente desarrollando nuestra web y UXCode : http://www.gcrew.es

4.77778
Tu voto: Ninguno Votos totales: 4.8 (9 votos)

Anuncios Google

Comentarios

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.
Imagen de ANI-KIBA

Como no recordar

el Motor RPG... gracias a el, me puse a experimentar, y a aprender LuaDEV (Aparte de que todos me lo recomendaban =).

Saludos!

Imagen de NauTiluS1

Multiplataforma? así qué no

Multiplataforma? así qué no tengo que estudiar typhon?

Imagen de Chimecho

jajajja

pues... está naciendo otra pequeña bestia en la nintendo wii :)

Imagen de ANI-KIBA

Wii,

=D, otra pequeña gran bestia en PS3 :).

Saludos!

Imagen de klozz

La verdad que me eh quedado

La verdad que me eh quedado voquiabierto y bueno solo puedo decir que eres muy bueno ;) eh usado LuaDev y la verdad es muy estable veloz y bueno :3 sigue asi con el luadev :3 mis felicitaciones

saludos Deviante


TEAM MEX Homebrew y desarrollo PSP

Metal TrooperV.Pre-Alpha (15%)Lua , 10% C .

Ubunshell VProof. (45%)C

RPG Magues (35%)Lua , 5% C


Android development for Xperia X8 ^^ mis roms en XDA-Developers ya que en Scenebeta no las publican xD

Xperience  | MIUI Pikachu | Semc debrand engine | Froyexp | Xperience walkman mod | Android 4.0.4 CN9 Crema de nieve

-- KLOZZ

Imagen de Chimecho

:D

jajajjaja me he reído con varias cosas que he leído, vaya, me alegro de estar en GCrew, y de tener un colega como tú, además de ser mi mentor ;)

Ya me imagino yo, en un futuro escribiendo sobre el nacimiento de LD4W jeje

Nada más, felicitaciones bro, gracias por este proyecto, gracias por ser mi mentor (see, molesto bastante xD) y gracias por aceptarme en GCrew ^^,

Saludos!



PSP FAT [5.00 M33-6] [6.60 ME] [Hard Moded] / Nintendo Wii [4.1U] [cIOS Hermes] [D2X cIOS] / iPhone 3G [4.2.1] [BB 05.13.04] [redsn0w] / iPod Touch 4 [6.1] [evasi0n]

07/05/10: Tuve el placer de llamarle con todo derecho "N00B" a molotovi xDDD

Recuerda: Sé el intérprete -_-

Imagen de DeViaNTe

Jaj, peloteo a parte,

Jaj, peloteo a parte, demostraste tener capacidades! No hay mas que ver LD4Wii, que está empezando a dar guerra! Asi k menos peloteo y mas al tajo, que quiero portar mi juego de naves a wii xD


Actualmente desarrollando nuestra web y UXCode : http://www.gcrew.es

Imagen de iRVing_Prog

proyecto

 LuaDEV para mi es un proyecto genial, desarrollado de una manera genial, y usado(dependiendo) pero se trata de que todo sea bueno :)

Ami me gusta mucho LuaDEV llevo un poco mas de 2 meses codificando para el interprete y hasta ahora no he tenido grandes problemas, me falta probarlo con el 3D como le comentaba a chime ;D pero no me hecho mis modelos jeje.

Por ultimo quiero felicitarte Deviante es un gran y excelente proyecto, me da gusto que se siga con el desarrollo y esperando no termine.

Salu2tes


 

Imagen de sting18

Que bueno que te decidiste

Que bueno que te decidiste hacer luaDEV asi los que no tenemos mucho tiempo para programar en C (creo te diste cuenta xD). podemos hacer buenas y mejores cosas espero y nunca dejes esto de programar dev eres bueno ;) y se podria aprender muchisimo de ti saludos .


:O

Ya con lo que leí (si, lo leí todo) y lo que me has dicho por msn... realmente veo que vas en serio, Dev (para fortuna de nosotros, claro está xD). La verdad es que ya se echaba de menos el módulo de saves.

No me queda más que felicitarte, y animarte para que sigas con este gran proyecto (por reportes de bugs no te preocupes... ya sabes que siempre testeo a fondo tus eboots y saco errores de vete a saber dónde xDD)

Saludos, Dev-Sensei

Imagen de DeViaNTe

Cosas bien hechas...

Las cosas se hacen bien, o se hacen mal, o se hacen dev-style. xDDDD
Any comments?

mmm

me da curiosidad, ¿Cuál es el Dev-style? (si no es asesinar a la mascota por la presion en el error de un codigo...) entonces?

Imagen de DeViaNTe

cuidar hasta el último

cuidar hasta el último detalle, y configurar hasta el último punto y coma. Las chapuzas están fuera de lugar, y si puedes ordenarlo todo mejor que mejor, ahi, a lo dev-style xD (era una coletilla para el post, no me lo tomen en serio xD)

Hombre por dios, deja a la mascota tranquila, no tiene la culpa... si fuera asi ya habría asesinado a los mios, pues esto de los saves me ha llevado un dia completo de freeze tras freeze. xD


Actualmente desarrollando nuestra web y UXCode : http://www.gcrew.es

Imagen de Samuelfrm

xD

Bueno aun no leo todo por que estoy haciendo la tarea pero.

De lo que eh leido eres grande no se como puedo ''Conocer'' a el creador de luadev, pero solo puedo decir espero puedas espero sigas como vaz y puedas seguir con este gran proyecto y apoyo para nosotros (los que vamos empezando) LuaDev.

No contesten que editare al leer toda xD.


Twitter

Opciones de visualización de comentarios

Seleccione la forma que prefiera para mostrar los comentarios y haga clic en «Guardar las opciones» para activar los cambios.