Es el mismo que salió para Wiz? O han metido actualizaciones a saco?
¡No! ¡Otro juego no!
¿Has jugado ya a...?: Ultratumba, Rock Rain, Rock Rain 2, Escape from Minos, La escoba, Batiscafo, Rookie Hero, EXP (para Wiz)
Mi web: Videojuegos de Rafa Vico.
En su día me bajé los fuentes del Yeti3D original e hice el port de uno de los "mini-juegos" (por así llamarlo) para Wiz y GBA. Se trataba del código fuente de la primera versión del motor que fué desarrollado para DreamCast y otras plataformas: Port para GBA de Yeti3D-Engine original.
Este Yeti3D-Pro es una versión del motor más trabajada con un editor de niveles que cómo digo es mucho más potente que el original ya que permite de forma más sencillo el modelado de mapas y la carga de texturas.
Yeti3d-Demo / GP2x-Wiz
Port para GP2X-Wiz de Yeti3D-Engine original
Última edición por jduranmaster; 09/01/2018 a las 12:18
Entonces estas usando este, no?
https://sourceforge.net/projects/yeti3dpro/
No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.
It is an undisputed truth that the Atari ST gets the best out of coders. No dedicated hardware, just the CPU and a frame buffer! Some call it Spartan, others name it Power Without The Price, and a select few say `challenge accepted'! --- by spkr from smfx
El que cuesta encontrar, o al menos a mí, es el original que tuvo incluso ports a PSX.
Cayó la web y con ella todo, por lo que parece... el PRO tiene bastantes modificaciones con respecto al original.
'A story in a game is like a story in a porn movie. It's supposed to be there but it's not that important' -John Carmack
Ole, que grande el Johnny!
@saucjedi Puede que lo que estés buscando sea esta versión (ver GIF). Esta fué la primera versión con la que estuve trabajando hace tiempo cuando hice el port de GBA. Esta bien porque es una versión muy mínima del motor para ver como se hacen las cosas desde cero pero luego me cambié a una versión más avanzada Port de Yeti3D-Engine para GBA que es la que acabé haciendo para GBA. Digamos que la versión para GBA es intermedia entre la básica que se ve en el GIF y el Yeti3D-Pro que es la más trabajada actualmente.
main.cppEngine Technical Notes
======================
These are design notes for the Yeti engine. Other engines use very different algorithms.
Im still refining the engine to improve quality while maintaining a acceptable rendering
speed.
- The current viewport is 120x80 pixels, 15bit.
- All textures are 64x64 8bit.
- Textures are converted to 15bit via a pre-calculated lighting LUT.
- Polygons can be any convex shape. Only squares are currently used.
- Each vertex is described as X, Y, Z, U, V and brightness.
- The renderer uses 24:8 fixed point maths.
- Polygons are clipped in 3D space using 45 degree planes. Distance to plane
calculations therefore use only additions and subtractions.
- Polygon edges are clipped using one divide and 6 multiplies.
- 4 clipping planes are used. No front plane is required. No back plane is used.
- No per-span clipping is used. Fixed point errors are hidden offscreen.
- Ray-casting is used to build a visablity list and valid polygon rendering order.
- Models are merged into the VIS without sorting.
- No Z-buffers are used. Rendering is back-to-front (painters algorithm).
- The is an acceptable level of overdraw. Complete polygons are culled. Polygon edges
are drawn faster than using a per span clipper.
- Lighting is pre-calculated on startup. Lighting can be moved at runtime.
- Lighting is expanded per vertex and interpolated along polygon edges.
- A reciprocal table is used to eliminate all divides from the DDA texture mapper.
- The affine texture loop is unrolled and renders blocks of 32 pixels.
yeti.cppCódigo:/* ** Name: Yeti3D ** Desc: Portable GameBoy Advanced 3D Engine ** Auth: Derek J. Evans ** ** Copyright (C) 2003 Derek J. Evans. All Rights Reserved. */ #include "yeti.h" void behaviour(entity_t* const e) { if (KEY_LEFT) { e->tt -= (12 << 16); e->r -= 800000; } if (KEY_RIGHT) { e->tt += (12 << 16); e->r += 800000; } if (KEY_UP) { e->xx += fixsin16(e->t >> 16) >> 5; e->yy += fixcos16(e->t >> 16) >> 5; } if (KEY_DOWN) { e->xx -= fixsin16(e->t >> 16) >> 5; e->yy -= fixcos16(e->t >> 16) >> 5; } e->xx -= ((e->xx + (e->xx < 0 ? -15 : 15)) >> 4); e->yy -= ((e->yy + (e->yy < 0 ? -15 : 15)) >> 4); e->tt -= ((e->tt + (e->tt < 0 ? - 3 : 3)) >> 2); e->r -= ((e->r + (e->r < 0 ? -7 : 7)) >> 3); e->x += e->xx; e->y += e->yy; e->z += e->zz; e->r += e->rr; e->t += e->tt; e->p += e->pp; entity_to_world_collision(e, 0x8000); } void world_create(world_t* world) { world->screen = (viewport_t*) 0x06000000; world->buffer = (viewport_t*) 0x0600A000; camera->x = MAP_SIZE << 15; camera->y = MAP_SIZE << 15; camera->z = 3 << 15; camera->p = 100 << 16; } int main(void) { int x, y; *(short*)0x4000000 = 0x405; *(short*)0x4000020 = 0; *(short*)0x4000022 = -128; *(short*)0x4000024 = 128; *(short*)0x4000026 = 0; *(short*)0x4000028 = i2f(120); *(short*)0x400002C = i2f(4); world_create(&world); entity_t* box = entity_create(33 << 16, 35 << 16, 1 << 16); entity_create(33 << 16, 33 << 16, 1 << 16); for (y = 0; y < MAP_SIZE; y++) { for (x = 0; x < MAP_SIZE; x++) { world.cells[y][x].l = 0; world.cells[y][x].bot = 0; world.cells[y][x].top = 4; world.cells[y][x].wtx = 0; world.cells[y][x].btx = 2; world.cells[y][x].ttx = 1; if (x == 0 || y == 0 || x == (MAP_SIZE - 1) || y == (MAP_SIZE - 1)) { world.cells[y][x].top = 0; world.cells[y][x].bot = 0; } } } for (x = 1; x < MAP_SIZE - 1; x++) { for (y = 1; y < MAP_SIZE - 1; y += 10) { if (rand() % 10) { world.cells[y][x].top = 0; world.cells[y][x].bot = 0; world.cells[x][y].top = 0; world.cells[x][y].bot = 0; world.cells[y][x].wtx = 0; world.cells[x][y].wtx = 0; } else { world.cells[y][x].top--; } } } for (x = 0; x < 400; x++) { cell_t* cell = &world.cells[rand() % MAP_SIZE][rand() % MAP_SIZE]; cell->bot += 2; cell->wtx = 3; cell->btx = 3; } for (y = 0; y < MAP_SIZE; y += 1) { for (x = 0; x < MAP_SIZE; x += 1) { world.cells[y][x].l = 0; } } for (y = 1; y < MAP_SIZE; y += 5) { for (x = 1; x < MAP_SIZE; x += 5) { draw_light((x << 16) + 0x8000, (y << 16) + 0x8000, 900); world.cells[y][x].ttx = 5; world.cells[y][x].btx = 6; } } while (!KEY_SELECT) { behaviour(camera); box->t += 50 << 16; box->r += 40 << 16; box->p += 30 << 16; draw_world(); } return 0; }
yeti.hCódigo:/* ** Name: Yeti3D ** Desc: Portable GameBoy Advanced 3D Engine ** Auth: Derek J. Evans ** ** Copyright (C) 2003 Derek J. Evans. All Rights Reserved. */ #include "yeti.h" /* ** Name: entity_create ** Desc: Creates a new entity and returns a entity pointer. */ entity_t* entity_create(int x, int y, int z) { entity_t* e = &entities[nentities++]; e->x = x; e->y = y; e->z = z; return e; } /* ** Name: draw_light ** Desc: Renders a spot light at a given cell location. */ void draw_light(const int lightx, const int lighty, const int diffuse) { world.time++; for (int i = 0; i < 2048; i += 8) { int x = lightx + 0x8000, xx = fixsin16(i) >> 1; int y = lighty + 0x8000, yy = fixcos16(i) >> 1; int l = i2f(63), d = 0; for (; l >= 0; x += xx, y += yy) { cell_t* cell = &world.cells[y >> 16][x >> 16]; if (CELL_ISSOLID(cell)) break; if (world.time != cell->time) { int nl = cell->l + f2i(l); cell->l = min(nl, 63); cell->time = world.time; } l -= d += diffuse; } } } /* ** Name: entity_to_world_collision ** Desc: Simple map to entity collision. */ void entity_to_world_collision(entity_t* const e, int const radius) { int x, y; cell_t* c; #define IS_COLLISION ((e->z > (c->top << 16)) || (e->z < (c->bot << 16))) c = &world.cells[e->y >> 16][(x = e->x - radius) >> 16]; if (IS_COLLISION) { e->x += 0x10000 - (x & 0xFFFF); e->xx = 0; } c = &world.cells[e->y >> 16][(x = e->x + radius) >> 16]; if (IS_COLLISION) { e->x -= (x & 0xFFFF); e->xx = 0; } c = &world.cells[(y = e->y - radius) >> 16][e->x >> 16]; if (IS_COLLISION) { e->y += 0x10000 - (y & 0xFFFF); e->yy = 0; } c = &world.cells[(y = e->y + radius) >> 16][e->x >> 16]; if (IS_COLLISION) { e->y -= (y & 0xFFFF); e->yy = 0; } }
data.cppCódigo:/* ** Name: Yeti3D ** Desc: Portable GameBoy Advanced 3D Engine ** Auth: Derek J. Evans ** ** Copyright (C) 2003 Derek J. Evans. All Rights Reserved. */ #ifndef __YETI3D_H__ #define __YETI3D_H__ #include <math.h> #include <stdio.h> #include <stdlib.h> #include <assert.h> #include <string.h> #include <limits.h> #define RGB_SET(r,g,b) (((b)<<10)+((g)<<5)+(r)) inline int abs(const int a) { return a < 0 ? -a : a; } inline int min(const int a, const int b) { return a < b ? a : b; } ... #endif
Script de compilación con devkitadv (se puede usar también devkitPro). Se puede obviar la línea donde se llama a gbafix sino se tiene la herramienta pero al no hacerlo la ROM generada no tirará en hardware real al no tener la cabecera el tamaño adecuado.Código:#include "data.h" const texture_t textures[] = { { {1,3,3,3,3,5,6,5,5,2,3,3,3,2,2,4,3,3,3,2,2,2,3,4,4,5,3,4,4,4,3,2,1,6,7,8,7,7,9,8,9,10,11,10,9,8,7,7,7,7,6,6,6,6,5,5,5,6,6,5,3,4,2,0}, {2,4,4,2,5,7,6,65,5,4,5,65,4,3,4,5,5,6,5,5,4,3,5,7,7,9,6,5,5,6,5,2,4,5,7,7,11,10,9,11,11,10,10,11,11,11,10,11,9,9,10,9,10,9,8,9,8,8,8,8,8,5,7,2}, {3,6,4,4,4,5,5,5,6,4,9,7,6,5,6,6,6,7,6,5,5,5,7,8,9,7,7,5,6,6,6,5,5,5,7,6,7,7,9,10,10,9,9,9,9,68,9,7,7,7,7,7,7,7,9,7,6,6,8,8,7,6,7,4}, {3,7,5,4,5,6,7,5,6,5,6,9,67,7,6,6,7,8,8,67,5,5,7,9,10,9,6,6,7,7,6,5,5,7,7,7,7,9,8,8,9,7,7,7,8,9,9,9,8,8,8,8,7,7,7,7,8,11,7,7,7,8,8,5}, {3,6,5,5,5,7,6,6,7,5,5,67,7,6,5,5,5,6,9,7,6,5,8,8,9,9,7,6,6,7,7,4,5,6,7,8,7,8,7,8,8,9,8,9,7,9,9,8,8,9,9,8,8,7,7,7,8,9,8,8,8,8,6,4}, {3,5,5,5,5,6,6,6,6,7,5,5,5,5,6,8,7,8,68,6,4,5,5,8,68,9,6,5,7,8,7,5,7,8,7,8,9,8,7,7,7,7,9,7,8,10,9,8,7,8,7,7,7,7,7,7,8,8,8,7,7,7,6,3}, {3,5,5,4,5,6,7,8,7,6,5,6,7,7,6,7,8,8,8,7,6,65,6,6,6,7,6,5,7,7,7,4,6,7,8,9,9,8,8,7,6,7,8,8,8,9,9,9,7,7,8,7,7,7,7,7,7,8,7,8,7,7,5,3}, ... -603, -402, -201 };
Código:g++ -marm -mthumb-interwork -mlong-calls -O3 -o game.elf data.cpp yeti.cpp draw.cpp main.cpp objcopy -O binary game.elf yeti3d-engine-gba-e1m0.gba gbafix yeti3d-engine-gba-e1m0.gba -p -tYeti3De1m0 -c7790 -m86 -r1 del game.elf del *.o
Última edición por jduranmaster; 11/01/2018 a las 12:26 Razón: Yeti3D-engine-first-version
Solo (11/01/2018), tSuKiYoMi (11/01/2018), ^OMAP-Cranck^ (11/01/2018)
Gracias @jduranmaster, tiene toda la pinta de ser esta, incluso la fecha de los comentarios en los fuentes cuadra
'A story in a game is like a story in a porn movie. It's supposed to be there but it's not that important' -John Carmack
Ole, que grande el Johnny!
Yo creo que esta versión es "portable" sin mucha dificultad prácticamente a cualquier sistema. La única pega la pone el entorno de desarrollo. Por ejemplo en el caso de PlayStation el devkit "Psy-Q" sólo funciona en Windows-XP (no sé si hay algún otro devkit) por lo que hay que virtualizar.
Lo poco que he visto del código es mas pequeño de lo que pensaba y tiene ideas curiosas como lo de los planos de clip a 45 grados y que no tiene plano de clip near.
Lo malo es que el viewport es ridículamente pequeño y no se si al hacerlo mas grande se verán problemas de precisión con las texturas o aristas de los polígonos.
No es lo mismo tener diez años de experiencia, que tener un año de experiencia diez veces.
It is an undisputed truth that the Atari ST gets the best out of coders. No dedicated hardware, just the CPU and a frame buffer! Some call it Spartan, others name it Power Without The Price, and a select few say `challenge accepted'! --- by spkr from smfx
Seguramente pero depende también de como lo vayas a usar. Yo ahora mismo me estoy dedicando a portar el Yeti3D-PRO a Android que es el último "target" que me falta por tener disponible. A partir de ahí quiero ver hasta donde puedo llegar porque a pesar de que Yeti3D-PRO es más avanzado que las dos versiones anteriores del yeti3D (incluida la primera "release" que he dejado antes) tiene algunas lagunas a la hora de construir "puertas" o "elevadores" con el editor de mapas.
Nuevos avances. Ya tengo el proyecto integrado en los "target" que pretendía: GBA, NDS, 3DS, Android y PC (default). El editor de mapas de Yeti3D-Pro es muy bueno la verdad (hasta donde he investigado) pero por desgracia no tiene retro-compatibilidad con los mapas diseñados con el editor antiguo de Yeti3D y tampoco veo que haya una herramienta para convertir mapas de Yeti3D a Yeti3D-Pro. Sea como sea el editor de mapas de Yeti3D-Pro me parece muy bueno y se aún se puede mejorar.
Ahora me estoy dedicando a investigar las herramientas de modelado de objetos. Pensaba que aquí iba a tener algún problema pero las herramientas son suficientes para convertir modelos ya existentes al formato de Yeti3D o bien modelar los objetos desde cero. En el fondo la mayoría de estas herramientas admiten modelos en definidos según el formato MD2 ("Quake 2") con lo que es bastante fácil de manejar.
Última edición por jduranmaster; 25/01/2018 a las 14:56
Una pregunta...
Jamás he intentado hacer nada parecido a un port de este tipo, pero si intentara portarlo a Wiz, ¿qué se necesitaría? Algo de hardware (aceleración, etc...), software (opengl, etc...)??? o es todo una librería software que escribe en la pantalla?
¡No! ¡Otro juego no!
¿Has jugado ya a...?: Ultratumba, Rock Rain, Rock Rain 2, Escape from Minos, La escoba, Batiscafo, Rookie Hero, EXP (para Wiz)
Mi web: Videojuegos de Rafa Vico.
El motor Yeti3D (tanto el normal como la versión Pro) es aceleración por software y no depende de ninguna librería externa como OpenGL. Sólo tiene dependencias con las librerías que necesites para mostrar el resultado de la "renderización" en una ventana. Por ejemplo, el target para Windows depende de SDL. Es más en su día cuando hice el port del Yeti3D para Wiz usé SDL, pero ya te digo que el engine en lo que a 3D se refiere es totalmente independiente.
Vaya pasada. La herramienta de modelado me suena. ¿Era una compatible también con MD3?
Marcadores