CURSO LUAPLAYERHM7 PARA PSP

 

LUAPLAYERHM7 por Homemister & PickDaT

 

TUTORIAL CREADO POR PIPAGERARDO.

http://pipagerardo.fortunecity.es/

Fecha de actualización: 28 - 08 - 2008

 

GRACIAS ESPECIALES A:

http://psp.scenebeta.com/

 

--------------------------------------------------------------------------------------------------------------------------------

 

INDICE

PALABRAS Y CARACTERES RESERVADOS EN LUA

CONVECIONES EN ESTE TUTORIAL LUA

VARIABLES

EXPRESIONES, OPERADORES BOOLEANOS Y LOGICOS

CONTROL DE FLUJO DEL PROGRAMA

FUNCIONES GRÁFICAS

FUNCIONES DE SONIDO

FUNCIONES DE CONTROL DE TIEMPO

FUNCIONES 3D

FUNCIONES, CORRUTINAS Y ERRORES

FUNCIONES CON TABLAS

FUNCIONES CON STRINGS

FUNCIONES MATEMÁTICAS

FUNCIONES DE FICHEROS

FUNCIONES DE INFORMACIÓN

FUNCIONES ADHOC, WLAN E IRDA

FUNCIONES DE ENERGIA

FUNCIONES DE LA CPU

FUNCIONES DE MEMORIA

FUNCIONES DE METATABLAS

FUNCIONES UMD, ISO Y PSX

FUNCIONES EBOOT, ELF, PRX Y SAVEGAMES

FUNCIONES HPRM

FUNCIONES DE COMPRESIÓN DE DATOS

FUNCIONES SYSTEM

FUNCIONES OS DE SISTEMA OPERATIVO

MÓDULOS

FUNCIONES DEBUG O DEPURADO

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 (Indice)

