Trasteando con el Lua Player de Saturn (Tutorial) »  Mostrar los mensajes de    a     

SEGASaturno - Saturn, SEGA y Videojuegos


Desarrollo - Trasteando con el Lua Player de Saturn (Tutorial)



Ryo Suzuki [ 10 Mayo 2014, 12:50 AM ]
Título del mensajeTrasteando con el Lua Player de Saturn (Tutorial)
He estado echándole un ojo a este entorno de desarrollo de la Saturn que sacó Rockin'-B hace más de cinco años y que desafortunadamente creo que no ha tenido mucha repercusión.

sega saturn lua dev homebrew

El desarrollo homebrew por parte de aficionados para la Sega Saturn prácticamente no existe, a diferencia de otras consolas clásicas que sí que tienen más proyectos y una comunidad sensiblemente activa en este campo. A parte del SDK oficial de SEGA, solo existía el Saturn Orbit, que es una especie de adaptación de Rockin'-B (omnipresente siempre en estos temas para la Saturn) y que ha comentado en varios tutoriales nuestro amigo y compañero del foro, FacundoARG. NOTA Edición: Ahora que recuerdo también existe el Game Basic que era comercial, todavía no lo he investigado. NOTA Edición 2: Tambien está disponible el libyaul que es totalmente open source.

Saturn Orbit si no me equivoco, y disculpadme si meto la pata porque en estos temas no sé prácticamente nada, es una especie de adaptación para trabajar con lenguaje C y las librerías de SEGA con compilador gcc optimizado para los procesadores de la Saturn. Un IDE (Integrated development enviroment) que tiene especificadas las librerías para compilar para la 32 bits de SEGA.

Sin embargo, este Saturn Lua Player tiene la capacidad de correr aplicaciones programadas en el lenguaje de programación Lua. Esas aplicaciones pueden tener acceso a cientos de funciones API y librerías que pueden ser necesarias como SGL (SEGA Graphics Library), PCM, GFS y STM.

Digamos que Lua Player para la Saturn es un intérprete del lenguaje de programación Lua, que hace buen uso de las librerías oficiales de SEGA para la Saturn. Es muy sencillo a la hora de ponerte a probar, ya que no necesita ningún tipo de configuración o setup, y solo te hace falta un editor de textos como el notepad y un emulador para empezar a programar en la Saturn.


¿Qué es Lua? El lenguaje del que parte este player portado a Saturn

Lua es un lenguaje de programación, basado en C y en Perl, imperativo, estructurado y bastante ligero que fue diseñado como un lenguaje interpretado con una semántica extendible. El nombre significa "luna" en portugués.

Más info en Wikipedia (que es de donde lo he copiado): http://es.wikipedia.org/wiki/Lua

Teóricamente Lua es más accesible y sencillo que otros lenguajes de programación, así que debería resultar más fácil para los principiantes hacer sus pinitos con el Lua Player que con el Saturn Orbit...

O sea que, vamos al grano. Voy a poneros un pequeño tutorial con un ejemplo por si queréis empezar a trastear con el Lua Player para Saturn.

NOTA: No tengo ni idea de programación. Solo hice cuatro chorradas en los tiempos de los 8 bits con el BASIC y poca cosa más. Quiero decir que teneis que coger todo esto con pinzas


Descargar Lua Player de Saturn

Como comentaba antes este entorno no tiene ningún tipo de configuración o problemas para instalarlo y demás. Es cuestión de bajarlo y empezar a picar código o liarse a probar con los ejemplos que vienen incluidos.

Por lo tanto, lo primero que tenemos que hacer es descargarlo y rápidamente estaremos ya funcionando. Podéis bajarlo en esa maravillosa página llamada SEGASaturno ( ) siguiendo este enlace, o en la web donde originalmente el gran Rockin'-B lo hizo público.

Bien, ya teneis el archivo comprido SaturnLuaPlayer_080701_R1. Lo descomprimis y vereis que os crea una carpeta llamada SaturnLuaPlayer. Ya podemos comenzar.


Primeros pasos

Si os fijais, teneis varias carpetas con diferentes contenidos (documentación, tools, librerías y demás historias), lo que nos interesa ahora para comenzar es la carpeta samples, donde están evidentemente los ejemplos.

Veremos diferentes carpetas con ejemplos que son proyectos que podemos probar y ver el código para copiar/trastear/modificar cosas, e incluso tratar de averiguar cómo funcionan. Tenemos la carpeta CHROME, DESIGN3, TORUS3, etc...

Bien, podéis probarlos todos en emulador si os apetece para ver como lucen estos ejemplos hechos con el Lua Player y fliparnos un poco de paso con lo que podríamos llegar a hacer. Para ello ejecutamos makeiso_all.bat que vemos en la carpeta samples y se compilan todas las isos de cada carpeta de ejemplos para que las podemos testear.


Usando emulador y unidad virtual para testear lo que programemos

Podríamos quemar cada iso en un CDROM y probarlo directamente en la Sega Saturn, pero está claro que lo mejor de momento es que usemos un emulador para catar los ejemplos y las cosas que podamos programar nosotros.

Una opción sería utilizar el Yabause, que directamente puede cargar isos y que podéis descargar en su página oficial: http://yabause.org

Pero yo prefiero usar el SSF porque es más fiel a la máquina original. No permite usar isos directamente, así que tendremos que montar las isos en una unidad virtual. Podeis bajar el emulador SSF aqui: http://www7a.biglobe.ne.jp/~phantasy/ssf/index.html (nota la pagina oficial se ha mudado y no recuerdo ahora donde, cuando la encuentre de nuevo la pongo)
Bajadlo desde nuestra web mismo.

Para el SSF, como decía, necesitais emular la iso con un CDROM virtual, algo que igual ya estáis acostumbrados a hacer para otros menesteres. Bajad el DAEMON Tools Lite 4, por ejemplo, si no lo tenéis, la versión Free de aquí:
http://www.daemon-tools.cc/products/dtLite#features
Instaladlo y ya contaréis con una o varias unidades virtuales para probar las isos que vayamos haciendo.

Vale, tenemos todo lo necesario. Estamos listos. Vamos a probar los ejemplos que vienen con el Lua Player y que hemos compilado con el makeiso_all.bat que hemos ejecutado anteriormente.

Abrimos el Daemon Tools y veremos la unidad virtual que nos ha creado tras la instalación. En mi caso es la letra M:, si le dais al boton derecho os aperece la opción "Montar" (también se puede arrastrar directamente la iso sobre la unidad). La seleccionamos y buscamos la iso de la carpeta samples/ CHROME para empezar. Vereis que en esa carpeta se encuentra el archivo sample.iso, lo montamos y ejecutamos el emulador.

En el SSF, a parte de necesitar la bios para un mejor funcionamiento (en este caso no lo recomiendo porque para esto va bien y así nos saltamos la animación de Saturn ide inicio cada vez), lo debeis configurar con la letra del CDROM para que sea la misma que la del Daemon Tools y así trague la unidad virtual y las isos que vayamos montando. Yo como os comentaba en Option del SSF en CD drive he seleccionado la letra M, haced vosotros lo propio con vuestra letra correspondiente. Bien, reiniciamos para que quede guardada la letra del CD pertinente (el SSF tras cada cambio en configuración hay que cerrar y abrir el emulador para que lo guarde) y lo ejecutamos de nuevo. Obtenemos esto:

emulador_saturn

NOTA Edición: He comprobado que si el SSF lo corres sin bios de la Saturn pueden mostrar mal algunos ejemplos y por ende algunas cosas que programemos (por ejemplo los colores de las letras no se ven bien en ocasiones). Así que es bueno que useis el emulador con BIOS.

Un objeto tridimensional rotando y mostrando varios valores de lo que va procesando, pintando en pantalla y demás. Muy bonito, luego veremos que el código se las trae

Podéis ir probando asi todos los ejemplos de las diferentes carpetas, tendréis el sample.iso correspondiente en cada carpeta DESIGN3, S_4_5, SBKLIB, etc. Probadlos todos si queréis, hay cosas bastante impresionantes para ser homebrew de la Saturn.


Al lío, primer ejemplo

Bueno, ya nos hemos hecho pajas mentales de lo que se puede hacer con este Lua Player. Ahora tendrás ganas de empezar a programar por ejemplo un Virtua Fighter 3 en hi-res y con los mismos gráficos que el Shenmue de Saturn... Bromas a parte, podemos ver el código de todos esos ejemplos para hacernos una idea de cómo están hechos.

El source code está en la carpeta de cada sample. Por ejemplo en el ejemplo DESIGN3, esta la carpeta cd y el código fuente está en el archivo 0_orig.lua. Vale para todos los ejemplos, siempre será así. Si lo abris con el bloc de notas os saldrá el contenido que empieza de esta guisa:

Código: [Ocultar] [Seleccionar]
--/*----------------------------------------------------------------------*/
--/* Design Check 3 */
--/*----------------------------------------------------------------------*/


local max_texture = 2

-- Note: GFS_Init() has already been called in the Saturn Lua Player
local len = GFS_Load_name("DATA.BIN", 0, CPU_WRAM_LO, CPU_WRAM_LO_LEN)-- filename case sensitive !!!!
if len == nil or len <= 0 then
slPrint("Error loading data file!", 9, 3)
end
local object_sample = CPU_WRAM_LO + 0x000
local tex_sample = CPU_WRAM_LO + 0x220
local pic_sample = CPU_WRAM_LO + 0x210
local cam = {}
cam.pos = {}
cam.ang = {}
cam.sca = {}
cam.base = getnewuserdata(4*3*4)--

local old_pos = {}
local old_scl = {}


Y sigue bastante... Si no entendeis nada no os preocupéis, ya somos dos.

Vamos a hacer nuestro primer ejemplo de prueba, bien sencillo para que nos familiaricemos un poco con el rollo.

Nos podemos crear una carpeta nueva llamada por ejemplo Samples Mios y ahí copiamos un sample original para modificarlo y hacer nuestros testeos. Copiamos, por coger uno, la carpeta del sample CHROME: osea toda la carpeta CHROME la copiamos al directorio que hemos creado llamado Samples Mios. Lo mejor es que una vez copiada le cambiemos el nombre y le llamemos por ejemplo TEXTO Y VARIABLE, que es lo que vamos a hacer en esta primera prueba de toma de contacto.

Nota de edición: Asegurate que en el directorio que crees para meter tus pruebas, en este caso Samples Mios, en la raiz copies el IP.bin que viene en la carpeta original Samples, de lo contrario no podrás generar las isos del código que crees ya que el mkisofs.exe que lo hace necesita la Ip.bin (te aparecerían isos que pesarían 0kbs)

Perfecto, vamos a editar el código en nuestra carpeta TEXTO Y VARIABLE así que buscamos el archivo que tiene el código fuente para modificarlo. No es otro que 0_orig.lua, que esta dentro del directorio cd como hemos dicho con anterioridad.

Abrimos 0_orig.lua con el bloc de notas para modificarlo. Borramos todo lo que tiene y ponemos este código sencillo que me he inventado yo:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_720x576,NULL,1)

local sega = 20


slPrint("www.segasaturno.com", 11, 3)

slPrint("Esto es una primera prueba", 5, 6)

slPrint("El valor de la variable es", 5, 7)

slPrint(sega, 32, 7)

slPrint("Saturn Lua Player", 11, 9)


while true do slSynch() end


¡Listo! Este ya se entiende algo mejor, ¿verdad? Guardamos este 0_orig.lua y ya tenemos preparado para "compilar" nuestra primera iso creada por nosotros y probarla en el emulador.

Si vais un directorio hacia atrás en nuestra carpeta TEXTO Y VARIABLE veréis que tenemos un ejecutable llamado makeiso_for_debugging.bat, que como su nombre indica se encarga de crear la iso con el código que acabamos de copiar. Lo ejecutamos e inmediatamente obtenemos nuestra iso con el archivo que se generará y que veremos que se llama sample.iso.

El mismo proceso nos va a tocar hacer. La montamos en la unidad virtual del Daemon Tools, ejecutamos el SSF y obtenemos nuestro primer programa ejecutándose:

sega_saturn_dev_homebrew

No es tan impresionante como los ejemplos que hemos visto antes y que venían con el Lua Player, pero lo hemos hecho nosotros y el código es corto y medio entendible a simple vista para newbies.

Repasemos el código de nuevo, esta vez con anotaciones digamos "para tontos", para que se comprenda mejor qué estamos haciendo con cada comando:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_720x576,NULL,1) -- pone el modo de video

local sega = 20 -- define la variable local sega y le asigna un valor de 20


slPrint("www.segasaturno.com", 11, 3) -- escribe en pantalla este mensaje en la linea 3 y tras 11 espacios

slPrint("Esto es una primera prueba", 5, 6) -- escribe en pantalla este mensaje en la linea 6 y tras 5 espacios

slPrint("El valor de la variable es", 5, 7) -- escribe en pantalla este mensaje en la línea 7 y tras 5 espacios

slPrint(sega, 32, 7) -- escribe en pantalla el valor de la variable sega que hemos definido al comienzo en la línea 7 tras 32 espacios para que quede justo después de la frase de antes

slPrint("Saturn Lua Player", 11, 9) -- escribe en pantalla este mensaje en la línea 9 y tras 11 espacios para finalizar

while true do slSynch() end -- lo mete en bucle creo algo así como mientras que sea cierto haz esto hasta el infinito


Ahora sí que queda bastante más claro, ¿verdad?

Con la tontería hemos aprendido algo más sin darnos casi cuenta, si escribimos -- detrás de cada orden podemos poner un comentario para identificar qué hace ese comando y escribir nuestra anotaciones personalizadas.

