Recuerdo cuando mis amigos y yo (de igual nivel de frikismo por aquellos tiempos) nos peleabamos por quien era mejor, mario o sonic, que si el puto gordo del fontanero, que si el cerdo de mierda…, todo con absoluta pureza y sin la malicia presente en los jóvenes de hoy. En mi caso defendía a Sonic, no tenía ninguna razón lógica, símplemente tenía la master system y debía que defender a toda costa mi compra, que por otro lado, mis meses de ahorro me costo (por aquel entonces me costó 13 mil pesetas).
Recientemente he estado jugando a algunos juegos de nintendo64 en un emulador (aunque tengo la N64 real me resulta más cómodo arrancar el emulador) con el objetivo de sacar algunas ideas para un pequeño proyecto que tengo en mente. A nivel gráfico se puede decir que, comparado con los gráficos de aquella época, eran bastante simplones y poco realistas si los comparamos con, sin ir más lejos, el gran turismo de playstation. Las texturas son simples, los mallas son tochas, los escenarios repetitivos… sin embargo hay algo que es diferente al resto de juegos para distintas plataformas, es la jugabilidad, los detalles insignificantes para el jugador pero que hacen que ese juego sea realmente atractivo, que sea un juego.
Es por esto que ahora recuerdo aquellas peleas y me doy cuenta de que nintendo ha seguido una linea que espero que sigan muchos años, que es la de hacer videojuegos para jugar y no simuladores para ver. Esto demuestra que aunque alguien no siga las directrices marcadas por quién sabe quien, aunque vaya contracorriente, si el producto es de calidad, se puede mantener y seguir adelante.
saludos
PD: Hoy no me apetece mucho hablar de programación aunque me quedo las ganas reservadas para hablar otro día de algunos detalles técnicos de los juegos de N64.
En un post de hace tres días comenté que me vengaría del formato del código que puse. Por casualidad visitando el weblog de Sencillo encontré un artículo sobre formateo de código. Con este código, un par de herramientas (CPP2HTML y python2html) he creado un script que exporta un código formateado y con sintaxis coloreada (de momento python y C++, mis dos amores, bueno… sin contar a mi novia XD ). Como muestra que mejor que el programa origen:
html = """
<table class="ContenedorCodigo">
<tr>
<td class="Codigo">
<div class="Embalaje">
<table class="FondoCode">
<tr>
<td class="Codigo">
<pre>
%s
</pre>
</td>
</tr>
</table>
</div>
</td>
</tr>
</table>
""";
css = """<style type="text/css">
.ContenedorCodigo
{
table-layout: fixed;
width: 90%;
padding: 0px;
}
.Embalaje
{
width: 100%;
overflow: auto;
}
.FondoCode
{
border: 1px solid black;
background-color: #efefef;
width: 100%;
padding: 7px;
}
.Codigo
{
width: 100%;
}
</style>
"""
import sys;
import os;
def CPP(file):
os.popen("c:\\\\bin\\\\formats\\\\cpp2html.exe %s" % file);
lines = open(file +".html","r").readlines();
css\_cpp = """<style type="text/css">""" + open("c:\\\\bin\\\\formats\\\\cpp.css").read() + "</style>";
lines\[0\] = "<pre>";
lines\[-1\] = "<pre>";
return css\_cpp + "".join(lines);
def Python(file):
os.popen("c:\\\\bin\\\\formats\\\\python2html.1.py %s" % file);
return open(file +".html","r").read();
class Format:
def \_\_init\_\_(self,formats):
""" \["py",fn\];
"""
self.\_formats = {};
for x in formats:
self.\_formats\[x\[0\]\] = x\[1\];
def get\_ext(self,file):
try:
return file.split(".")\[1\];
except:
return "";
def Do(self,fich):
code = \[\];
for x in fich:
ext = self.get\_ext(x);
if(self.\_formats.has\_key(ext)):
code.append(self.\_formats\[ext\](x));
c = open("code.txt.html","w");
c.write(css);
for x in code:
c.write(html % x);
c.close();
formats = \[("py",Python), ("cpp",CPP), ("h",CPP),("c",CPP)\];
if \_\_name\_\_ == "\_\_main\_\_":
if(len(sys.argv) < 2):
sys.exit();
f = Format(formats);
f.Do(sys.argv\[1:\]);
un saludo
PD: después de tener problemas con blogger ya que añade unos cuantos br’s “by the face”, gracias a la ayuda de Sencillo y un poco de ñapeo he consiguido que quede decentillo. Trataré de mejorarlo.
Siempre me había gustado, entusiasmado diría yo, C++, su notación (probablemente porque venía de C), el que esté orientado a objetos, las excepciones, los templates, la herencia, las funciones virtuales… y mucho más después de leerme (effective c++, more effective c++ y modern c+ design). No es que me haya dejado de gustar, pero quizás es que haya abierto los ojos, me explico, el otro día en clase de Sistemas de tiempo real, estabamos dando una introducción a ADA95. En un primer momento se parecía a VHDL (un lenguaje de descripción HW) en su notación, aunque según avanzó la exposión del profesor me di cuenta de que tenía mucho más puntos en común, y lo mejor, orientados al software. ADA 95 tiene implementada concurrencia builtin, sistemas para la gestión de las contiendas, tareas, además de disponer de características propias de los lenguajes orientados a objetos, tanto las “standard” (herencia, etc), como las de facto (paquetes, operadores de rango, tipos algo más completos). La característica que más me gustó es la implementación de task, puedes tener una tarea con su código y tener ejecutando varias concurrentemente sin tener que preocuparte por threads o fork’s y lo mejor, un sistema para la sincronización muy agradable y eficaz. Quizás ADA95 por ser un lenguaje orientado al tiempo real y por tener una notación muy distinta a C puede que no sea el preferido de muchos (me incluyo) pero me parece un lenguaje bastante potente y muy apropiado para las máquinas que vienen con varios cores. En conclusión, C++ quizás se haya quedado un poco desfasado con respecto a lenguajes como C#, java, python que implementan herramientas mucho más agradecidas y manejables para el programador, aunque para mi sigue siendo el lenguaje más potente :)
En otro orden de cosas, esta mañana me sobraron un par de horas que pude invertir en perder el tiempo en internet. Entre mis búsquedas encontré algunas cosas interesantes:
- Texturas procedurales: visitando http://www.sorgonet.com/modules.php?name=News&file=article&sid=103 encontré un enlace a una página que ya conocía, pero de la cual desconocía el artículo siguiente: “texturas procedurales”
Es posible que no sepas de qué van las texturas procedurales, seguro que google te puede ayudar más que yo pero en resumen son texturas generadas mediante artefactos matemáticos. Quizás algún día ponga mi código de mi generador de texturas. Para ver algún ejemplo de texturas procedurales lo mejor es visitar páginas como esta
GLSL: si no estás muy familiarizado te preguntarás qué es esa puñeta, pues se trata d eun lenguaje que soportan ciertas tarjetas gráficas para poder realizar operaciones a medida en los render con OpenGL. Buscando un tutorial he encontrado el de lighthouse3d, (revisad la página porque tiene detallados tutoriales de opengl), que además de ser bastante buena calidad y comprensible, utiliza un Shader Designer, un programa creado por la empresa de un cyberamigo y del cual he visto su evolución. Me alegra ver como el trabajo duro tiene sus frutos.
Bueno, dos shots de la herramienta en la que estoy trabajando últimamente. La verdad es que apenas hay nada de momento debido a que he tenido que ir codeando algunas cosas referentes al ruido y otras cosas. Sin más:

