Anuncios Google

Curso LuaPlayer HM7 para PSP (Por pipagerardo)

Este es el curso/documentación de LuaPlayer HM7 de pipagerardo. Lo he subido debido a que su página web no está disponible debido a causas desconocidas.

Como lo he guardado en txt por mi comodidad, no tiene el mismo formato que en la web, por lo que iré editándolo poco a poco, modificando algunas cosas pero respetando la organización original del propio autor.


CURSO LUAPLAYERHM7 PARA PSP

LUAPLAYERHM7 por Homemister & PickDaT

http://luaplayerhm.xtreemhost.com/

http://www.homemister.axspace.com/LuaPlayerHM7.zip


http://luaplayerhm.xtreemhost.com/upload/LuaPlayerHM8.zip

 

TUTORIAL CREADO POR PIPAGERARDO.

Fecha de actualización: 4 - 6 - 2012

 

GRACIAS ESPECIALES A:

http://psp.scenebeta.com/

 

MIS JUEGOS LUA

CAÑONES CORAZAS: http://psp.scenebeta.com/noticia/ca-ones-corazas

http://dl.qj.net/Guns-Armors-v2.01-PSP-Homebrew-Games/pg/12/...

http://dl.qj.net/LUA-Games/pg/12/fid/17074/catid/194

ASTEROID BARRIER: http://psp.scenebeta.com/noticia/asteroid-barrier

http://pspupdates.qj.net/NeoFlash-Spring-Competition-08-Aste...

CABALLO DE COPAS: http://psp.scenebeta.com/noticia/caballo-de-copas


ÍNDICE

  1. PALABRAS Y CARACTERES RESERVADOS EN LUA
  2. PALABRAS FRECUENTES EN ESTE TUTORIAL LUA
  3. VARIABLES
  4. EXPRESIONES, OPERADORES BOOLEANOS Y LÓGICOS
  5. CONTROL DE FLUJO DEL PROGRAMA
  6. FUNCIONES GRÁFICAS
  7. FUNCIONES DE SONIDO
  8. FUNCIONES DE CONTROL DE TIEMPO
  9. FUNCIONES 3D
  10. FUNCIONES, CORRUTINAS Y ERRORES
  11. FUNCIONES CON TABLAS
  12. FUNCIONES CON STRINGS
  13. FUNCIONES MATEMÁTICAS
  14. FUNCIONES DE FICHEROS
  15. FUNCIONES DE INFORMACIÓN
  16. FUNCIONES ADHOC, WLAN E IRDA
  17. FUNCIONES DE ENERGIA
  18. FUNCIONES DE LA CPU
  19. FUNCIONES DE MEMORIA
  20. FUNCIONES DE METATABLAS
  21. FUNCIONES UMD, ISO Y PSX
  22. FUNCIONES EBOOT, ELF, PRX Y SAVEGAMES
  23. FUNCIONES HPRM
  24. FUNCIONES DE COMPRESIÓN DE DATOS
  25. FUNCIONES SYSTEM
  26. FUNCIONES OS DE SISTEMA OPERATIVO
  27. MÓDULOS
  28. FUNCIONES DEBUG O DEPURADO
  29. LPHMDRIVERS LuaPlayerHM8

Palabras y caracteres reservados en LUA: (Índice)


Estas palabras y caracteres no pueden o no deben usarse para crear variables ni funciones, LUA hace distinción entre mayúsculas y minúsculas de tal manera que si se podría usar AND o AnD como nombre valido.

and	break		do	else	elseif	end	false
 
for	function	if	in	local	nil	not
 
or	repeat		return	then	true	until	while
 
^	#		-	*	/	%	+
 
..	<		>	<=	>=	~=	==
 
[	]		{	}	""	''	,

Palabras frecuentes en este tutorial LUA: (Índice)


nil			Nulo, vacío o no existe.
 
boolean			true, false, variable de dos estados, verdadero y falso.
 
number			Cualquier número.
 
string			Cualquier carácter o cadena de caracteres.
 
table			Cualquier tabla o array.
 
metatable		Tipo especial de table.
 
var			Variable genérica, boolean, number, string o table.
 
function		Variable de Función.
 
thread			Función creada como corrutina, multiprocesos.
 
userdata		Datos cargados por el usuario como con "image.load()"
 
color			Variable de Color gráfico.
 
table_color[r,g,b,a]	Tipo especial de tabla con los componentes de un color.
 
image			Imagen, superficie gráfica, screen, archivo gráfico "PNG" o "JPG"
 
font			Fuente de texto tipo "TTF"
 
path			Dirección donde se encuentra un archivo.
 
filename		Nombre de Archivo.
 
file			Variable de Archivo, descriptor de archivo..
 
data			Datos cargados desde un archivo.
 
[ ]			Entre corchetes opcional, salvo que sea una tabla[índice].
 
x			Number generalmente entre 0 y 480, coordenadas X de pantalla.
 
y			Number generalmente entre 0 y 272, coordenadas Y de pantalla.
 
ancho			Number la anchura de algo.
 
alto			Number la altura de algo.
 
timer			Temporizador.
 
music			Musica tipo UNI, IT, XM, S3M, MOD, MTM, STM, DSM, MED, FAR, ULT o 669
 
sound			Sonido tipo PCM WAV monoaural. Máximo 16 bit 22050 KHz
 
UMD			Es el disco que se inserta en la PSP. Puede ser UMD-Game, UMD-Video y UMD-Demo.
 
firm			Es el sistema operativo de la PSP, está firmado por Sony lo cual lo hace "no manipulable".
 
kernel			Es el conjunto de funciones de bajo nivel de un sistema operativo. En la PSP el más famoso es el kernel 1.50, pero actualmente se utilizan los kernel 3.xx y 4.xx. Hablando claro, si el programa "Eboot.pbp" usa funciones del kernel 1.50 y la PSP solo tiene instalado el Kernel 3.xx pues no funciona o lo hace mal.
 
