Iniciar sesión

Ver la versión completa : Hilo de Programación en MegaDrive [SGDK]



mills332
29/04/2014, 19:09
He creado este hilo para que pongamos aquí todo lo que vayamos intentando y consiguiendo con el kit de desarrollo SGDK para MegaDrive.

Copio el código del rotozoom que estoy intentando, no da error pero no pinta nada en la pantalla.




#include "genesis.h"
#include "BKG.h"

int XX = 0;
int x = 0;
int y = 0;
int u = 0;
int v = 0;
int W = 0;

u16 color = 0x0000;

int main(){

BMP_init(1, 0, 1);
VDP_drawBitmap(VDP_PLAN_A,&bkg,0,0);

while (1){

if (W == 1024) W = 0; //el ángulo en no se que unidades

//copiar y pegar pixeles de imagen, resolución de 160x128, El modo BMP de dibujo de imágenes, usa pixeles de 2x2
for(y=0;y<=224;y+=2){
for(x=0;x<=320;x+=2)
{
u = fix16Int(x*cosFix16(W)+y*(-sinFix16(W)));
v = fix16Int(x*sinFix16(W)+y*cosFix16(W));
color = BMP_GETPIXEL(x,y); //Copia pixel
BMP_SETPIXEL(u,v,color); //pega pixel
}
}

W++;


BMP_clear(); //no hace nada..
BMP_flip(1); //no hace nada...

BMP_showFPS(1);

VDP_waitVSync();

}

}

mills332
29/04/2014, 21:50
Otro efecto bueno, este si funciona porque han creado una función específica para el, pero estába un poco rara, o yo no la entendía muy bien... Bueno, para novatos.

Se trata de mover un plano con una función seno o coseno, para que haga ondas.



#include <genesis.h>

int i = 0;

int LINES = 0; //screen lines

u16 hscroll[1024] = {0}; //scroll values

int SPEED = 0; // wave speed

int main(){

VDP_setScreenWidth320();

VDP_setScrollingMode(HSCROLL_LINE, VSCROLL_PLANE);

LINES = VDP_getScreenHeight();

while(1){

for(i = 0; i < (LINES+1); i++) hscroll[i] = sinFix16( ((SPEED + (i << 2)) & 1023));


VDP_drawText("Test", 17, 11);

VDP_drawText("Line scroll", 14, 13);

VDP_drawText("-----------", 14, 15);

VDP_setHorizontalScrollLine(VDP_PLAN_A, 0, hscroll,LINES,1);

SPEED += 3;


VDP_waitVSync();
}
}

swapd0
29/04/2014, 21:53
Puede que falle en el BMP_SETPIXEL(u, v) ¿que rango de valores tiene u,v?
Prueba a hacer un BMP_SETPIXEL(x,y,x), para ver si pinta algo o te falta volcar el bmp.

Si cosFix16 y sinFix16 tiene un rango de salida de -512 a 511, lo multiplicas por la X y se te va al carajo, aunque después hagas el fix16Int (no he visto en la doc el intervalo de valores de entrada ni de salida).

De todas formas para hacer el rotozoom, se hace así:
Coges un angulo de entrada
Coges una escala X y escala Y
Para ese angulo, sacas un vector para recorrer lineas "horizontales" y otro para pasar de linea en linea.
Escalas los dos vectores por la escala X y la escala Y.
Recorres un bitmap usando esos vectores y vuelcas en la pantalla de forma secuencial (igual que la estas recorriendo ahora)

Si lo haces así el centro de rotación estara en la esquina de la pantalla, ahora es cuestión de cambiarlo antes de dibujar.

K-teto
29/04/2014, 22:44
Pos aqui me apunto yo XDD

mills332
29/04/2014, 22:57
Puede que falle en el BMP_SETPIXEL(u, v) ¿que rango de valores tiene u,v?
Prueba a hacer un BMP_SETPIXEL(x,y,x), para ver si pinta algo o te falta volcar el bmp.

Si cosFix16 y sinFix16 tiene un rango de salida de -512 a 511, lo multiplicas por la X y se te va al carajo, aunque después hagas el fix16Int (no he visto en la doc el intervalo de valores de entrada ni de salida).

De todas formas para hacer el rotozoom, se hace así:
Coges un angulo de entrada
Coges una escala X y escala Y
Para ese angulo, sacas un vector para recorrer lineas "horizontales" y otro para pasar de linea en linea.
Escalas los dos vectores por la escala X y la escala Y.
Recorres un bitmap usando esos vectores y vuelcas en la pantalla de forma secuencial (igual que la estas recorriendo ahora)

Si lo haces así el centro de rotación estara en la esquina de la pantalla, ahora es cuestión de cambiarlo antes de dibujar.

De todas formas, para que funcione a 3 o 4 FPS hay que saltarse pixeles de 8 en 8, o sea que una resolucion a nivel de tiles, así que es más facil mover los tiles, creo yo. O si no pues se hace un fake metiendo una secuencia de imágenes rotadas en diferentes ángulos, puede que se vea mejor... jeje.

swapd0
29/04/2014, 23:28
Seguro que se puede hacer en tiempo real y que funcione a mas fps, mira las demos de Atari ST y veras que no van tan mal. Eso si, tendrías que pasar de C y hacerlo en ensamblador.

ArChEr
30/04/2014, 00:10
He cogido el codigo que ha puesto K-teto y he estado trasteando un poco con el y he sacado el dibujado de los tiles fuera del while que mueve el scroll... creo que ahora he entendido lo de los planos...

Corregidme si me equivoco, los planos son de 512x512 pixeles y solo son para poner fondos con scroll? porque un mapa es mucho mas grande que esos 512x512...

aqui pongo el codigo por si quereis probarlo.


#include <genesis.h>

s32 coordY = 5;
s32 coordX = 5;
u16 numtile = 1;
s16 ScrollX = 0;