`
La pena es la calidad de las imágenes que no puede ser mayor ya que el servidor donde las alojo no tengo demasiado espacio, aunque eso sí, es muy fiable ;)
`
Es tarde, sí, y mañana tengo que levantarme pronto, pero creo que este post merece la pena. En el post anterior comentaba que estaba haciendo una aplicación para generación de contenidos procedurales. Llegado un punto de la aplicación me veo en el aprieto de tener que exportar e importar un montón de variables y, la verdad, es una pesadez. Esto me recordó que hace tiempo viendo la web de chaos - componente de farbrauch - y en concreto un artículo sobre, textualmente, “Load&Save” , había una forma interesante de serializar los structs/clases. La verdad que el método es cutre, mejor dicho, poco elegante, incluso leyendo un poco comenta que reserva de entrada 64mb - ahora la memoria es barata -. Aún así el método es efetivo y simple y deduzco por sus comentarios que lo usa en su demo editor .werkkzeug1 - este editor merece un post aparte en mi opinión -.
Con todo esto pensé en crear un serializer basado en esto lo más simple posible y aquí está:
#define SERIALIZER(var,type,ser) do { if(ser.rw) { (var) = *(type*)(ser.mem); ((unsigned char*)ser.mem)+= sizeof(type); } else { *(type*)(ser.mem) = var;((unsigned char*)ser.mem)+= sizeof(type); } } while(0)
struct serializer
{
serializer(bool _rw):
rw(_rw)
{
// 6 megas está bien
if(!rw) base = mem = new unsigned char [ 6*1024*1024];
}
bool rw;
unsigned char *base;
unsigned char *mem;
void Save(const char* file){ }
void Load(const char* file) {}
void debug_dump()
{
int len = mem - base;
unsigned char *p = base;
while(len–)
{
printf(“0x%x “,*p++);
if(!len%20) printf(“\n”);
}
}
};
El código está codeado en poco tiempo y poco testeado. Tiene dos métodos para cargar y guardar en fichero que aún no están implementados y que de momento no he implementado. Tampoco sigo las típicas reglas de código elegante y bien diseñado pero estoy hasta las pelotas, me dedico a hacer cosas que funcionen, y en este caso parece que funciona, y para muestra, un botón:
struct A
{
int a;
int b;
short c;
char d;
A(int seed)
{
a = seed++;
b = seed++;
c = seed++;
d = seed++;
}
void Serialize(serializer& s)
{
SERIALIZER(a,int,s);
SERIALIZER(b,int,s);
SERIALIZER(c,short,s);
SERIALIZER(d,char,s);
}
void print()
{
printf(“%d %d %d %d\n”,a,b,c,d);
}
};
struct B
{
A a;
A b;
B(int o)
:a(o),b(o+1)
{}
void Serialize(serializer& s)
{
a.Serialize(s);
b.Serialize(s);
}
void print()
{
a.print();
b.print();
}
};
int _tmain(int argc, _TCHAR* argv[])
{
serializer s(false);
B a(1);
a.Serialize(s);
s.debug_dump();
a.print();
serializer s2(true);
s2.base = s2.mem = s.base;
printf(“\n”);
B b(0);
b.print();
printf(“\n”);
b.Serialize(s2);
b.print();
return 0;
}
da como salida por pantalla:
C:\temp\serialize\Debug>serialize.exe
0x1 0x0 0x0 0x0 0x2 0x0 0x0 0x0 0x3 0x0 0x4 0x2 0x0 0x0 0x0 0x3 0x0 0x0 0x0 0x4
0x0 0x5
1 2 3 4
2 3 4 5
0 1 2 3
1 2 3 4
1 2 3 4
2 3 4 5
Como conclusión decir que a buen entendedor, pocos printf’s bastan y que tengo que encontrar algún método para que el código quede bien y no me joda los identados