eboot.pbp		Archivo ejecutable de la PSP. Consta de:
 
	param.sfo		Información del eboot.pbp, nombre, tipo, firm, etc...
 
	icon0.png		Icono de 144x80p que se muestra al seleccionar el eboot.pbp
 
	icon1.pmf		Animación del icon0.png
 
	pic0.png		Foto de 480x272p que se muestra al arrancar el eboot.pbp
 
	pic1.png		Foto de 480x272p que se muestra al seleccionar el eboot.pbp
 
	snd0.at3		Música que se escucha al seleccionar el eboot.pbp
 
	data.psp		Código ejecutable, realmente es un elf.
 
	data.psar		Código firmado por Sony, no se puede modificar ni un solo bit.
 
	elf			Es la parte de un "Eboot.pbp" donde se encuentra el código ejecutable.
 
	prx			Es código auxiliar, usado para drivers y plugins adicionales.

Variables: (Índice)


string type( variable )

Retorna el tipo de su único argumento, codificado como string. Los posibles resultados de esta función son "nil" (un string, no el valor nil), "number", "string", "boolean, "table", "function", "thread" y "userdata".

screen:print( 10, 10, "Tipo = " .. type( "Hola" ), blanco )	-- Tipo = string
 
screen:print( 10, 20, "Tipo = " .. type( 123 ), blanco )	-- Tipo = number


nil

Variable nula, vacía, sin definir. Dicho esto vamos a ver nuestra primera variable:

_variable = nil

El nombre de la variable es "_variable" y su contenido es indefinido y nulo. Si se asigna "nil" a una variable anteriormente asignada, borra los datos que esta tuviera:

_nombre = "Gerardo"	-- Asigna "Gerardo" a la variable _nombre.
 
_nombre = nil		-- Borra el contenido de la variable _nombre.


boolean

Variable de solo dos estados [true/false], verdad o falso. Es utilizada por los comparadores para decir si una comparación es cierta o falsa. También algunas funciones la utilizan para retornar si ha habido fallo u para activar laguna opción. Recuerda la función "screen:blit() " y su parámetro "Alpha".

_boolean = ( 5 > 3 )	-- true
 
_boolean = ( 5 < 3 )	-- false
 
_musica	= false		-- variable utilizada como interruptor para apagar la música.
 
_casado	= false		-- Variable con dos opciones, casado o soltero.
 
_activo	= true


number

Variable para contener números, cualquier tipo de número.

_entero		= 3
 
_negativo	= -5
 
_real		= 3.1416
 
_exponencial	= 314.16e-2
 
_EXPONENCIAL	= 0.31416E1
 
_hexadecimal	= 0xff3a	-- en decimal 65338


string

Variable para contener caracteres alfanuméricos, esto es letras u números. Se pueden definir de tres maneras: con dobles comillas, comilla simple y doble corchete. Como podéis imaginar hay caracteres especiales que podrían causar problemas, para evitarlo se utilizan las siguientes secuencias de escape dentro de un "string" :

\a -- campana			\b -- backspace			\f -- form feed
 
\n -- nueva línea		\r -- retorno de carro		\t -- tabulador horizontal
 
\v -- tabulador vertical	\\ -- contrabarra		\" -- comillas dobles
 
\' -- comilla simple		\[ -- abre corchete		\] -- cierra corchete

En el LuaPlayer para PSP no funcionan las siguientes secuencias de escape a la hora de escribirlas en pantalla con la función screen:print(), pero si son válidas cuando se trabaja con archivos:

\a      \b      \f      \n      \r      \t      \v

Ejemplos:

_string_1 = "Hola mundo!"
 
_string_2 = 'Hola mundo!'
 
_string_3 = [[Hola mundo!]]
 
_string_4 = 'Me dijo: "Hola" y se fue.'
 
_string_5 = [[Me dijo: "Hola" y se fue.]]
 
_string_6 = "1974"			-- Ojo no es un "number" es un "string"
 
_string_7 = "En 1974 nací."
 
_string_8 = string.char( 65, 66, 67 )	-- _string_8 = "ABC"
 
_string_9 = "\\ \" \' \[ \]"		-- Mostraría esto: \ " ' [ ]


userdata

Son variables no gestionadas por el "LUA" sino por algún módulo exterior, generalmente hecho en "C". Por ejemplo los colores, las imágenes o superficies, los sonidos y las músicas, fuentes de texto, etc...

_color  = Color.new( _rojo, _verde, _azul )	-- "userdata"
 
_imagen = Image.createEmpty( _ancho, _alto )	-- "userdata"


function

Las funciones tienen un nombre y este al fin y al cabo es una variable. Realmente contiene la dirección de memoria donde ha sido alojada la función propiamente dicha.

suma = function( a, b ) return a + b end        -- suma -> "function"


thread

Mas adelante veremos como pueden ejecutarse varias funciones a la vez gracias a las corrutinas, este tipo de función multitarea es llamada "thread":

co = coroutine.create( function ( n, m )
 
				for i = 1, m do
 
					n = n + m
 
					coroutine.yield()
 
				end
 
				return n
 
			end	) -- co -> "thread"


table

Este tipo de variable lo es todo. Una tabla no es más que una variable que contiene un grupo de variables de cualquier tipo. Una tabla puede contener varios "numbers", varios "string", incluso una tabla puede contener otra tabla. Es mas puede contener diferentes tipos de variables. Ejemplo:

_table_1 = {}			--> variable de tipo "table" vacía, nula.
 
_table_1 = { 3, 4, 6 }		--> tabla "number" de tres elementos.
 
_table_1[3] = 6			--> Asignación del valor 6 al tercer índice de la tabla.
 
 
 
_table_3 = { { 1, 2, 3 },	--> tabla "number" de 6 elementos dispuestos en 2
 
	{ 4, 5, 6 } }		--> columnas. También llamado "Array" de 2 dimensiones
 
_table_3[2][3] = 6
 
 
 
_table_2 = { {},{} }		-- Constructor de tabla de dos dimensiones
 
_table_2[1][1] = 1		-- Asignación de valores.
 
_table_2[1][2] = 2
 