Probadlo si quereis, cambiar el código por el que os he puesto con comentarios (o cread comentarios propios para testearlo), recread la iso de nuevo y montadla en el Daemon y vereis que sigue funcionando igual en el emulador. Eso quiere decir que todo lo que pongamos detrás de -- lo interpreta como un comentario y no da error ni se lia con ese texto. Esto creo que se denomina REMARK o algo asi, en BASIC me parece que se hacía con REM. Parece una gilipollez pero viene muy bien anotarse cosas, sobre todo cuando nuestros códigos comiencen a complicarse y convertirse en galimatías que hasta a nosotros nos costará entender.


LUA y SEGA

Mirando de nuevo nuestro código tan sencillo llego a otra conclusión. Si os fijáis parece que hay órdenes que son del lenguaje Lua y otras que son de la librerías de SEGA.

Por ejemplo:

Citar:
local sega = 20

Esto lo he sacado de algun sample de documentación de Lua de cómo definir el valor de una variable local y ha funcionado. O sea yo interpreto que esto es Lua.

Sin embargo, otra orden como esta:

Citar:
slPrint("El valor de la variable es", 5, 7)

Esto es Sega Library. No os saldrá nada así en la documentación de Lua, los print en Lua son directamente print y lo he probado y no parece funcionar. Así que tenemos que usar este print particular para que escriba en pantalla, este print es de las librerías gráfica de Sega con casi toda seguridad, si os fijais empieza por "sl" (sega library) lo que le delata.

Así que llego a la conclusión de que habrá que trabajar unos temas como pueden ser variables, procesos, rutinas y demás programándolos con Lua, pero para otras cosas particulares tendremos que "hablarle" a la Saturn en su lenguaje con las librerías de Sega para que nos haga caso.

Creo entender pues que con el Saturn Orbit sucede algo similar pero con el lenguaje C. Aquí es con Lua, que en principio es más sencillo.


¿Y ahora qué hago?

Pues eso mismo me pregunto yo. Sería cuestión de investigar y hacer cosas más complicadas. Estas historias suelen ser al principio todo basado casi en la prueba y el error (os cansaréis de cambiar código, regenerar la iso, montarla en el daemon y rularla de nuevo en el emulador).

Una buena idea quizás para inspirarse un poco sería echarle un ojo a la documentación sobre Lua que incluye este Player, está en la carpeta docs\Lua

Tenemos el manual de programación y luego el de referencia en dos pdfs bien majos. Ahí en docs también tenemos las carpetas SBL y SGL con pdfs oficiales (SEGA Confidential, lol!) y varios textos que nos pueden ayudar y mucho.

Añado yo además en clave SEGA este manual que puede ser muy interesante y no está incluido en la documentación del Lua Player. Se trata del Manual de referencia del desarrollador, donde estan creo que todas las funciones (los comandos sl que hablábamos antes) listados y explicados cómo funcionan, así como estructuras, apéndices y demás. Me parece que puede venir muy bien, la verdad.

Junto a esto y los ejemplos que vienen podemos tratar de descifrar cómo diablos hacen las cosas. Objetos en 3D, uso de sprites, como se cargan texturas, reproducir audio... se me ocurren muchas cuestiones... Supongo que hay que ir paso a paso y armarse de paciencia.

No creo que nadie del foro se anime a hacer nada, sinceramente. Ni siquiera tengo demasiada fe en que nadie haya leido todo este tutorial al completo , solo lo pongo para documentar un poco el Lua Player de Rockin'-B que por lo que veo estaba muy huerfano de este tipo de cosas en todo internet y me da un poco de pena, si soy sincero.

Con este entorno Rockin'-B y otro colaborador suyo estaban programando la videoaventura Police Officer Smith que quizás recordaréis. En teoría se podrían llegar a hacer homebrew bastante ambiciosos...

En fin, espero que os haya gustado el tutorial y alguno se anime a hacer sus pinitos. También espero que amigos como Indiket, FacundoARG, vbt y demás compañeros que pasan por aquí y saben de programación igual les pique el gusanillo, o puedan echarnos un cable si surgiera alguna duda probando otras cosas.

Un saludo y pongo deberes para mi o para quien se atreva a ver si se pueden llegar a hacer.


DEBERES:
Pintar texto con diferentes colores en pantalla
Pintar un sprite en pantalla, no solo letras!


BONUS:
Existe Lua Player para PSP. Creo que igual la idea surgió de aquí para llevarlo a Saturn. ¿Se podrían portar homebrew sencillos como estos a Saturn gracias al estar los dos en Lua?:
http://bugz.luaplayer.org/gallery/index.html
(creo que va a ser que no )


Enlaces de interés:

Web oficial de Lua: http://www.lua.org/
Manual en castellano (es 5.1 pero creo que servirá): http://www.lua.org/manual/5.1/es/manual.html
Lua Users: http://lua-users.org/

Documentación dev Saturn: http://koti.kapsi.fi/~antime/sega/docs.html
Más de dev en SegaXtreme (foro donde normalmente hablan de Orbit, pero nos puede servir para Lua Player por el tema de las librerías de SEGA): http://segaxtreme.net/forum/forumdisplay.php?fid=34