const u32 tile[8]=
{
0x00111100, // Línea 1: pixels 1 a 8
0x01144110, // Línea 2
0x11244211, // Línea 3
0x11244211, // Línea 4
0x11222211, // Línea 5
0x11222211, // Línea 6
0x01122110, // Línea 7
0x00111100 // Línea 8: píxels 57 a 64
};
const u32 tile2[8]=
{
0x00111100, // Línea 8: píxels 57 a 64
0x01122110, // Línea 7
0x11222211, // Línea 6
0x11222211, // Línea 5
0x11244211, // Línea 4
0x11244211, // Línea 3
0x01144110, // Línea 2
0x00111100 // Línea 1: pixels 1 a 8
};


int main( )
{
VDP_setScrollingMode (HSCROLL_PLANE, VSCROLL_PLANE); // le decimos que tipo de scroll queremos, tile a tile, linea a linea...
VDP_loadTileData( (const u32 *)tile, 1, 1, 0);
VDP_loadTileData( (const u32 *)tile2, 2, 1, 0);
VDP_setBackgroundColor(0);

coordX = 0;
coordY = 2;
while (coordY<28)
{
while (coordX<64)
{
numtile = 1 - numtile;
VDP_setTileMapXY(VDP_PLAN_A, 1 + numtile, coordX, coordY);
coordX++;
}
coordY++;
coordX = 0;
}

VDP_drawText("00000000011111111112222222222333333333344444444445 55555555566666", 0, 0);
VDP_drawText("12345678901234567890123456789012345678901234567890 12345678901234", 0, 1);


VDP_drawText("El texto tambien forma parte del PLANO A", 2, 10);

while(1)
{
VDP_setHorizontalScroll( VDP_PLAN_A, ScrollX ); //movemos el mapa x puntos a la izquierda, voy a usar la variable ciclo mismamente

if ( ScrollX == -256 ) ScrollX = 256;
ScrollX--;

VDP_waitVSync();
}
return (0);
}


Un saludo!

K-teto
30/04/2014, 00:23
Mierda, yo decia que por hoy ya no mas, que llevaba toda la tarde.
Y aqui estoy, arrancando windows para volver a ponerme, te odio! XDD

K-teto
30/04/2014, 05:16
Pues partiendo de tu codigo, le he dado unas vueltas para hacerte un ejemplo de scroll por lineas.

#include <genesis.h>

u16 numtile = 1;
s16 lineaY = 0;
s32 i,wait,numwait = 0;
char texto [3];
const u32 tile[8]=
{
0x00111100, // Línea 1: pixels 1 a 8
0x01144110, // Línea 2
0x11244211, // Línea 3
0x11244211, // Línea 4
0x11222211, // Línea 5
0x11222211, // Línea 6
0x01122110, // Línea 7
0x00111100 // Línea 8: píxels 57 a 64
};
const u32 tile2[8]=
{
0x00111100, // Línea 8: píxels 57 a 64
0x01122110, // Línea 7
0x11222211, // Línea 6
0x11222211, // Línea 5
0x11244211, // Línea 4
0x11244211, // Línea 3
0x01144110, // Línea 2
0x00111100 // Línea 1: pixels 1 a 8
};

u16 desplazamiento[32]={0,1,2,2,3,3,4,4,4,5,5,5,5,6,6,6,6,6,5,5,5,5,4,4, 4,3,3,2,2,1,1,0}; // una forma de onda suave

void myJoyHandler( u16 joy, u16 changed, u16 state)
{
//Si el botón pulsado corresponde al pad en el puerto 1
if (joy == JOY_1)
{
//La sintaxis del código para comprobar el estado
//del botón será la que sigue variando el valor
//con el que se compararán sendos atributos:
//state y change, state correspondiéndose con la
//pulsación del botón y change con la liberación
//del mismo
if (state & BUTTON_START) //Si se pulsa START
{
//Que específicamente elijamos estas determinadas
//coordenadas (x=5, y=13) se debe a que en la
//función main vamos a mostrar el rótulo
//correspondiente al estado del botón START en
//dichas coordenadas. Lo que lo que estaremos
//haciendo será sobreescribir el rótulo cada vez
//que se pulse o suelte el botón, ya sea mostrando
//"START button 1" o "START button 0" según el caso
//VDP_drawText("START button 1", 5, 13);
//El área para disponer texto en pantalla en
//megadrive se corresponde exactamente con el área
//de tiles visibles en pantalla (no hay razón para
//no considerar cara caracter un tile, que es lo
//que también son). Por lo tanto, en el modo PAL
//"normal" en que disponemos de una resolución de
//320x224 tendremos un área de 40x28 caracteres;
//La primera fila y la primera columna toma valor
//cero, por lo que para comenzar un texto en la
//esquina superior izquierda lo haríamos tal que
//así: //VDP_drawText("texto", 0, 0);
}
else if (changed & BUTTON_START) //Si se suelta
{
//VDP_drawText("START button 0", 5, 13);
}

if (state & BUTTON_A) //Si se pulsa A
{
//VDP_drawText("A button 1", 5, 14);

}
else if (changed & BUTTON_A) //Si se suelta A
{
//VDP_drawText("A button 0", 5, 14);
}

if (state & BUTTON_B)
{
//VDP_drawText("B button 1", 5, 15);
}
else if (changed & BUTTON_B)
{
//VDP_drawText("B button 0", 5, 15);
}

if (state & BUTTON_C)
{
//VDP_drawText("C button 1", 5, 16);
}
else if (changed & BUTTON_C)
{
//VDP_drawText("C button 0", 5, 16);
}

if (state & BUTTON_X)
{
//VDP_drawText("X button 1", 17, 14);
}
else if (changed & BUTTON_X)
{
//VDP_drawText("X button 0", 17, 14);
}

if (state & BUTTON_Y)
{
//VDP_drawText("Y button 1", 17, 15);
}
else if (changed & BUTTON_Y)
{
//VDP_drawText("Y button 0", 17, 15);
}

if (state & BUTTON_Z)
{
//VDP_drawText("Z button 1", 17, 16);
}
else if (changed & BUTTON_Z)
{
//VDP_drawText("Z button 0", 17, 16);
}

if (state & BUTTON_UP)
{
//VDP_drawText("UP button 1", 5, 17);
}
else if (changed & BUTTON_UP)
{
//VDP_drawText("UP button 0", 5, 17);
}

if (state & BUTTON_DOWN)
{
//VDP_drawText("DOWN button 1", 5, 18);
}
else if (changed & BUTTON_DOWN)
{
//VDP_drawText("DOWN button 0", 5, 18);
}

if (state & BUTTON_LEFT)
{
//VDP_drawText("LEFT button 1", 5, 19);
}
else if (changed & BUTTON_LEFT)
{
if (numwait>0)
numwait--;
//VDP_drawText("LEFT button 0", 5, 19);
}

if (state & BUTTON_RIGHT)
{
numwait++;
//VDP_drawText("RIGHT button 1", 5, 20);
}
else if (changed & BUTTON_RIGHT)
{
//VDP_drawText("RIGHT button 0", 5, 20);
}
}


// otras funciones interesante
// JOY_update() refresca el estado del pad, se llama en cada refresco de la pantalla
// JOY_readJoypad( joy ) ¨devuelve el estado del pad1
// JOY_waitPressBtn() espera a que se pulse un boton (no direcciones)
// JOY_waitPress(joy, BUTTON_A | BUTTON_UP) espera a pulsar un boton indicado en un pad especifico

}//end myJoyHandler()