_table_2[1][3] = 3
 
_table_2[2][1] = 4
 
_table_2[2][2] = 5
 
_table_2[2][3] = 6
 
 
 
_table_4 = {}			--  Constructor primera dimensión.
 
_table_4[3] = 5
 
_table_4[3] = {}		--  Constructor segunda dimensión.
 
_table_4[3][2] = 6
 
 
 
_punto = { nombre = "A",		--> "string"
 
	x = 120,			--> "number"
 
	y = 100,			--> "number"
 
	color = Color.new( 255, 0, 0 )	--> "userdata"
 
	}           
 
_punto.nombre = "A"
 
_punto.x = 120
 
_punto.y = 100
 
_punto.color = Color.new( 255, 0, 0 )


local

do ... end

El sufijo "local" delante de una variable la hace accesible solo dentro de un área local. Un área local suele estar definida por la palabra clave "do" al comienzo y "end" al final. También es una área local el cuerpo de las funciones, siendo aquí donde realmente es super útil. Terminada la ejecución del código que hay dentro del área local, las variables locales son destruidas y sus valores perdidos.

x = 3
 
do					--> Comienzo área local
 
	local x = 7
 
	screen:print( 0,10, x, blanco)	--> 7
 
end					--> Fin área local
 
screen:print( 0, 20, x, blanco )	--> 3

function diferencia_entre_suma_y_resta( a, b )
 
	local suma = a + b
 
	local resta = a - b
 
	return suma - resta
 
end

En LUA no existe la palabra clave "static" para crear variables estáticas dentro de una función. Esto son variables que guardan su valor entre llamadas y solo son visibles dentro de la función. Lo más parecido sería el siguiente ejemplo con el fallo de que la variable es accesible desde fuera de la propia función:

function variable_estatica()
 
	var = var or 0	-- Si no existe la crea asignándole el valor 0
 
	var = var + 1	-- Incrementa var
 
	return var + 1	-- Retorna el valor de la variable
 
end
 
for x = 1, 40, 10 do
 
      screen:print( x, 0, variable_estatica(), blanco)
 
end			-- Este código imprimiría en la pantalla: 1 2 3 4

 

Expresiones, operadores booleanos y lógicos: (Índice)


Expresiones

Son la forma más elemental de interactuar con las variables. La mayoría solo son válidos para variables tipo "number" aunque usando metatablas se pueden especificar su comportamiento respecto a los distintos tipos de variables del LUA. Toman uno o dos operadores y les asignan una expresión matemática simple ( +, -, *, /, %, ^ )


= "Asignación"

Asignación (no confundir con "==" igual ), como su nombre indica sirve para asignar algo a una variable, puede ser otra variable o un valor introducido directamente.

a = 125			-- Asignamos directamente el valor 125 a la variable a
 
a, b = 125, 5		-- Igual que:	a = 125; b = 50
 
a, b, c = 125, 50	-- Igual que:	a = 125, b = 50, c = nil
 
a, b = b, a		-- Intercambia los valores de a y b, ahora: a = 50; b = 125


+ "Suma" Adición, operación matemática simple. "number"

a = 3 + 5		-- Igual a:	a = 8
 
b = a + 1		-- Igual a:	b = 9
 
c = "Hola" + 5		-- Error
 
d = 5 + "5"		-- Igual a:	d = 10		-- Auto conversión a number "tonumber()"
 
e = "6" + "6"          	-- Igual a:	e = 12		-- Auto conversión a number "tonumber()"


- "Resta" Substracción, operación matemática simple. "number"

x = 5 - 3		-- Igual a:	x = 2
 
y = 3 - 5		-- Igual a:	y = -2
 
z = x + y		-- Igual a:	z = 0


- "Unario" Cambia el signo a un número. "number"

x, y = 7, -4
 
x = -x			-- Igual a:	x = -7
 
y = -y			-- Igual a:	y = 4


* "Multiplicación" Operación matemática simple. "number"

d = 4 * 5		-- Igual a:	d = 20
 
d = d * 2		-- Igual a:	d = 40
 
n = 5 * -1		-- Igual a:	n = -5
 
p = -5 * -1		-- Igual a:	p = 5


/ "División" Operación matemática simple. "number"

d = 10 / 2		-- Igual a:	d = 5
 
e = 7 / 2		-- Igual a:	e = 3.5
 
f = 5 / 0.5		-- Igual a:	f = 10


% "Resto división" Calcula el resto de una división. "number"

a % b == a - math.floor(a/b)*b
 
r = 7 % 2		-- Igual a:	r = 1
 
r = 10 % 2		-- Igual a:	r = 0
 
f = 5 / 0.5		-- Igual a:	f = 10


^ "Potencia" Multiplica el primer operador entre sí tantas veces como el segundo operando. "number"

p = 2 ^ 3		-- Igual a:	p = 2 * 2 * 2
p = 4 ^0.5		-- Igual a:	p = 2


# "Tamaño" Obtiene el tamaño de una "table" o "string"

pstring = "Hola"
table = {1, 2, 4, 7}
x = #string		-- Igual a:	x = 4
x = #table		-- Igual a:	x = 4


.. "Concatenación" Junta sus factores creando un string que es la unión de ellos.

"Mari" .. "posa"	-- Igual a:	"Mariposa"
"File_" .. 5		-- Igual a:	"File_5"
5 .. 5			-- Igual a:	"55"
"A" .. "B" .. "C"	-- Igual a:	"ABC"


OPERADORES BOOLEANOS

Sirven para comparar dos expresiones y siempre retornan uno de estos dos estados, verdadero o falso. Por eso se les llama operadores booleanos.


== "Igualdad" Verifica la igualdad de las dos expresiones.

5 == 5			-- Igual a:	true
5 == 6			-- Igual a:	false
5 + 3 == 8 + 2		-- Igual a: 	true
a = 5			-- Asignamos el valor 5 a la variable a.
a == 5			-- Igual a:	true


~= "Distinto" Es lo contrario de la igualdad.

5 ~= 6			-- Igual a:	true
5 ~= 5			-- Igual a:	false