Rick Fdez [ 10 Mayo 2014, 09:57 AM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Interesante, no soy programador, ni siquiera informatico, pero me atraen estas cosas una barbaridad, prometo intentar algo en cuanto tenga tiempo aunque puede que no pase de poner texto y porque lo has explicado estupendamente.


Sh0X [ 10 Mayo 2014, 11:04 AM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Muy buenas!. La verdad que también me parece un mini-tutorial muy interesante y coincido con Ryo, me da muchisima lástima que la scene de Saturn sea prácticamente inexistente. Creo que sería interesante discutir el por qué de esto, puesto que no creo que sus herramientas disten mucho de las ofrecias por la scene de Dreamcast, aunque quizás si habría que pasarlas a limpio ( llevan mucho tiempo desactualizadas ).

En cualquier caso, espero que esta tendencia cambie poco a poco. Y personalmente en cuanto tenga algo de tiempo espero poder contribuir a ello! =).

Un saludo!.


zeros [ 10 Mayo 2014, 07:15 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Buenísima clase tio!! Me ha gustado lo de proponer un ejercicio XD Pordía montarse un curso de programación en saturn no? Saber que funciones van de SEGA library, cuales de LUA. (yo creo que el estar ahi con el prueba y erro es lo que más echa atras.

Con que funciones se presentan graficos 3d, con que cambias resolución, con que usas un procesador u otro (si se puede). Lo que pasa que eso requiere un esfuerzo titánico por parte del profesor, de sintetizar tanta info, descartar variables, preparar ejercicios, agrupar conceptos... flipas. Pero esta primera clase ha molao mil, lo de los comentarios y tal parece fácil, lo has hecho fácil.

Ese gráfico que has mostrado 3D, ese cubo rectángulo, lo que sea... no lo generas por código no? o sea le das un archivo al lua que carga aparte, un archivo hecho con un editor 3D supongo, no? si es así que extensión tiene?

No creo que la scene de Saturn esté muerta pq si, alguna razón de peso habrá. Hay juegos homebrew en PSOne? yo no he oido muchos, he oido más de Dreamcast (tb puede ser que cuando oigo Playstation dejo de escuchar XD), igual es un problema generacional de las 32 bits. Que necesiten mucha optimización, para cualquier cosa mínima que se haga en 3D o 2D. No lo se, hablo por hablar, estoy divagando.

Por ejemplo, usar este lenguaje de programación, asegura poder sacar rendimiento a la consola? o hay que programar a más bajo nivel para hacer algo parecido al Sonic Jam por ejemplo?


Noon [ 10 Mayo 2014, 08:32 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
O_O a mi me gustaria programar un juego de saturn... es mi consola favorita no se nada de programacion pero podriamos juntarnos unos pocos he ir sacando ideas y ir repartiendo tareas cuando sepamos como programar... claro... un juego asi de rol a lo zelda en 2d por ejemplo pa empezar... joer molaria un monton eh?


Indiket [ 10 Mayo 2014, 09:44 PM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Este post me estaba llamando a gritos!! jajajaaja. Buen aporte Ryo!!

Mirad, yo llevo ya años programando cosas para Dreamcast, y lo sigo haciendo... es un tema que cada día me apasiona más: siempre aprendes y descubres cosas fascinantes!!

Entonces, por qué no hay tanta scene en Saturn? Yo coincido con vosotros y considero estos puntos:

- La arquitectura de la consola: programar para Dreamcast es muy sencillo, al disponer de 1 procesador RISC (SH4) tipo Little Endian. Es fácil de acceder a memoria, a las funciones 3D del PVR, y al chip gráfico AICA. No conozco al dedo la de Saturn, pero al tener 2 procesadores SH2 creo que es lo que realmente complica (y mucho) la programación.

Dreamcast tiene 16MB de RAM general, que no es ninguna maravilla, pero en Saturn hay menos... bastante menos. Eso reduce mucho las posibilidades de la consola!

- Las herramientas: siento contradecir el comentario de Sh0X, pero en Dreamcast hay herramientas muy potentes para desarrollar: desde S.O enteros como KOS, a librerías gráficas como SDL o Allegro. Gracias a ello, la portabilidad de muchos códigos es rápida y factible.

Ok, en Saturn también hay cosas muy interesantes!! El Lua Player mismo, a mi me fascina porqué... no está en Dreamcast y sí en Saturn!! jajaja.

- La accesibilidad: Nos guste o no, en Dreamcast es muy fácil cargar binarios sin firmar (tan fácil que ni siquiera se necesita chip y custom firmware ni nada!!). Y cada vez hay más opciones: vía SD, vía BBA, pronto vía HDD....
En Saturn, hay que tener la consola chipeada (creo). Y luego, ¿qué opciones hay de cargar binarios? La única que conozco es quemando CD's... hay alguna otra???


En PSOne es cierto que no hay mucho homebrew, pero también hubo muchísimo homebrew en la época activa de la consola (recordad en las revistas): SONY ofrecía kits para programar (las consolas Net Yazore), y su arquitectura era más fácil (MIPS y otros chips más conocidos).


Total, luego de esta "chapa", tenéis más ganas de aprender a programar? Es un camino duro y lleno de dolor, yo aviso!! jajajaja.

El mayor problema de la scene de Saturn quizá sea la dificultad para ejecutar código, y luego que necesita más herramientas y, sobretodo, librerías, para que sea atractiva!!

Seguimos!!

PD: Ryo, hay pendiente ver una demo rulando de Sonic Jam, cierto? jajaja


Noon [ 10 Mayo 2014, 11:00 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Oye si segun tu en dreamcast es tan facil... dime como programar por alli, o algun tutorial o algo me da= que sea sega saturn o dreamcast total... tengo las 2 xDDDDD.


apietoteae [ 11 Mayo 2014, 02:29 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
simple y llanamente maravilloso

estoy DESEANDO meterle mano al lenguaje C y aprender a programar algun que otro juego (aunque me encantaria empezar por megadrive jejeje).


Jose [ 12 Mayo 2014, 01:00 AM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
A ver si siguen aportando material diferentes programadores.
Gracias de ante mano.


Ryo Suzuki [ 12 Mayo 2014, 04:19 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Qué buen rollo! Luego os contesto a todos. Voy a dar la "clase" de hoy y luego os cito y os comento a cada uno.

Bueno, lo primero es decir que no he podido hacer los particulares deberes que me auto impuse. No he sido capaz aún de poner sprites en pantalla porque es bastante más difícil de lo que sospechaba -también hay que señalar que para mi todo es complicado-, creo que los sprites al fin de al cabo hay que tratarlos un poco como polígonos. Es delicado por lo que veo convertir al formato adecuado, cargarlo en la memoria de video y demas rollos... No os aburro pero, de momento, queda pospuesto.

Lo de mostrar texto de diferente color tampoco lo he conseguido. Pensaba que seria una chorrada con el comando slCurColor, pero no ha resultado tan sencillo como sospeché. Parece ser que hay que definir la paleta primero y en las pruebas que he realizado no he conseguido tampoco tener éxito.
Igual alguno de vosotros consigue hacerlo, sería bienvenido si lo lograis y lo explicaráis por aquí (os pongo un post de SegaXtreme en el que hablan de ello y tienen también problemas para lograrlo, es en Orbit pero nos puede dar ideas para tratar de hacerlo en Lua: http://segaxtreme.net/forum/showthread.php?tid=9166 )

Estas dos cosas ya las investigaré por mi cuenta, o trataré de consultaos por aquí a los compañeros que puedan echar un cable al saber mas del tema. Para no estancarme voy a sacarme alguna otra cosa de la manga:


Azar y condicionales

Vamos a aprender a generar un número al azar con la Saturn. En principio puede parecer que no tiene mucha utilidad, pero, con casi toda seguridad, es posible que le saquemos partido con algo de ingenio, ya vereis.
También nos va a servir para tocar los condicionales. Se ve que las sentencias condicionales en programación junto con los bucles son los pilares de la programación estructurada.

Empecemos con el número al azar. Para hacer que la máquina se invente un número al azar vamos a tirar de un comando de la librería de Sega, en este caso es slRandom()

Una función matemática que está descrita de esta forma en la documentación oficial:

Citar:
slRandom
Random number generator

Format: FIXED slRandom()
Parameters: None
Function: This function generates a random FIXED-type value in a range from 0 to 1. Return Value A FIXED-type value ranging from 0.0 to 1.0

Vale, por lo que dice se usa sin parámetros y te genera un numero random que puede oscilar entre el 0.0 y el 1. Ahora lo probaremos, que es gratis

En cuanto a los condicionales, esta vez tiramos de Lua. Le echo un vistazo a la documentación buscando por internet y me pone algo así:

Citar:
An if statement tests its condition and executes its then-part or its else-part accordingly. The else-part is optional.

if a<0 then a = 0 end

if a<b> MAXLINES then
showpage()
line = 0
end

De acuerdo, tambien puedo mirar en los ejemplos del Lua Player que hacen uso de condicionales, como es normal.


A programar de nuevo

Pero menos cháchara y vayamos al grano otra vez. Me he inventado este código tras quebrarme un rato la cabeza y tener varios fallos de sintaxis, problemas varios, etc.. Ahora ya funciona:

Código: [Ocultar] [Seleccionar]
--//------------------------------------------------------------------------
--// Ejemplo de azar y condicionales
--//------------------------------------------------------------------------


slInitSystem(TV_320x240,NULL,1)

slPrint("Generamos un numero al azar -", 2, 1)

slRandom()

if slRandom()<0.49999999999999 then slPrint("RESULTADO: Ha salido menos de medio", 2, 3)
else slPrint("RESULTADO: Ha salido mas de medio", 2, 3)
end

slPrint("Para los desconfiaos,", 2, 5)
slPrint("aqui esta la prueba:", 2, 6)
slPrint(slRandom(), 2, 7)

slPrint("-------------------", 2, 10)
slPrint("Ahora generamos otro distinto -", 2, 11)
slRandom()
if slRandom()<0.49999999999999 then slPrint("Ha salido menos de medio", 2, 13)
else slPrint("Ha salido mas de medio", 2, 13)
end

slPrint("A las pruebas me remito:", 2, 14)
slPrint(slRandom(), 2, 15)

slPrint("Ryo Suzuki _ www.segasaturno.com", 2, 18)

while true do slSynch() end


¿Qué tal? ¿Parece sencillo?

Lo repito, pero esto se dará por hecho cada vez que haya algo nuevo de código que hagamos, copiamos uno de los ejemplos que tengamos y le cambiamos el nombre para usarlo con esta nueva prueba. Podemos por ejemplo darle el nombre a la carpeta IFRANDOM o lo que se os ocurra. Guardamos el correspondiente 0_orig.lua con este codigo que os he puesto, generamos la iso y a correrla rápidamente en el emulador.

Nos aparecerá esto:

azar

Bien, ha funcionado. Ha generado un par de números al azar y ha puesto una condición en ambos casos para comprobar su valor, si el valor era menos de 0.5 ha puesto en pantalla una cosa que correspondía y si era más ha puesto la otra conveniente.

En definitiva, hemos usado generación de azar y sentencias condicionales para que nuestro programa obre en consecuencia.

-continua...


Ryo Suzuki [ 12 Mayo 2014, 04:26 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
--sigo aqui, tengo problemas en ponerlo en un solo tema--


Lo comento linea a linea para que os quede más claro lo que he hecho:

Código: [Ocultar] [Seleccionar]
--//------------------------------------------------------------------------
--// Ejemplo de azar y condicionales
--//------------------------------------------------------------------------


slInitSystem(TV_320x240,NULL,1) -- Inicio el sistema de video, esta vez he puesto una resolución más baja que el otro dia me flipe

slPrint("Generamos un numero al azar -", 2, 1) -- Los print ya los conocemos, ponemos en pantalla una información

slRandom() -- El comando nuevo que hemos aprendido, con esto ya ha generado un número entre 0.0 y el 1 con un montón de decimales

if slRandom()<0.49999999999999 then slPrint("RESULTADO: Ha salido menos de medio", 2, 3)
else slPrint("RESULTADO: Ha salido mas de medio", 2, 3)
end -- Aqui tenemos el primer condicional, le estamos diciendo que si el número que ha generado al azar con el comando slRandom es más pequeño que 0.5 o medio, entonces que ponga en pantalla que efectivamente ha salido menos. Luego el else le dice que si no es asi, por logica aplastante es que será más, por lo tanto en ese caso tiene que escribir en pantalla que ha salido más

slPrint("Para los desconfiaos,", 2, 5) -- prints normales de texto no los comento ya
slPrint("aqui esta la prueba:", 2, 6)
slPrint(slRandom(), 2, 7) -- Esto es en parte lo que aprendimos en la anterior lección, imprimir una variable. En este caso el resultado del comando slRandom que lo ha guardado como una variable interna y con ese resultado hemos hecho el condicional y obrado en consecuencia

slPrint("-------------------", 2, 10)
slPrint("Ahora generamos otro distinto -", 2, 11)
slRandom() -- Lo mismo, generamos otro nuevo
if slRandom()<0.49999999999999 then slPrint("Ha salido menos de medio", 2, 13)
else slPrint("Ha salido mas de medio", 2, 13)
end -- Volvemos a comprobar el valor que tiene con el condicionante y le decimos que haga una cosa u otra

slPrint("A las pruebas me remito:", 2, 14)
slPrint(slRandom(), 2, 15) -- Volvemos a imprimir el número con el que hemos trabajado para demostrar que funciona

slPrint("Ryo Suzuki _ www.segasaturno.com", 2, 18) -- Un poco de autobombo nunca viene mal xD

while true do slSynch() end


Ryo Suzuki [ 12 Mayo 2014, 04:30 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
--sorry, tengo que ponerlo en tres temas o el foro se vuelve loco por los codes y me los junta :S --



Muy bonito, ¿y para qué coño quiero esto?

Es algo que quizás os preguntaréis. Yo lo he hecho, la verdad.
Los condicionales no hay duda que nos van a servir para muchas cosas y como decía antes se ve que son importantísimos en la programación en general. En cuanto al tema del azar... puede ser también interesante.

Le voy a dar un uso práctico para que os hagais una idea que todo con algo de ingenio se puede adecuar a lo que necesitemos. Imaginaos que cuando aprendamos más estamos haciendo un juego 3D simple y que generamos como escenario una serie de cubos que están por ahí por el fondo de la pantalla.

Podríamos hacer por ejemplo que los cubos tuvieran un color al azar. No sería muy costoso y así cada vez que viéramos ese escenario cambiaría ligeramente y nunca sería exactamente igual. Supongamos que vamos a colocar cubos verdes o rojos y dejaremos que la máquina decida al azar con las mismas posibilidades.

El mismo código de antes adaptado a esa idea, algo asi:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_320x240,NULL,1)

slPrint("Generamos un color al azar -", 2, 1)

slRandom()

if slRandom()>0.49999999999999 then slPrint("RESULTADO: El cubo es verde", 2, 3)
else slPrint("RESULTADO: El cubo es rojo", 2, 3)
end

slPrint("Lo hemos determinado,", 2, 5)
slPrint("con este numero:", 2, 6)
slPrint(slRandom(), 2, 7)

slPrint("-------------------", 2, 10)
slPrint("Ahora queremos otro cubo -", 2, 11)
slRandom()
if slRandom()>0.49999999999999 then slPrint("Esta vez el cubo sera verde", 2, 13)
else slPrint("Esta vez el cubo sera rojo", 2, 13)
end

slPrint("Al azar con las mismas posibilidades:", 2, 14)
slPrint(slRandom(), 2, 15)

slPrint("Los pondria en pantalla si supiese", 2, 19)
slPrint("dibujar y colorear poligonos xD", 2, 20)
slPrint("De momento habra que esperar...", 2, 21)
slPrint("Ryo Suzuki _ www.segasaturno.com", 2, 24)

while true do slSynch() end


Otra vez a general la iso y a correrla en el emulador y nos encontraríamos con esto:

azar2

Fijaos que esta vez el azar ha determinado que los dos números sean superiores a 0.5, por lo tanto los cubos son rojos los dos. Cosas del random...

También es curioso, y este concepto no lo acabo de asimilar del todo, que el slRandom() aunque crea un número al azar lo hace de forma fija. De este modo en el emulador si lo probais siempre será el mismo una vez que ha decidido ese azar. Habrá que correr la iso en otro emulador para que os aparezcan otros números, no sé cómo funciona bien pero queda como grabado a fuego. Es azar, pero totalmente fijo una vez que lo ha determinado.


Como podeis ver lo de generar un número al azar nos habría servido para algo práctico. Supongo que lo podemos usar para muchas más cosas, es cuestión de sacarle punta al tema (se me ocurren varias historias más que ya tocaré si puedo).

Si tuviese la capacidad de renderizar polígonos simples pondría unos cuantos verdes y rojos en la pantalla al azar, de momento os lo tengo que mostrar en modo texto porque hasta ahí no llego aun

En fin, eso es todo por hoy. Espero que os haya gustado y que os animeis a usar Lua y podamos aprender entre todos.

Luego os contesto a lo que me pusisteis, ya mañana



P.D: Añado en documentacion esta pagina muy interesante:
http://ppcenter.free.fr/satdocs/
Tiene por ejemplo el manual que comentaba al principio de comandos en html para que podamos copiar y pegar (los pdfs estaban protegidos):
http://ppcenter.free.fr/satdocs/ST-238-R1-051795.html

P.D2: Hay una pequeña errata en el primer post que puse. Es una pequeña trampa que coloqué, en realidad.
Citar:
Nos podemos crear una carpeta nueva llamada por ejemplo Samples Mios y ahí copiamos un sample original para modificarlo y hacer nuestros testeos.

En la carpeta Samples Mios habría que copiar en la raíz la IP.BIN tal y como está en la original Samples. Porque de lo contrario no podriais generar las isos de lo que programeis.


zeros [ 12 Mayo 2014, 08:52 AM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Es curiosa la forma en la que se usa el comando de random. Nornalmente, cuando haces una funcion random (que suelen funcionar con el reloj) metes en una variable su resultado por ejemplo asi.

Código: [Ocultar] [Seleccionar]
Var alea -- declaro la variable vacia alea, aunque no se si esta seria la forma correcta de acerlo en lua
alea = slRandom() -- ejecuto la funcion random y el resultado que devuelve lo introduzco en la variable alea


Sin embargo de la forma que lo usas es como si la propia funcion se quedase el valor, porque al meterla en un if en otros lenguajes de programacion lo que haria es volver a ejecutarse.

Código: [Ocultar] [Seleccionar]
If slRandom() < 0.5 -- aqui normalmente se ejecutaria la funcion nuevamente dando otro resultado diferente
If alea < 0.5 -- esta seria la forma de hacerlo normalmente con una variable a la que previamente le has introducido el contenido
slPrintf(alea,2,5) -- aquí muestra el contenido en pantalla de la variable con el numero random introducido al principio


No estoy diciendo que lo uses de forma incorrecta, lo que digo es que es curiosa esa diferencia respecto a otros lenguajes que he visto.

En el ejemplo la ejecutas y luego la comparas usando la misma función, que de hacer eso en otro lenguaje se volvería a ejecutar y a dar un resultado diferente:

Código: [Ocultar] [Seleccionar]
slRandom() -- aqui normalmente se ejecuta y da un resultado que no va a ninguna variable y por lo tanto se pierde
If slRandom() < 0,5 -- aqui generaría un resultado (diferente del anterior) que se compara en un if
slPrintf(slRandom(),2,5) -- aquí generaría otro resultado diferente y lo imprimiría


Es posible que Lua al ser mas facil no ejecute las funciones en una comparación o una impresión, sino que se guarde su ultimo resultado y lo compare.

PD: es posible que el reloj del emu este siempre a la misma hora exacta? Y como nada mas cargarse la iso se ejecuta el programa siempre tarda lo mismo siempre te el mismo numero, en teoria los randoms salen del reloj del sistema, si el emu comienza a contar desde el 17 de noviembre de 1995 a las 00:00 cuando lo enciendes, siempre sera la misma hora exacta y te dara el mismo random.

Si estoy en lo cierto, al cambiar el programa, que ejecute mas lineas de codigo por ejemplo, tardara mas y dara un numero diferente.

PD2: la utilidad del random, ademas de para crear objetos alea, es para decidir que puntuacion sacas sacas en un combate por turnos: si fallas o no, si sacas critico o cuanto daño haces.

PD3: esto es divertido!! ^^


AngelSega [ 12 Mayo 2014, 11:49 AM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Esto son palabras mayores,, me voy a otro post


Ryo Suzuki [ 12 Mayo 2014, 04:56 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
zeros escribió: [Ver mensaje]
Buenísima clase tio!! Me ha gustado lo de proponer un ejercicio XD Pordía montarse un curso de programación en saturn no? Saber que funciones van de SEGA library, cuales de LUA. (yo creo que el estar ahi con el prueba y erro es lo que más echa atras.

Has visto? He intentado hacer de profe como tu

zeros escribió: [Ver mensaje]

Ese gráfico que has mostrado 3D, ese cubo rectángulo, lo que sea... no lo generas por código no? o sea le das un archivo al lua que carga aparte, un archivo hecho con un editor 3D supongo, no? si es así que extensión tiene?

Efectivamente, si te miras el sample veras que hay una carpeta llamada data donde hay varios recursos que necesita ese codigo para funcionar. El objeto tridimensional, el model en sí creo que es MDL_6.MDL.

Fijate en este tutorial que publicó el amigo Facundo ARG (él sí que sabe de estos temas!!):

http://www.segasaturno.com/portal/viewtopic.php?t=4125

Convierte de 3D Studio Max a .mdl que es el formato que parece ser que maneja la Saturn. Todo esto es igual en Saturn Orbit que en Lua, ya que al fin del cabo los assets graficos y demás deben tramitarse igual por lo que estoy viendo.

Pero ahi no queda todo en este ejemplo de Lua. Veo que hay un archivo que tiene relacion con el objeto 3D .mdl, en este caso es poly.c , que contiene esto:

Código: [Ocultar] [Seleccionar]
//------------------------------------------------------------------------
//
// X
//
// POLYGON DATA
//
// CONFIDENTIAL
// Copyright (c) 1996, Sega Technical Institute
//
// AUTHOR
// CHRIS COFFIN
//
// TARGET
// SEGA SATURN
//
// REVISION
// 00/00/00
//
// ORIGINAL FILE
// s:\sgl_3\sgl\sample\chrome\poly.c
//
//------------------------------------------------------------------------

#include "sgl.h"
#include "sega_sys.h"


//#define NO_TEXTURE

// test chrome/bump object

#ifdef NO_TEXTURE

// NON TEXTURED FLAGS
#define Chrome_ATR (MESHoff | CL_Gouraud | CL256Bnk)
#define Chrome_OPT (UseGouraud | UsePalette)
#define Chrome_COL (16)
#define Chrome_TEX (No_Texture)
#define Chrome_POLY (sprPolygon)

#else

// TEXTURED FLAGS
#define Chrome_ATR (CL256Bnk|CL_Gouraud|MESHoff|SPdis|ECdis)
#define Chrome_OPT (UseGouraud)
#define Chrome_COL (1024)
#define Chrome_TEX (0)
#define Chrome_POLY (sprNoflip)

#endif


// DEMO MODEL DATA

#include "mdl_6.mdl"


Como ves define una serie de atributos y hace referencia al mdl_6.mdl que comentabamos. Tambien te habras fijado que esta en C, creo. Esto me parece que es porque Lua soporta trabajar y llamar cosas de C sin problemas, varios samples lo hacen.

Lo único que no me queda muy claro es que es otro archivo relacionado que se llama poly.o que encontramos tambien en la carpeta data, pero parece linkar informacion importante referente a poly.c ....


P.D: Por cierto, fijaos que el código lo firma el propio CHRIS COFFIN . O sea, Christina Coffin, que estaba haciendo el Sonic Xtreme para la Saturn.

zeros escribió: [Ver mensaje]

Por ejemplo, usar este lenguaje de programación, asegura poder sacar rendimiento a la consola? o hay que programar a más bajo nivel para hacer algo parecido al Sonic Jam por ejemplo?


No estoy seguro. Creo que con el Lua bien optimizado y usando las librerias de SEGA bien, cosas en C, optimizando recursos y demas se podria hacer alguna cosa bastante decente. Por lo que leo que comentó Rockin'-B con Lua se podría programar en la Saturn de forma algo más sencilla y no mencionaba nada que se pierda capacidad respecto a Saturn Orbit/SDK oficial.

Ahora, para hacer al como lo que se ve en Sonic Jam la parte 3D nueva que lleva... Yo creo que eso, para empezar nunca podemos aspirar a ello (colocar un puto poligono es una movida, no me quiero imaginar controlar un engine asi) y luego a mi me da la nariz que ahí ya hay bastante tema en ensamblador para poder sacarle más partido a la máquina.

Luego sigo contestando al crack de Indiket, que queda muy largo esto...


Indiket [ 12 Mayo 2014, 11:12 PM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Noon, tienes un EXCELENTE foro de habla hispana de programación Dreamcast!!!

http://dreamcast.es/forum/viewforum.php?forum_id=21

Tienes tutoriales para crear tu Toolchain, montarte las herramientas, preguntar... ^^ . Si sabes C o C++ y dominas librerías gráficas como SDL, lo tienes chupado!

Ryo le estás dando caña de la buena amigo!! Pregunta general, sabéis si el homebrew puede aprovechar la RAM del cartucho? Sumándolo todo, cual es el máximo de RAM que puede soportar la Saturn?


FacundoARG [ 12 Mayo 2014, 11:41 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
@Ryo:
Excelente, los veo capacitados para ayudarme con el bonus stages del Sonic Jump


Ryo Suzuki [ 13 Mayo 2014, 02:50 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Contesto lo del colega Indiket del primer post, que se me acumula la faena:

Indiket escribió: [Ver mensaje]

- La accesibilidad: Nos guste o no, en Dreamcast es muy fácil cargar binarios sin firmar (tan fácil que ni siquiera se necesita chip y custom firmware ni nada!!). Y cada vez hay más opciones: vía SD, vía BBA, pronto vía HDD....
En Saturn, hay que tener la consola chipeada (creo). Y luego, ¿qué opciones hay de cargar binarios? La única que conozco es quemando CD's... hay alguna otra???


Si que las hay. Yo tengo por ejemplo el USB Data Link que permite conectar el PC por USB al Action Replay y ejecutar codigo:

http://www.gamingenterprisesinc.com/DataLink/

Tambien está esa opción:

http://koti.kapsi.fi/~antime/sega/usbcart/usbcart.html

Y luego esta es mas hardcore y aunque puede hacerse como han demostrado no han liberado la info para hacerlo:

http://policeofficersmith.de/cgi-bin/weblog_basic/index.php?p=52

Con eso se podrian vender juegos en cartucho y no necesitarias chip ni nada raro para cargarlos

Indiket escribió: [Ver mensaje]


PD: Ryo, hay pendiente ver una demo rulando de Sonic Jam, cierto? jajaja


¿Quieres decir Sonic Jump? Facundo nos va a matar, jaja!!

-----------------------------
Y a bueno de Zeros:

zeros escribió: [Ver mensaje]

PD: es posible que el reloj del emu este siempre a la misma hora exacta? Y como nada mas cargarse la iso se ejecuta el programa siempre tarda lo mismo siempre te el mismo numero, en teoria los randoms salen del reloj del sistema, si el emu comienza a contar desde el 17 de noviembre de 1995 a las 00:00 cuando lo enciendes, siempre sera la misma hora exacta y te dara el mismo random.

Si estoy en lo cierto, al cambiar el programa, que ejecute mas lineas de codigo por ejemplo, tardara mas y dara un numero diferente.

No, creo que no es por el reloj, no se como lo hace ni donde lo guarda. Pero no te despegas de ese numero ni a tiros

Si cambias lineas de codigo y vuelves a compilar la iso, vuelven a salir los mismos numeros!! La unica forma que he encotrado es cambiar de emulador para que salgan otros. Pruebalo si puedes, ya lo veras...

zeros escribió: [Ver mensaje]
PD2: la utilidad del random, ademas de para crear objetos alea, es para decidir que puntuacion sacas sacas en un combate por turnos: si fallas o no, si sacas critico o cuanto daño haces.


Bien dicho. Supongo que lo haran asi, lo que pasa es que eso tiene que ser un azar bastante más manipulado que el que hemos usado aqui, porque hay juegos que se las traen de lo cabrones que son xD

----------------------------
Y vuelvo a Indi:

Indiket escribió: [Ver mensaje]

Ryo le estás dando caña de la buena amigo!! Pregunta general, sabéis si el homebrew puede aprovechar la RAM del cartucho? Sumándolo todo, cual es el máximo de RAM que puede soportar la Saturn?


Efectivamente, se puede hacer uso de los 4 megas. Algun homebrew de Rockin'-B lo usa, creo que sin ir más lejos una util para pasar partidas del CD a la memoria interna que hemos usado para la traduccion de Policenauts y que creo que viste en el RetroMadrid del 2013 usaba esa capacidad. Creo que soportaba archivos comprimidos y si detectaba la ram extra lo procesaba más rápido.

Es posible usar la Ram extra y creo que eso no seria muy dificil de hacer (aunque en Saturn me da a mi que cualquier minucia entraña su dificultad, lol!)

En total contaríamos con nada menos que 6 megas. 2 Mb que trae la consola y 4 más que podríamos sumarle si tenemos el cartucho metido (y cualquier usuario que vaya a usar un homebrew tiene con casi toda seguridad un Action Replay, o sea que podriamos considerarlo un estandar)

Esto la deja por arriba dos de sus contemporaneas más o menos, la PSX (que tiene 2mb y no se pueda ampliar) y la N64 que gasta 4 megas (aunque esta podria llegar hasta los 8 megas si le poniamos el expansion pack, aunque salio dos años despues de la Saturn). Si es tan importante como comentas, podria darle un plus interesante usar el cartucho siempre.

-----------------------------------------------------------------
FacundoARG escribió: [Ver mensaje]
@Ryo:
Excelente, los veo capacitados para ayudarme con el bonus stages del Sonic Jump

En lo que se pueda, maestro. Pero tu eres aqui el que dominas del tema. A ver si hablamos que quiero preguntarte varias cosas de poligonos y sprites


Indiket [ 13 Mayo 2014, 11:17 PM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Que interesante es el USB Data Link!! Ryo, sabes si es fácil obtenerlo? Vale para todos los Action Replay?? Me interesaría tener uno ya!!!

6 MB de RAM es ya una cantidad interesante en comparación con sus competidores, pero es realmente muy poco si lo comparamos con la mayoría de juegos y ports homebrew!! Pocos conozco que ocupen poco en RAM, la verdad! Casi todos suelen estar entre 10-14 y más!!!

Por esas razones, Rockin-B o vbt sólo hizo ports de XRick (SDL), Another World (intérprete RAW), Wolf3D, Wolf4SDL y Flashback (otro intérprete, no me acuerdo del nombre)!!!! Son juegos en origen DOS, que no ocupan casi nada de RAM y se pueden portear a multitud de sistemas (sabían que hace nada han hecho un port de XRick para SNES?? jajajaja).

Por ejemplo: Another World ocupaba menos de 1 diskette (1.4MB!!), y Wolf3D corría en un 286 con 640kb de RAM!

Eso sí, todos ellos hay un currazo detrás amigos! Ya que hay que reconvertir todas las rutinas de pintado, las de sonido, los controles... a código SGL o parecido! Peeeroo.. He leído que vbt hizo un "wrapper" de la SDL, usando librerías SGL! Eso es lo que sirve amigos, para ir haciendo ports fácilmente y rápidamente!!!

http://www.segasaturno.com/portal/viewtopic.php?t=6910

Sabéis si Rockin-B publica los códigos fuentes de los ports? Dónde se puede obtener ese wrapper, aunque sea con SGL y no libyaul? Sería interesante ver que libs usó y cómo lo hizo, para tener ideas!!!


Wesker [ 14 Mayo 2014, 12:03 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Indiket escribió: [Ver mensaje]
Por esas razones, Rockin-B o vbt sólo hizo ports de XRick (SDL), Another World (intérprete RAW), Wolf3D, Wolf4SDL y Flashback (otro intérprete, no me acuerdo del nombre)!!!! Son juegos en origen DOS, que no ocupan casi nada de RAM y se pueden portear a multitud de sistemas (sabían que hace nada han hecho un port de XRick para SNES?? jajajaja).


REminiscence

Por cierto, vbt también lleva un tiempo trabajando en una versión Sega Saturn del emulador Final Burn Alpha. Cada cierto tiempo la va mejorando añadiendo mayor compatibilidad de juegos, aunque lógicamente está bastante limitado en los arcades que puede emular Sega Saturn (según él, más por tema CPU que por tema RAM).


Indiket [ 14 Mayo 2014, 12:55 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Gracias Wesker, ese era jeje.

Para que os animéis un poco, algo de homebrew Saturnero que encontré: http://vieille.merde.free.fr/
Son juegos programados directamente en SGL pero ya aviso que no es un camino de rosas! xD


FacundoARG [ 14 Mayo 2014, 04:09 AM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Indiket escribió: [Ver mensaje]

Sabéis si Rockin-B publica los códigos fuentes de los ports? Dónde se puede obtener ese wrapper, aunque sea con SGL y
no libyaul? Sería interesante ver que libs usó y cómo lo hizo, para tener ideas!!!


Indiket, el wrapper esta publicado en segaxtreme. Es el que vbt usó con el Wofl3D, le envié un mensaje privado hace 1 año más o menos y nunca me contestó.

Fijate si tenes suerte en compilarlo, no parece difícil pero no tengo mucho tiempo.


Ryo Suzuki [ 16 Mayo 2014, 03:15 PM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Indiket escribió: [Ver mensaje]
Que interesante es el USB Data Link!! Ryo, sabes si es fácil obtenerlo? Vale para todos los Action Replay?? Me interesaría tener uno ya!!!


Es facil. Vienes a verme y te lo dejo junto a un Action Replay de los antiguos que tiene puerto para conectarlo.

Quiero que el bueno de Indiket se meta en Saturn, este hombre es un crack de los ports, etc...

FacundoARG escribió: [Ver mensaje]

Indiket, el wrapper esta publicado en segaxtreme. Es el que vbt usó con el Wofl3D, le envié un mensaje privado hace 1 año más o menos y nunca me contestó.

Fijate si tenes suerte en compilarlo, no parece difícil pero no tengo mucho tiempo.


Tenemos que mirar lo del SDL Wrapper a fondo. Facundo enviale un privado desde aqui mismo si puedes, que el bueno de vbt anda por aqui por el foro y he hablado con el hace poco.

Bueno, sigo con mis tutoriales. ¿Que pensabais que os iba a dejar en paz?



Más estructuras de control: while

Hemos visto y usado estructuras de control como el if. Ahora vamos a ver otra que es el buqle while cuyo propósito es repetir un bloque de código mientras una condición se mantenga verdadera.

Imaginate, por poner un ejemplo practico de la vida real, que tienes un juego de segunda mano para vender y piensas "por menos de 10 euros no lo vendo". Varios amigos te van haciendo ofertas, te doy 3 euros, te doy 7, te doy...

Entonces llega uno que te ofrece 11 leuros y automaticamente se lo vendes. O sea que mientras(while) que no te ofrezcan al menos 10 euros tu no lo soltabas

Pues esto es lo mismo que hace el comando while en Lua. Te mete en un bucle en el que se ejecuta un bloque de codigo hasta que no se cumpla esa condicion.

Citar:
- while loop

while condition do
block
end


Vamos a verlo con un caso practico con el Lua Player de Saturn. He vuelto a perpetrar un codigo de los mios, aqui lo teneis:

Código: [Ocultar] [Seleccionar]
--/***************************************************
--
-- WHILE SAMPLE SATURNO TUTORIAL
--
--***************************************************/

local variable_numerica = 1

local variable_saltolinea = 4

slInitSystem(TV_320x240,NULL,1)

slPrint("- EJEMPLO DE WHILE -", 12, 1)


while variable_numerica<10 do

slPrint(variable_numerica, 3, variable_saltolinea)
variable_numerica = variable_numerica + 1
variable_saltolinea = variable_saltolinea + 2

end


slPrint("Ryo Suzuki para www.segasaturno.com", 3, 25)

while true do slSynch() end


Generamos la iso como siempre y lo probamos en el emulador. Nos aparece esto:

while

Ha funcionado. Le hemos dicho que vaya imprimiendo una variable numerica en pantalla y que esa variable se vaya incrementando +1 cada vez y la vaya mostrando en pantalla en ese proceso, MIENTRAS sea menor de 10. Cuando sea mayor o igual a 10 ya el bucle del while deja de ejecutarse y en este caso el programa termina.

Vamos a ver el codigo comentado para que quede mas claro y explicar las instrucciones y como lo he montado:

Código: [Ocultar] [Seleccionar]
--/***************************************************
--
-- WHILE SAMPLE SATURNO TUTORIAL
--
--***************************************************/

local variable_numerica = 1 -- creamos la variable que vamos a imprimir en pantalla y vamos a ir incrementando hasta que llega a 10

local variable_saltolinea = 4 -- esto es una variable extra que no se va a ver pero nos va a servir para que imprima cada vez la variable anterior en una linea diferente porque si no no veriamos como se incrementra en pantalla (seria instantaneo a nuestros ojos)

slInitSystem(TV_320x240,NULL,1)

slPrint("- EJEMPLO DE WHILE -", 12, 1)


while variable_numerica<10 do -- comienzo de la estructura de control while, le estamos diciendo como veis que mientras la variable numerica sea menor de 10 que haga el siguiente bucle

slPrint(variable_numerica, 3, variable_saltolinea) -- *comienzo del bucle, imprime la variable con el valor que tenga en ese momento, el 3 son tres espacios en la linea que le toque, la variable salto de linea es en la linea de la pantalla que la queremos (empezara en la 4)
variable_numerica = variable_numerica + 1 -- incrementamos la variable numerica en uno, cada vez le sumamos uno en este bucle
variable_saltolinea = variable_saltolinea + 2 -- incrementamos la variable salto de linea dos, para que cada vez imprima la variable numerica dos lineas mas abajo y no se pise con la anterior impresion en pantalla *fin del bucle

end -- fin del while


slPrint("Ryo Suzuki para www.segasaturno.com", 3, 25)

while true do slSynch() end


Creo que habra quedado bastante claro. Como el if el while nos puede servir de mucho a la hora de programar cualquier cosa que hagamos. Luego le doy una vuelta de tuerca a este mismo ejemplo si puedo, que voy mal de tiempo ahora mismo y me tengo que ir a comer.

Un saludo y que no se anime tanta gente a probar estos tutoriales y a trastear con Lua que estoy desbordado de preguntas


Indiket [ 19 Mayo 2014, 12:46 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Mientras Ryo se prepara para la siguiente clase de programación 101, os comunico que he estado estos días trasteando con la libyaul

LibYaul es una nueva librería para programar en Saturn, con la diferencia que es 100% opensource! Y eso atrae mucho amigos, es como el KOS de Dreamcast!!

https://github.com/ijacquez/libyaul

Conseguí compilar mi tool-chain saturnera, la librería y el ejemplo gracias a la ayuda del mismo Piratero ;) . En los próximos días pondré un nuevo hilo con todos los detalles para que os la podáis compilar y algunas capturas interesantes ^.^


Raizing [ 19 Mayo 2014, 09:00 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Muy buen curro Ryo.

A raíz de ver este hilo me he puesto a leer las documentación que todo kiski tiene sobre la SBL y la SGL (los manuales i tal) y me estaban dando ganas de toquetear xD.

Indiket, tengo ganas de ese post... el LibYaul pinta bien, en qué estado estaba? es que creo que desde 2012 no había mucho movimiento, no?

Saludos,


Indiket [ 20 Mayo 2014, 12:47 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Cierto Raizing, no hubo mucho movimiento. Pero recientemente contacte con Piratero y me comentó que hizo muchos cambios internos. Algunas cosas están rotas, pero pinta muy bien!!

Mañana redacto el tutorial, espero que os guste!


Indiket [ 20 Mayo 2014, 11:56 PM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Lo prometido es deuda Raizing!! Aquí tenéis el tuto ;)

http://www.segasaturno.com/portal/t...370.html#p78370


Ryo Suzuki [ 24 Mayo 2014, 04:19 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Raizing escribió: [Ver mensaje]
Muy buen curro Ryo.
A raíz de ver este hilo me he puesto a leer las documentación que todo kiski tiene sobre la SBL y la SGL (los manuales i tal) y me estaban dando ganas de toquetear xD.


A ver si os animáis. Yo voy haciendo mis pruebas tratando de aprender un poco.


El azar de Lua

Si antes vimos la función azar de la librería de SEGA slRandom() que nos devolvía un número al azar con bastantes decimales, ahora he estado echándole un ojo a esta misma función pero desde Lua. Es la ventaja que tenemos con este Lua Player tan particular para Saturn, en ocasiones podemos usar cosas de las librerías oficiales de SEGA, pero también podemos hacer uso del lenguaje Lua en esta particular mezcla que es el Lua Player.

La función para azar es math.random
Citar:

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, math.random devuelve un número pseudoaleatorio entero uniforme en el rango [1, m]. Cuando se invoca con dos argumentos m y n enteros, math.random devuelve un número pseudoaleatorio entero uniforme en el rango [m, n].


Imaginemos que necesitamos un número entero al azar del 1 al 10. Creo que debería usar el comando:

Código: [Ocultar] [Seleccionar]
math.random(1,10)


Lo pruebo haciendo un pequeño programa que genere e imprima en pantalla varios números al azar, como ya sabemos y obtengo esto:

azar_saturn_lua

No os pego el código simple porque ya sabéis hacerlo. Como veis, ha funcionad. Lo de pseudoaleatorio al final va a ser verdad porque parece ser que tiende a repetir números... cosas del azar?

Con Lua, en este sentido, vemos que tenemos más flexibilidad, ya que con el de la librería de SEGA el rango de azar era solo entre 0.0 y el 1 con 14 decimales y ahora podemos definir nosotros más el azar a nuestras necesidades:

azar500

Ahora le he dicho math.random(0,500) y me ha generado números al azar desde el 0 al 500 -ambos incluidos-, también como habréis visto se me ha olvidado editar el título del programa... soy un programador chapucero


Funciones no usadas por SEGA en la Saturn

Quizás pensáis que es osado que yo que no tengo ni idea de estos temas crea haber descubierto algo así, pero me parece a mi que es cierto. Por lo que he estado viendo hay varias funcionalidadades de la Saturn que estoy comprobando que nunca se han usado en ningún juego comercial a pesar de que la consola era capaz de ello.

Una de ellas es la posibilidad de en los juegos multilenguaje no obligarte a seleccionar el idioma y por el contrario coger esa información de cómo tenemos configuradad nuestra máquina y mostrar el idioma correspondiente, como hicieron consolas posteriores como la Dreamcast, PlayStation 2, etc...

Podríamos determinar que la Saturn se adelantó a su tiempo en esta posibilidad, aunque nunca se llegó a usar

Esto se podría hacer con el comando slGetLanguage() que obtiene el número de lenguaje almacenado en la bios de la consola. Con eso y con algo como el IF que hemos aprendido ya podríamos derivar a nuestro programa -o juego comercial, como decía- a que muestre un idioma u otro en pantalla según nos interese.

Pero no solo eso, podemos con un programa a "obligar" a nuestra Saturn a configurarse con un lenguaje concreto que nos convenga. Por ejemplo tenemos la consola configurada en inglés y podemos forzarla a que se ponga en español.

Esto se haría con este comando de la librería SEGA:

Citar:
slSetLanguage(numero del lenguaje que queramos)


Por ejemplo, yo creo un pequeño programa que ejecute: slSetLanguage(3)
Con esta orden pondría la bios de la consola en castellano, con independencia de qué idioma tuviese configurado. Como digo, algo que ningún juego comercial ha hecho y por lo tanto una funcionalidad no usada en la Saturn...

El problema es que en cuanto hacemos reset se va a tomar viento, ya que no hemos almacenado este cambio. Edito mi código con otro comando nuevo que sirve para precisamente eso, que no es otro que:

Citar:
slSetSmpcMemory()


Le estoy diciendo que tras cambiar a castellano guarde los cambios del estado como está en ese momento la SmpcMemory que es toda la info de configuración de la bios.

Os pongo el programita para que lo veais:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_320x240,NULL,1)


slPrint("Lenguaje de la Bios en castellano", 3, 1)

slSetLanguage(3) -- pone la bios de la Saturn en spanish, que es el numero 3
slPrint("- OK, ahora es SPANISH", 3, 15)

slSetSmpcMemory() -- guarda la bios tal y como esta en este momento, en este caso guardaria el cambio de lenguaje que hemos hecho
slPrint("- OK, guardo los cambios", 3, 17)

slPrint("Aunque hagas reset o ", 3, 20)
slPrint("apagues la consola sera asi.", 3, 21)

slPrint("Ryo Suzuki de www.segasaturno.com", 3, 27)


while true do slSynch() end


Le hemos dicho que poga el lenguaje 3, que es el castellano. He comprobado que el 4 es el italiano y el 5 el japonés. Los demás podéis probadlos vosotros mismos...

Ejecuto el tema y sale esto:

language_saturn_dev

Podeis comprobadlo en el emulador que efectivamente funciona. Hace lo que dice incluso en consola real, a no ser -claro está- que no tengáis pila en vuestra consola

Podeis configurar la bios en el SSF con cualquier idioma diferente al español y comprobar que tras ejecutar esta iso que generemos y volver a la bios del emulador, la consola queda configurada en castellano.

Un pequeño ejemplo de que hay funciones de las librerías de SEGA que nunca fueron usadas en la vida comercial de la SEGA Saturn.

Eso es todo por el momento, ya seguiré con más "lecciones" si os apetecen. Un saludo!!



P.D: De momento continuaré con el Lua Player hasta que pueda avanzar más y pueda migrar al YAUL que ha posteado el bueno de Indiket

P.D2: Os pongo otra página con buena info sobre Lua y varios samples que la estoy consultando en busca de info: http://lua-users.org


Wesker [ 24 Mayo 2014, 06:23 PM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Ryo, la función de que la consola detecte el idioma de la bios y configure el arranque de los juegos de acuerdo a ese idioma sí que se llegó a utilizar. Sin ir más lejos, hay juegos como las versiones PAL de Panzer Dragoon y Exhumed que se inician directamente en castellano si la consola detecta el castellano como idioma de la bios.

Incluso hay juegos que sólo salieron en Japón como The King of Fighters '96 que se inicia directamente en castellano (o pseudo-castellano según se interprete las traducciones chusqueras que hacía SNK ) si la bios está en castellano, o Final Fight Revenge que se inicia en inglés si detecta en la bios cualquier idioma que no sea japonés.

Hay muchos más, sobre todo los típicos juegos multi-idioma que son de third parties. Se podría hacer el típico listado para tenerlos referenciados.


Ryo Suzuki [ 26 Mayo 2014, 12:20 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Veis lo que me pasa a veces? Que soy un bocazas

Es cierto que haciendo memoria sí que conocía al menos el Panzer Dragoon que lo tengo japonés y europeo en mi colección y que efectivamente tenía que haber recordado que es un juego que hace uso de esta funcionalidad (el PAL, of course).

Además, como estuvimos hablando luego, creo que la Saturn es la consola pionera en este sentido de tener una bios configurable con opciones como idioma, fecha, hora, etc; y que guarda esa información por medio de una pila. Si estoy confundido y hubo otra antes que alguien me desmienta esta info...

En cuanto a lo de funciones no usadas, en mi defensa diré -y tras la metedura de pata- que slSetLanguage sí que estoy casi seguro que no lo usa ningún juego. De hecho no tiene mucho sentido que un juego te cambie esa configuración, o al menos yo personalmente no le veo razón de ser... pero en fin, que el comando ahí está....


Bueno, sigo avanzando un poco más en mis devaneos con el Lua Player. Voy a abordar una lección que acabo de improvisar hace unos minutos. Hoy toca el turno de:


Detectando el pad y periféricos conectados

Para esto me he documentado mirando este hilo del amigo y maestro saturnero FacundoARG. Ahí explicaba como controlar un cuadrado blanco con el mando bajo Saturn Orbit y me ha servido de mucho ya que adaptando un poco en ocasiones la sintaxis a este Lua Player he conseguido que me funcione, al menos hasta cierto punto.

Cito al bueno de Facundo que explicó muy bien como administra la Saturn este tema:

Citar:
Primero vamos a entender como se manejan los pads.
El SMPC(System Manager & Pheriperal Control) Sistema de administración y Control de Periféricos, tiene como una de sus tantas tareas controlar nuesotros joysticks.

Tenemos dos constantes Per_Connect1 y Per_Connect2 que contienen el estado de los periféricos/puertos 1 y 2 respectivamente.
El resultado/valor que se puede obtener en todo momento (lo asigna el SMPC) son:

0 Si hay algo conectado al puerto.
1 Si no esta conectado algún pad al puerto.


Con esta valiosa información y ajustando un poco los condicionales a Lua, lo pongo en práctica:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_720x576,NULL,1)


slPrint("- SAMPLE DE ESTADO DE PUERTOS 1 Y 2 -", 2, 2)

if Per_Connect1()==0 then slPrint("-Puerto 1: Nada conectado", 2, 6) else slPrint("-Puerto 1: Algo conectado", 2, 6)
end

if Per_Connect2()==1 then slPrint("-Puerto 2: Algo conectado", 2, 8)
else slPrint("-Puerto 2: Nada conectado", 2, 8)
end


slPrint("www.segasaturno.com", 10, 25)

while true do slSynch() end

Creamos la iso correspondiente como siempre, ejectuamos en el el emulador y obtenemos este resultado:

01_mandos

Parece haber funcionado bien. Vamos a cercionárnos de que sea correcto y esté detectando bien. Configuramos en emulador y en el puerto dos le decimos, por enchufar algo virtual, que tenemos metido un ratón de Saturn:

02_mandos

Volvemos a ejecutar la iso en el Yabause para comprobar que todo haya ido bien:

03_mandos

Como dirían los ingleses, so far so good. Volvamos a las enseñanzas saturneras del master FacundoARG:

Citar:
Por otro lado tenemos Smpc_Peripheral[] que es un array, donde el indice del arreglo/vector es el número de pad. Que van desde el 0 al 11.
Recuerden que podemos conectar 12 joysticks con el multitap; 6 por cada puerto.

Tenemos 3 tipos de datos en la estructura del array Smpc_Peripheral[].
data (es el metodo conocido como Pressed que significa persionado constantemente ó mantener presionado)

push (es el metodo conocido como press, que significa que ejecuta la accion apenas presionamos el boton)

pull (es el metodo conocido como release, que significa que se ejecuta la accion una vez soltado el boton que hayamos presionado)


Los botones:

PER_DGT_ST
PER_DGT_KU
PER_DGT_KR
PER_DGT_KD
PER_DGT_KL

PER_DGT_TA
PER_DGT_TB
PER_DGT_TC

PER_DGT_TX
PER_DGT_TY
PER_DGT_TZ

PER_DGT_TL
PER_DGT_TR


Supongo que PER_DGT significa Peripheral_Didital, TA = Trigger A, KU = Keypad Up , ST = Start .


Genial, vamos a añadir esto a nuestro pequeño programa que hemos creado antes para detectar si los puertos uno y dos tenían algo conectado.

Imaginemos que queremos detectar y que nos informe en pantalla si estamos pulsando el boton A del mando 1.

A Lua, yo lo adaptaría así:

Citar:
if bit.band(data, PER_DGT_TA) == 0 then slPrint("Estas pulsando A en el mando 1", 5, 12)
end


Cambia ligeramente de como lo hacía Facundo en el Saturn Orbit. Lo he mirado de los ejemplos de Lua que usan la gestión y detección del mando. Por lo que veo necesitamos hacer también esto antes de dar ese condicional para detectar que botón estamos pulsando:

Citar:
id,ext,data = Smpc_Peripheral(0)


Por lo que entiendo son como tres variables asociadas al system managament y al periferical control. Con esto y la linea que he puesto arriba podemos detectar en este caso si estamos pulsando A (fijaos que hemos puesto PER_DGT_TA) y poner un mensaje en pantalla en cuanto lo hagas.


Integrando con todo lo aprendido

Voy a poneros un código que he hecho usando la detección del mando y pulsación de un botón concreto y a la vez tratándolo de unificar con todo lo que he ido aprendiendo anteriormente (variables, condicionales, bucles whiles, etc). Por lo que estoy intuyendo en el tema este de la programación es importante ir adquiriendo conocimientos y tener la capacidad de integrarlos todos y hacer buen uso de ellos.

Ahí va mi nuevo programa:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_320x240,NULL,1)

local bucle = 3

local variablepad = 0.25

local variableautoincremento = 0

slPrint("- VARIABLES LOCAS Y TAL -", 7, 1)


while bucle < 30000000000 do

slPrint("-Esta variable va subiendo", 1, 6)
slPrint(" al pulsar A", 1, 7)

slPrint(variablepad, 20, 7)

slPrint("-Sin embargo esta se incrementa ", 1, 9)
slPrint(" por la puta cara", 1, 10)

slPrint(variableautoincremento, 20, 10)

variableautoincremento = variableautoincremento + 0.02

id,ext,data = Smpc_Peripheral(0)
if bit.band(data, PER_DGT_TA) == 0 then variablepad = variablepad + 0.25
end
if bit.band(data, PER_DGT_TA) == 0 then slPrint("----Pulsando----", 10, 16) else slPrint("--No Pulsando---", 10, 16)
end

slPrint("Ryo Suzuki de www.segasaturno.com", 3, 25)
end

while true do slSynch() end


Si lo miráis detalladamente no es muy complicado, ¿no? Luce tal que así:

variables_locas

Como veis y podéis probar si compiláis este código y creáis la correspondiente iso, este pequeño programa muestra dos variables en pantalla. Una de ellas se incrementa cuando pulsamos el bóton A, mientras que la otra va subiendo de valor sin que hagamos nada.

También podéis comprobar que tenemos un "chivato" que nos indica si estamos o no pulsado el bóton, para decorar un poco.

Creo que es bastante entendible, pero aun así lo comento que puede venir bien por si alguno se pierde:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_320x240,NULL,1)

local bucle = 3 -- creo esta variable que la voy a usar para crear el bucle principal del while del programa

local variablepad = 0.25 -- esta es la variable que se va a incrementar con la pulsación del pad

local variableautoincremento = 0 -- ahora defino la variable que como su nombre indica se auntoincrementa automaticamente

slPrint("- VARIABLES LOCAS Y TAL -", 7, 1)


while bucle < 30000000000 do -- bucle del while principal, hasta que no llega a un numero muy alto haz esto...

slPrint("-Esta variable va subiendo", 1, 6)
slPrint(" al pulsar A", 1, 7)

slPrint(variablepad, 20, 7) -- muestro en pantalla la variable del pad

slPrint("-Sin embargo esta se incrementa ", 1, 9)
slPrint(" por la puta cara", 1, 10)

slPrint(variableautoincremento, 20, 10) -- muestro en pantalla la variable que va subiendo de valor sola

variableautoincremento = variableautoincremento + 0.02 -- comoe esta dentro del bucle a cada pasada la variable autoincremento va a subir 0.02

id,ext,data = Smpc_Peripheral(0) -- necesito hacer esto que no se bien lo que es para detectar el pad, es valido solo para el mando uno porque hemos puesto 0, como hemos explicado antes

if bit.band(data, PER_DGT_TA) == 0 then variablepad = variablepad + 0.25 -- Si pulsamos A, la variable pad de incrementea 0.25
end -- esto es el end de este if, ¿queda claro?

if bit.band(data, PER_DGT_TA) == 0 then slPrint("----Pulsando----", 10, 16) else slPrint("--No Pulsando---", 10, 16) -- aqui lo que hago es usando el mismo condicional además de sumar 0.25 como ha hecho antes que imprima si estas pulsando o no (gracias al uso del else que ya hemos aprendido). Tengo que tener cuidado con la colocación del texto para que uno "pise" a otro y quede bien
end -- end de este if, NOTA: esto se podria hacer con un If combinado que a la vez que sume imprima, seria algo asi if con then "haz esto" y "haz esto otro tambien", como no se hacerlo aun o no encuentro la sintaxis correcta tengo que usar dos ifs :(

slPrint("Ryo Suzuki de www.segasaturno.com", 3, 25) -- A lo Cristiano Ronaldo
end -- Para los despistados este es el end de nuestro bucle principal while

while true do slSynch() end


No está nada mal la fusión de conocimientos que he aplicado. Sin embargo tiene una pequeña pega. Si lo probáis vereis que pulsando A, aunque lo hagamos muy ligeramente la variable se incrementa de golpe bastante -como 1 y pico cada vez-, o sea no podemos ver el incremento de 0.25 a cada pequeña pulsación. Esto no sé como afinarlo bien, aunque supongo que se debe poder hacer... Si teneis idea o podéis ayudarme, ya sabéis...

En fin, que eso es todo por hoy. Añado en esta ocasión la iso de este último sample por si os apetece probarlo y no os animáis a compilarlo por vosotros mismos.

Pronto +


Ryo Suzuki [ 10 Junio 2014, 08:03 PM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Después del arrollador éxito (es lo que esperaba, jeje) sigo con este tema.

Antes de nada os comentaré dos cosas. La primera es este framework para hacer juegos 2D con Lua que acabo de descubrir:

https://www.love2d.org/

En principio no nos sirve para nada con el Lua de la Saturn, pero ahí lo dejo para investigarlo porque puede ser interesante.

También, como documentación y os lo pongo ahora todo junto que luego me lío con el rollo y se me olvida, es muy bueno esto:

http://www.rockin-b.de/saturn/satur...ameTutorial.htm

Podríamos decir que es la biblia de la programación en Sega Saturn de la mano del maestro The Rockin'-B'. Aunque es para Orbit, muchos conceptos son aplicables a lo que podamos hacer con Lua. Esto lo deberíamos guardar a buen recaudo para consultar en cualquier momento.

Y bueno, voy a la lección de hoy que se me hace tarde...


¿Donde están las subrutinas?

A medida que iba haciendo mis pruebas y chapucillas para intentar aprender algo de programación en Saturn con este Lua Player una duda se iba planteando en mi cabeza. Hasta ahora hemos hecho cosas como imprimir texto en pantalla, manejar movidas con condicionales y actuar en consecuencia, trato con variables, detectar qué pasaba con el mando, etc... El que caso es que siempre pensé qué sucedería cuando el código se fuese complicando un poco más y a su vez fuese creciendo.

Es decir, recordando los buenos tiempos de BASIC para los veteranos del lugar, ¿dónde están las rutinas y subrutinas? Trozos de código a los que llamabas con GOTO O GOSUB y luego retornabas con RETURN. O sea, partes de código que se encarguen de una cosa en concreto y que podamos llamar desde el programa principal a nuestro gusto.

Para que me entendáis con un ejemplo práctico, imaginaos que tenemos una porción de código -como hemos visto en los ejemplos que he ido creando- que se encargue de comprobar si una variables es mayor que tal número, u otro que chequeé si hay un mando conectado en el puerto 2, o quizás una parte de código que genere dos valores al azar y se los asigne a una variable...

El meollo es, vamos a suponer que esto lo necesitamos hacer varias veces en nuestro programa. Cada vez que necesitemos realizar estas operaciones tendremos que volver a escribir/colocar ese código con los comandos correspondientes... ¿No sería mejor llamar a esa rutina cuando nos haga falta y que lo haga las veces que sea necesario y cuando nos convenga manejándolo nosotros?

En BASIC, y creo que en otros lenguajes antiguos, a esto se llamaba rutinas. En Lua, se llaman funciones (queda más cool) y vamos a explicarlo con un pequeño y sencillo ejemplo que he creado:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_320x240,NULL,1)


function PRUEBA()
slPrint("Esto es la funcion PRUEBA", 1, 1)
end

function MIERDA()
slPrint("Esto es la funcion MIERDA", 2, 3)
end

function NOSEUSA()
slPrint("Esto es la funcion NOSEUSA", 3, 5)
end

PRUEBA()
MIERDA()

while true do slSynch() end


Ejecutamos en el emu como ya sabemos y obtenemos algo tan espectacular como esto:

funciones_lua_saturn

Puede parecer una tontería pero nos resuelve el problema que teníamos antes y nos dará mucha vida en el futuro. Podemos invocar a rutinas que tengamos hechas cuando queramos y acceder a ellas cuantas veces las necesitemos.

Además podemos dividir nuestro código en diferentes parte más definidas y a la hora de abordar lo que queramos hacer será mucho mejor y más organizado.

Lo que hemos realizado en este ejemplo que he puesto es definir tres sencillas funciones con su código específico y luego hemos llamado solo a dos de ellas.

Lo comento aunque salte a la vista:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_320x240,NULL,1) -- Inicia el sistema SGL


function PRUEBA() -- Definimos la función llamada PRUEBA
slPrint("Esto es la funcion PRUEBA", 1, 1) -- Esto para no liaros es el código simple de esta función, podría ser mucho más complicado, ya veréis más adelante...
end -- Finalizamos lo que contiene esa función

function MIERDA() -- Ahora defino otra función que se llama MIERDA
slPrint("Esto es la funcion MIERDA", 2, 3) -- Lo mismo, la función tiene un print sencillo
end -- Hasta aquí llega esta función

function NOSEUSA() -- Definimos una función que no vamos a usar en este programa, es para que se vea que la podemos llamar si queremos o no...
slPrint("Esto es la funcion NOSEUSA", 3, 5) -- Una cosa que no se va a llegar a ver que es lo que tiene esta función de código
end -- Se acabó esta función, amigos

PRUEBA() -- Invocamos a esta función, así se hace. Esto es lo primero que ejecuta este programa, el código que haya en esa función
MIERDA() -- después invocamos a esta segunda función llama MIERDA y que hemos definido antes

while true do slSynch() end-- Lo mete en el bucle infinito que tanto nos gusta



Lua puede llamar (y manejar) funciones escritas en su propio lenguaje. Pero no solo eso, además puede ejecutar funciones escritas en C!! Esto es algo que todavía no sé bien cómo va, pero que he visto en los ejemplos que vienen con el Lua Player que en ocasiones hacen uso de funciones en C... De hecho, creo que llaman a cosas hechas con el Saturn Orbit.

Pero no nos desviemos del tema. Esta es la forma más simple de definir funciones e invocarlas, pero luego me temo que se pueden hacer llamadas con argumentos y demás, que ya tocaré más adelante cuando lo domine más...


Un ejemplo un poco más elaborado

Por si acaso no habéis pillado bien para que podemos usar las funciones o pensáis que esto es una soberana chorrada, lo voy a mostrar con un ejemplo que por lo común que es y al que estamos todos muy habituados lo vais a coger sin duda el concepto y para qué nos va a servir.

He perpetrado/improvisado este código:

Código: [Ocultar] [Seleccionar]
function OPCIONES()
slTVOff()
slInitSystem(TV_320x240,NULL,1)
slTVOn()
slPrint("Esto serian las OPCIONES", 2, 2)
while true do slSynch() end
end


function CREDITOS()
slTVOff()
slInitSystem(TV_320x240,NULL,1)
slTVOn()
slPrint("Esto serian los CREDITOS", 2, 2)
while true do slSynch() end
end


function JUGAR()
slTVOff()
slInitSystem(TV_320x240,NULL,1)
slTVOn()
slPrint("Esto seria el JUEGO en si", 2, 2)
while true do slSynch() end
end



local bucle = 1

slInitSystem(TV_320x240,NULL,1)

slPrint("----JUEGO TRAPERO----", 6, 5)
slPrint("Imaginaos unos graficos que te cagas xD", 1, 10)


while bucle < 2 do

slPrint("Pulsa A para OPCIONES", 1, 19)
slPrint("Pulsa X para CREDITOS", 1, 21)
slPrint("Pulsa START para JUGAR", 1, 23)

id,ext,data = Smpc_Peripheral(0)
if bit.band(data, PER_DGT_TA) == 0 then OPCIONES()
end
if bit.band(data, PER_DGT_TX) == 0 then CREDITOS()
end

if bit.band(data, PER_DGT_ST) == 0 then JUGAR()
end


end



while true do slSynch() end


Al ejecutarlo nos aparecerá esto:

juego_saturn_lua

Tendréis que echarle algo de imaginación. Imaginaos un juego simple que tiene un menú con tres opciones como veis, lo típico que hemos visto tantas y tantas veces.

Supongamos que pulsamos la X para ver los créditos del juego y ver a sus programadores:

creditos_lua

Lo mismo pasa con las demás opciones, el programa nos lleva a cada una de ellas. Lo hemos hecho a través de las funciones. En juego en sí sería un código muy complicado que estaría dentro de la función JUEGO y al que llamaríamos cuando el jugador pulse START.

Comento el código por si las moscas:

Código: [Ocultar] [Seleccionar]
function OPCIONES() -- defino lo que serán las opciones con esta función
slTVOff() -- esto es para limpirar la pantalla luego lo comento mejor
slInitSystem(TV_320x240,NULL,1) -- vuelvo a poner el SGL
slTVOn() -- y enciendo, esto son nuevas librerías de SEGA que ahora explicaré
slPrint("Esto serian las OPCIONES", 2, 2) -- Aqui estaría todo el código de las opciones pertinente
while true do slSynch() end -- Lo meto en un bucle para que no salga de aquí, pero podríamos e incluso deberíamos poder regresar al menú principal, para no complicarlo más lo dejo así.
end -- se acaba aquí la función OPCIONES


function CREDITOS() -- Definimos la función CREDITOS, todo lo demás es igual
slTVOff()
slInitSystem(TV_320x240,NULL,1)
slTVOn()
slPrint("Esto serian los CREDITOS", 2, 2)
while true do slSynch() end
end


function JUGAR() -- Ahora el juego en sí, que seria la función JUGAR
slTVOff()
slInitSystem(TV_320x240,NULL,1)
slTVOn()
slPrint("Esto seria el JUEGO en si", 2, 2) -- Aquí estaría todo el código y el meollo del juego
while true do slSynch() end
end



local bucle = 1 -- Lo voy a meter en un bucle con esta variable para detectar la pulsación del mando

slInitSystem(TV_320x240,NULL,1) -- Esto es lo primero que se va a ejecutar ya que hemos definido las funciones pero aun no hemos llamado a ninguna de ellas

slPrint("----JUEGO TRAPERO----", 6, 5) -- Esto seria el Main Menu del juego típico
slPrint("Imaginaos unos graficos que te cagas xD", 1, 10)


while bucle < 2 do -- Le pongo una condición que será infinita porque nunca cambiaría y siempre será así, si sabéis alguna manera mejor de hacerlo... soy todo oídos!

slPrint("Pulsa A para OPCIONES", 1, 19)
slPrint("Pulsa X para CREDITOS", 1, 21)
slPrint("Pulsa START para JUGAR", 1, 23)

id,ext,data = Smpc_Peripheral(0) -- Detectamos lo que pulse el jugador como aprendimos en los otros ejemplos que puse
if bit.band(data, PER_DGT_TA) == 0 then OPCIONES() -- Si pulsa A lo mandamos a la función OPCIONES
end
if bit.band(data, PER_DGT_TX) == 0 then CREDITOS() -- Si pulsa X lo mandamos a la funcion CREDITOS,
end

if bit.band(data, PER_DGT_ST) == 0 then JUGAR() -- Fijaos que estamos usando funciones combinandolas con condicionales, aquí lo mando a el juego en sí que sería la función JUGAR que definimos antes
end


end -- fin del while eterno en el que le he metido para que este todo el rato mostrando el menú principal y esperando que pulsemos alguna cosa



while true do slSynch() end -- lo de siempre


Y listo, ahora veis mejor tal vez para que podemos usar las funciones. Solo faltaría hacer un juegazo con unos gráficos y sonido tremendos y meterlo en la función JUGAR

Una cosa, he aprovechado para meter algunos comandos nuevos de librerías de SEGA que repaso fugazmente:

slTVOff()
Aquí necesitaba algo así como un CLS de BASIC (clear screen) para limpiar la pantalla y he usado esto. Por lo que veo según SEGA:

Citar:
Drawing end declaration - This function turns off scroll drawing processing in the monitor


Esto me ha funcionado, va acompañado inevitablemente de:

slTVOn()

Citar:
Drawing start declaration - This function starts drawing in the scroll screen monitor -


Y eso es todo. Con eso he conseguido que cada vez que llamemos a una función limpie la pantalla para que no se vea nada de la anterior.


Pues nada, eso es todo por hoy. Necesito, o sigo necesitando más bien, manejar gráficos ya.. pero todavía no lo he conseguido. Pido a algún alma caricativa que me eche una mano, jaja

Nos vemos en las próximas lecciones. Un saludo!


Ryo Suzuki [ 21 Junio 2014, 04:18 AM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Muy buenas amijos, amantes de la Saturn. Por aquí sigo con mi pequeño curso de programación con el SLP (Saturn Lua Player) del gran Rockin'-B.

Le voy echando un vistazo de vez en cuando en los momentos en que las obligaciones me lo permiten. Ir escribiendo en este post con estas particulares "lecciones" me obliga de alguna forma a seguir y a plasmar lo que voy aprendiendo.

En ocasiones me cuesta bastante avanzar ya que no hay practicamente nada de documentación de este port del player para Saturn, el original como ya habré comentado era para PSP.

Los ejemplos que vienen apenas estan comentados y son de un nivel ya bastante alto, rollo lo que le puede parecer fácil a Rockin'-B , además me da la nariz que está pensado para gente que ya se maneja desarrollando para la Saturn con el Orbit y quiera saltar a este SLP... está claro que yo no tenía ni idea


Virtual LUA

Bueno, hoy vamos a poner polígonos en pantalla. Me ha costado lo suyo conseguir averiguar cómo se hace con este Lua Player. He conseguido entender y separar qué es lo que hace cada cosa de los ejemplos hasta poder aislar la parte de poner una figura poligonal en pantalla. También he conseguido usar figuras poligonales que no estaban en los samples, e incluso exportar modelos tridimensionales que pueda hacer yo mismo con un software 3D gratuíto, como es el Blender...

Pero el tema es bastante complicado, así que hoy explicaré sólo cómo se hace de forma relativamente simple, desde uno de los ejemplos y ya en futuros posts veréis cómo lo hago compilando mis propios datos de modelos poligonales que también nos servirá para otras cosas como sprites y demás.

Vamos a coger el ejemplo de la carpeta samples llamado S_3_2. Con el objetivo, como ya dije, de aprovechar el modelo poligonal de este ejemplo y no tener que hacer todo el proceso de crear e importar el modelo 3D por nosotros mismos.

Copiamos la carpeta S_3_2 haciendo un duplicado y le cambiamos el nombre por otro que nos guste más y que la diferencie (yo he puesto POLIGONEO). Ya que hemos clonado ese sample para editarlo vamos como es habitual a editar el código de Lua que está almacenado como siempre en 0_orig.lua. Abrimos ese archivo con el notepad y nos preparamos para crear nuestro propio código, os iré guiando.


Intermedio

Hablando del notepad. Es algo que os quería recomendar, es preferible usar un editor de texto más orientado a temas de programación que son mucho más visuales y tal ya que reconocen las cosas y las organizan mejor para que de un vistazo identifiquemos con más comodidad el código.

Ahora estoy utilizando uno que se llama CODEMAX y que os recomiendo. Es gratuito: http://codemax.luaforge.net/

Fijaos como se ve el código ahora con este editor:

codemax_lua

Mucho más visual y ordenado con los colores para diferenciar cada cosa, ahora siempre usaré este CodeMAX para código del Lua Player.


Poniendo Polígonos en pantalla

Vamos al grano y a dejarnos de intermedios. Hoy, para innovar un poco, lo voy a hacer del revés. Primero pongo el código linea a linea comentado y luego adjunto todo el código final para que lo copiéis/peguéis a 0_orig.lua y lo probéis o trastéis con él modificando, o lo que queráis.

Vamos allá. Empezamos:

Código: [Ocultar] [Seleccionar]
--/*----------------------------------------------------------------------*/
--/* Primeros poligonos en pantalla */
--/*----------------------------------------------------------------------*/


Primero pongo un comentario con el título y tal... (como ya aprendimos con los --)

Seguimos con:
Código: [Ocultar] [Seleccionar]
local ang, pos = {}, {}

Esto es nuevo, declaramos de esta manera un tanto especial estas variables con valores vacios. ang y pos parecen ser varibales globales ya predefinidas y si no hacemos esto nos saltará un error diciéndonos que intentamos indexar un valor nil.

Un valor nil en Lua es:

Citar:
Nil es el tipo del valor nil, cuya principal propiedad es ser diferente de cualquier otro valor; normalmente representa la ausencia de un valor útil.


O para que nos quede más claro:

Citar:
Nil is a type with a single value, nil, whose main property is to be different from any other value. As we have seen, a global variable has a nil value by default, before a first assignment, and you can assign nil to a global variable to delete it. Lua uses nil as a kind of non-value, to represent the absence of a useful value.


Creo que lo que estamos haciendo con local ang, pos = {}, {} es decir que esas variables globales(me parece que aunque las pongamos no son locales) las vamos a asignar un valor y no van a ser nil. El caso es que si no hacemos esto tendremos este error (podeis intentar omitir esta linea y vereis lo que sucede...):roll:

P.D: Como habréis supuesto, ang se refiere a angulo mientras pos hace referencia a la posición. Dos valores importantes de nuestro primer modelo poligonal que vamos a mostrar en pantalla.

Seguimos con esto:

Código: [Ocultar] [Seleccionar]
slInitSystem(TV_320x224,NULL,1)

Vale, nada nuevo bajo el sol. Inciamos el sistema con la resolución y demás como ya tenemos masterizado de otras lecciones.

Continuamos con más cosas nuevas:
Código: [Ocultar] [Seleccionar]
ang.X = DEGtoANG(20.0)
ang.Y = DEGtoANG(22.0)
ang.Z = DEGtoANG( 5.0)

pos.X = 5.0
pos.Y = 8.0
pos.Z = 190.0

Quedaos con la copla que la variable ang tiene tres subvalores por así decirlo. En las coordenadas Y, Z y X.
No solo eso, sino que se definen con algo que parece propio de las libreías de SEGA, ese DEGtoANG() y el valor entre los parentesis del ángulo.

Le hemos dado 20 grados en X, 22 en Y y 5 en el eje Z. Nuestro modelo poligonal estará girado en esos angulos esos grados cuando se vea en screen por primera vez.

Luego tenemos la variable pos, que volvemos a ver que el tema de que al definirla con el . detrás podemos asignarle varias subvariables, si no entiendo mal. En este caso, como comprenderéis se trata de la posición de la pantalla en la que aparecerá nuestro objeto poligonal Saturnero.

Podéis cambiar esos valores luego para hacer pruebas de colocación como he hecho yo. El tema parece ir, en el eje de la X si le das un valor positivo es hacia la derecha, 0 es el centro, etc...
En el eje de la Y un valor negativo es arriba, positivo abajo, evidentemente.
El el eje de la Z un valor positivo implica enviar el objeto más atrás, negativo traerlo hacia adelante.

Pero no quiero alejarme con explicaciones, continuo con mi código:

Código: [Ocultar] [Seleccionar]
local datoscd = GFS_Load_name("DATA.BIN", 0, CPU_WRAM_LO, CPU_WRAM_LO_LEN)

Otra cosa nueva a la par que interesante e importante. Creamos la variable llamada datoscd y le decimos que es igual a un archivo del CDROM que le obligamos a cargar justo en ese momento que la declaramos y que como veis se llama DATA.BIN.

Efectivamente, si vais al ejemplo os dareis cuenta que entre los archivos, además de nuestro querido 0_orig.lua, 0.bin (que creo que no lo he comentado pero es el binario que lee la Saturn primero y hace de interprete y ejecuta nuestro código .lua) y demás files está precisamente data.bin.

Como imaginaréis, en ese archivo está la información matemática de nuestro modelo polígonal que vamos a mostrar en este ejemplo. Ya os daré más explicaciones de cómo es su estructura y demás pero ahora sigo adelante...

Bien, es la primera vez que cargamos algo desde CD. Hasta ahora nuestro código solo se ejecutaba a sí mismo y no hacía uso de otros recursos. Pero en un futuro tendremos que cargar imagenes, modelos polígonales, música y demás cosas... así que no os habrá extrañado.

Vamos a mirar con un poco de detalle qué he hecho y trato de explicarlo en la medida de lo posible.

GFS_Load_name("DATA.BIN", 0, CPU_WRAM_LO, CPU_WRAM_LO_LEN)
Ok, GFS_Load_name es parte del manejo de files del Cd de las librerías de la Saturn. Nada que ver con Lua, ya os lo digo. GFS_ ese prefijo hace referencia a manipulación del CDROM de la 32 bits de SEGA. Va seguido en este caso de Load_name, que no hace falta ser muy listo para adivinar que lo carga en memoria sin ejecutarlo, como los loads de toda la vida (os acordáis de las cintas del Spectrum )

O sea, le estamos diciendo que cargue DATA.BIN y que lo meta en 0, CPU_WRAM_LO, CPU_WRAM_LO_LEN. Esto puede sonar más a marcianada, pero yo entiendo que lo emplaza en la posición 0, WRAM debe ser algo así como working ram si mi intuición no me falla y veo que hay LO y LO_LEN, que deber ser con len referido quizás a longitud (length). Y LO pues igual algo así como LOW, vete tú a saber que a demasiado llego... jeje

Bien hecho, hemos cargado el archivo DATA.BIN que contiene nuestros poligonos en la ram de la Saturn, está listo para ser llamado y ser puesto en pantalla, cuando sea necesario.
Código: [Ocultar] [Seleccionar]
if datoscd == nil or datoscd <= 0 then
slPrint("Error cargando DATA.BIN desde el CD!", 2, 15)
end

Esto puede parecer un poco paranoico, pero es lo suyo. Los condicionales nos iban a valer para muchas cosas como anticipé. Aquí lo que hago es comprobar si el archivo del CD lo ha cargado bien la Saturn. Imaginaos yo que sé.. que por cualquier cosa falle la carga (CD no lee bien, etc...) es un mensaje de error que estaría bien mostrar.

Como apreciaréis le estamos diciendo que si la variable datoscd tiene un valor nil(que ya hemos aprendido lo que es) o es igual o menor que 0 -lo que significaría que no ha cargado el archivo porque por poco que pese en la RAM no será nil ni igual o menor que 0- entonces nos imprima en pantalla avisándonos que ha habido un problema con la carga del archivo desde el CDROM.

Esto en principio nunca lo veremos pero saldría esto si llega a suceder:

error_loading

Si sois muy puntillosos podeis montar la iso quitando DATA.BIN o cambiar el nombre o lo que sea y comprobaréis que funciona como es debido. Así nos cercionamos con este condicional que la Saturn cargue bien el archivo en su ram desde el CD.

Sigo, que me estoy enrrollando como una persiana pero es que es inevitable ya que hay muchos conceptos nuevos:

Código: [Ocultar] [Seleccionar]
local CUBOMODELO = CPU_WRAM_LO

Aquí lo que estoy haciendo es creando la variable CUBOMODELO que va a ser nuestro modelo poligonal -y si no lo he dicho ya por su nombre intuiréis que se trata de un cubo en 3D- y la asigno a la CPU_WRAM_LO. Como decía antes debe ser la working ram en la que acabamos de cargar el archivo data.bin.

En esta ocasión es porque en data.bin solo está nuestro modelo poligonal del cubo, en un futuro os enseñaré que puede contener más cosas y entonces será algo más complicado llamarlo y saber en qué posición de la RAM se encuentra. En ese caso, lo que hago es decirle a la Saturn que lo que tienes en la ram que acabas de cargar desde el CDROM es mi CUBOMODELO.

Prosigo:

Código: [Ocultar] [Seleccionar]
slPrint("Primeros poligonos" , 9, 2)
slPrint("Saturn Lua Player tutorial", 9, 3)
slPrint("by Ryo Suzuki", 9, 4)
slPrint("www.segasaturno.com", 9, 5)

No es necesario explicar el autobombo que ya conocemos, ¿verdad?
Código: [Ocultar] [Seleccionar]
while true do
slPushMatrix()

De acuerdo, lo meto en el bucle principal del programa que va mostrar el cubo con el "while sea verdad", que va a ser siempre, haz todo esto que te detallo a continuación...

Empezamos con slPushMatrix()

Citar:
slPushMatrix Temporary storage of matrix (up to 20 matrices can be nested)

Vale, sé que los temas 3D tienen que ir sobre una matriz.

Citar:
This function advances the matrix buffer pointer, copies the previous current matrix
to the stack, and makes that the new current matrix.
If pointer allocation failed, the function returns the FALSE value.
Up to 20 matrices can be nested in the buffer. If an attempt is made to nest more than 20 matrices in the matrix buffer, the
function returns the FALSE value.

Buff, da un poco de miedo. Yo no quiero 20, de momento con una me vale. Es inevitable y necesitamos tener la matriz.

NOTA: Os sonará igual de temas de programación el stack o pila de ejecución. Aquí teneis más info, pero parece claro que con este slPushMatrix estamos apilando esta matriz.

Seguimos ya casi para bingo:
Código: [Ocultar] [Seleccionar]
slTranslate(pos.X,pos.Y,pos.Z)

Otro nuevo comando de las librerías de SEGA. Como podréis intuir lo traslada a una posición. Más que trasladar en este caso es el punto inicial en cuanto a posición en el cual estará nuestro objeto 3D. Fijaos que son las variables que pusimos antes (5 en el eje de la x, 8 en el de la Y y 190 en el eje Z), pero no pueden ser expresadas con números directamente sino que hay que asignarlo así.

Es necesario definir esto, de lo contrario la Saturn no sabría donde poner nuestro cubo poligonal en pantalla.

Más:
Código: [Ocultar] [Seleccionar]
slRotX(ang.X)
slRotY(ang.Y)
slRotZ(ang.Z)

Esto es opcional, que quede claro. Pero como ya veríais venir de antemano ibamos a rotarlo x grados en los tres ejes, que para algo hicimos antes las variables!!

Sega nos dice (o mejor dicho les decía a los pobres programadores profesionales que en su día lidiaban con el infernal sistema) sobre este comando:
Citar:
slRotX
Description: Adding rotation around X axis to current matrix
Format: void slRotX(angx)
ANGLEangx;
Parameters: angx Angle of rotation around X axis
FunctionThis function multiplies an X axis rotation matrix with the current matrix. The
rotation matrix is expressed below

Como comprenderéis slRotY y slRotZ hacen lo propio en sus respectivos ejes.

El caso es que giro un poco el cubo en esos ángulos no solo por capricho, sino también para que se vea mejor. De lo contrario, saldría completamente recto y solo veriamos una cara, que sería muy triste para nuestro primer modelo 3D en pantalla

Y ya por fin:
Código: [Ocultar] [Seleccionar]
slPutPolygon(CUBOMODELO)

Argghh! Que valle de lágrimas. Finalmente ponemos nuestro modelo poligonal de un cubo en pantalla. En esas posiciones que hemos definido en los ejes x,y,z y con los angulos en x,y,z también. El comando slPutPolygon como su propio nombre indica pone el polígono, entre parentesis está nuestra variable CUBOMODELO que como recordaréis es el archivo DATA.BIN, con los datos de geometría del cubo de marras que tenemos cargado en la ram de la consola.

Ya finalizo, hay que cerrar el bucle y darle a la matriz caña:
Código: [Ocultar] [Seleccionar]
slPopMatrix()
slSynch()
end


Con slPopMatrix() he hecho la operación inversa de lo que hice antes con slPushMatrix, es decir, retirar (o desapilar, con pop) del stack.

slSynch() es el pan nuestro de cada código con la sincronización con el evento. Y por último el end del bucle while en el que le habiamos metido, que no se nos puede olvidar.

Y ya lo tenemos. Generamos la iso y vamos a ver esto:

poligonos_lua

Disfrutad como si no hubiese un mañana de ese cubito 3D que está mostrando la Saturn, jaja. Nuestro -o mejor dicho, mi- primer objeto poligonal puesto en la screen con bastante sudor con este Lua Player.

Os pongo el código completo, ahora ya está debidamente explicado todo:

Código: [Ocultar] [Seleccionar]
--/*----------------------------------------------------------------------*/
--/* Primeros poligonos en pantalla */
--/*----------------------------------------------------------------------*/


local ang, pos = {}, {}

slInitSystem(TV_320x224,NULL,1)

ang.X = DEGtoANG(20.0)
ang.Y = DEGtoANG(22.0)
ang.Z = DEGtoANG( 5.0)
pos.X = 5.0
pos.Y = 8.0
pos.Z = 190.0


local datoscd = GFS_Load_name("DATA.BIN", 0, CPU_WRAM_LO, CPU_WRAM_LO_LEN)
if datoscd == nil or datoscd <= 0 then
slPrint("Error cargando DATA.BIN desde el CD!", 2, 15)
end

local CUBOMODELO = CPU_WRAM_LO


slPrint("Primeros poligonos" , 9, 2)
slPrint("Saturn Lua Player tutorial", 9, 3)
slPrint("by Ryo Suzuki", 9, 4)
slPrint("www.segasaturno.com", 9, 5)


while true do
slPushMatrix()

slTranslate(pos.X,pos.Y,pos.Z)
slRotX(ang.X)
slRotY(ang.Y)
slRotZ(ang.Z)
slPutPolygon(CUBOMODELO)

slPopMatrix()
slSynch()
end


Como os decía al principio, sigo investigando y ya sé como poner otros modelos de distinas procedencias e incluso creados por mi mismo, pero eso ya os lo cuento otro día porque para ilustrar esta pequeña tontería me ha dado mucho trabajo para que quede entendible y claro así que temo lo que puede ser lo otro... Espero que haya sido fácil para vosotros, para mi con la documentación que había... no lo fue


Fase Bonus

No, no me refiero al programa de nuestros amigos. Me parece que queda un poco desangelado el cubo ahí tan triste en pantalla. Vamos a moverlo un poco con lo que hemos aprendido en otros ejemplso de sumar valores a variables dentro de un bucle. En su momento podía parecer una parida, pero ahora nos viene bien porque lo trasladará y rotará en el bucle del while.

Añadid esto despues del slPutPolygon(CUBOMODELO)

Código: [Ocultar] [Seleccionar]
pos.X = pos.X+0.1
ang.Z = ang.Z+10
ang.X = ang.X+40

Luego ya el slPopMatrix() y demás como estaba en el código de antes...

Con eso la liamos parda porque lo desplazamos lentamente hacia la derecha (el eje de las X, valores positivos cada vez más) y lo rotamos algo más rápido en el eje de la z y de la x, para que podamos ver todas sus caras con diferentes colores y tal...

Además, apreciaremos que la Saturn falla más que una escopeta de feria a la hora de mostrar polígonos, por lo visto. ¿Es cosa mía o hay bastantes errores de perspectiva y cosas raras? Os pongo la iso directamente por si la quereis bajar y probar en el emulador para ver cómo se mueve y me contais.

cubista_lua

Eso es todo por hoy. ¿Da mucho miedo y nadie se atreve a trastear con el Lua de Saturn?


FacundoARG [ 21 Junio 2014, 06:16 AM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Excelente, luego te comparto el modelo 3D de Sonic


Fdx [ 07 Junio 2017, 12:11 AM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Muy buen Post!! Me atrae la idea de programar en saturn mas alla de que no se nada de esto salvo algo de VisiualBatari basic y algun juego a medias para la Atari 2600. Ya me estoy leyendo todo


Ryo Suzuki [ 11 Junio 2017, 09:51 PM ]
Título del mensajeRe: Trasteando con el Lua Player de Saturn (Tutorial)
Por desgracia Rockin'-B parece que hace mucho que está fuera del mundillo y no llegó a sacar más versiones de este Lua.

Yo te recomendaría que si vas a programar para la Saturn optases por la nueva posibilidad que ofrece Johannes Fetz con su Jo Engine.

http://www.jo-engine.org/

Va realmente bien, da soporte y tiene muchísimas más posibilidades diría yo que cualquier otra opción que pueda haber para esta consola. Además va a quitar ahora las SGL así que sería incluso totalmente legal si se hiciesen en un futuro juegos comerciales...


ULTIM4TEGAM3RPR0 [ 25 Septiembre 2017, 10:32 PM ]
Título del mensajeRe: Trasteando Con El Lua Player De Saturn (Tutorial)
Habrá que ir probando este incipiente dev indie saturnino




Powered by Icy Phoenix