void initTileMap() // crea el mapa de tiles
{
s32 coordY = 0;
s32 coordX = 0;

while (coordY<28)
{
while (coordX<64)
{
numtile = 1 - numtile;
VDP_setTileMapXY(VDP_PLAN_B, 1 + numtile, coordX, coordY); // dibujamos en el plano B para que no interfiera con el texto
coordX++;
}
coordY++;
coordX = 0;
}
}
int main()
{
// empezamos a inicializar cosas y a preparar el programa
JOY_init(); //joystick
JOY_setSupport(PORT_1, JOY_SUPPORT_6BTN); // puerto y tipo de pad
JOY_setEventHandler( &myJoyHandler ); // indicamos que funcion es la que controla el pad
VDP_setScrollingMode (HSCROLL_LINE, VSCROLL_PLANE); //necesitamos que el scroll horizontal sea por lineas
VDP_loadTileData( (const u32 *)tile, 1, 1, 0); // cargamnos el tile 1
VDP_loadTileData( (const u32 *)tile2, 2, 1, 0); // cargamos el tile 2, el mismo que el 1 pero invertido
VDP_setBackgroundColor(63); //ponemos un color de fondo, el 63 es un azul brillante en la paleta por defecto
initTileMap(); // esta es la funcion que dibuja el mapa de tiles
numwait=1; // le ponemos por lo menos un retrazado, que si no no se ve una leche
// ya hemos terminado de inicializar todo lo necesario, vamos con el bucle principal

while(1)
{
for (lineaY=0;lineaY<=223;lineaY++) // vamos a recorrer toda la resolucion vertical, de 0 a 223 (224 pixels de alto)
{
if (i<=32) i=0; //nuestro array de desplazamientos tiene 32 valores distintos, si alcanzamos el ultimo, volvemos al primero
VDP_setHorizontalScrollLine (VDP_PLAN_B, lineaY,&desplazamiento[i],32,1); //movemos el plano B, en el A esta el texto
i++;
for (wait=1;wait<=numwait;wait++) VDP_waitVSync(); //cuantas veces esperamos el vsync? (para hacerlo mas lento y ver algo)
VDP_drawText("Numero de retrazos:", 1, 4);
intToStr (numwait,texto,3);
VDP_drawText(texto, 20, 4);
}
}
return (0);
}


Con las direcciones derecha e izquierda del pad, controlas la velocidad de la "animacion", añadiendo o quitando esperas al retrazado vertical.

EDIT: Enlace a la rom por si alguien lo quiere probar.
https://mega.co.nz/#!TEtTEAJQ!-lC_ALSsAk2GHHLECnBnBe5lQieidcIUqy0CNWMRsas

-----Actualizado-----

Me acabo de dar cuenta de un pequeño error releyendo el codigo, los tiles siempre se iban a ver desplazados un pixel a la derecha porque el "i++;" deberia ir despues de dibujarlos y no antes, si no, el valor minimo de i a la hora de dibujar va a ser 1 y no 0.
Solucionado, he puesto el incremento de i justo despues de dibujar el efecto.

-----Actualizado-----

Sobe el tema de los mapas, si los planos son de 512x512, como habria que hacerlo para meter un mapa mas grande que eso digamos en horizontal? desplazando el mapa una linea vertical de tiles y añadiendo la siguiente linea vertical de tiles al final?

mills332
30/04/2014, 12:28
Sobe el tema de los mapas, si los planos son de 512x512, como habria que hacerlo para meter un mapa mas grande que eso digamos en horizontal? desplazando el mapa una linea vertical de tiles y añadiendo la siguiente linea vertical de tiles al final?

No tengo ni idea, segun stef, para hacer mapas estilo sonic, hay que usar trozos grandes de pantalla y los vas metiendo uno detras del otro. Una vez vi los niveles del sonic que alguien había ripeado, y cada parte era grande, por ejemplo el looping era un "tile", un trozo de suelo con 3 palmeras era otro mega-tile. y luego los ordena en una matriz.

K-teto
30/04/2014, 15:53
Habra que mirar documentacion y el trabajo de otros para saber como va el tema.
Porque no se si el sgdk ya viene preparado para manejar mapas de tiles grandes.

Alguien conoce el super hydlide? un rpg temprano de megadrive, te movias de pantalla en pantalla, cuando llegabas al borde de una pantalla, hacia un scroll a la siguiente y asi.
Me recuerda a este problema XDD

https://www.youtube.com/watch?v=Ql_Cm3fn08s
Por cierto, uno de mis juegos favoritos, y su banda sonora me encanta.

ArChEr
30/04/2014, 17:03
Sobe el tema de los mapas, si los planos son de 512x512, como habria que hacerlo para meter un mapa mas grande que eso digamos en horizontal? desplazando el mapa una linea vertical de tiles y añadiendo la siguiente linea vertical de tiles al final?

Creo que los 2 planos son para hacer el efecto paralax o rellenar el fondo y que lo que son los tiles de escenario realmente es en la capa de sprite y se dibujarían haciendo como el "frustum culling" de los motores 3D pero con los tiles... seria dividir el escenario en porciones grandes y depende de donde se encuentre el personaje dibujarías solo las porciones que quedan dentro de la pantalla ahorrando tener que rastrear todo el escenario completo y así ahorrar tiempo de proceso.