> "Mayor" Verifica si el primer operador es mayor que el segundo.

5 > 2			-- Igual a:	true
5 > 8			-- Igual a:	false
5 > 5			-- Igual a:	false


>= "Mayor o igual" Verifica si el primer operador es mayor o igual que el segundo.

5 >= 2			-- Igual a:	true
5 >= 8			-- Igual a:	false
5 >= 5			-- Igual a:	true


< "Menor" Verifica si el primer operador es menor que el segundo.

5 < 2			-- Igual a:	false
5 < 8			-- Igual a:	true
5 < 5			-- Igual a:	false


<= "Menor o igual" Verifica si el primer operador es menor o igual que el segundo.

5 <= 2			-- Igual a:	true
5 <= 8			-- Igual a:	true
5 <= 5			-- Igual a:	false


OPERADORES LOGICOS

Son tres: "or", "and" y "not". Equivalen a "O", "Y", "Negación". Trabajan evaluando una lógica entre sus dos operadores.


or "O"

Si una de las dos expresiones es cierta o existe la retorna. Si las dos son ciertas o existen retorna la primera.

false or false		--> false
false or true		--> true
truo or false		--> true
true or true		--> true
false or nil		--> nil  
true or nil		--> true
nil or false		--> false
nil or true		--> true
10 or 20		--> 10
20 or 10		--> 20
nil or 20		--> 20
20 or nil		--> 20

x = nil
x = x or 5		--> x = 5
 
 
x = 8
x = x or 5		--> x = 8


and "Y"

Las dos expresiones deben ser ciertas para retornar "true". Si dos expresiones existen retorna la segunda.

false and false		--> false
false and true		--> false
true and false		--> false
true and true		--> true
false and nil		--> false
true and nil		--> nil
nil and false		--> nil
nil and true		--> nil
10 and 20		--> 20
20 and 10		--> 10
nil and 20		--> nil
20 and nil		--> nil

a = 8 ;	b = 3
c = 3;	d = 8
c = ( a > b ) and a or b	--> c = a
d = ( c > d ) and a or b	--> d = b


not "Negación" Niega la expresión.

not false		--> true
not true		--> false
not nil			--> true
not 20			--> false


PRIORIDAD ENTRE EXPRESIONES Y OPERADORES:

En LUA al igual que en otros lenguajes existe una prioridad entre Expresiones y Operadores. Algunos tienen prioridad sobre otros y viceversa. Si son del mismo rango se aplican empezando por la izquierda hasta llegar a otro de diferente rango.

1º	or
2º	and
3º	<	>	<=	>=	~=	==
4º	..
5º	+	-
6º	*	/	%
7º	not	#	- (unario)
8º	^

Ejemplos :

a = 5 > 2 + 4			Es igual a: false		porque: ( 5 > 2 )
a = 5 > (2 + 4 )		Es igual a: true		porque: ( 5 > 7 )
a = 5 + 2 * 2			Es igual a: a = 5 + ( 2 * 2 )	Resultado: 9  no 14
Cuidado:  5 + 2 * 2		No es igual que:  ( 5 + 2 ) * 2

Control de flujo del programa: (Índice)


if _exp  then ... end

if _exp  then ... else ... end

if _exp1 then ... elseif _exp2 then ... else ... end

Es el condicional por excelencia, significa: "Si se cumple tal expresión entonces haz esto, sino haz lo otro." Tiene tres posibles formas desde la más simple hasta los condicionales encadenados:

if _exp  then ... end

Es la más simple forma de "if" dice así: "Si se cumple la expresión haz lo siguiente."

x , y = 2, 7
if x < y then	x = y	-- Si se cumple:	x = y
end			-- Igual a:		x = ( x < y ) and y or x
Resultado:	x = 7

 

if _exp  then ... else ... end

Igual que la anterior pero si no se cumple la condición también hace algo: "Si se cumple la expresión haz esto, si no haz lo otro."

x , y = 7 , 2
if x < y then	x = y		-- Si se cumple:	x = y
else		y = y +1	-- Si no se cumple:	y = y + 1
end
Resultado:	y = 3

 

if _exp1  then ... elseif _exp2 then ... else ... end

Este es un "if" encadenado en el cual se evalúan múltiples expresiones hasta que se cumple una.

x = 2
if	x == 1 then	y = 8
elseif	x == 2 then	y = 12
elseif	x == 3 then	y = 24
else			y = 56
end
Resultado:		y = 12


for _var =_exp1 , _exp2 do ... end

for _var_1, ..., _var_n in _funcion_iteradora do ... end

Los bucles "for" sirven para recorrer variables en un intervalo. Si el intervalo no es especificado se asume como un incremento de una unidad. Vamos a ver un ejemplo con el bucle "for" más simple posible.

y = 0
for x = 1, 10, 2 do	-- Asignará a x los valores 1, 3, 5, 7 y 9.
	screen:print( 0, y, "x = " .. x, blanco )
	y = y + 10
end

 

Un intervalo negativo sirve para realizar una cuenta atrás:

y = 0
for x = 10, 1, -1 do	-- Asignará a x los valores 10, 9, 8, 7, 6, 5, 4, 3, 2 y 1.
	screen:print( 0, y, "x = " .. x, blanco )
	y = y + 10
end

 

Para casos más complejos el bucle "for" admite usar una función iteradora que le diga la forma de recorrer una variable. El LUA tiene funciones iteradoras para recorrer tablas y archivos como: ipairs(), pairs(), next(), files(), etc. Para esto hay que usar la palabra clave "in" dentro de la construcción "for". Ver el siguiente ejemplo que imprime en pantalla todos los elementos de una tabla de índices numéricos:

y = 0
table = {"one", "two", "three"}
for indice, valor in ipairs( table ) do
	screen:print( 0, y, indice .."-".. valor, blanco )
	y = y + 10
end

 

Esta función viene ya hecha, pero vamos ha hacerla nosotros para ver como funciona. Primero haremos una función iteradora que dada una tabla y un índice, incrementa el índice y lo retorna más el valor al índice asignado dentro de la tabla.