--------------------------------------------------------------------------------------------------------------------------------

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 LOGICOS (Í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, 50       -- 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

--------------------------------------------------------------------------------------------------------------------------------

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

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"

string = "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:       false

5 <= 8                   -- Igual a:       true

5 <= 5                   -- Igual a:       true

--------------------------------------------------------------------------------------------------------------------------------

OPERADORES LOGICOS

Son tres "or", "and", "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.

 

Rango:

Expresiones y Operadores:

or

and

<   >          <=       >=       ~=       ==

..

+   -

*    /           %

not             #          - (unario)

^

 

Ejemalos :

 

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: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 do                -- Asignará a x los valores 1, 2, 3, 4, 5, 6, 7, 8, 9 y 10.

screen:print( 0, y, "x = " .. x, blanco )

y = y + 10

end

 

Si ponemos un tercer parámetro este será interpretado como el intervalo, véase el ejemplo:

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 =  21

--------------------------------------------------------------------------------------------------------------------------------

break              -- Rompe los bucles "for", "repat ... 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:

blanco          = Color.new ( 255, 255, 255 )

negro            = Color.new (   0,   0,   0 )

pad, oldpad = Controls.read(), pad

opcion_menu, opcion_max  = 1, 6

fin_sel_menu, fin_fin_menu = false, false

local function pinta_menu()

screen:clear( negro )

screen:print( 100, 80, "TUTORIAL DE UN MENU POR PIPAGERARDO." , blanco)

screen:print( 100, 90, "------------------------------------" , blanco)

screen:print( 200,100, "OPCION 1." , blanco)

screen:print( 200,110, "OPCION 2." , blanco)

screen:print( 200,120, "OPCION 3." , blanco)

screen:print( 200,130, "OPCION 4." , blanco)

screen:print( 200,140, "OPCION 5." , blanco)

screen:print( 200,150, "SALIR." , blanco)

if          opcion_menu == 1  then screen:print( 160, 100, "-1->" , blanco)

elseif   opcion_menu == 2  then screen:print( 160, 110, "-2->" , blanco)

elseif   opcion_menu == 3  then screen:print( 160, 120, "-3->" , blanco)

elseif   opcion_menu == 4  then screen:print( 160, 130, "-4->" , blanco)

elseif   opcion_menu == 5  then screen:print( 160, 140, "-5->" , blanco)

elseif   opcion_menu == 6  then screen:print( 160, 150, "-S->" , blanco)

end

screen.waitVblankStart() ; screen.flip()

end

repeat

pinta_menu()

repeat

pad = Controls.read()

if     pad:right() and not oldpad:right() then

opcion_menu = opcion_menu + 1

if opcion_menu > opcion_max then opcion_menu = 1 end

pinta_menu()

elseif pad:left() and not oldpad:left() then

opcion_menu = opcion_menu - 1

if opcion_menu < 1 then opcion_menu = opcion_max end

pinta_menu()

elseif pad:up() and not oldpad:up()   then

opcion_menu = opcion_menu - 1

if opcion_menu < 1 then opcion_menu = opcion_max end

pinta_menu()

elseif pad:down() and not oldpad:down() then

opcion_menu = opcion_menu + 1

if opcion_menu > opcion_max then opcion_menu = 1 end

pinta_menu()

end

if pad:cross() or pad:circle() then fin_sel_menu = true end

screen.waitVblankStart(2)

oldpad = pad

until fin_sel_menu

fin_sel_menu = false

screen:clear( negro )

if          opcion_menu == 1  then screen:print(200, 100, "OPCION 1.", blanco)

elseif    opcion_menu == 2  then screen:print(200, 110, "OPCION 2.", blanco)

elseif    opcion_menu == 3  then screen:print(200, 120, "OPCION 3.", blanco)

elseif    opcion_menu == 4  then screen:print(200, 130, "OPCION 4.", blanco)

elseif    opcion_menu == 5  then screen:print(200, 140, "OPCION 5.", blanco)

elseif    opcion_menu == 6  then screen:print(200, 150, "SALIR."   , blanco)

fin_fin_menu = true

end

screen.waitVblankStart(); screen.flip()

screen.waitVblankStart( 60 )

until fin_fin_menu

System.Quit()

 

Ejemplo de control usando máscaras:

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 (Indice)

--------------------------------------------------------------------------------------------------------------------------------

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:

 

Ejemplo de una función para escribir en Español:

-- 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

--------------------------------------------------------------------------------------------------------------------------------

font = Font.createProportional()     -- Crea una fuente de texto de caracteres proporcionales.

 

letra25 = Font.createProportional()        -- La anchura de los caracteres es proporcional.

letra25:setPixelSizes(0, 25)                    -- Altura de la letra 25 pixeles.

blanco = Color.new( 255, 255, 255 )

screen:fontPrint( letra25, 120, 100, "Script de Ejemplo",  blanco )

screen.flip()

 

font = Font.createMonoSpaced()    -- Crea una fuente de texto con los caracteres monoespaciados.

 

letra30 = Font.createMonoSpaced()       -- Todos los caracteres tiene la misma anchura.

letra30:setPixelSizes( 0, 30 )                  -- Altura de la letra 30 pixeles.

blanco = Color.new( 255, 255, 255 )

screen:fontPrint( letra30, 120, 100, "Script de Ejemplo", blanco )

screen.flip()

 

nil font:setPixelSizes( ancho , alto )

Especifica la altura y anchura de la letra. Ver los ejemplos de arriba.

 

nil font:setCharSize( ancho , alto , number_dpiX , number_dpiY )

Especifica la altura y anchura de la letra igual que "font:setPixelSizes()" y además permite definir la resolución dpi de la fuente de texto.

 

ancho , alto = font:getTextSize( string )

Debuelve el ancho y el alto que ocuparía un "string" si fuese escrito con cierta fuente de texto "font".

 

font = Font.load( path/filename.ttf )

 

fuente = Font.load( "./fuentes/font.ttf" )             -- Carga una fuente de texto formato "TTF"

fuente:setPixelSizes(0, 20)                                  -- Altura de la fuente 20 pixeles.

blanco = Color.new( 255, 255, 255 )

screen:fontPrint( fuente, x, y, "Script de Ejemplo", blanco )

screen.flip()

 

nil image:fontPrint( font , x , y , var , color )

Escribe en una imagen un texto o variable usando una fuente "TTF", ver ejemplo de arriba. Por lo demás funciona igual que "image:print(x,y, var, color)"

--------------------------------------------------------------------------------------------------------------------------------

FUENTES DE TEXTO APARTIR DEL LUAPLAYERHM8

--------------------------------------------------------------------------------------------------------------------------------

Font.init()       Inicializa la nueva libreria de fuentes de texto "TTF".

 

Font.term()     Termina y cierra la libreria de fuentes de texto "TTF".

 

Font.load( "font.ttf", slot )    Carga una fuente de texto "TTF" en uno de los cinco "slots". Rango de 1 a 5.

Ejemplo:         Font.load( "ms0:/font.ttf" , 1 )

 

Font.unload( fontslot )          Borra una fuente "TTF" de un "slot".

Ejemplo:         Font.unload( 1 )

 

Font.color( Rojo, Verde, Azul, Alpha )   Retorna un valor Hexadecimal de los componentes de un color.

Ejemplo:         rojo = Font.color( 255, 0, 0, 255 )  -- "0xFF0000FF

 

Font.print( x, y, var, color, fontslot )       Escribe en la pantalla "screen" con una fuente de texto "TTF".

Ejemplo:

Font.init()

Font.load( "ms0/font.ttf", 1 )

blanco = Font.color( 255, 255, 255, 255 )

Font.print( 10, 10, "Hola Betapeseperos.", blanco, 1 )

screen.flip()

Font.unload(1)

Font.term()

 

IntraFont.init()     Inicializa la nueva libreria de las IntraFont o fuentes propias de la PSP "PGF".

 

IntraFont.term()  Termina y cierra la libreria IntraFont.

 

IntraFont.load( "flash0:/font/ltn8.pgf", opcion )     Carga una fuente texto "PGF" y una opción de las cuatro:

opcion: 1 = Normal      2 = Calidad Rápida    3 = Calidad Buena     4 = Japaniese

Ejemplo:     IntraFont.load( "flash0:/font/ltn8.pgf", 2 )

 

IntraFont.color( Rojo, Verde, Azul, Alpha )       Retorna un valor Hexadecimal de los componentes de un color.

Ejemplo:         rojo = IntraFont.color( 255, 0, 0, 255 )  -- "0xFF0000FF

 

IntraFont.print( x, y, var, Size, Color, Glow )    Escribe en pantalla con un Color y una Sombra.

Ejemplo:

IntraFont.init()

IntraFont.load( "flash0:/font/ltn8.pgf", 2 )

red = IntraFont.color( 255, 0, 0, 255 )

yellow = IntraFont.color( 0, 255, 255, 255 )

screen:clear()

Gu.start3d()

IntraFont.print( 1, 35, "WARNING", 3, yellow, red )

IntraFont.print( 1, 90, "PELIGRO", 1, red, 0 )

Gu.end3d()

screen.flip()

IntraFont.term()

--------------------------------------------------------------------------------------------------------------------------------

image  = Image.createEmpty( ancho , alto )

Crea una imagen de una determinada anchura y altura. En teoría se pueden crear imágenes de1600x1440 pixeles, aunque la pantalla de la PSP es de tan solo 480x272 pixeles. Hay que tener cuidado porque estas imágenes a lo bruto ocupan muchísima memoria. Un simple calculo estimativo, una imagen de 480 x 272 puntos tiene en total 130.560 píxel, cada píxel tiene cuatro componentes R,G,B y A, si lo multiplicamos por cuatro nos da 522.240, si cada componente ocupa un Byte (0-255) lo dividimos por 1024 para que nos de en KiloBytes la friolera de 510 Kbytes, más de medio mega una imagen.

 

blanco = Color.new( 255, 255, 255 )

imagen = Image.createEmpty( 50, 50 )  -- Creamos una imagen de 50x50

imagen:clear( blanco )                           -- La pintamos de blanco.

screen:blit( 100, 60, imagen )

screen.flip()

--------------------------------------------------------------------------------------------------------------------------------

nil image_a:blit( x ,  y , image_b [ ,  x1,  y1, ancho, alto ] [ , Alpha = true / false ] )

Esta función en su forma más básica pega la imagen_b sobre la imagen_a. Pero tiene más opciones, como pegar solo una parte de la imagen_b sobre la imagen_a. Y por último tiene un "boolean" que activa o desactiva el canal "Alpha" de las imágenes. Esto son las transparencias de una imagen, si la imagen tiene partes transparentes tendremos que pones al final un "true". Si no se pone nada por defecto utiliza las transparencias aunque supongo que al desactivarlas se gana algo de velocidad.

 

rojo = Color.new( 255, 0, 0 )

azul = Color.new( 0, 0, 255 )

imagen_a = Image.createEmpty( 50, 50 )             -- Creamos una imagen de 50x50

imagen_b = Image.createEmpty( 25, 25 )             -- Creamos una imagen de 25x25

imagen_a:clear( rojo )                                           -- La pintamos de rojo.

imagen_b:clear( azul )                                          -- La pintamos de azul.

imagen_a:blit( 12, 12, imagen_b, false )              -- Pegamos imagen_b sobre imagen_a

screen:blit(100, 80, imagen_a, 0, 0, 25, 25, false)         -- Pegamos parte de imagen_a en pantalla.

screen.flip()                                                           -- Mostramos la pantalla.

--------------------------------------------------------------------------------------------------------------------------------

nil image:drawLine( x , y , x1, y1, color )                      -- Dibuja una línea.

--------------------------------------------------------------------------------------------------------------------------------

nil image:fillRect( x ,  y , ancho , alto , color )               -- Dibuja un rectángulo.

--------------------------------------------------------------------------------------------------------------------------------

nil image:pixel( x , y , color )                                          -- Pinta un pixel o punto.

 

imagen = Image.createEmpty( 50 , 50 )

blanco = Color.new( 255, 255, 255 )

imagen:pixel( 10, 10, blanco )

screen:blit( 0, 0, imagen, true )

screen.flip()

--------------------------------------------------------------------------------------------------------------------------------

color = imagen:pixel( x , y ) -- Obtiene el color de un punto o pixel.

--------------------------------------------------------------------------------------------------------------------------------

table_color[r,g,b,a] = color:colors() -- Crea una tabla con las componentes R,G,B,A del color dado.

 

imagen = Image.load( "./imagenes/foto.png" )

color = imagen:pixel( 10, 30 )

table_color       = color:colors()

table_color.r    = Componente_Roja_0-255

table_color.g    = Componente_Verde_0-255

table_color.b    = Componente_Azul_0-255

table_color.a    = Componente_Opacidad_0-255

--------------------------------------------------------------------------------------------------------------------------------

boolean ( color_a == color_b )         -- Sirve para comparar si dos colores son iguales.

--------------------------------------------------------------------------------------------------------------------------------

dibuja_circulo( imagen , x, y, radio, color )

En el LuaPlayer no viene por defecto una función para dibujar circulos, pero podemos crearla fácilmente con las herramientas que nos proporciona el LUA.

 

function dibuja_circulo( imagen , x, y, radio, color)

local paso   = 0.1

local fin    = 6.28

for grados = 0, fin, paso do

local x1 = math.floor(radio * math.cos(grados)) + x

local y1 = math.floor(radio * math.sin(grados)) + y

if x1 < 480 and x1 > 0 then

if y1 < 272 and y1 > 0 then imagen:pixel( x1, y1, color ) end

end

end

end

 

red = Color.new(255,0,0)

screen:clear()

dibuja_circulo( screen, 240, 136, 130, red )

screen.flip()

--------------------------------------------------------------------------------------------------------------------------------

image  = Image.load( path/filename.png| .jpg | .bmp )

Crea una imagen o superficie con el archivo gráfico dado.

 

imagen = Image.load( "./imagenes/foto.png" )

screen:blit( 0, 0, imagen )

screen:flip()

--------------------------------------------------------------------------------------------------------------------------------

ancho = image:width()                        -- Obtiene el ancho en pixels de una imagen.

 

imagen    = Image.load( "./imagenes/foto.png" )

ancho       = imagen:width()

alto          = imagen:height()

--------------------------------------------------------------------------------------------------------------------------------

alto = image:height()                          -- Obtiene el alto en pixels de una imagen.

--------------------------------------------------------------------------------------------------------------------------------

image = Image.loadFromMemory( data )

Crea una imagen con los datos de un archivo gráfico cargado anteriormente en memoria. Primero se carga un  archivo gráfico ( .png | .jpg ) en la memoria. Como está comprimido no ocupa mucho. Luego cuando se desee utilizar la imagen  se descomprime y pega en una imagen especificada. Las imágenes ocupan mucho espacio en la memoria si no están comprimidas.

 

jpg_lectura_imagen = io.open("./Imagenes/foto.jpg", "rb") 

jpg_imagen_foto    = jpg_lectura_imagen:read("*a")          -- Lectura a memoria.

jpg_lectura_imagen:close()

img_foto = Image.loadFromMemory( jpg_imagen_foto )   -- Descompresión en una imagen.

--------------------------------------------------------------------------------------------------------------------------------

nil image:save( filename.png | .jpg | .bmp )               -- Graba en un archivo la imagen.

--------------------------------------------------------------------------------------------------------------------------------

nil screen.flip()

Muestra en pantalla lo dibujado en "screen". La pantalla de la PSP tiene dos imágenes o superficies, de tal manera que cuando dibujes algo siempre lo haces en la imagen que no se está mostrando. Con esta función  produces un volteo de imágenes. Es como una pizarra con dos caras; pintas en la cara posterior y cuando usas "screen.flip" volteas la pizarra enseñando lo que habías dibujado. Si vuelves a dibujar ahora dibujarás en la cara que antes se estaba mostrando. Hay que tenerlo muy claro porque si dibujas algo en una cara y en la otra no se pueden producir efectos gráficos no deseados.

--------------------------------------------------------------------------------------------------------------------------------

nil screen.waitVblankStart( [number] )

Espera hasta que la pantalla esté preparada para empezar a dibujar. Normalmente las pantallas empiezan a dibujar por la parte de arriba línea por línea hasta llegar abajo del todo. Si la pantalla es de 30 fotogramas por segundo realizará esta operación 30 veces en un segundo. Suficientemente rápido para engañar al ojo humano. Pero si no esperamos a que la pantalla esté lista y mandamos la orden de "screen.flip()" cuando va por mitad de  la pantalla, se producirá el efecto que durante un breve intervalo de tiempo veremos solo media imagen pintada en la pantalla. Para evitar esto se usa esta función. También se le puede indicar cuantos ciclos de pantalla se desea esperar. Esto puede servir para producir el efecto de cámara lenta o para producir una pausa en la ejecución de un programa. Aunque para producir una pausa es mejor usar "System.sleep( milisegundos )"

 

--

FUNCIONES DE SONIDO (Índice)

--------------------------------------------------------------------------------------------------------------------------------

nil System.oaenable()

nil System.oadisable()

Por problemas de compatibilidad entre la vieja librería de sonidos "WAV, IT, XM, S3M, MOD" y la nueva librería "MP3, AA3, OGG" no pueden estar activas las dos a la vez. Por defecto el LuaplayerHM arranca con la librería "MP3, AA3, OGG", así que cuando se vallan ha reproducir sonidos "WAV, IT, XM, S3M, MOD" hay que activar la vieja librería usando "System.oaenable()", y si después se va ha usar la otra pues se desactiva usando "System.oadisable()". No debe ser desactivada la vieja librería si no ha sido activada.

 

Nota: En el LuaPlayerHM7 una vez desactivada la librería vieja "System.oadisable()" se cuelga la PSP si se vuelve a activar con "System.oaenable()". Este fallo está comunicado a Homemister & PickDat, esperemos que lo corrigan en posteriores versiones.

 

System.oaenable()                                     -- Activa la vieja librería.

sound = sound.load( "./path/sonido.wav")

sound:play()

System.oadisable()                                    -- Desactiva la vieja librería.

Mp3me.load( "./path/sonido.mp3" )

Mp3me.play()                 

--------------------------------------------------------------------------------------------------------------------------------

number SoundSystem.panoramicSeparation( number_0-128 )

--------------------------------------------------------------------------------------------------------------------------------

number SoundSystem.reverb( number_0-15 )

--------------------------------------------------------------------------------------------------------------------------------

number SoundSystem.SFXVolume( number_0-128 )

--------------------------------------------------------------------------------------------------------------------------------

sound Sound.load( ./path/filename.wav , boolean_replay )

WAV PCM unsigned [ 8 bit | 16 bit ] y [ 22050 | 16000 | 11025 | 8000 | 7333 | 6000 | 5500 |  KHz mono ]

 

-- Si sólo se quiere reproducir sin editarlo:

System.oaenable()

_sound = sound.load( "./path/sonido.wav", false)

_sound:play()                        

 

-- Si se quiere modificar:

System.oaenable()

_sound = sound.load( "./path/sonido.wav")

_voice = _sound:play()                                 

_voice:volume( [0-255] )                         -- Volumen.

_voice:stop()                                             -- Para el sonido.

_voice:resume()                                        -- Continúan el sonido. Posible fallo o bug.

_voice:pan( [0-255] )                                -- Balance izquierda-derecha del sonido.

_voice:frequency(number [1-80000])      -- Frecuencia de reproducción.

_boolean = _voice:playing()                     -- true si se esta ejecutando.

 

-- Por investigar:

_sound:tostring()

_voice:tostring()

_sound:gc()

--------------------------------------------------------------------------------------------------------------------------------

nil Music.playFile( ./path/filename.it.xm.mod , boolean_replay )

Musica tipo UNI, IT, XM, S3M, MOD, MTM, STM, DSM, MED, FAR, ULT o 669

System.oaenable()

Music.playFile("./cancion.it", true)     -- true repite musica infinito.

--------------------------------------------------------------------------------------------------------------------------------

number Music.volume( number_0-128 )      -- 0 a 128 max

--------------------------------------------------------------------------------------------------------------------------------

nil Music.pause()       -- Pausa

--------------------------------------------------------------------------------------------------------------------------------

nil Music.resume()    -- Reanuda.

--------------------------------------------------------------------------------------------------------------------------------

nil Music.stop()         -- Para.

--------------------------------------------------------------------------------------------------------------------------------

boolean Music.playing()        --> boolean = Music.playing()          -- true si se esta tocando la musica.

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.load()                        Aa3me.load()                        Mp3.load()                    Ogg.load()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.stop()                        Aa3me.stop()                        Mp3.stop()                    Ogg.stop()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.pause()                     Aa3me.pause()                     Mp3.pause()                 Ogg.pause()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.play()                        Aa3me.play()                        Mp3.play()                    Ogg.play()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.eos()                         Aa3me.eos()                         Mp3.EndOfStream()                                               Ogg.EndOfStream()

"eos" es igual a "Endofstream" en otras palabras el final de la canción, canción terminada.

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.gettime()                  Aa3me.gettime()                  Mp3.getTime()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.songTime()              Aa3me.songTime()              Mp3.songTime()           Ogg.songTime()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.artist()                      Aa3me.artist()                      Mp3.artist()                  Ogg.artist()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.title()                        Aa3me.title()                        Mp3.title()                    Ogg.title()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.album()                     Aa3me.album()                     Mp3.album()                 Ogg.album()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.genre()                     Aa3me.genre()                     Mp3.genre()                 Ogg.genre()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.year()                       Aa3me.year()                       Mp3.year()                   Ogg.year()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.trackNumber()        Aa3me.trackNumber()        Mp3.trackNumber()    Ogg.trackNumber()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.layer()                      Aa3me.layer()                      Mp3.layer()                  Ogg.layer()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.kbit()                        Aa3me.kbit()                        Mp3.kbit()                    Ogg.kbit()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.mode()                      Aa3me.mode()                      Mp3.mode()                  Ogg.mode()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.percent()                  Aa3me.percent()

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.rawSongTime()       Aa3me.rawSongTime()

Devuelve la cantidad de segundos en una canción. los datos en  para uso de barras de progreso.

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.instantBitrate()       Aa3me.instantBitrate()       -- Devuelve el instante bitrate.

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.vis()                          Aa3me.vis()

Devuelve los datos correspondientes a una visualización (utilizar un número entre 1 y 100).

Por ejemplo: Mp3me.vis(45) -- 1 es más Trebel donde 100 es como la mayoría de base.

--------------------------------------------------------------------------------------------------------------------------------

NUEVAS FUNCIONES SONIDO LUAPLAYERHM8

--------------------------------------------------------------------------------------------------------------------------------

Mp3me.setPos()   Ajusta la posición del archivo mp3, puede ser usado para FastFwd o Back. Retorna la posición.

Mp3me.getPos()  Retorna la posición en el archivo.

Mp3me.stream()  Retorna el buffer restante del mp3.

Mp3me                 Flujo de canciones de Internet

Mp3me.visL()      Devolverá el Visualtion datos para canal izquierdo.

Mp3me.visR()      Devolverá el Visualtion datos para canal derecho.

Aa3me.setPos()   Ajusta la posición del archivo mp3, puede ser usado para FastFwd o Back. Retorna la posición.

Aa3me.getPos()   Retorna la posición en el archivo

Aa3me.stream()   Retorna el buffer restante del Aa3.

Aa3me                  Flujo de canciones de Internet

Aa3me.visL()       Devolverá el Visualtion datos para canal izquierdo.

Aa3me.visR()       Devolverá el Visualtion datos para canal derecho.

Aac.load()

Aac.play()

Aac.stop()

Aac.eos()

Aac.gettime()

Aac.percent()

Aac.pause()

Aac.songTime()

Aac.artist()

Aac.title()

Aac.album()

Aac.genre()

Aac.year()

Aac.trackNumber()

Aac.layer()

Aac.kbit()

Aac.mode()

--

FUNCIONES CONTROL DE TIEMPO (Índice)

--------------------------------------------------------------------------------------------------------------------------------

timer Timer.new()     -- CONTADORES DE TIEMPO

contador = Timer.new()                       -- Define un contador.

contador:start()                                    -- Lo pone en marcha.

contador:stop()                                     -- Lo para.

tiempoActual = contador:time()          -- Lectura.

contador:reset(0)                                  -- Lo pone a 0.

 

Ejemplo que cuenta hasta 10 segundos :

contador = Timer.new()             -- Crea un nuevo contador llamado "contador"

while true do                              -- Bucle infinito.

contador:start()                 -- Arranca el contador.

repeat                                 -- Repite hasta que el tiempo sobrepase de 10000 milisegundos.

tiempo = math.floor( contador:time() / 1000 )       -- Convierte milisegundos a segundos.

screen:clear( negro )                                               -- Borra la pantalla.

screen:print( 0, 0, "Tiempo en segundos = " .. tiempo, blanco )

screen.waitVblankStart()                                        -- Espera a que se prepare la pantalla.

screen.flip()                                                             -- Muestra la pantalla.

until tiempo > 10000

contador:stop()                  -- Detiene el contador.

contador:reset(0)               -- Pone a cero el contador.

end

--------------------------------------------------------------------------------------------------------------------------------

nil System.sleep( number_milisegundos )

Pone la aplicación homebrew ha dormir x milisegundos, por ejemplo: System.sleep (3000) --"3 segundos"

 

Ejemplo que cuenta 10 segundos usando System.sleep():

blanco = Color.new( 255, 255, 255 )

negro  = Color.new(   0,   0,   0 )

for s = 1, 10 do

System.sleep(1000)                        -- Espera un segundo.

screen:clear( negro )

screen:print( 0, 0, "Tiempo = " .. s, blanco )

screen.waitVblankStart(); screen.flip()

end

--------------------------------------------------------------------------------------------------------------------------------

os.time( [tabla] )

Devuelve el tiempo actual cuando se llama sin argumentos, o un tiempo representando la fecha y hora  especificadas en la tabla dada. Ésta debe tener los campos year, month y day, y puede tener los campos hour, min, sec e isdst (para una descripción de esos campos, véase la función os.date). El valor retornado es un número, cuyo significado depende del sistema. En POSIX, Windows y algunos otros sistemas este número cuenta el número de segundos desde alguna fecha inicial dada (la "época"). En otros sistemas el significado no está especificado, y el número retornado por time puede ser usado sólo como argumento de las funciones date y difftime.

--------------------------------------------------------------------------------------------------------------------------------

os.date( [formato [, tiempo]] )

Devuelve un string o una tabla conteniendo la fecha y hora, formateada de acuerdo con el string dado en  formato. Si el argumento tiempo está presente entonces ese tiempo concreto es el que se formatea (véase la  función os.time para una descripción de este valor). En caso contrario, date formatea el tiempo actual. Si formato comienza con '!' entonces el tiempo se formatea de acuerdo al Tiempo Universal Coordinado. Después de este carácter opcional, si formato es *t entonces date devuelve una tabla con los siguientes campos: year (cuatro dígitos), month (1--12), day (1--31), hour (0--23), min (0--59), sec (0--61), wday (día de la semana, el domingo es 1), yday (día dentro del año), e isdst (booleano, verdadero si es horario de verano). Si formato no es *t entonces date devuelve el tiempo como un string, formateado de acuerdo con las mismas reglas que la función strftime de C. Cuando se invoca sin argumentos date devuelve una representación razonable de la fecha y la hora que depende    de la máquina y del sistema local (esto es, os.date() equivale a os.date("%c")).

 

%c    fecha/hora (locale)                                      %x    solo fecha (local)

%X   solo hora (local)                                          %y    año (nn)

%Y   año (yyyy)                                                   %j    día del año (001..366)

%m  mes (01..12)                                                 %b    nombre abreviado del mes (local)

%B   nombre completo del mes (local)               %d    día del mes (01..31)

%U   número semana (01..53), Domingo            %W  número semana (01..53), Lunes

%w   día semana (0..6), 0 es Domingo                %a    nombre abreviado día semana (local)

%A   nombre día de la semana (local)                 %H   hora (00..23)

%I    hora (01..12)                                                %p    AM o PM

%M  minuto (00..59)                                            %S   segundo (00..61)

%Z   nombre zona horaria, si lo hay.

 

Ejemplo:

tiempo          = os.time()                                    -- Retorna el tiempo del sistema.

string_fecha = os.date( "%c", tiempo )             -- Formatea el tiempo a un "string"

table_fecha  = os.date( "*t", tiempo )               -- Formatea el tiempo a una "table"

anno             = table_fecha.year                        -- Año en cuatro dígitos Ej: 2008

mes              = table_fecha.month                     -- 1 = Enero, 2 = Febrero, etc...

dia                = table_fecha.day                         -- Dia del mes del 1 al 31.

dia_semana = table_fecha.wday                      -- 1 = Domingo, 2 = Lunes, etc...

dia_anno      = table_fecha.yday                       -- Del 1 al 365.

hora_verano = tostring( table_fecha.isdst )      -- Booleano "true" para verano.

hora              = table_fecha.hour

minuto         = table_fecha.min

segundo       = table_fecha.sec

screen:print(0,  0, "Fecha en string = " .. string_fecha    , blanco)

screen:print(0, 10, "Anno                = " .. anno                , blanco )

screen:print(0, 20, "Mes                  = " .. mes                 , blanco )

screen:print(0, 30, "Dia                   = " .. dia                   , blanco )

screen:print(0, 40, "Dia Semana     = " .. dia_semana     , blanco )

screen:print(0, 50, "Dia Anno         = " .. dia_anno         , blanco )

screen:print(0, 60, "Hora Verano    = " .. hora_verano    , blanco )

screen:print(0, 70, "Hora                 = " .. hora                 , blanco )

screen:print(0, 80, "Minuto             = " .. minuto            , blanco )

screen:print(0, 90, "Segundo           = " .. segundo          , blanco )

screen.waitVblankStart(); screen.flip()

--------------------------------------------------------------------------------------------------------------------------------

os.clock()       -- Devuelve una aproximación al total de segundos de CPU usados por el programa.

--------------------------------------------------------------------------------------------------------------------------------

os.difftime( t2, t1 )

Devuelve el número de segundos desde el instante t1 hasta el t2. En POSIX, Windows y algunos otros sistemas este valor es exactamente t2-t1.

 

Rojo = Color.new (255, 0, 0)

Negro= Color.new (0, 0, 0)

Tiempo = os.date ("!*t")

Tiempo_viejo = Tiempo.min

while true do 

Tiempo = os.date ("!*t")

Tiempo_nuevo = Tiempo.min

Diferencia = os.difftime( Tiempo_nuevo, Tiempo_viejo )

screen:clear( Negro )

screen:print(5, 5, Diferencia.." minuto(s) han pasado.", Rojo )

screen.flip()

end

--------------------------------------------------------------------------------------------------------------------------------

System.getDate( opción )

Retorna la fecha de la consola PSP, no funciona en el PC al ser una función específica. Solo una opción a la vez: año = 1, mes = 2, día = 3

anno = System.getDate(1)              -- Retorna el año.

--------------------------------------------------------------------------------------------------------------------------------

System.getTime( opción )

Devuelve la hora de la consola PSP, no funciona en el PC al ser una función específica. Solo una opción:  hora = 1, minutos = 2, segundos = 3, microseg = 4,  pm-am = 5.

hora = System.getTime(1)              -- Retorna la hora de la PSP.

 

--

FUNCIONES 3D (Indice)

--------------------------------------------------------------------------------------------------------------------------------

Gu.start3d()   Gu.end3d()

Arranca y finaliza el modo "Gu" para dibujar en 3D. Cuando se finaliza con la función "Gu.end3d()" todo lo dibujado pasará a "screen" para ser mostrado con la función "screen.flip()"

--------------------------------------------------------------------------------------------------------------------------------

Gu.clearColor( color )

Toma un color como argumento establecido por la función "Color.new()". Con este color se borra la pantalla en el modo "Gu" entorno 3D cuando se use la función "Gu.clear()".

--------------------------------------------------------------------------------------------------------------------------------

Gu.clearDepth( [0-255] ) 

Toma un valor entero de 0 a 255, siendo 0 sin profundidad y 255 es la profundidad más profunda posible. Sirve para no dibujar nada de lo que no esté dentro del rango de profundidad especificado, cuando se invoca la función "Gu.clear" se borran los polígonos que no estén dentro del rango de profundidad.

--------------------------------------------------------------------------------------------------------------------------------

Gu.clear( Gu.COLOR_BUFFER_BIT + Gu.DEPTH_BUFFER_BIT )

Gu.COLOR_BUFFER_BIT -- Borra el buffer de color para el valor fijado por "Gu.clearColor()"

Gu.DEPTH_BUFFER_BIT -- Borra la profundidad del bufer para el valor fijado por "Gu.clearDepth()"

--------------------------------------------------------------------------------------------------------------------------------

Gum.matrixMode( matiz )

Matrizes:

Gu.PROJECTION   -- Matriz de CAMARA

Gu.VIEW                 -- Matriz de Ventana, para ejectuar los calculos.

Gu.TEXTURE          -- Matriz de Texturas para Objetos 3D.

Gu.MODEL             -- Matriz de Modelado y Modificación de Objetos 3D.

--------------------------------------------------------------------------------------------------------------------------------

Gum.loadIdentity()               -- Pasa los parámetros a la "Matriz" activa, es lo mismo que "screen.flip()"

--------------------------------------------------------------------------------------------------------------------------------

Gum.perspective( screenDepth , screenRatio , nearClipping , farClipping )

screenDepth    = [1-255]          Zoom, 1 minimo, 255 máximo.

screenRation   = 480/272         Proporciones de la pantalla, tipica 480/272

nearClipping   = 0.5                 Corte del eje Z cercano a la camara

farClipping     = 1000              Corte del eje Z lejano a la camara.

--------------------------------------------------------------------------------------------------------------------------------

Gum.translate( X , Y , Z )                   -- Traslada un objeto 3D.

--------------------------------------------------------------------------------------------------------------------------------

Gum.rotateXYZ(X , Y ,  Z )                -- Gira y rota un objeto 3D.

--------------------------------------------------------------------------------------------------------------------------------

Gu.drawArray( Primitive , Gu.COLOR_8888 + Gu.VERTEX_32BITF + Gu.TRANSFORM_3D , Verticies )

Primitive:

Gu.POINTS - dibuja puntos, 1v puntos en la pantalla.

Gu.LINES    - dibuja líneas, 2v del punto de partida al punto final.

Gu.LINES_STRIP- dibuja líneas conectadas, 2v para la primera línea  y 1v para las siguientes líneas (del punto de partida al punto final para la primera línea y el punto final después para cada nueva línea)

Gu.TRIANGLES - dibuja triángulos, 3v (el  punto de empiece, el  punto medio y el punto final ).

Gu.TRIANGLES_STRIP - dibuja triángulos conectados, 3v para el primer triángulo y 1v para los siguientes (el  punto de empiece, el  punto medio y el punto final para el primer triángulo y el punto medio para los siguientes triángulos). Dibuja triángulos en la pantalla uniendo los nuevos triángulos con los dos últimos vértices pasados como el punto de empiece, el  punto final y el nuevo vértice como el  punto medio.

Gu.TRIANGLES_FAN - dibuja triángulos conectados, 3v para el primer triángulo y 2v para los siguientes. Dibuja triángulos en la pantalla uniendo los nuevos triángulos con el último punto pasado y los dos siguientes vértices pasados.

Gu.SPRITES - Dibuja Sprites, 2v (de la parte inferior-izquierda a la parte superior-derecha). Dibuja Sprites o cajas en la pantalla. Ojo, no son cuadrados ni rectángulos, si se giran sus puntos sus lados siempre son paralelos a los lados de la pantalla.

 

Texture/colour depth variables:

Gu.TEXTURE_8BIT   - Draws an object using an 8-bit depth texture image (256 colours)

Gu.TEXTURE_16BIT - Draws an object using a 16-bit depth texture image (512 colours)

Gu.TEXTURE_32BITF -Draws an object using a 32-bit depth texture image (1024 colours)

Gu.COLOR_5650    - Draws an object using a 16-bit depth colour with a red value of 5-bits (160 red shades), a green value of 6-bits (192 green shades), a blue value of 5-bits (160 blue shades) and an ALPHA value of 0-bits (0 levels of transparency).

Gu.COLOR_5551    - Draws an object using a 16-bit depth colour with a red value of 5-bits (160 red shades), a green value of 5-bits (160 green shades), a blue value of 5-bits (160 blue shades) and an ALPHA value of 1-bit (32 levels of transparency).

Gu.COLOR_4444    - Draws an object using a 16-bit depth colour with a red value of 4-bits (128 red shades), a green value of 4-bits (128 green shades), a blue value of 4-bits (128 blue shades) and an ALPHA value of 4-bit (128 levels of transparency).

Gu.COLOR_8888    - Draws an object using a 32-bit depth colour with a red value of 8-bits (256 red shades), a green value of 8-bits (256 green shades), a blue value of 8-bits (256 blue shades) and an ALPHA value of 8-bit (256 levels of transparency).

You can pass the following vertex position sizes/normal sizes:

Gu.NORMAL_8BIT               Gu.NORMAL_16BIT                  Gu.NORMAL_32BITF

Gu.VERTEX_8BIT                 Gu.VERTEX_16BIT                   Gu.VERTEX_32BITF

You can pass the following weights:

Gu.WEIGHT_8BIT                Gu.WEIGHT_16BIT                  Gu.WEIGHT_32BITF

You can pass the following vertex index sizes:

Gu.INDEX_8BIT                   Gu.INDEX_16BIT

 And the number of weights and verticies:

Gu.WEIGHTS(n)   - 1-8        Gu.VERTICIES(n) - 1-8

You will also need to pass a 2D or 3D transformation variable:

Gu.TRANSFORM_2D            Gu.TRANSFORM_3D

--------------------------------------------------------------------------------------------------------------------------------

Gu.enable( opciones )           Gu.disable( opciones )

Opciones:

GU_ALPHA_TEST

GU_DEPTH_TEST

GU_SCISSOR_TEST

GU_BLEND

GU_CULL_FACE

GU_DITHER

GU_CLIP_PLANES

GU_TEXTURE_2D          -- Activa Texturas

GU_LIGHTING

GU_LIGHT0

GU_LIGHT1

GU_LIGHT2

GU_LIGHT3

GU_COLOR_LOGIC_OP

--------------------------------------------------------------------------------------------------------------------------------

Gu.enable(Gu.BLEND)

Gu.blendFunc( Gu.ADD, Gu.SRC_ALPHA, Gu.ONE_MINUS_SRC_ALPHA, 0, 0 )

Gu.blendFunc( int  op, int  src,  int  dest, unsigned int  srcfix, unsigned int  destfix )

Parameters:

op              - Blending Operation 

src             - Blending function for source operand

dest            - Blending function for dest operand

srcfix         - Fix value for GU_FIX (source operand)

destfix       - Fix value for GU_FIX (dest operand)

GU.ADD                   - (Cs*Bs) + (Cd*Bd)                  Cs - Source color

GU.SUBTRACT       - (Cs*Bs) - (Cd*Bd)                   Cd - Destination color

GU.REVERSE_SUBTRACT - (Cd*Bd) - (Cs*Bs)     Bs - Blend function for source fragment

GU.MIN                    - Cs < Cd ? Cs : Cd                     Bd - Blend function for destination fragment

GU.MAX                  - Cs < Cd ? Cd : Cs

GU.ABS                    - |Cs-Cd|

Gu.SRC_COLOR

Gu.ONE_MINUS_SRC_COLOR

Gu.SRC_ALPHA

Gu.ONE_MINUS_SRC_ALPHA

Gu.DST_ALPHA

Gu.ONE_MINUS_DST_ALPHA

Gu.DST_COLOR

Gu.ONE_MINUS_DST_COLOR

Gu.FIX

--------------------------------------------------------------------------------------------------------------------------------

Gu.light ( int light, type, components, position )    

light  - Light index

Available light types are:

GU_DIRECTIONAL        - Directional light

GU_POINTLIGHT           - Single point of light

GU_SPOTLIGHT             - Point-light with a cone

Available light components are:

GU_AMBIENT_AND_DIFFUSE

GU_DIFFUSE_AND_SPECULAR

GU_UNKNOWN_LIGHT_COMPONENT

--------------------------------------------------------------------------------------------------------------------------------

Gu.lightAtt( int light,  float  atten0float  atten1,  float  atten2 )

Set light attenuation, Parameters:

light          - Light index 

atten0       - Constant attenuation factor 

atten1       - Linear attenuation factor 

atten2       - Quadratic attenuation factor 

--------------------------------------------------------------------------------------------------------------------------------

Gu.lightColor( int  light ,   int  component , color )

Set light color. Available light components are:

GU_AMBIENT

GU_DIFFUSE

GU_SPECULAR

GU_AMBIENT_AND_DIFFUSE

GU_DIFFUSE_AND_SPECULAR

--------------------------------------------------------------------------------------------------------------------------------

Gu.lightMode( int  mode 

Set light mode. Available light modes are:

GU_SINGLE_COLOR

GU_SEPARATE_SPECULAR_COLOR

Separate_specular_colors se utilizan para interpolar los especular componente independiente, a fin de que pueda ser añadido al fragmento después de la textura del color.

--------------------------------------------------------------------------------------------------------------------------------

Gu.lightSpot ( int  light ,  direction ,  float  exponent , float  cutoff )   

Set spotlight parameters. Parameters:

light          - Light index 

direction   - Spotlight direction 

exponent   - Spotlight exponent 

cutoff        - Spotlight cutoff angle (in radians) 

--------------------------------------------------------------------------------------------------------------------------------

Gu.ambientColor( color )     -- Color ambiente zonas no iluminadas.

--------------------------------------------------------------------------------------------------------------------------------

Gu.texEnvColor( color  )  

Especificar la textura del color medio ambiente. Esto se utiliza en función de la textura cuando un color constante que se necesita. Ver "sceGuTexFunc()" para obtener más información.

--------------------------------------------------------------------------------------------------------------------------------

Gu.texFilter ( int  min ,  int  mag  )    

Establecer la forma en que la textura se filtra. Los filtros disponibles son los siguientes:

GU_NEAREST

GU_LINEAR

GU_NEAREST_MIPMAP_NEAREST

GU_LINEAR_MIPMAP_NEAREST

GU_NEAREST_MIPMAP_LINEAR

GU_LINEAR_MIPMAP_LINEAR

Parámetros:

min            - Reducción al mínimo de filtro.

mag           - Aumento del filtro.

--------------------------------------------------------------------------------------------------------------------------------

Gu.texFunc( int  tfx ,  int  tcc

Establecer cómo se aplican las texturas. Clave para aplicar los modos:

Cv - Valor color resultado

Ct - Color Textura

Cf - Fragmento de color ent color

Cc - Color constante (especificado por sceGuTexEnvColor() )

Available apply-modes are: (TFX)

GU_TFX_MODULATE    - Cv=Ct*Cf TCC_RGB: Av=Af TCC_RGBA: Av=At*Af

GU_TFX_DECAL            - TCC_RGB: Cv=Ct,Av=Af TCC_RGBA: Cv=Cf*(1-At)+Ct*At Av=Af

GU_TFX_BLEND            - Cv=(Cf*(1-Ct))+(Cc*Ct) TCC_RGB: Av=Af TCC_RGBA: Av=At*Af

GU_TFX_REPLACE        - Cv=Ct TCC_RGB: Av=Af TCC_RGBA: Av=At

GU_TFX_ADD                 - Cv=Cf+Ct TCC_RGB: Av=Af TCC_RGBA: Av=At*Af

The fields TCC_RGB and TCC_RGBA specify components that differ between the two different component modes.

GU_TFX_MODULATE   - The texture is multiplied with the current diffuse fragment

GU_TFX_REPLACE        - The texture replaces the fragment

GU_TFX_ADD                - The texture is added on-top of the diffuse fragment

Available component-modes are: (TCC)

GU_TCC_RGB       - The texture alpha does not have any effect

GU_TCC_RGBA     - The texture alpha is taken into account

Parameters:

tfx                            - Which apply-mode to use 

tcc                           - Which component-mode to use 

--------------------------------------------------------------------------------------------------------------------------------

Gu.texImage( int  mipmap ,  int  width ,  int  height ,  int  tbw ,  const void *  tbp )    

Selecciona un mapa de textura. Toma una imagen para usarla como textura en los polígonos.

Parámetros:

mipmap      - Nivel Mipmap.

width         - Anchura de la textura, debe ser una potencia de 2.

height        - Altura de la textura, debe ser una potencia de 2. 

tbw             - Ancho de Buffer de Textura (bloque-alineados) 

tbp             - Puntero del buffer Textura (16 byte alineados) 

--------------------------------------------------------------------------------------------------------------------------------

Gu.texOffset( float  u ,  float  v )

Selecciona el offset de la textura. Produce desplazamientos de la textura sobre el polígono a aplicar. Solo es válido para renders con "Gu.TRANSFORM_3D". Los renders con "GU_TRANSFORM_2D" no son afectados por esta función.

Parámetros:

u  - Offset a añadir a la coordenada U. Desplaza la textura en horizontal.

v  - Offset a añadir a la coordenada V. Desplaza la textura en vertical.

--------------------------------------------------------------------------------------------------------------------------------

Gu.texScale( float  u ,  float  v  )   

Selecciona la escala de la textura. Aumenta o disminuye la textura a aplicar sobre un polígono.  Solo es válido para renders con "Gu.TRANSFORM_3D". Los renders con "GU_TRANSFORM_2D" no son afectados por esta función.

Parámetros:

u  - Escalar a multiplicar la coordenada U ancho de la imagen de la textura.

v  - Escalar a multiplicar la coordenada alto de la imagen de la textura.

--------------------------------------------------------------------------------------------------------------------------------

-- EJEMPLO DIBUJO EN 3D --

--------------------------------------------------------------------------------------------------------------------------------

Ejemplo de función para rotar imágenes:

function ZoomIMG( image, axeX, axeY, zoom, rotation)

a_ = image:width()/10

b_ = image:height()/10

axeX = axeX - (480/2)

axeY = axeY - (272/2)

axeX = axeX + image:width()/2

axeY = axeY + image:height()/2

axeX = axeX/10

axeY = axeY/10

X_ = 0-axeX+ a_/2/10

Y_ = 0-axeY+ b_/2/10

Z_ = zoom + 50

Rot = rotation + 180

Gu.start3d()

Gu.clearDepth(0)

Gu.clear(Gu.COLOR_BUFFER_BIT+Gu.DEPTH_BUFFER_BIT)

Gum.matrixMode(Gu.PROJECTION)

Gum.loadIdentity()

Gum.perspective(30, 16/9, 3, 10000)

Gum.matrixMode(Gu.VIEW)       

Gum.loadIdentity()

Gum.lookAt(0,0,0,0,0,Z_,0,1,0)

Gu.enable(Gu.TEXTURE_2D)

Gu.texImage(image)

Gu.texFunc(Gu.TFX_MODULATE, Gu.TCC_RGBA)

Gu.texEnvColor(Color.new(255,255,255))

Gu.texFilter(Gu.LINEAR, Gu.LINEAR)

Gu.texScale(1,0.8)

Gu.texOffset(0, 0)

Gu.ambientColor(Color.new(255,255,255))

Gum.matrixMode(Gu.MODEL)

Gum.loadIdentity()

Gum.translate(X_ , Y_ , Z_);

Gum.rotateXYZ(0,0,math.rad(0-Rot))

Gum.drawArray(Gu.TRIANGLES, Gu.TEXTURE_32BITF+Gu.VERTEX_32BITF+Gu.TRANSFORM_3D,

{   {1,1,  a_/2,  b_/2, 0},      {0,0,  -a_/2,  -b_/2,  0},    {1,0, a_/2,  -b_/2,  0},

     {0,0,  -a_/2,  -b_/2, 0},   {1,1, a_/2,  b_/2, 0},         {0,1, -a_/2,  b_/2, 0}        } )

Gu.end3d()

end

--------------------------------------------------------------------------------------------------------------------------------

Ejemplo de renderizado de objetos 3D:

red      = Color.new(255, 0, 0)

green  = Color.new(0, 255, 0)

blue    = Color.new(0, 0, 255)

black  = Color.new(0, 0, 0)

white  = Color.new(255, 255, 255)

gray    = Color.new(128, 128, 128)

cyan   = Color.new(100, 255, 255)

val      = 0

logo    = Image.createEmpty(64, 64)

logo:clear(gray)

logo:print(20, 20, "Lua", black)

logo:print(10, 40, "Player", black)

cube = {    {0, 0, red, -1, -1,  1},           {2, 0, red, -1,  1,  1},           {2, 2, red,  1,  1,  1},

{0, 0, red, -1, -1,  1},           {2, 2, red,  1,  1,  1},            {0, 2, red,  1, -1,  1},

{0, 0, red, -1, -1, -1},           {2, 0, red,  1, -1, -1},           {2, 2, red,  1,  1, -1},

{0, 0, red, -1, -1, -1},           {2, 2, red,  1,  1, -1},           {0, 2, red, -1,  1, -1},

{0, 0, green,  1, -1, -1},       {2, 0, green,  1, -1,  1},        {2, 2, green,  1,  1,  1},

{0, 0, green,  1, -1, -1},       {2, 2, green,  1,  1,  1},        {0, 2, green,  1,  1, -1},

{0, 0, green, -1, -1, -1},       {2, 0, green, -1,  1, -1},       {2, 2, green, -1,  1,  1},

{0, 0, green, -1, -1, -1},       {2, 2, green, -1,  1,  1},        {0, 2, green, -1, -1,  1},

{0, 0, blue, -1,  1, -1},         {2, 0, blue,  1,  1, -1},          {2, 2, blue,  1,  1,  1},

{0, 0, blue, -1,  1, -1},         {2, 2, blue,  1,  1,  1},          {0, 2, blue, -1,  1,  1},

{0, 0, blue, -1, -1, -1},         {2, 0, blue, -1, -1,  1},         {2, 2, blue,  1, -1,  1},

{0, 0, blue, -1, -1, -1},         {2, 2, blue,  1, -1,  1},          {0, 2, blue,  1, -1, -1}

}

plane = {   {blue, -8, -3,  0},                 {cyan, 8,  3,  0},                  {blue,  8,  -3,  0},

         {cyan, 8, 3,  0},                   {blue, -8,  -3,  0},                {cyan,  -8,  3,  0}

}

while true do

Gu.start3d()

Gu.clearColor( black )                             -- Color de Fondo R G B A

Gu.clearDepth(0)                                      -- Z-Buffer reinicia la matriz Z a 0

Gu.clear(Gu.COLOR_BUFFER_BIT+Gu.DEPTH_BUFFER_BIT) -- Borra Pantalla y Z-Buffer.

Gum.matrixMode(Gu.PROJECTION)     -- Matriz de CAMARA

Gum.loadIdentity()                                   -- Activa CAMARA

Gum.perspective(75, 16/9, 0.5, 1000)     -- Perspectiva 75 grados de apertura

                                                                  -- 16/9 Relaccion Ancho/Alto

                                                                  -- Zmin = 0.5  Zmax = 1000

Gum.matrixMode(Gu.VIEW)                  -- Matriz de TRABAJO o VISTA

Gum.loadIdentity()                                   -- Activa VISTA

--------------------------------------------------------------------------------------------------------------

Gum.matrixMode(Gu.MODEL)              -- Matriz de MODELADO

Gum.loadIdentity()                                   -- Activa MODELADO

Gum.translate(0, 0, -3)                             -- Traslada a Z = -3

Gu.disable(Gu.TEXTURE_2D)               -- Desactiva TEXTURA

Gum.drawArray(Gu.TRIANGLES, Gu.COLOR_8888 + Gu.VERTEX_32BITF + Gu.TRANSFORM_3D, plane)

                                                                  -- Dibuja un Plano formado por dos triangulos.

--------------------------------------------------------------------------------------------------------------

Gu.enable(Gu.BLEND)

Gu.blendFunc(Gu.ADD, Gu.SRC_ALPHA, Gu.ONE_MINUS_SRC_ALPHA, 0, 0)

Gu.enable(Gu.TEXTURE_2D) -- Activa Texturas

Gu.texImage(logo)                     -- Carga la Textura Imagen

Gu.texFunc(Gu.TFX_MODULATE, Gu.TCC_RGBA) -- Funciones de TEXTURA

                                                    -- Gu.TFX_MODULATE  Mezcla la textura con el color del modelo.

                                                    -- Gu.TFX_REPLACE      Pega la textura sin mas.

Gu.texEnvColor(white)          

Gu.texFilter(Gu.LINEAR, Gu.LINEAR)

Gu.texScale(1, 1)                       -- Escla de la Textura

Gu.texOffset(0, 0)

Gu.ambientColor(white)            -- Color ambiente zonas no iluminadas.

--------------------------------------------------------------------------------------------------------------

Gum.matrixMode(Gu.MODEL)

Gum.loadIdentity()

Gum.translate(0, 0, -3.5);

Gum.rotateXYZ(val * 0.79 * (Gu.PI/180), val * 0.98 * (Gu.PI/180.0), val * 1.32 * (Gu.PI/180.0))

Gum.drawArray(Gu.TRIANGLES, Gu.TEXTURE_32BITF + Gu.COLOR_8888 + Gu.VERTEX_32BITF + Gu.TRANSFORM_3D, cube)

--------------------------------------------------------------------------------------------------------------

Gu.end3d()

screen.flip()

val = val + 1

end

 

--

FUNCIONES, CORUTINAS Y ERRORES (Indice)

--------------------------------------------------------------------------------------------------------------------------------

type( v )

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".

--------------------------------------------------------------------------------------------------------------------------------

function()

Las funciones son fragmentos de código especializado en una tarea que puede y debe usarse repetidas veces. Esto simplifica la programación y el código repetitivo. Las funciones pueden tener o no tener argumentos de entrada. También pueden retornar argumentos con la palabra clave "return" teniendo en cuenta que al ejecutarse "return" la función termina.

----------------------------------------------------------------------------------

function pausa()                                   -- Crea una pausa de un segundo.

System.sleep(100)

end

pausa()

----------------------------------------------------------------------------------

function nuevo_vector()                      -- Crea un nuevo vector bidimensional.

return { x = 0, y = 0, magnitud = 0, angulo = 0 }

end

vector = nuevo_vector()

screen:print( 0,0, vector.x, blanco )                            --> 0

----------------------------------------------------------------------------------

function imprime( texto )

screen:print( 0,0, texto, Color.new(255,255,255))

end

imprime( "Hola betapeseperos.")                                --> Hola betapeseperos.

----------------------------------------------------------------------------------

function restaNumeros( a, b )                                      --> Resta dos números

resta = a - b

return resta

end

screen:print( 0,0, restaNumeros( 5, 3 ), blanco )        --> 2

restaNumeros = function( a, b ) return a -b end          --> Versión abreviada de restaNumeros

----------------------------------------------------------------------------------

function el_mayor( a, b )                                             --> Retorna el número mayor.

if a > b then return a end

return b                                                               -- Solo se ejecuta un "return"

end

screen:print( 0,0, el_mayor( 5, 3 ) ,blanco )               --> 5

----------------------------------------------------------------------------------

function suma_y_resta( a, b )                                      --> Varios argumentos retornados.

return a + b, a - b

end

suma, resta = suma_y_resta( 5, 3 )                             --> suma = 8; resta = 2

----------------------------------------------------------------------------------

 

Y por último tres formas alternativas de definir unas funciones dentro de una tabla, las tres formas producen el mismo resultado:

 

lib = {}

function lib.suma(x, y)

return x + y

end

function lib.resta(x, y)

return x - y

end

 

lib = {}

lib.suma = function( x,y)

return x + y

end

lib.resta = function( x, y )

return x - y

end

 

lib = {

suma  = function( x, y )

return x + y

end ,

resta = function( x, y )

return x - y

end

}

sumar = lib.suma( 2, 3 )              -- sumar == 5

restar = lib.resta( 2, 3 )               -- restar == -1

 

--------------------------------------------------------------------------------------------------------------------------------

local function()

Se pueden definir funciones de carácter local que solo son accesibles dentro de un bloque "do..end" En este ejemplo la primera función suma sus argumentos, pero luego es definida una nueva función con el mismo nombre pero de carácter local dentro del bucle "do..end". La misma llamada produce valores diferentes dentro y fuera del bucle "do..end"

 

suma = function( a, b ) return a + b end

do

local suma = function( a, b ) return a * b end

screen:print( 0,10, suma( 2, 3), blanco)                                     --> 6

end

screen:print( 0,20, suma( 2, 3), blanco)                                              --> 5

 

Otro ejemplo más práctico puede ser crear funciones locales dentro de otra función para simplificarla o mejorar su comprensión:

 

function diferencia_entre_suma_y_resta( a , b )

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

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

return math.abs( suma( a, b) - resta( a, b )

end

screen:print( 0,0, diferencia_entre_suma_y_resta( 2, 5 ), blanco)     --> 10

--------------------------------------------------------------------------------------------------------------------------------

select( índice, ··· )

Si índice es un número retorna todos los argumentos después del número índice. En otro caso índice debe ser el string "#", y select retorna el número total de argumentos extra que recibe.

 

x = select( 3, "A", "B", "C", "D", "E" )

screen:print( 0, 0, "x = " .. x , blanco )               -- > Imprime en pantalla: x = C

 

x = select( "#", "A", "B", "C", "D", "E" )

screen:print( 0, 0, "x = " .. x , blanco )               -- > Imprime en pantalla: x = 5

 

--------------------------------------------------------------------------------------------------------------------------------

function( ... )

Función con entrada variable de argumentos. Cuando en una función no se sabe el número exacto de argumentos que pueden ser pasados se pone entre paréntesis "..." para definirlo. Luego dentro del cuerpo de la función los argumentos serán pasados como una tabla llamada arg[numero_argumento]. Ejemplos:

----------------------------------------------------------------------------------

function select( n, ... )

return arg[n]

end

----------------------------------------------------------------------------------

function print_varios_argumentos( ... )

for i, v in ipairs( arg ) do

resultado = resultado ... tostring( v )

end

screen:print( 0, 0, resultado, color ); screen.flip()

end

--------------------------------------------------------------------------------------------------------------------------------

assert( v [, mensaje] )

Activa un error cuando el valor de su argumento v es falso (por ejemplo, nil o false); en otro caso retorna todos sus argumentos. Mensaje es un mensaje de error; cuando está ausente se utiliza por defecto "assertion failed!".

 

function suma( n, m )

if not n or not m then error("Entrada no valida") end

return n + m

end

 

x = suma( 2, 3 )        --> x = 5

x = suma( 2 )            --> error: ./system/system.lua:7: Entrada no valida

 

Esa combinación de "if not" ... "then error()" es tan común que Lua ha incorporado en función sólo para ese trabajo, llamada "assert()":

 

function suma( n, m )

n = assert( n, 'Entrada "n" no valida')

m = assert( m, 'Entrada "m" no valida')

return n + m

end

 

x = suma( 2, 3 )        --> x = 5

x = suma( 2 )            --> error: ./system/system.lua:8: Entrada "m" no valida

 

 

La función "assert()" comprueba si su primer argumento es falso y no simplemente devuelve ese argumento, si el argumento es falso (es decir, falso o nulo), "assert()" se produce algún error. Su segundo argumento, el mensaje, es opcional, por lo que si no quieren decir nada en el mensaje de error, usted no tiene que. Tengan cuidado, sin embargo, "assert()" que es una función regular. Como tal, siempre Lua evalúa sus argumentos antes de llamar a la función. Por lo tanto, si usted tiene algo así como:

 

function suma( n, m )

assert( tonumber(n), "Entrada " .. n .. " no valida" )

assert( tonumber(m), "Entrada " .. m .. " no valida" )

return n + m

end

 

x = suma( 2, 3 )        --> x = 5

x = suma( "Hola", 2 )      --> error: ./system/system.lua:8: Entrada Hola no valida

 

Lua siempre hacer la concatenación, incluso cuando "n" es un número. Tal vez sea más prudente utilizar una prueba explícita en estos casos. Cuando una función se encuentra una situación inesperada (una excepción), puede asumir dos comportamientos: puede devolver un código de error (normalmente nula) o puede plantear un error, llamando a la función de error. No hay reglas fijas para la elección entre estas dos opciones, pero podemos dar una orientación general: Una excepción es que debe evitarse fácilmente un error plantear, de lo contrario, debe devolver un código de error.

 

--------------------------------------------------------------------------------------------------------------------------------

error ( mensaje [, nivel] )

Termina la última función protegida llamada, estableciendo mensaje como mensaje de error. La función error nunca retorna. Normalmente error añade, al comienzo del mensaje, cierta información acerca de la posición del error. El argumento nivel específica cómo obtener la posición del error. Con nivel 1 (por defecto) la posición del error es donde fue invocada la función error. Nivel 2 apunta el error hacia el lugar en que fue invocada la función que llamó a error; y así sucesivamente. Pasar un valor 0 como nivel evita la adición de la información de la posición al mensaje.

--------------------------------------------------------------------------------------------------------------------------------

pcall( f, arg1, ··· )      -- Llamada a una función en modo protegido.

Invoca la función f con los argumentos dados en modo protegido. Esto significa que ningún error dentro de f se propaga; en su lugar pcall captura el error y retorna un código de estatus. Su primer resultado es el código de estatus (booleano), el cual es verdadero si la llamada tiene éxito sin errores. En ese caso pcall también devuelve todos los resultados de la llamada después del primer resultado. En caso de error pcall retorna false más un mensaje de error.

 

function suma( n, m )

return n + m

end

 

estatus, resultado = pcall( suma, 2, 3 )    --> estatus = true           resultado = 5

estatus, resultado = pcall( suma,"H", 2) --> estatus = false          resultado = "attempt to perform arithmetic"

--------------------------------------------------------------------------------------------------------------------------------

xpcall( f, err )

Esta función es similar a pcall, excepto que se puede establecer un manejador de error. xpcall invoca a la función f en modo protegido, usando err como manejador de error. Ningún error dentro de f se propaga; en su lugar xpcall captura el error, llamando a la función err con el objeto de error original, y retorna un código de estatus. Su primer resultado es el código de estatus (un booleano), que es verdadero si la llamada tiene éxito sin errores. En ese caso xpcall también devuelve todos los resultados de la llamada después del primer resultado. En caso de error xpcall retorna false más el resultado de err.

--------------------------------------------------------------------------------------------------------------------------------

co = coroutine.create( function [, argumentos ... ] )

Retorna una nueva co-rutina, un objeto de tipo "thread". Las corutinas tienen tres estados "suspended", "running" y "dead" :

Ejemplos:

co = coroutine.create( function() print("hola.") end )

print( co )                                    --> thread

print( coroutine.status( co ) )     --> suspend

coroutine.resume( co )               --> hola.

print( coroutine.status( co ) )     --> dead

----------------------------------------------------------

co = coroutine.create( function ()

for i = 1, 3 do

print( "co", i )

coroutine.yield()

end

end )

coroutine.resume( co )               --> co 1

print( coroutine.status( co ) )     --> suspended

coroutine.resume( co )               --> co 2

coroutine.resume( co )               --> co 3

coroutine.resume( co )               --> no imprime nada y dead

coroutine.resume( co )               --> return false

----------------------------------------------------------

co = coroutine.create( function( a, b, c )

                print( "co", a,b,c )

    end )

coroutine.resume( co, 1, 2, 3 )                 --> co 1 2 3

----------------------------------------------------------

co = coroutine.create( function( a, b )

                coroutine.yield( a + b, a - c )

    end )

print( coroutine.resume( co, 20, 10 ))     --> true 30 10

--------------------------------------------------------------------------------------------------------------------------------

boolean [ , yield( .. ) ] = coroutine.resume( co [, val1, ···] )

Comienza o continúa la ejecución de la co-rutina co. La primera vez que se llama a esta función la co-rutina comienza ejecutando su cuerpo. Los valores val1, ···  se pasan como argumentos al cuerpo de la función. Si la co-rutina ha cedido el control del flujo, resume la reinicia; los valores val1, ··· son pasados como resultados de la cesión. Si la co-rutina se ejecuta sin error resume retorna true más los valores pasados a yield (si la co-rutinarealiza la cesión) o los valores retornados por el cuerpo de la función (si la co-rutina acaba). Si existe cualquier   error resume retorna  false más un mensaje de error.

--------------------------------------------------------------------------------------------------------------------------------

coroutine.yield( ··· )

Suspende la ejecución de la co-rutina invocante. La co-rutina no puede estar ejecutando una función C, un metamétodo o un iterador. Cualquier argumento de yield es pasado como resultado extra a resume.

--------------------------------------------------------------------------------------------------------------------------------

string coroutine.status( thread )

Retorna el estatus de la co-rutina co como un string:

"running"     si la co-rutina está en ejecución (esto es, invocó a status);

"suspended" si la co-rutina está  suspendida en una llamada a yield, o si todavía no ha comenzado a ejecutarse;

"normal"      si la co-rutina está activa pero no ejecutándose (esto es, si ha resumido otra co-rutina);

"dead"          si la co-rutina ha finalizado su función o si se ha detenido con un error.

--------------------------------------------------------------------------------------------------------------------------------

coroutine.running() 

Retorna la co-rutina en ejecución o nil cuando se invoca desde el proceso principal.

--------------------------------------------------------------------------------------------------------------------------------

coroutine.wrap( function [, argumentos ... ] )

Crea una nueva co-rutina con función Lua. Retorna una  función que resume la co-rutina cada vez que es  invocada. Cualquier argumento pasado a la función se comporta como un argumento extra para resume. Retorna los mismos valores devueltos por resume, excepto el primer booleano. En caso de error, éste se propaga.

--------------------------------------------------------------------------------------------------------------------------------

EJEMPLO MULTI-TAREA

--------------------------------------------------------------------------------------------------------------------------------

blanco , negro = Color.new( 255, 255, 255 ) , Color.new(   0,   0,   0 )

math.randomseed(os.time())

threads = {}                                         -- Crearemos una tabla donde insertar los nuevos procesos.

proceso = 1                                          -- Variable para contar el número de procesos ejecutados.

 

function objeto()                                 -- Esta función va ha ser ejecutada en modo multitarea.

local x , y  = math.random( 40, 440 ) , math.random( 40, 232 )

local xv , yv = nil , nil

repeat

xv , yv = math.random( -6, 6 ) , math.random( -6, 6 )

until xv ~= 0 and yv ~= 0

local r, g, b = math.random( 70, 255 ), math.random( 70, 255 ), math.random( 70, 255 )

local color = Color.new( r, g, b )

local p  = proceso

repeat                                          -- Pintará el número de proceso hasta salirse de la pantalla.

screen:print( x, y, p, color )

coroutine.yield()               -- Retornamos a la función principal.

x , y = x + xv , y + yv

until x > 480 or y > 480 or x < 0 or y < 0

end

 

function nueva_coroutine()                -- Función para crear nuevos procesos.

local co = coroutine.create( objeto )

table.insert( threads, co )           -- Insertamos el nuevo proceso en la tabla.

proceso = proceso + 1

end

 

while true do                                       -- Función principal o Main.

local n = table.getn( threads )

if             proceso > 100             then break       -- Finalizamos la aplicación a los 100 procesos.

elseif       n < 10                          then                 -- Creación aleatoria de nuevos procesos.

if math.random( 0, 100 ) > 90 then nueva_coroutine() end

end

screen:clear( negro )

for i in pairs( threads ) do                                              -- Recorremos toda la tabla de procesos.

local estado = coroutine.resume( threads[i] )      -- Ejecuta los procesos.

if not estado then table.remove( threads, i ) end  -- Borra procesos terminados.

end

screen:print( 0, 0, "threads = " .. n, blanco )

screen:print( 0,10, "proceso = " .. proceso, blanco )

screen.waitVblankStart(); screen.flip(); screen.waitVblankStart( 1 )

end

 

screen:fillRect( 140, 126, 195, 30, blanco )

screen:print( 150,136, "Fin de las coroutines.", negro )

screen.flip()

--------------------------------------------------------------------------------------------------------------------------------

setfenv( f, tabla )

Establece el entorno que va a ser usado por una función. f puede ser una función Lua o un número que especifica la función al nivel de pila: nivel 1 es la función que invoca a setfenv. setfenv retorna la función dada. Como caso especial, cuando f es 0 setfenv cambia el entorno del proceso que está en ejecución. En este caso setfenv no retorna valores.

--------------------------------------------------------------------------------------------------------------------------------

getfenv( [f] )

Retorna el entorno actualmente en uso por la función. f puede ser una función Lua o un número que especifica la función a ese nivel de la pila: nivel 1 es la función que invoca a getfenv. Si la función dada no es una función Lua o si f es 0, getfenv retorna el entorno global. El valor por defecto de f es 1.

 

--

FUNCIONES CON TABLAS (Índice)

--------------------------------------------------------------------------------------------------------------------------------

#table  Devuelve número total de elementos de una tabla, que no tiene por que ser el número del último índice.

 

table = {};         table[1] = "uno";        table[2] = "dos";          table[9] = "nueve"

n = #table          --> n = 3

--------------------------------------------------------------------------------------------------------------------------------

table.getn( table )                  -- Devuelve el número total de elementos de una tabla igual que "#".

--------------------------------------------------------------------------------------------------------------------------------

number table.maxn( tabla )

Devuelve el mayor índice numérico positivo de una tabla dada o cero si la tabla no tiene índices numéricos positivos. (Para hacer su trabajo esta función realiza un barrido lineal de la tabla completa.)

 

table = {};         table[1] = "uno";        table[2] = "dos";           table[9] = "nueve"

n = table.maxn( table )                         --> n = 9

 

Otro Ejemplo:

 

_table    = {}

_table[9] = "Nueve."

_table[5] = "Cinco."

_table[1] = "Uno."

_table[3] = "Tres."

_table[2] = "dos."

 

y = 0

screen:print( 1, y, "-- for indice, table.maxn( _table ) do end --" , blanco)

ultimo_indice = table.maxn ( _table )                                   -- último índice de la tabla

for indice = 1 , ultimo_indice do

if _table[indice] ~= nil then

screen:print( 1, y, indice .. " " .. _table[indice] , blanco)

y = y + 10

end

end

--------------------------------------------------------------------------------------------------------------------------------

in         -- Palabra clave usada en el bloque "for"

for _var_1, ..., _var_n in _explist do _bloque end      -- Recorre una tabla con una función iteradora.

for i, v in ipairs(t)  do bloque end                               -- Recorre una tabla con índices numéricos.

for k, v in pairs(t)  do bloque end                                -- Recorre una tabla con índices alfanuméricos.

--------------------------------------------------------------------------------------------------------------------------------

ipairs( table -- Retorna una función iteradora que recorre una tabla de índices numéricos.

 

table = { "uno", "dos", "tres", "cuatro" )

for indice, valor in ipairs( table) do print( indice, valor ) end

 

La función "iparis()" garantiza que los índices numéricos salgan por orden, pero para su ejecución en cuanto encuentre un indice "nil" vacío, aunque después haya más.

 

y = 0

screen:print( 1, y, "-- ipairs( a ) -- Tabla de 1 dimensión numérica.", blanco )

a = {"one", "two", "three"}

for i, v in ipairs( a ) do

screen:print( 1, y,  i .. " - " .. v , blanco )

y = y + 10

end

 

y = y + 10

screen:print( 1, y, "-- ipairs( b) -- Tabla de 2 dimensiones numéricas." , blanco )

b    = { }

b[1] = {"one",  "two",  "three"}

b[2] = {"four", "five", "six"  }

for i_1, tabla in ipairs( b) do

for i_2, v in ipairs( tabla ) do

screen:print( 1,  y,  i_1 .. " " .. i_2 .. " - " .. v , blanco )

y = y + 10

end

end

--------------------------------------------------------------------------------------------------------------------------------

pairs( table )

Retorna una función iteradora que recorre una table de índices alfanuméricos o numéricos.

 

table = { nombre = "pipagerardo", edad = "34", sexo = "varón" }

for indice, valor in pairs(table) do print( indice, valor ) end

 

La función "pairs()" no garantiza que los índices alfanuméricos ni numéricos salgan por orden.

 

y = 0

screen:print( 1,  y, "-- pairs( c ) -- Tabla de 1 dimensión alfanumérica." , blanco )

c = { nombre = "pipagerardo", sexo = "varón", edad = 34 }

for i, v in pairs( c ) do

screen:print( 1, y,  i .. " - " .. v , blanco )

y = y + 10

end

 

y = y + 10

screen:print( 1, y, "-- pairs(_d) -- Tabla de 2 dimensiones alfanuméricas." , blanco)

d    = { }

d[1] = { nombre = "pipagerardo",          sexo = "varón",          edad = 34 }

d[2] = { nombre = "carmen",      sexo = "hembra",       edad = 30 }

for i_1, tabla in ipairs( d ) do

for i_2, v in pairs( tabla ) do

screen:print( 1, y,  i_1 .. " " .. i_2 .. " - " .. v , blanco )

y = y + 10

end

end

--------------------------------------------------------------------------------------------------------------------------------

next( tabla [, índice] )           -- Recorre los campos de una tabla.

Permite al programa recorrer todos los campos de una tabla. Su primer argumento es una tabla y su segundo argumento es un índice en esta tabla.

- next retorna el siguiente índice de la tabla y su valor asociado.

- Cuando se invoca con nil como segundo argumento next retorna un índice inicial y su valor asociado.

- Cuando se invoca con el último índice o con nil en una tabla vacía next retorna nil.

- Si el segundo argumento está ausente entonces se interpreta como nil.

En particular se puede usar next(t) para comprobar si una tabla está vacía. El orden en que se enumeran los índices no está especificado, incluso para índices numéricos. (Para recorrer    una tabla en orden numérico úsese el for numérico o la función ipairs.)

 

table = { "uno", "dos", "tres", "cuatro" )

indice, valor = nil, nil

y = 0

while true do

indice, valor = next( table , indice )

if indice ~= nil then                       screen:print( 1, y, indice .." - " .. valor , blanco )

                                            y = y + 10

else                                     break

end

end

--------------------------------------------------------------------------------------------------------------------------------

unpack(lista [ , i [, j] ] )

Retorna los elementos de una tabla dada. Esta función equivale a return lista[i], lista[i+1], ···, lista[j] excepto que este código puede ser escrito sólo para un número fijo de elementos. Por defecto i es 1 y j es la longitud de la lista, como se define a través del operador longitud "#". Este seria un ejemplo de función recursiba que explica el funcionamiento de la función "unpack()" :

 

function unpack( table, indice )

indice = indice or 1

if table[indice] then

return table[indice], unpack( table, indice + 1 )

end

end

--------------------------------------------------------------------------------------------------------------------------------

table.insert( tabla , [posición,] valor )

Inserta el elemento valor en la posición dada en la tabla, desplazando hacia adelante otros elementos para abrir hueco, si es necesario. El valor por defecto de posición es n+1, donde n = #tabla es la longitud de la tabla, de tal manera que table.insert( t, x ) inserta x al final de la tabla t.

--------------------------------------------------------------------------------------------------------------------------------

var table.remove( tabla [, posición] )

Elimina de tabla el elemento situado en la posición dada, desplazando hacia atrás otros elementos para cerrar espacio, si es necesario. Devuelve el valor del elemento eliminado. El valor por defecto de posición es n, donde n es la longitud de la tabla, por lo que la llamada table.remove(t) elimina el último elemento de la tabla t.

--------------------------------------------------------------------------------------------------------------------------------

table.sort( tabla [, comparador] )

Ordena los elementos de la tabla en un orden dado modificando la propia tabla, desde table[1] hasta table[n],  donde n es la longitud de la tabla. Si se proporciona el argumento comparador éste debe ser una función que recibe dos elementos de la tabla y devuelve verdadero cuando el primero es menor que el segundo (por lo que not comparador(a[i+1],a[i]) será verdadero después de la ordenación). Si no se proporciona una función comparador entonces se usa el operador estándar < de Lua. El algoritmo de ordenación no es estable; esto es, los elementos considerados iguales por la ordenación dada pueden sufrir cambios de orden relativos después de la ordenación.

 

--

FUNCIONES CON STRINGS (Indice)

--------------------------------------------------------------------------------------------------------------------------------

#string Devuelve número de caracteres de un string.

texto = "Hola"

4 == #texto --> true

--------------------------------------------------------------------------------------------------------------------------------

number string.len ( string )   -- Devuelve número de caracteres de un string.

Recibe un string y devuelve su longitud. El string vacío "" tiene longitud 0. Los caracteres cero dentro del string también se cuentan, por lo que "a\000bc\000" tiene longitud 5.

texto = "Hola"

4 == string.len( texto ) --> true

--------------------------------------------------------------------------------------------------------------------------------

string tostring ( number )

Recibe un argumento de cualquier tipo y lo convierte en un string con un formato razonable. Para un control completo de cómo se convierten los números, úsese string.format. Si la metatabla tiene un campo "__tostring"   entonces tostring invoca al correspondiente valor con e como argumento y usa el resultado de la llamada como su propio resultado.

--------------------------------------------------------------------------------------------------------------------------------

number string.byte( string [, i [, j] ] )

Devuelve los códigos numéricos internos de los caracteres s[i], s[i+1], ···, s[j]. El valor por defecto de i es 1; el valor por defecto de j es i. Téngase en cuenta que los códigos numéricos no son necesariamente portables de unas plataformas a otras.

--------------------------------------------------------------------------------------------------------------------------------

string string.char( number [, ··· ] )

Recibe cero o más enteros. Devuelve un string con igual longitud que el número de argumentos, en el que cada carácter tiene un código numérico interno igual a su correspondiente argumento.  Téngase en cuenta que los códigos numéricos no son necesariamente portables de unas plataformas a otras.

--------------------------------------------------------------------------------------------------------------------------------

string string.lower( string )

Recibe un string y devuelve una copia del mismo con todas las letras mayúsculas cambiadas a minúsculas. El resto de los caracteres permanece sin cambios. La definición de letra mayúscula depende del sistema local.

--------------------------------------------------------------------------------------------------------------------------------

string string.upper( string )

Recibe un string y devuelve una copia del mismo con todas las letras minúsculas cambiadas a mayúsculas. El resto de los caracteres permanece sin cambios. La definición de letra minúscula depende del sistema local

--------------------------------------------------------------------------------------------------------------------------------

string string.rep( s, n )           -- Devuelve un string que es la concatenación de n copias del string s.

--------------------------------------------------------------------------------------------------------------------------------

string string.reverse( s )       -- Devuelve un string que es el original s invertido.

--------------------------------------------------------------------------------------------------------------------------------

string string.sub( s, i [, j] )

Retorna el substring de s que comienza en i y continúa hasta j; i y j pueden ser negativos. Si j está ausente entonces se asume que vale -1 (equivalente a la longitud del string). En particular, la llamada string.sub(s,1,j) retorna un prefijo de s con longitud j, y string.sub(s, -i) retorna un sufijo de s con longitud i.

--------------------------------------------------------------------------------------------------------------------------------

string string.format( formato,  ··· )

Devuelve una versión formateada de sus argumentos (en número variable) siguiendo la descripción dada en su primer argumento (formato, que debe ser un string). El string de formato sigue las mismas reglas que la familia   de funciones C estándar printf. Las únicas diferencias son que las opciones/modificadores *, l, L, n, p, y h no   están soportadas, y que existe una opción extra q. Esta última opción da formato a un string en una forma adecuada para ser leída de manera segura de nuevo por el intérprete de Lua: el string es escrito entre dobles  comillas, y todas las dobles comillas, nuevas líneas, ceros y barras inversas del string se sustituyen por las  secuencias de escape adecuadas en la escritura. Por ejemplo, la llamada

 

string.format('%q', 'un string con "comillas" y \n nueva línea')

producirá el string:     "un string con \"comillas\" y \

nueva línea"

 

Tipos de Campos:

%c     Carácter del código pasado como entero              integer = 64

%d     Entero decimal                                                        decimal_integer = 56

%o     Entero octal                                                            octal_integer = 0177

%x     Entero hexadecimal                                                hexadecimal_integer = 0xfa3c

%X    Entero hexadecimal mayusculas                            hexadecimal_integer = 0xFA3C

%f     Punto flotante                                                         floating-point  =  [-]nnnn.nnnn

%e     Exponencial                                                            exponencial = [-]n.nnnn e [+|-]nnn

%E    Exponencial                                                            exponencial = [-]n.nnnn E [+|-]nnn

%g     Autoexponente

%s     Cadena de carácteres sin ceros incrustados         string = "Hola pepe."

%q     Cadena de carácteres entre doble corchetes         double_quotes = [[ she said "hi" ]]

%%   Caracter '%'

 

Banderas de formato:

-             justificación izquierda dentro de campo ancho [por defecto: justificación derecha]

+            prepone el signo (sólo se aplica a los números)

(space)  prepone signo negativo, si es positivo espacio en blanco.

#             añade "0x" antes de x%, fuerza el punto decimal %e, % f, sale del rastreo de ceros por g%

 

Anchos de campo y precisión:

n    pone al menos n (<100) caracteres, rellena a la izquierda con espacios en blanco.

0n  pone al menos n (<100) caracteres, rellena a la izquierda con ceros.

.n   pone al menos n (<100) dígitos para los enteros; rondas a n decimales de punto flotante; pone no más de n (<100) para cadenas de caracteres.

 

Ejemplos:                                                                 Resultado:

string.format("results: %d, %d", 13, 27)          results: 13, 27

string.format("<%5d>", 13)                              <  13>

string.format("<%-5d>", 13)                            <13 >

string.format("<%05d>", 13)                            <00013>

string.format("<%06.3d>", 13)                         <  013>

string.format("<%f>", math.pi)                        <3.141593>

string.format("<%e>", math.pi)                        <3.141593e+00>

string.format("<%.4f>", math.pi)                     <3.1416>

string.format("<%9.4f>", math.pi)                   < 3.1416>

string.format("<%c>", 64)                                <@>

string.format("<%.4s>", "goodbye")                <good>

string.format("%q", [[she said "hi"]])              "she said \"hi\""

--------------------------------------------------------------------------------------------------------------------------------

string.gsub( s, patrón, reemplazamiento [, n] )

Devuelve una copia de "s" en la que todas (o las "n" primeras, si se especifica el argumento opcional) las apariciones del patrón han sido reemplazadas por el reemplazamiento especificado, que puede ser un string, una tabla o una función. gsub también devuelve, como segundo valor, el número total de coincidencias detectadas. Si reemplazamiento es un string entonces su valor se usa en la sustitución. El carácter % funciona como un carácter de escape: cualquier secuencia en reemplazamiento de la forma %n, con "n" entre 1 y 9, significa el valor de la captura número "n" en el substring (véase más abajo). La secuencia %0 significa toda la coincidencia. La secuencia %% significa un carácter porcentaje %. Si reemplazamiento es una tabla entonces en cada captura se devuelve el elemento de la tabla que tiene por clave la primera captura; si el patrón no proporciona ninguna captura entonce toda la coincidencia se utiliza como clave. Si reemplazamiento es una función entonces la misma es invocada cada vez que exista una captura con todos los substrings capturados pasados como argumentos en el mismo orden; si no existen capturas entonces toda la coincidencia se pasa como un único argumento. Si el valor devuelto por la tabla o por la llamada a la función es un string o un número, entonces se usa como string de reemplazamiento; en caso contrario si es false o nil, entonces no se realiza ninguna sustitución (esto es, la coincidencia original se mantiene en el string).

 

Clases de caracteres del Patrón [cc]:

.         cualquier caracter.

%a     cualquier letra.                                  %A   cualquier no letra.

%c     cualquier caracter de control.           %C   cualquier no caracter de control.

%d     cualquier dígito.                                 %D   cualquier no dígito.

%l     cualquier letra minúscula                  %L    cualquier no letra minúscula..

%p     cualquier caracter de puntuación     %P    cualquier no caracter de puntuación.

%s     cualquier espacio en blanco.             %S    cualquier no espacio en blanco.

%u     cualquier letra mayúscula.                %U   cualquier no  letra mayúscula.

%w    cualquier caracter alfanumérico       %W  cualquier no caracter alfanumérico

%x     cualquier dígito hexadecimal            %X   cualquier no dígito hexadecimal

%z     cualquier byte de valor cero              %Z    cualquier no-cero caracter

%x    si x es un símbolo del símbolo en sí x, si x no es:  ^$()%.[]*+-? el carácter propio

[ set ] cualquier carácter en cualquiera de las clases dadas; puede ser también una gama [c1-c2], e.j. [a-z].

[ ^set ] cualquier carácter no en el conjunto.

 

Formato general de patrón: [símbolos de patron]:

cc      coincide con un carácter único en la clase cc (véase el Plan clases de caracteres a continuación)

cc*     coincide con cero o más caracteres en la clase cc; coincide con la secuencia más larga (codiciosos).

cc-     coincide con cero o más caracteres en la clase cc; coincide con la secuencia más corta (no codiciosos).

cc+    coincide con una o más caracteres en la clase cc; coincide con la secuencia más larga (codiciosos).

cc?     coincide con cero o un caracter en la clase cc

%n     coincide con el n-ésimo capturado cadena (n = 1 .. 9, véase captura)

%bxy coincide con la cadena equilibrada del carácter "x" al "y". ( por ejemplo,% b () de paréntesis anidados)

^        ancla el patrón al comienzo del "string", debe ser el primer simbolo del patrón.

$        ancla el patrón al final del "string", debe ser el último símbolo del patrón.

 

Capturas:

(patrón) tiende subcadena que coinciden con el patrón como la captura ..% 1% 9, con el fin de abrir paréntesis.

()            tiende de cadena actual posición como la captura.

 

  He aquí algunos ejemplos:

string.gsub("Lua is great!", "%s"              , "-")                             Lua-is-great!                               2

string.gsub("Lua is great!", "[%s%l]"      , "*")                            L***********!                           11

string.gsub("Lua is great!", "%a+"           , "*")                            * * *!                                           3

string.gsub("Lua is great!", "(.)"               , "%1%1")                   LLuuaa iiss ggrreeaatt!!             13

string.gsub("Lua is great!", "%but"          , "")                              L!                                                 1

string.gsub("Lua is great!", "^.-a"             , "LUA")                      LUA is great!                              1

string.gsub("hola mundo", "(%w+)", "%1 %1")                           hola hola mundo mundo

string.gsub("hola mundo", "%w+", "%0 %0", 1)                          hola hola mundo

string.gsub("hola mundo desde Lua", "(%w+)%s*(%w+)", "%2 %1")

                                                                                                        mundo hola Lua desde

string.gsub("casa = $HOME, usuario = $USER", "%$(%w+)", os.getenv)

                                                                                                        casa = /home/roberto, usuario = roberto

string.gsub("Lua is great!", "^.-a", function(s) return string.upper(s) end)

                                                                                                        LUA is great!                               1

string.gsub("4+5 = $return 4+5$", "%$(.-)%$", function (s) return loadstring(s)() end)

                                                                                                        4+5 = 9

local t = {nombre="lua", versión="5.1"}

string.gsub("$nombre-$versión.tar.gz", "%$(%w+)", t)               lua-5.1.tar.gz

--------------------------------------------------------------------------------------------------------------------------------

string.find(s, patrón [, inicio [, básica]])

Busca la primera aparición de patrón en el string s. Si la encuentra, find devuelve los índices de s donde comienza y acaba la aparación; en caso contrario retorna nil. Un tercer argumento numérico opcional inicio  específica dónde comenzar la búsqueda; su valor por defecto es 1 y puede ser negativo. Un valor true como cuarto argumento opcional básica desactiva las utilidades de detección de patrones, realizando entonces la función una operación de "búsqueda básica de substring", sin caracteres "mágicos" en el patrón. Téngase en cuenta que si se proporciona el argumento básica también debe proporcionarse el argumento inicio. Si el patrón tiene capturas entonces en una detección con éxito se devuelven los valores capturados, después de los dos índices.

 

Ejemplos:                                                      Resultados:

string.find("Lua is great!", "is")           5          6

string.find("Lua is great!", "%s")         4          4

--------------------------------------------------------------------------------------------------------------------------------

string.match(s, patrón [, inicio])

Busca la primera aparición del patrón en el string s. Si encuentra una, entonces match retorna la captura del patrón; en caso contrario devuelve nil. Si el patrón no produce ninguna captura entonces se devuelve la coincidencia completa. Un tercer y opcional argumento numérico inicio especifica dónde comenzar la búsqueda; su valor por defecto es 1 y puede ser negativo.

--------------------------------------------------------------------------------------------------------------------------------

string.gmatch( s, patrón )

Devuelve una función iteradora que, cada vez que se invoca, retorna las siguientes capturas del patrón en el string s. Si el patrón no produce capturas entonces la coincidencia completa se devuelve en cada llamada. Como ejemplo, el siguiente bucle:

 

s = "hola mundo desde Lua"

for w in string.gmatch(s, "%a+") do

print(w)

end

 

iterará sobre todas las palabras del string s, imprimiendo una por línea. El siguiente ejemplo devuelve en forma de tabla todos los pares clave=valor del string dado:

 

t = {}

s = "desde=mundo, a=Lua"

for k, v in string.gmatch(s, "(%w+)=(%w+)") do

t[k] = v

end

 

Para esta función, un '^' al principio de un patrón no funciona como un ancla, sino que previene la iteración.

 

--

FUNCIONES MATEMÁTICAS (Indice)

--------------------------------------------------------------------------------------------------------------------------------

number tonumber( e [, base] )

Intenta convertir su argumento en un número. Si el argumento es ya un número o un string convertible a un número entonces tonumber retorna este número; en otro caso devuelve nil. Un argumento opcional especifica la base para interpretar el número. La base puede ser cualquier entero entre 2 y 36, ambos inclusive. En bases por encima de 10 la letra 'A' (en mayúscula o minúscula) representa 10, 'B' representa 11, y así sucesivamente, con 'Z' representando 35. En base 10 (por defecto), el número puede tener parte decimal, así como un exponente opcional (véase §2.1). En otras bases sólo se aceptan enteros sin signo.

--------------------------------------------------------------------------------------------------------------------------------

number math.abs( number )              -- Devuelve el valor absoluto de x. --> 5 == math.abs(-5)

--------------------------------------------------------------------------------------------------------------------------------

number math.ceil( number_x )         -- Devuelve el menor entero mayor o igual que x.

--------------------------------------------------------------------------------------------------------------------------------

number math.floor( number_x )       -- Devuelve el mayor entero menor o igual que x.

--------------------------------------------------------------------------------------------------------------------------------

number math.random( [m [, n] ] )

Esta función es un interface a rand, generador simple de números pseudo-aleatorios proporcionado por el ANSI C. (Sin garantías de sus propiedades estadísticas.) Cuando se invoca sin argumentos devuelve un número pseudoaleatorio real uniforme en el rango [0,1]. Cuando se invoca con un número entero m mayor o igual que 1, math.random devuelve un número pseudoaleatorio entero en el rango [1, m] con igual probabilidad para cada entero entre 1 y m. Cuando se invoca con dos argumentos m y n enteros, math.random devuelve un número pseudoaleatorio entero en el rango [m, n] (siempre que m < n ) con igual probabilidad para cada entero en el rango dado. Si se utilizan números no enteros los resultados no son equiprobables puesto que m y n se convierten a enteros usando lua_tointeger, que trunca de una manera no especificada.

 

Ejemplo de creación de un "table" con múmeros aleatorios y no repetidos:

 

blanco, negro = Color.new( 255, 255, 255 ), Color.new( 0, 0, 0 )

screen:clear( negro )

 

function table_aleatorio( min, max )

math.randomseed(os.time())

local numero = {}

local ale_1, ale_2 = 0, 0

for n = min, max do numero[n] = n end

for n = min, max do

ale_1 = math.random( min , max )

repeat

ale_2 = math.random( min , max )

screen.waitVblankStart(2)

until ale_1 ~= ale_2

numero[ale_1], numero[ale_2] = numero[ale_2], numero[ale_1]

end

return numero             

end

 

aleatorio = table_aleatorio( 1, 50 )

do

local x, y = 0, 0

for n = 1, 50 do

screen:print( x, y, aleatorio[n], blanco )

x = x + 50

if x > 400 then x, y = 0, y + 10 end

end

end

screen.flip()

 

--------------------------------------------------------------------------------------------------------------------------------

nil math.randomseed( number )

Establece x como "semilla" para el generador de números pseudoaleatorios: iguales semillas producen iguales secuencias de números.

 

math.randomseed(os.time())

aleatorio = math.random( num_min , num_max )

 

--------------------------------------------------------------------------------------------------------------------------------

number math.pow( number_x , number_y )

Devuelve xy. (Se puede también usar la expresión x^y para calcular este valor.)

--------------------------------------------------------------------------------------------------------------------------------

number math.sqrt( number_x )

Devuelve la raiz cuadrada de x. (Se puede usar también la expresión x^0.5 para calcular este valor)

--------------------------------------------------------------------------------------------------------------------------------

number math.exp( number_x )                       -- Devuelve el valor de ex.

--------------------------------------------------------------------------------------------------------------------------------

number math.fmod ( number_x , number_y ) -- Devuelve el resto de la división de x por y.

--------------------------------------------------------------------------------------------------------------------------------

 e , f  = math.modf( number_x )                      -- Devuelve dos números, las partes entera y fraccional de x .

--------------------------------------------------------------------------------------------------------------------------------

number math.max( number_a , number_b ,  ··· )

Devuelve el mayor valor de entre sus argumentos.   -> 5 == math.max( 1, 2, 5 )

--------------------------------------------------------------------------------------------------------------------------------

number math.min( number_a , numer_b ,  ··· )

Devuelve el menor valor de entre sus argumentos.     -> 1 == math.min( 1, 2 )

--------------------------------------------------------------------------------------------------------------------------------

number math.log( number_x )          -- Devuelve el logaritmo natural de x.

--------------------------------------------------------------------------------------------------------------------------------

number math.log10( number_x )      --  Devuelve el logaritmo decimal (base 10) de x.

--------------------------------------------------------------------------------------------------------------------------------

number math.pi                                  -- Variable que contiene el valor de pi.

--------------------------------------------------------------------------------------------------------------------------------

number math.rad( number_x )

Devuelve en radianes el valor del ángulo x (dado en grados sexagesimales).

--------------------------------------------------------------------------------------------------------------------------------

number math.deg( number_radianes_x )

Devuelve en grados sexagesimales el valor de x (dado en radianes).

--------------------------------------------------------------------------------------------------------------------------------

number math.sin( number_radianes )           -- Devuelve el seno.

--------------------------------------------------------------------------------------------------------------------------------

number math.asin( number_radianes )         -- Devuelve el arco seno..

--------------------------------------------------------------------------------------------------------------------------------

number math.sinh( number_x )                     -- Devuelve el seno hiperbólico de x.

--------------------------------------------------------------------------------------------------------------------------------

number math.cos( number_radianes )          -- Devuelve el coseno.

--------------------------------------------------------------------------------------------------------------------------------

number math.acos( number_radianes )        -- Devuelve el arco coseno.

--------------------------------------------------------------------------------------------------------------------------------

number math.cosh( number_radianes )        -- Devuelve el coseno hiperbólico.

--------------------------------------------------------------------------------------------------------------------------------

number math.tan( number_radianes )          -- Devuelve la tangente.

--------------------------------------------------------------------------------------------------------------------------------

number math.atan( number_radianes )        -- Devuelve el arco tangente.

--------------------------------------------------------------------------------------------------------------------------------

number math.atan2(number_y, number_x )

Devuelve el arco tangente de y/x (en radianes), pero usa los signos de ambos argumentos para determinar el cuadrante del resultado. (También maneja correctamente el caso en que x es cero.)

--------------------------------------------------------------------------------------------------------------------------------

number math.tanh( number_x )        -- Devuelve la tangente hiperbólica de x.

--------------------------------------------------------------------------------------------------------------------------------

number math.ldexp( m , e )               -- Devuelve m 2e (e debe ser un entero).

--------------------------------------------------------------------------------------------------------------------------------

??? math.frexp( number_x )

Devuelve m y e tales que x = m 2e, e es un entero y el valor absoluto de m está en el intervalo [0.5,1] (o cero cuando x es cero).

--------------------------------------------------------------------------------------------------------------------------------

??? math.huge

El valor HUGE_VAL, un valor más grande o igual que otro valor numérico cualquiera.

--

FUNCIONES DE FICHEROS (Indice)

--------------------------------------------------------------------------------------------------------------------------------

dofile( path/file.lua )

Carga y ejecuta código LUA que esté en un archivo. Es útil para organizar el programa en partes, en un archivo los colores e imágenes, en otro los sonidos, en otro las funciones, etc... Es util para descomponer un programa en módulos para su mejor extructuración evitando un único archivo demasiado extenso.

 

dofile("./archivos/variables.lua")

dofile("./archivos/colores.lua")

dofile("./archivos/imagenes.lua")

dofile("./archivos/sonidos.lua")

dofile("./archivos/funciones.lua")

do

-- "Codigo principal del programa o Main"

end

--------------------------------------------------------------------------------------------------------------------------------

loadfile( path/file.lua )

Carga código LUA que esté en un archivo. Es util para descomponer un programa en módulos que se ván ha ejecutar varias veces, como presentaciones, animaciones, tutoriales, etc... En definitiva ejecuta código similar a una función solo que es externa y sin argumentos de entrada ni salida.

 

_tutorial = loadfile("./System/tutorial.lua")           -- Carga el código.

_tutorial()                                                                -- Ejecuta el código como una función.

--------------------------------------------------------------------------------------------------------------------------------

load( func [, nombre_de_chunk] )

Carga un chunk usando la función func para obtener sus partes. Cada llamada a func debe retornar un string que se  concatena con los resultados previos. Un retorno de nil (o no valor) señala el final del chunk. Si no hay errores retorna el chunk compilado como una función; en otro caso retorna nil más un mensaje de error. El entorno de la función retornada es el global. nombre_de_chunk se utiliza para identificar el chunk en los mensajes de error y para información de depuración.

--------------------------------------------------------------------------------------------------------------------------------

string string.dump( function )

Devuelve un string que contiene la representación binaria de la función dada, de tal manera que una llamada posterior a loadstring con este string devuelve una copia de la función. func debe ser una función Lua sin upvalues.

--------------------------------------------------------------------------------------------------------------------------------

loadstring( string [, nombre_de_chunk] )

 Similar a load, pero obtiene el chunk del string proporcionado.

Para cargar y ejecutar un string dado úsese :

assert(loadstring( string ))()