Juraria que había un emulador en el que podías desactivar los planos pero ahora no me acuerdo del nombre, si cargamos el sonic podríamos ver en que plano se carga el escenario... juraría que es en el de sprites.


Un saludo!

Lo retiro, acabo de mirarlo con el emulador y el escenario esta en el plano A y el fondo en el plano B, ademas cada plano se divide en 2: low e high, el low dibuja los tiles por debajo de los sprites y el high por encima de los sprites...

Pues viendo esto debe ser algo como lo que dice K-teto...

mills332
01/05/2014, 15:16
Lo retiro, acabo de mirarlo con el emulador y el escenario esta en el plano A y el fondo en el plano B, ademas cada plano se divide en 2: low e high, el low dibuja los tiles por debajo de los sprites y el high por encima de los sprites...

Pues viendo esto debe ser algo como lo que dice K-teto...

El plano A es el más cercano, está por defecto sobre el plano B. Pero puedes cambiar la prioridad de tiles o de trozos completos del plano B para que estén encima del A.

Los dos planos tienen transparencia, el color transparente es el mas "oscuro" de la paleta, Pero si no hay nada debajo y la zona tiene prioridad cero, se supone que se ve el color. no lo he probado...
Si dos zonas tienen la misma prioridad, se respeta el orden por defecto, esprites sobre pano B y plano B sobre plano A

En el juego del minigolf he hecho el plano A con prioridad 1, el B 0 y los esprites 0. De esta forma los esprites se ven encima del plano B y debajo de las partes no transparentes del plano A.


La prioridad es e valor que va detras de PAL


//PLANOS
ind = TILE_USERINDEX;
VDP_drawImageEx(BPLAN, &FONDO, TILE_ATTR_FULL(PAL0,0,0,0,ind),0,0,0,1);
ind += bkg.tileset->numTile;
VDP_drawImageEx(APLAN, &SOBRE_FONDO, TILE_ATTR_FULL(PAL1,1,0,0,ind),0,0,0,1);
ind += Title.tileset->numTile;

OBJETOS
SPR_initSprite(&objects[0], &sprite0, fix16ToInt(posx), fix16ToInt(posy), TILE_ATTR(PAL2,1,0,0)); un puntero sobre todos los demas
SPR_initSprite(&objects[1], &sprite1, fix16ToInt(posx), fix16ToInt(posy), TILE_ATTR(PAL2,0,0,0)); un objeto, sobre el plano B y bajo el plano A

mills332
19/05/2014, 13:24
Trabajando en el juego de minigolf he conseguido detectar bordes para las colisiones.

Definimos una pared inclinada mediante las coordenadas de una recta con 97 puntos:


u16 B1x[97] =
{
0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19, 20,
21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37 ,38,39,40,
41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57 ,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73,7 4,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90, 91,92,93,94,95,96
};
u16 B1y[97] =
{
38,38,37,37,37,36,36,35,35,35,34,34,33,33,33,32,32 ,31,31,31,
30,30,29,29,29,28,28,27,27,27,26,26,25,25,25,24,24 ,23,23,23,
22,22,21,21,21,20,20,19,19,19,18,18,17,17,17,16,16 ,15,15,15,
14,14,13,13,13,12,12,11,11,11,10,10,9,9,9,8,8,7,7, 7,6,6,5,5,
5,4,4,3,3,3,2,2,1,1,1,0,0
};

Definimos un punto dentro de la recta, un valor de 0 a 97 de los de arriba:


u16 Col_Point;

Ahora dentro del while, metemos un for, que va chequeando en cada frame, si la posicion de la bola coincide con alguno de los 97 pares x,y.



while(1){

for (Col_Point = 0; Col_Point < 98; Col_Point++ )
{
if ((posx == B1x[Col_Point]) && (posy == B1y[Col_Point]))
{
//aqui activamos alguna variable que indique colision y la usamos para otras cosas fuera del for.
}
}

}


Para que detecte mejor la colisión, hay que chequear si las coordenadas de la bola entran dentro de un intervalo de los valores de la recta +4 y -4 pixeles. Por que si la bola va muy rápido, se puede saltar la coordenada sin rebotar.

Luego está el tema de calcular vectores que no tengo ni idea, esta formula se supone que lo hace, pero no entiendo como sacar la x y la y del vector resultante.


V = Vector entrante
V = (vx, vy)
N = Vector Normal de la pared (vector unitario)
N = (nx, ny).

VectorRebote = -2*(V * N)*N + V

V * N = v.x*n.x+v.y*n.y.
N + V = nx + vx , ny + vy}

calcular vector unitario N partir de M: N = M/ Raiz de (M * M)

A ver si alguien lo pilla mejor que yo. Seguiré intentándolo.

swapd0
19/05/2014, 21:09
Es mejor que hagas las colisiones por geometría y no mirando un mapa de bits/bytes para ver si hay colisión. Ademas así de un tirón resuelves las colisiones con paredes en cualquier dirección.

mills332
20/05/2014, 13:31
Es mejor que hagas las colisiones por geometría y no mirando un mapa de bits/bytes para ver si hay colisión. Ademas así de un tirón resuelves las colisiones con paredes en cualquier dirección.

Vale... y como se hace por geometría... jaja

swapd0
20/05/2014, 19:58
Teniendo cada nivel como segmentos haciendo productos escalares y vectoriales entre cada segmento y la bola puedes sacar todo lo que necesitas.

Imagina que tienes tres puntos, O, A y B. El punto 'O' puede ser el origen del punto de vista, o el origen de un segmento. El punto 'A' seria el punto al que estamos mirando o el final de un segmento. El punto 'B' es el punto que queremos ver donde leches esta.

Con estos puntos podemos sacar los vectores VA (a - o) y VB (b - o). Con estos dos vectores podemos hacer un productor vectorial o un producto escalar, mirando el signo podemos saber la posición del punto 'B' respecto a 'O' usando como referencia 'A'.