function iteradora(table, indice)
	indice = indice + 1
	local valor = table[indice]
	if valor then return indice, valor end
end

 

Luego creamos la función "nuestra_ipairs()" que va ha hacer lo mismo que la función estándar del LUA "ipairs()". Toma una tabla y si el índice es valido retorna la función iteradora, sino retorna la propia tabla y 0 como índice:

function nuestra_ipairs( table )
	return iteradora, table, 0
end

 

Con las dos funciones anteriores ahora hacemos la siguiente construcción que funcionará exactamente igual que si usamos la función estándar "ipairs()" :

y = 0
a = {"one", "two", "three"}
for i, v in nuestra_ipairs(a) do
	screen:print( 0, y, i .."-".. v, blanco )
	y = y + 10
end


while _expresion do ... end

Este comando del LUA repite un área local o bloque mientras es verdadera una expresión. Traducido significa: Mientras se cumpla la expresión haz esto. Si no se cumple la condición al menos una vez, no ejecuta el código de la área local. En el primer ejemplo hacemos lo mismo que usando "for x = 1, 10, do ... end", imprimirá en pantalla los valores de x desde el 1 al 10:

while true do código end		-- Bucle infinito ejecutando "código"
while false do código end		-- No ejecuta ni una vez el "código"

 

x , y = 1 , 0
while x <= 10 do
	screen:print( 0, y, "x = " .. x, blanco )	-- x = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 y 10 ]
	x , y = x + 1, y + 10
end
screen:print( 0, y, "x = " .. x, blanco )		-- x =  11

Veamos el siguiente ejemplo para ver que pasa si no se cumple la expresión ni una sola vez, como x es mayor o igual que 10, no se ejecutará el código del área local ni se imprimirá nada en pantalla:

x , y = 15 , 0
while x <= 10 do
	screen:print( 0, y, "x = " .. x, blanco )	-- Nada será imprimido en pantalla.
	x , y = x + 1, y + 10
end
screen:print( 0, y, "x = " .. x, blanco )		-- x =  15


repeat ... until _expresion

Este comando es prácticamente igual que el anterior "while", la diferencia es que la evaluación de la expresión se realiza al final del área local, por lo cual aunque no se cumpla la expresión ni una sola vez, por lo menos se ejecuta el código del área local una vez. Significa: Repite esto hasta que se cumpla la expresión.

repeat código until false		-- Bucle infinito ejecutando "código"
repeat código until true		-- Ejecuta una vez "código"

 

x , y = 1 , 0
repeat
	screen:print( 0, y, "x = " .. x, blanco )	-- x = [ 1, 2, 3, 4, 5, 6, 7, 8, 9 y 10 ]
	x , y = x + 1, y + 10
until x > 10						-- Ahora solo ">" en vez de "<="
screen:print( 0, y, "x = " .. x, blanco )		-- x =  11

 

Ahora veremos que pasa si no se cumple ni una sola vez la expresión. Si no se cumple, al estar la evaluación al final del área local, el código se ejecuta una vez. Esta es la gran diferencia entre "while" y "repeat" :

x , y = 20 , 0
repeat
	screen:print( 0, y, "x = " .. x, blanco )		-- x = 20
	x , y = x + 1, y + 10
until x > 10
screen:print( 0, y, "x = " .. x, blanco )			-- x =  2


break

Rompe los bucles "for", "repeat ... until" y "while"

y = 0
for x = 1, 10 do					-- Imprimirá:  x = [ 1, 2, 3, 4, 5 y 6 ]
	screen:print( 0, y, "x = " .. x , blanco)
	y = y + 10
	if x > 5 then break end				-- Si x > 5 rompe el bucle "for"
end

 

x, y = 1, 0
while true do						-- Bucle infinito, siempre verdadero.
	screen:print( 0, y, "x = " .. x , blanco)	-- Imprimirá: x = [ 1, 2, 3, 4 y 5 ]
	x, y = x + 1, y + 10
	if x > 5 then break end				-- Si x > 5 rompe el bucle "while"
end

 

x, y = 1, 0
repeat
	screen:print( 0, y, "x = " .. x , blanco)	-- Imprimirá: x = [ 1, 2, 3, 4 y 5 ]
	x, y = x + 1, y + 10
	if x > 5 then break end				-- Si x > 5 rompe el bucle "repeat"
until false						-- Bucle infinito, siempre verdadero.


Controls.read()

Esta función captura las teclas pulsadas en el teclado de la PSP. Depende del uso retorna un "boolean", "true" o "false" si se a pulsado la tecla, o un "number". Si se opera con "number" a través de las máscaras de bits "Mask" se pueden conseguir combinaciones de botones más fácilmente que de la otra forma.
El mando analógico siempre retorna "number" en un rango de [-127 a 128] para sus dos ejes.