Producto vectorial: corresponderia a la imagen central. Si nos quedamos con el signo, este sera positivo si esta a la izquierda del vector VA, imaginate que vas en coche y quieres ir al punto 'B'. Calculas el producto vectorial y si da positivo tienes que girar hacia la izquierda, negativo derecha. Igual a cero seria si esta sobre el vector VA.

pv = VA.x * VB.y - VA.y * VB.x;

Producto escalar: imagen de la derecha. Si nos quedamos con el signo, este dará positivo si esta "hacia" delante de la linea perpendicular al vector 'VA' que pasa por 'O', negativo si esta detrás y cero si esta en la misma linea.

pe = VA.x * VB.x + VA.x * VB.y;
39143

K-teto
21/05/2014, 00:48
No me he enterado de un carajo, que lastima que mi nivel de matematicas sea tan insuficiente >__<.
Pero lo intentare entender, palabrica XDD
Si no fuera por esas, ni me habria puesto a aprender pascal en su dia.

swapd0
21/05/2014, 01:40
Version resumida:

Teniendo dos vectores, el signo del producto vectorial te da hacia donde gira el segundo punto respecto al primero (izquierda o derecha) y el signo del producto escalar te dice si esta hacia delante o detrás del "origen".

La linea discontinua en los dibujos representa una linea infinita, y los signos + o - es que cualquier punto en esa zona (respecto a la linea infinita) te dará como resultado un valor positivo o negativo.

En el esquema del dibujo la linea discontinua y VA son perpendiculares, se me paso dibujarlo.

Limonetti
05/07/2014, 01:15
Por fin me he decido a probar a programar algo para la megadrive. :D

Dudo mucho que salga de mis manos algo jugable, pero espero pasármelo bien.

Por ahora solo he llegado a instalar el sgdk para trabajar con el codeblocks y he compilado un hola mundo un uno de los ejemplos que venían con él.

Ya que en esto estoy super pez, y si no es dar mucho la lata ¿Podrías indicarme un poco donde puedo conseguir información para empezar con buen pie? Aunque buscare por mi cuenta, seguramente una indicación vuestra por pequeña que sea me ahorra muchos quebraderos de cabeza.

Mi base es saber C en plan básico y lo que mas he tocado son microcontroladores. Nada que ver con esto, me imagino.

mills332
05/07/2014, 01:32
Por fin me he decido a probar a programar algo para la megadrive. :D

Dudo mucho que salga de mis manos algo jugable, pero espero pasármelo bien.

Por ahora solo he llegado a instalar el sgdk para trabajar con el codeblocks y he compilado un hola mundo un uno de los ejemplos que venían con él.

Ya que en esto estoy super pez, y si no es dar mucho la lata ¿Podrías indicarme un poco donde puedo conseguir información para empezar con buen pie? Aunque buscare por mi cuenta, seguramente una indicación vuestra por pequeña que sea me ahorra muchos quebraderos de cabeza.

Mi base es saber C en plan básico y lo que mas he tocado son microcontroladores. Nada que ver con esto, me imagino.

Yo no tenía ni idea de c, a parte de saber lo que significa un If y como se lee el codigo. Empecé con la Game Boy leyendo cosas ya hechas, y luego miré el sgdk de MegaDrive.

Para ver toda la documentación del sgdk mira esto está en ingles, el mismo creador de sgdk está por ese foro (stef): http://gendev.spritesmind.net/forum/viewtopic.php?t=14

Limonetti
05/07/2014, 21:21
Siento daros mal, pero hay cosas que he ido sacando durante el día, pero de esta no salgo. Por ejemplo me he vuelto loco buscando por internet la documentación, cuando estaba en un html generado con doxygen en el propio paquete que descargué.