pad = Controls.read()
	boolean  pad:select()	boolean Controls.read():select()     
	boolean  pad:start()	boolean Controls.read():start()
	boolean  pad:up()	boolean Controls.read():up()
	boolean  pad:right()	boolean Controls.read():right()
	boolean  pad:down()	boolean Controls.read():down()
	boolean  pad:left()	boolean Controls.read():left()
	boolean  pad:l()	boolean Controls.read():l()
	boolean  pad:r()	boolean Controls.read():r()
	boolean  pad:triangle()	boolean Controls.read():triangle()
	boolean  pad:circle()	boolean Controls.read():circle()
	boolean  pad:cross()	boolean Controls.read():cross()
	boolean  pad:square()	boolean Controls.read():square()
	boolean  pad:home()	boolean Controls.read():home()
	boolean  pad:hold()	boolean Controls.read():hold()
	boolean  pad:note()	boolean Controls.read():note()
	number pad:analogX()	number Controls.read():analogX()		-- Rango de -127 a 128.
	number pad:analogY(	number Controls.read():analogY()		-- Rango de -127 a 128.

pad = Controls.read()            -- Version "number" con máscaras de bits.
	number pad:buttons()		number Controls.read():buttons()
	number Controls.selectMask	number Controls.triangleMask
	number Controls.startMask	number Controls.circleMask
	number Controls.upMask		number Controls.crossMask
	number Controls.rightMask	number Controls.squareMask
	number Controls.downMask	number Controls.homeMask
	number Controls.leftMask	number Controls.holdMask
	number Controls.ltriggerMask	number Controls.noteMask
	number Controls.rtriggerMask

LuaPlayerHM8:

number Controls.wlan()  Interruptor WLAN. Retorna 1 para encendido y 0 para apagado.

 

Ejemplo, el teclado de la PSP:

blanco = Color.new( 255, 255, 255 )
negro = Color.new( 0, 0, 0 )
while true do
	screen:clear( negro )
	pad = Controls.read()
	if pad:up()		then screen:print( 10,   0, "Arriba", blanco )			end
	if pad:down()		then screen:print( 10,  10, "Abajo", blanco )			end
	if pad:right()		then screen:print( 10,  20, "Derecha", blanco )			end
	if pad:left()		then screen:print( 10,  30, "Izquierda", blanco )		end
	if pad:cross()		then screen:print( 10,  40, "Cruz", blanco )			end
	if pad:circle()		then screen:print( 10,  50, "Circulo", blanco )			end
	if pad:triangle()	then screen:print( 10,  60, "Triangulo", blanco )		end
	if pad:square()		then screen:print( 10,  70, "Cuadrado", blanco )		end
	if pad:r()		then screen:print( 10,  80, "Gatillo Derecho", blanco )		end
	if pad:l()		then screen:print( 10,  90, "Gatillo Izquierdo", blanco )	end
	if pad:start()		then screen:print( 10, 100, "Start", blanco )			end
	if pad:select()		then screen:print( 10, 110, "Select", blanco )			end
	if pad:home()		then screen:print( 10, 120, "Home", blanco )			end
	if pad:note()		then screen:print( 10, 130, "Note", blanco )			end
	if pad:hold()		then screen:print( 10, 140, "Hold", blanco )			end
	analogico_x = pad:analogX() ; analogico_y = pad:analogY()	
	screen:print( 10, 150, "Analogico_X = " .. analogico_x, blanco )
	screen:print( 10, 160, "Analogico_Y = " .. analogico_y, blanco )
	screen.flip() ; screen.waitVblankStart( 2 )
end

 

Ejemplo de una pausa hasta pulsar "X":

screen:print( 10, 10, 'Pulse "X" para continuar.' , blanco )
screen.waitVblankStart( ) ; screen.flip()
repeat
	screen.waitVblankStart( 2 )
until Controls.read():cross()

 

Ejemplo de un MENU de selección:

pad, oldad	= Controls.read(), pad
blanco		= Color.new ( 255, 255, 255 ) ;					negro		= Color.new ( 0, 0, 0 )
patada		= Controls.crossMask ;						n_patada	= 0
golpe		= Controls.circleMask ;						n_golpe		= 0
combo_1		= Controls.rightMask + Controls.crossMask ;			n_combo_1   = 0
combo_2		= Controls.downMask + Controls.rightMask + Controls.crossMask ;	n_combo_2 = 0
esp_combo	= Controls.leftMask
esp_combo	= esp_combo + Controls.leftMask + Controls.downMask
esp_combo	= esp_combo + Controls.downMask
esp_combo	= esp_combo + Controls.downMask + Controls.rightMask
esp_combo	= esp_combo + Controls.rightMask
esp = 0 ;	  n_esp = 0
esp_t = Timer.new() ; tiempo = Timer.new() ; tiempo:start()
 
repeat
	pad = Controls.read()
	screen:clear( negro )
	screen:print(110,  36, "Haz 5 golpes de cada en 20 segundos." , blanco)
	screen:print(120,  46, "Tiempo = ".. math.floor( tiempo:time() / 1000 )		, blanco)
	screen:print(120,  66, "Patada   ( X )                     = ".. n_patada	, blanco)
	screen:print(120,  76, "Golpe    ( O )                     = ".. n_golpe	, blanco)
	screen:print(120,  86, "Combo 1  ( > + X )           = ".. n_combo_1		, blanco)
	screen:print(120,  96, "Combo 2  ( V + > + X )    = ".. n_combo_2		, blanco)
	screen:print(120, 106, "Especial ( <  + v + > )       = ".. n_esp		, blanco)
	screen:print(120, 126, "Mascara = " .. pad:buttons()				, blanco)
 
	if pad:buttons() == Controls.leftMask then
		esp = Controls.leftMask
		esp_t:stop(); esp_t:reset(0); esp_t:start()
	elseif esp_t:time() < 500 and pad:buttons() ~= oldpad:buttons() then
		esp = esp + pad:buttons()
	elseif esp_t:time() >= 500 then
		esp_t:stop(); esp_t:reset(0); esp = 0
	end
 
	if esp == esp_combo then
		esp = 0 ; n_esp = n_esp + 1
	elseif pad:buttons() == patada and oldpad:buttons() ~= patada then
		n_patada = n_patada + 1
	elseif pad:buttons() == golpe  and oldpad:buttons() ~= golpe then
		n_golpe = n_golpe + 1
	elseif pad:buttons() == combo_1 and oldpad:buttons() ~= combo_1 then
		n_combo_1 = n_combo_1 + 1
	elseif pad:buttons() == combo_2 and oldpad:buttons() ~= combo_2 then
		n_combo_2 = n_combo_2 + 2
	end
 
	oldpad = pad
	screen.waitVblankStart(2); screen.flip()
until tiempo:time() > 20500
 
tiempo:stop();	esp_t:stop();	screen.waitVblankStart(120)
System.Quit()


System.message()

Imprime un mensaje a la pantalla con las opciones: "Yes, No and back." "Sí, no, y volver".

System.message("Hola",0)	-- muestra solo la opcion de " back" "volver".
System.message("Hola",1)	-- muestra las opciones: "Yes, No and back." "Sí, no, y volver".


System.buttonPressed()

Retorna la acción de la opción seleccionada en la función System.message(). Utilice "1" para retornar un string "Yes/No" o "0" para retornar "number" "1/0".

button = System.buttonPressed(1) ; If button == "yes" then System.Quit() end
button = System.buttonPressed(0) ; If button == 1 then System.Quit() end


string System.startOSK( string_defecto , string_mensaje )

Muestra el teclado en pantalla.

isoname = System.startOSK( "ms0:/ISO/*.ISO", "Enter Name and Path" )
screen:print( 1, 1, isoname, red )

 

Funciones gráficas (Índice)


color = Color.new( rojo_0-255 , verde_0-255 , azul_0-255 [ , alpha_0-255 ] )

Crea un color a base de sus componentes roja, verde y azul. Además se puede definir la opacidad o la transparencia del color con una tercera componente llamada "alpha". Estas componentes tienen un valor numérico entre 0 y 255, siendo 0 la ausencia de color u opacidad y 255 la máxima cantidad de color u opacidad. Un color con opacidad 0 es totalmente transparente.

blanco   = Color.new( 255, 255, 255 )
negro	= Color.new( 0, 0, 0 )
gris	= Color.new( 127, 127, 127 )
rojo	= Color.new( 255, 0, 0 )
verde	= Color.new( 0, 255, 0 )
azul	= Color.new( 0, 0, 255 )
gris_translucido = Color.new( 127, 127, 127, 127 )


nil image:clear( color )

Pinta o borra una imagen con el color dado.

azul = Color.new( 0, 0, 255 )
screen:clear( azul )		-- Borra una imagen rellenándola con un color.
screen.flip()			-- Muestra la pantalla pintada de azul.


nil image:print( x, y, var, color)

Escribe en la posición dada de una imagen y con un color definido un "string", "number" o "table". Si la variable es del tipo "boolean" escribirá "true" o "false" según su estado. También permite la concatenación ".." de dos "string" u operaciones matemáticas "+, -, *, /, etc"

"Mari" .. "posa" == "Mariposa" == 'Mariposa' == [[Mariposa]]
"Archivo_" .. 2 == "Archivo_2"      
"Dijo: \"Adiós\" y se fue." == 'Dijo: "Adiós" y se fue.' == [[Dijo: "Adiós" y se fue.]]

Por desgracia para nosotros de momento no son soportados ciertos caracteres en LUA, aunque no muestren error si que muestran caracteres extraños cuando se intenta escribir los siguientes:

ñ, Ñ, ¿, ¡, á, é, í, ó, ú, ü, Á, É, Í, Ó, Ú, Ü, ...

blanco = Color.new( 255, 255, 255 )
texto = "Script de ejemplo"
numero = 134.56
screen:print( 0,  0, texto, blanco )			-- Muestra: Script de ejemplo
screen:print( 0, 10, numero, blanco )			-- Muestra: 134.56
screen:print( 0, 20, "Mari" .. "posa", blanco )		-- Muestra: Mariposa
screen:print( 0, 30, "Cara\\Cruz", blanco )		-- Muestra: Cara\Cruz
screen:print( 0, 30, 2 + 5 , blanco )			-- Muestra: 5
screen:print( 0, 40, math.floor( 5.6 ), blanco )	-- Muestra: 5
screen.flip()

Como hemos visto antes la función "screen:print()" no es muy buena para nuestro idioma, así que adjunto una función llamada "escribe()" que además de corregir los acentos y las "ñ", centra el texto en pantalla cuando las coordenadas están fuera de rango, asume como blanco el color por defecto y permite cambiar el tamaño de la letra automáticamente solo dando su tamaño en pixels:

-- escribe( [imagen,] x, y, texto [,color] [, tamanno] )	-- Función programada por pipagerado.
function escribe( imagen, x, y, texto, color, tamanno )
	if type( imagen ) == "number" then						-- El primer argumento "imagen" es opcional
		if type( texto ) == "userdata" then					-- El "color" y "tammano" también.
			tamanno = color or 8
			color = texto or Color.new( 255, 255, 255 )
		else
			tamanno = texto or 8
			color = Color.new( 255, 255, 255 )
		end
		texto = y or "nil"
		y = x or -1; x = imagen or -1
		imagen = screen
	else
		if type( color ) == "userdata" then
			tamanno = tamanno or 8
			color = color or Color.new( 255, 255, 255 )
		else
			tamanno = color  or 8
			color = Color.new( 255, 255, 255 )
		end
		texto= texto or "nil"
		y = y or -1; x = x or -1
		imagen = imagen or screen
	end
	if	tamanno < 8	then tamanno = 8
	elseif	tamanno > 80	then tamanno = 80
	end
	if type(texto) ~= "string" then texto = tostring(texto) end
	local acentos, ennes, texto_f, caracter = "", "", "", ""
	local longitud = string.len( texto )
	for c = 1, longitud do
	caracter = string.sub( texto, c, c )
		if		caracter == "á" then caracter = "a"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "é" then caracter = "e"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "í" then caracter = "i"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "ó" then caracter = "o"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "ú" then caracter = "u"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "ü" then caracter = "u"; acentos = acentos .. "^"; ennes = ennes .. " "
		elseif	caracter == "Á" then caracter = "A"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "É" then caracter = "E"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "Í" then caracter = "I"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "Ó" then caracter = "O"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "Ú" then caracter = "U"; acentos = acentos .. "'"; ennes = ennes .. " "
		elseif	caracter == "Ü" then caracter = "U"; acentos = acentos .. "^"; ennes = ennes .. " "
		elseif	caracter == "¿" then caracter = "?"; acentos = acentos .. " "; ennes = ennes .. " "
		elseif	caracter == "¡" then caracter = "!"; acentos = acentos .. " "; ennes = ennes .. " "
		elseif	caracter == "ñ" then caracter = "n"; acentos = acentos .. " "; ennes = ennes .. "~"
		elseif	caracter == "Ñ" then caracter = "N"; acentos = acentos .. " "; ennes = ennes .. "~"
		else	acentos = acentos .. " "; ennes   = ennes   .. " "
		end
		texto_f = texto_f .. caracter
	end
	if tamanno == 8 then
		if x < 0 or x > 480 then x = (484 - ( longitud * tamanno )) / 2 end
		if y < 0 or y > 272 then y = 133 end
		imagen:print( x, y - 3, ennes  , color )
		imagen:print( x, y - 2, acentos, color )
		imagen:print( x, y,     texto_f, color )
	else
		tamanno = math.floor( math.abs( tamanno ) )
		if x < 0 or x > 480 then x = ( 480 - (longitud * tamanno / 1.66 ) ) / 2 end
		if y < 0 or y > 272 then y =  136 + ( tamanno  / 2.5 ) end
		local z      = math.ceil( y - ( tamanno / 3.5 ) )
		local w    = math.ceil( y - ( tamanno / 1.8 ) )
		local letra = Font.createMonoSpaced()
		letra:setPixelSizes(0, tamanno )
		imagen:fontPrint( letra, x, w, ennes,   color)
		imagen:fontPrint( letra, x, z, acentos, color)
		imagen:fontPrint( letra, x, y, texto_f, color)
		z, w,letra = nil, nil, nil
	end
	acentos, ennes, texto_f, caracter, longitud = nil, nil, nil, nil, nil
	collectgarbage()
end

Ejemplo de uso de la función personalizada "escribe" :

blanco = Color.new( 255, 255, 255 )
rojo = Color.new( 255, 255, 255)
imagen = Image.createEmpty( 480, 272 )
escribe( screen, 10, 10, "Hola Peseperos.", blanco, 8 )           -- Color blanco, tamaño 8 pixels.
escribe( 10, 10, "Hola Peseperos." )                                      -- Versión abreviada de la de arriba.
escribe( -1, 10, "Texto centrado en horizontal.", rojo)             -- Color rojo, tamaño 8 pixels
escribe( 10, -1, "Texto centrado en vertical.", 20 )                  -- Color blanco, tamaño 20 pixels
escribe( -1, -1, "Texto centrado en pantalla.", rojo, 20 )         -- Color rojo, tamaño 20 pixels.
escribe( imagen, -1, -1, 123.56 )                                           -- Color blanco, tamaño 20 pixels.
screen:blit( 0, 0, imagen )
screen.waitVblankStart() ; screen.flip()


Fuentes de texto hasta LuaPlayerHM7



En construcción...


NekeOS, el nuevo shell para PSP

PS4 500GB OFW, PS3 320GB OFW, PS3 500GB OFW, PSP 6.39 PRO-C Fix4.

Sony Xperia Z1 Compact con Android 5.1.1

Portatil Lenovo z50-70 Intel® Core™ i7-4510U y NVIDIA GeForce 840M con Elementary OS 0.3.2 Freya (64 bits) y Windows 10 (64 bits).


Anuncios Google

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 jorge_97

By Jorge_97

Genial!!! Muy bien Nekerafa :D Sin duda buenos tutoriales... yo los vi en su momento los del Ad Hoc, viene bien repasarlos

Un saludo

Have a nice day


Risa Dos años en SCENEBETA Risa

Click aquí para ver la Entrada de Bitácora.

Imagen de NEKERAFA

XD

Agradeceselo a pipagerardo, jejeje, y a mi astucia de guardarlo en mi HDD (Es que cuando iba de viaje no tenía una tarifa plana en el movil como ahora, y así podría verlo desde la propia PSP)


NekeOS, el nuevo shell para PSP

PS4 500GB OFW, PS3 320GB OFW, PS3 500GB OFW, PSP 6.39 PRO-C Fix4.

Sony Xperia Z1 Compact con Android 5.1.1

Portatil Lenovo z50-70 Intel® Core™ i7-4510U y NVIDIA GeForce 840M con Elementary OS 0.3.2 Freya (64 bits) y Windows 10 (64 bits).

Imagen de Jepte

yo lo tengo en .html, si

yo lo tengo en .html, si quieres te lo paso.

Imagen de NEKERAFA

Oh!

Mucho mejor estaría, aunque estoy editandole para dejarlo mejor, creo que avanzaría más rápido. Ok, pasamelo.

Imagen de Jepte

aqui esta

Imagen de NEKERAFA

Mmm...

Muchísimas gracias.

Aún así tengo que editar algunas cosas del tutorial original para que se vea bién en SceneBeta

Imagen de Andres_Ne

Me parece bn que hagas esto

Me parece bn que hagas esto Neke lastima porque nos irian bn unos en luadev ,a mi sobre todo sobre la manipulacion de archivos,(conste que prometiste hacer unos tutos sobre algunos modulos xD)Guiño

Suerte amigo.


 

 

Imagen de NEKERAFA

Mmm...

Pues ya no me acuerdo... Indeciso

Lo que me acuerdo es que dije que iba a volver a colgar este tutorial (Aunque sale para LuaPlayer HM7, muchos módulos sirven en LuaDEV, como los de archivos, sockets, tablas, strings, etc...), acabar los tutos de PS3 (a ver cuando me pongo a ello), subir una documentación entera de todo lo que conocemos de LuaDEV (a ver cuando me pongo a ello XD), y subir todos mis proyectos (Tengo más de dos) y actualizarlos.

Pero como te dije, los módulos generales, que sirven para todos, los puedes ver en la documentación oficial de Lua (No me canso de repetirlo XD), donde sale toda la documentación sobre manipulación de archivos.


NekeOS, el nuevo shell para PSP

PS4 500GB OFW, PS3 320GB OFW, PS3 500GB OFW, PSP 6.39 PRO-C Fix4.

Sony Xperia Z1 Compact con Android 5.1.1

Portatil Lenovo z50-70 Intel® Core™ i7-4510U y NVIDIA GeForce 840M con Elementary OS 0.3.2 Freya (64 bits) y Windows 10 (64 bits).

Imagen de Andres_Ne

Ok Ok  ya entendi 

Ok Ok Llora ya entendi 

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.