Estoy intentando cargar una imagen "moon.bmp" que viene con los ejemplos de la pagina de sgdk de manejo de tiles (https://code.google.com/p/sgdk/wiki/Tiles). Pero estoy atascado ahí.

Creo que todo viene de que no se usar la utilidad de rescomp que viene con el paquete. ¿Como tengo que usar lo que hay? Solo he visto las fuentes, así que me ha dado por compilarlo con el GCC para tener el ejecutable, y aparte de darme el error de que me falta un archivo llamado "libgcc_s_dw2-1.dll" cuado lo abro por linea de comando, poco mas he sacado.

Seguro que me estoy liando y es una tontería bien fácil de resolver. ¿Como cargáis vosotros las imágenes desde .bmp o .png? ¿Me echáis un cable?

--- EDITO ---

He avanzado un poco. He incluido el archivo "libgcc_s_dw2-1.dll" (descargado de internet) en la carpeta del rescomp.exe, y ya lo puedo ejecutar. Luego he intentado con los comandos que se ven en la imagen.

39792

Y también podéis en esta ver el código que uso (el del ejemplo) y los archivos que están incluidos en el proyecto. Lo unico es que como me había creado un resources.h lo he renombrado a moon.h.

Compilar me compila, pero al abrir la rom con el Kega no veo la luna dibujada por ningún sitio. ¿Que hago mal?

La imagen moon.bmp la tengo en la carpeta ./res respecto del proyecto, y he metido ahí también el moon.h y el resources.res que he incluido.

-- EDITO (otra vez) --

Vale, conseguido.

Soy un parras y había cargado la imagen en la memoria de vídeo pero no había escrito la función de dibujado. Depende de la compresión que uses la dibuja mal.

Creo que he ido por mal camino de todas formas. Viéndolo ahora con perspectiva es mucho mas fácil sabiendo como declarar las variables en el ".h" y en el ".res" para que las pille el rescomp.

Pero bueno, compilandolo en el sgdk digamos que te lo genera él la plantilla también y lo puedes compilar a parte.

No es por malmeter, pero las guías que he ido viendo por ahí, o son para gente que sabe, o son copia pega traducciones sin más. Hay pasos en que la gente torpe se pierde fácilmente, como en mi caso.

mills332
06/07/2014, 13:07
No es por malmeter, pero las guías que he ido viendo por ahí, o son para gente que sabe, o son copia pega traducciones sin más. Hay pasos en que la gente torpe se pierde fácilmente, como en mi caso.

Si es verdad, yo porque pude hablar (en ingles) con el creador de sgdk, si no... además el tutorial de la luna esta mal, lo dijo el mismo.
Hay otro bug, si usas la función fade in/out, luego tienes que volver a poner la paleta, porque no termina en la paleta real y le faltan colores.

Limonetti
06/07/2014, 20:42
Gracias por responder y por el aviso del otro bug.

De todas formas dije eso porque me pillo después de desesperarme unas horas de estar atascado. El currazo que lleva todo lo que han hecho para poder programar de forma sencilla es innegable y merece mucho respeto.

A ver si sigo avanzando poco a poco con los ejemplos y practicando con las librerías que han hecho, que el ansia es mala consejera.

Limonetti
18/08/2014, 21:09
Hola de nuevo.

Si pudierais ayudarme tanto los que habéis trasteado con esto, como los que domineis el tema de la programación lo agradecería un montón.

Estoy intentando dibujar una pantalla con un tileset a modo de fondo, y ando un poco perdido.

Hay un ejemplo en esta página (https://code.google.com/p/sgdk/wiki/sgdk_tile_functions), pero no he podido seguirlo por no poder descargar los archivos que enlaza.

De todas formas no creo que me hubiera servido, ya que la idea era cargar por mi cuenta una imagen al gusto. Así que para ello he probado con el Imagenesis4000 para crear a partir de ahí tanto las estructuras de la paleta de colores, tiles y tilemap, que he incluido en un archivo "tilemap.h" como código en C.

Hasta ahora lo máximo que he conseguido es lo que veis abajo, que es cargar los tiles y dibujar una linea con una función un poco a pelo. Hay muchas funciones de las cuales no veo diferencia con otras de la librería, y no encuentro la que querría en la que poder cargar el vector con el tilemap.

Aparte de eso, como veis la estructura map es una parte de lo que seria mi tilemap, con la cual tengo un problema al incluirla (la tengo comentada) ya que no me compila. Lo cual tampoco estoy seguro porque no lo hace (tamaño o tipo?).

Y no se que más comentar. Si alguien me puede ayudar a orientarme un poco le deberé una (o más de una).


#include <genesis.h>
#include "tilemap.h"


int main()
{

unsigned int c;

unsigned int map [240] = {0x0000,0x0001,0x0002,0x0003,0x0004,0x0005,0x0006, 0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0 x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x 0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0 006,0x0007,0x0008,0x0009,0x0000,0x0001,0x0002,0x00 03,0x0004,0x0005,0x0006,0x0006,
0x000A,0x000B,0x000C,0x0006,0x000D,0x000E,0x0006,0 x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x 0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0 006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x00 06,0x000F,0x0010,0x0011,0x000A,0x000B,0x000C,0x000 6,0x000D,0x000E,0x0006,0x0006,
0x0012,0x0013,0x0014,0x0006,0x0015,0x0006,0x0006,0 x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x 0006,0x0006,0x0016,0x0017,0x0006,0x0006,0x0006,0x0 006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x00 06,0x0018,0x0006,0x0019,0x0012,0x0013,0x0014,0x000 6,0x0015,0x0006,0x0006,0x0006,
0x001A,0x001B,0x0006,0x001C,0x001D,0x001E,0x0006,0 x001F,0x0020,0x0021,0x0022,0x0006,0x0006,0x0006,0x 0006,0x0023,0x0024,0x0025,0x0026,0x0027,0x0006,0x0 006,0x0006,0x0006,0x0006,0x0006,0x0006,0x0006,0x00 06,0x0006,0x0006,0x0006,0x001A,0x001B,0x0006,0x001 C,0x001D,0x001E,0x0006,0x001F,
0x0028,0x0029,0x002A,0x002B,0x002C,0x002D,0x002E,0 x002F,0x0030,0x0031,0x0032,0x0033,0x0006,0x0006,0x 0034,0x0035,0x0036,0x0036,0x0037,0x0038,0x0039,0x0 03A,0x003B,0x003C,0x003D,0x003E,0x003F,0x0006,0x00 06,0x0006,0x0006,0x0006,0x0028,0x0029,0x002A,0x002 B,0x002C,0x002D,0x002E,0x002F,
0x0040,0x0041,0x0042,0x0043,0x0044,0x0045,0x0046,0 x0047,0x0048,0x0049,0x004A,0x004B,0x004C,0x0006,0x 004D,0x004E,0x0036,0x0036,0x0036,0x0036,0x0036,0x0 036,0x004F,0x0050,0x0051,0x0036,0x0052,0x0053,0x00 06,0x0006,0x0006,0x0006,0x0040,0x0041,0x0042,0x004 3,0x0044,0x0045,0x0046,0x0047};

VDP_setPalette (PAL0, (const u16 *)tilemap1_palette);

VDP_loadTileData ((const u32 *)tilemap1_data,1, 428, 1);

for (c = 0; c < 40; c++ ){
VDP_fillTileMapInc ( APLAN, TILE_ATTR_FULL(APLAN,1,0,0,(unsigned int) map[c]), c, 1);
}

while(1)
{
VDP_waitVSync();
}
return (0);
}



40325

kappa64
19/08/2014, 02:01
...........................

Limonetti
19/08/2014, 15:34
Muchas gracias por responder kappa64.

El error me lo debía dar porque el tamaño que le indicaba en la declaración no se correspondía con lo inicializado. No me lo indicaba claramente, ni me resaltaba ninguna linea (ahora no puedo reproducirlo para pegar el log).

Pero bueno ya en teoría he podido cargar el tilemap entero. No tengo muy claro de que este toda la imagen ahí.

40328

Y lo cargo en el plano, claro. Veré si puedo ajustar el dibujado a solo la pantalla. Pero vamos, muy contento por haber avanzado algo.

En la wiki de google no encuentras nada porque la documentación viene en el propio zip del sgdk, pero no la veo muy aclaratoria tampoco (supongo que para alguien acostumbrado a estas cosas quizás si, es que estaré muy verde). Ando como loco buscando esa función, de verdad.

Por ahora lo único que he visto es cargar imágenes completas en bmp con genres, pero no estoy seguro de si eso es eficiente en cuanto a ocupar espacio en la rom. Por eso os preguntaba a los programadores, ya que se supone que habría un montón de tiles repetidos que también me ocuparían memoria de vídeo de esa forma.

Me habría molado que diera señales de vida mills332 porque se que el seguramente habrá tocado mucho más el sgdk. Insistiré y buscaré más hoy con tiempo, y preguntare en el foro que me indico mills.

Muchísimas gracias de nuevo, temía que nadie contestase.

EDIT: Subo también el proyecto por si a alguien le apetece trastear con el, junto con la documentación del sgdk.

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

Vale, ya lo tengo casi. He simplificado el problema para una imagen mas pequeña y he ido haciendo pruebas con las funciones de las librerías y los argumentos que les pasaba.

Al final después de encontrar la función mágica, algo así tendría que dibujarme la imagen.


#include <genesis.h>

#include "tilemap.h"

#define BGB_TILES 35
#define BGB_WIDTH 7
#define BGB_HEIGHT 7

#define POS_X 10
#define POS_Y 10

#define MEM_POS 0


int main()
{

//void VDP_setPalette ( u16 num, const u16 *pal )
VDP_setPalette (PAL0, (const u16 *)palette_post);

// void VDP_loadTileData ( const u32 *data, u16 index, u16 num, u8 use_dma )
VDP_loadTileData ((const u32 *)tileset_post, MEM_POS, BGB_TILES, 1);

// void VDP_setTileMapDataRectEx ( u16 plan, const u16 *data, u16 basetile, u16 x, u16 y, u16 w, u16 h, u16 wm )
//TILE_ATTR_FULL ( pal, prio, flipV, flipH, index )
VDP_setTileMapDataRectEx ( APLAN, (const u16 *)tilemap_post, MEM_POS, POS_X, POS_Y, BGB_WIDTH, BGB_HEIGHT, 7);

while(1)
{
VDP_waitVSync();
}
return (0);
}

Pero el resultado es la pobre cara de sonico el espingardo amorfo...

40352

Imagino que ya el problema ira por como comprime la imagen el imagenesis quizás, ¿no?

Bueno, solo añado esto para no acaparar el hilo.

mills332
28/08/2014, 17:14
Ahora estoy un poco en otra cosa, pero leí el mensaje de limonetti.

La verdad es que no he sabido meter tiles y maps con sgdk, lo pregunté en otro foro y terminé descargando los "tiles" del sonic 1.

Lo que pasa es que no son tiles, son trozos enormes de imagenes, como de 128x128 pixeles, ahora no recuerdo. El caso es que se supone que en el sonic, los va colocando sobre la marcha leyendo un array no demasiado grande, pero los tiles son enormes y los va metiendo.

En sgdk no consegui nada mas que cargar imagenes grandes, que por otro lado es lo que necesita el juego de minigolf.

DarkDijkstra
28/08/2014, 17:35
No había visto el hilo hasta ahora, así que aprovecho para subir un mini-proyecto que hice en un fin de semana.
Era el cumpleaños de mi novia, es super-fan de Locoroco, acababa de rescatar su megadrive del trastero y yo tenía un everdrive nuevecito... la solución era obvia ! ; )

He metido en el zip la carpeta del proyecto, así que asumo que estará todo (música, imágenes y código fuente)

Si tengo un rato (que por ahora no lo voy a tener) podría ver exactamente qué es cada cosa y comentar el código (os aseguro que no será bonito, cuando programo de maratón por la noche ni lo entiendo por la mañana) pero al menos escarbando un poco se podrá ver como cargar imágenes más o menos grandes, hacer scroll, mover objetos, estados de juego, etc...

40435

Limonetti
28/08/2014, 17:59
Me alegro de ver movimiento por aquí.

Gracias por colgar el código DarkDijkstra. Aun no le he echado un ojo pero imagino que tener más donde mirar siempre ayuda.

No he seguido dando la brasa porque pensaba que no había ya interés, pero estos días he ido trasteando bastante. Al final conseguí cargar con el propio sgdk las imagenes (usando rescomp) y creo que es el método mas cómodo.

Tengo una practica de como hacer scrolls por línea, que en post atrás comentabais acerca de ello.

Ahora ando liado con las animaciones de los sprites. Si tenéis algún ejemplo más y lo queréis compartir a mi igual me resuelven dudas que me van surgiendo.

Os pongo mis pequeños engendros.40436 40437

mills332
28/08/2014, 20:23
Eso el rescomp, con eso lo cargo yo.
Para probarlos antes de meterlos a lamegadrive, usar el emulador regen, porque si no metemos todos los datos en orden y no los vamos cargando y borrando, se puede petar la consola, hay problemas con la memoria y los otros emuladores no los detectan.

Esto es lo que llevo yo del juego.. no puedo con el tema mates y las colisiones no me salen..
Si pulsais "A" ireis al menu.. "A" otra vez a un hoyo con musica y una animacion. "B" a otro hoyo con la misma musica.

Como mola el locoroco jaja yo lo compre para mi psp.

Limonetti
30/08/2014, 19:48
De nuevo a preguntar cosillas. [wei]

Por cambiar e ir practicando cosillas diferentes he intentado ponerme a hacer un matamarcianos y me han surgido dos dudas. Una que tiene que ver más con las librerías y otra de lo que seria el algoritmo en si.

Empiezo con la segunda.

Tengo en principio el sprite de un avión unicamente, y cada vez que pulso el boton A inicializo otro sprite para el disparo. De este nuevo disparo guardo la información en un array (de structuras) con sus coordenadas, indice (en la tabla de sprites) y si esta activo o no (dentro de los limites de la pantalla). De esta forma con cada disparo incremento un indice en ese array y puedo tener un numero n de disparos simultaneos en pantalla cada uno moviendose a su bola.

Ahora bien, no me parece una buena solución ya que conforme los disparos salen de la pantalla tendría que eliminarlos y "liberar espacio" para otros (por ahí andan los tiros de mi segunda duda). Sin embargo es posible por ejemplo que el disparo 4 este inactivo, mientras que el disparo 3 y 5 no. Con lo que no puedo por ejemplo quitarme uno de enmedio del array ¿Tendría que usar una lista o algo así? ¿Veis alguna solución más sencilla?

Imagino que esto se extenderá luego a las naves enemigas. Es posible que me cargue alguna que tenga el numero 7 y existan sin embargo la 8 y la 9.

La otra duda es por si me lee alguien que haya usado el sgdk en concreto y es si existe alguna función contraria a la de "SPR_initSprite". Es decir, que me libere de la memoria de vídeo los sprites que ya no uso.

Os enlazo el engendro por si alguien quiere echarle un ojo.

40463

swapd0
30/08/2014, 20:12
Como la megadrive tiene un máximo de sprites a dibujar, puedes tener un array de tamaño fijo con todos los sprites a "dibujar". Cada elemento de ese array sera una estructura con los valores x, y, tile, y algo mas que necesites, también añadele unos indices para crear una lista sobre ese array.

Cuando creas o borras un sprite del array modifica la lista según sea necesario, después a la hora de dibujar recorres esa lista y no el array creando los sprites correspondientes.

Limonetti
30/08/2014, 20:57
Gracias, le daré vueltas a lo que me has contado. Me cuesta aún bastante entender todas estas cosas.

De todas formas tendré que ver como libero la memoria de vídeo para poder cargar los sprites que necesite sobre la marcha o me da que me quedare sin espacio enseguida. Lastima que no trasteeis con las librerías mas gente por aquí.

nolddor
27/11/2014, 20:00
Buenas, he visto que hay cierto interés por la MegaDrive

Os dejo por aquí mi segundo juego, incluye el código fuente así que seguro que os ayuda.
Un saludo.


DOWNLOAD: Chase (Homebrew) [Sega Mega Drive / Genesis] (https://dl.dropboxusercontent.com/u/1383198/SegaRoms/ChaseMD/index.html)

rapiqui
31/12/2014, 00:22
Buenas, he visto que hay cierto interés por la MegaDrive

Os dejo por aquí mi segundo juego, incluye el código fuente así que seguro que os ayuda.
Un saludo.


DOWNLOAD: Chase (Homebrew) [Sega Mega Drive / Genesis] (https://dl.dropboxusercontent.com/u/1383198/SegaRoms/ChaseMD/index.html)

Mil gracias por facilitar el código fuente del juego. ¡La verdad es que está muy divertido!

Acabo de empezar en esto de la programación en sgdk. Uso code:blocks y no pasaba del maldito hello world y la captura de pulsaciones de botones del joystick que vienen en la documentación del sdk.

Espero verlo todo diferente con tu código, pero hasta ahora todo era bastante frustrante: rescomp no me importaba ni un fichero .bmp y la documentación muy incompleta en el wiki de sgdk (he dejado un comentario en el mismo comentándolo).

En todo caso, de nuevo, muchas gracias.

josepzin
31/12/2014, 00:52
Esos mojonstwins :D

nolddor
29/04/2015, 14:51
También hemos subido a github el código fuente de BugHunt, quizas os ayude.

LINK: https://github.com/moon-watcher/BugHuntMD

swapd0
29/04/2015, 15:17
Le he echado un vistazo por encima al código y te voy a dar un consejo.

El procesador de la megadrive es el motorola 68000, un procesador de 16bits y muchas de las instrucciones están pensadas para trabajar con 16bits. En el código he visto que usas mucho bytes con signo (s8). A no ser de que tengas problemas con la memoria es mas rápido usar enteros de 16bits, claro que si no estas llegando al limite del procesador no lo notaras, pero si sigues programando mas juegos puede que algun día necesites optimizar esto.

PD: yo programaba en ensamblador del 68000 en el Atari ST.

nolddor
04/05/2015, 08:42
Gracias por el consejo, lo que no me ha quedado del todo claro es que debería usar entonces u8 (char) o u16(short) ?

PD: Porqué no te animas y programas algo en ASM para MegaDrive??
[Tutorial ASM para Sega MegaDrive] (http://www.hacking-cult.org/?r/18)

mills332
01/09/2015, 11:22
Buenas, no se si sigue habiendo interés en esto, yo lo deje un poco porque nunca supe añadir las colisiones a mi juego.

Ayer me acordé de un juego llamado TITUS the Fox seguro que os suena. Entonces encontré un codigo fuente en c llamado opentitus, y pensé que estaría bien poder usarlo en megadrive.

El juego parece pensado para megadrive porque todos los niveles y personajes están hechos con tiles de 16x16 pixels y a 16 colores por pixel, lo que pasa es que hay que sacar mapas y tiles de las imagenes de los niveles (eso es muy fácil).

Lo dificil es meter los mapas en la rom, porque son imagenes de 4000 pixeles de ancho y el rescom p solo deja de 512.


Bueno si a alguien le interesa, esta aqui: http://sourceforge.net/projects/opentitus/files/
Y aquí hay una pagina con programas y los niveles ya sacados en imagen.. incluyen los sprites encima, pero es facil borrarlos y dejar solo el fondo http://ttf.mine.nu/

A claro tambien hay que crear la musica pero eso creo que yo podria :)

swapd0
01/09/2015, 11:39
Las imágenes hay que convertirlas a tiles para ahorrar memoria, eso es un trabajo de chinos aunque se podría hacer con un programa.

mills332
01/09/2015, 13:33
Las imágenes hay que convertirlas a tiles para ahorrar memoria, eso es un trabajo de chinos aunque se podría hacer con un programa.

Nada de eso, encontre varios programas genericos y uno para sgdk que convierte imagenes en tiles y mapas.

Por ejemplo estos niveles del Fox, usan 256 tiles, y el mapa es simplemente una tabla con los numeros de tile ordenados.

Pero sigo sin saber como cargarlos en sgdk

darthelevous
19/09/2021, 18:11
Hola amigos, soy nuevo aquí y quiero saludarlos. Soy de Brasil y tengo la intención de hacer muchos amigos aquí.

Estoy aprendiendo el lenguaje C y pronto desarrollaré juegos para mi consola favorita, sega genesis.

josepzin
20/09/2021, 23:26
Hola amigos, soy nuevo aquí y quiero saludarlos. Soy de Brasil y tengo la intención de hacer muchos amigos aquí.

Mal te veo por aquí si vienes con esta intención...

Yo hago mi aporte al hilo:

https://www.youtube.com/watch?v=rk5lw3mTH-U