Wiilander

¡Enséñanos tu creación!

Wiilander

Notapor manny » Martes, 23 de Diciembre de 2008 14:20

Bueno.. ahora que estoy de vacas. a ver si le doy un empujo y para reyes.. esta terminado.. la idea es ir poniendo los avances y las dudas que vayam surgiendo aquí, para que le sean de utilidad a otros que empiezan a programar para la wii como yo..

Estoy usando las librerías de Hermes.. quien quiera compilarlo solo tienen que seguir el curso de programación de Hermes:
viewtopic.php?f=6&t=94

y copiar el siguiente código en el ejemplo 2:

Código: Seleccionar todo
/* Example2: interaccion con las GX

Copyright (c) 2008 Hermes <www.entuwii.net>
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of
  conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
  of conditions and the following disclaimer in the documentation and/or other
  materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#define USE_MODPLAYER 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <ogcsys.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

#include <fat.h>
#include <fcntl.h>
#include "unistd.h"

#include "screen.h"

#include "asndlib.h"

#ifdef USE_MODPLAYER
// MOD Player
#include "gcmodplay.h"

MODPlay mod_track;

#include "hybris.h"

#endif



int return_reset=1;

int exit_by_reset=0;

void reset_call() {exit_by_reset=return_reset;}
void power_call() {exit_by_reset=3;}



void fun_exit()
{

   ASND_End();      // finaliza el sonido
   WPAD_Shutdown();
   Screen_flip();  // espera a que acabe el GX si está en uso
   fatUnmount(PI_INTERNAL_SD); // desmonta la partición de la SD
   usleep(500);   // espera 500 ms por si hay algo que esté trabajando todavía
   if(exit_by_reset==2)
      SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
   if(exit_by_reset==3)
      SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);

exit(0);
}

int tabla[81]; // tabla de alturas (usa 81 elementos para generar 80 lineas)
unsigned int Nave_x=320,Nave_y=130;      // Posicion Inicial de la Nave, por defecto 400,240


int main(int argc, char **argv)
{

int n,m;

int counter=0;

short Line_x1,Line_y1,Line_x2,Line_y2;
int  Modelo_Nave[24][4]= {
                           { -2,   7,  0,  10},
                           {  0,  10,  2,   7},
                           { -3, -10,  3, -10},
                           {  3, -10,  6,  -7},
                           {  6,  -7,  6,  -4},
                           {  6,  -4,  3,  -1},
                           { -3,  -1, -6,  -4},
                           { -6,  -4, -6,  -7},
                           { -6,  -7, -3, -10},
                           { -6,  -1,  6,  -1},
                           {  6,  -1,  6,   4},
                           {  6,   1,  8,   7},
                           {  4,   4,  8,   7},
                           {  8,   7,  8,  10},
                           {  6,  10, 10,  10},
                           {  6,   4, -6,   4},
                           { -6,  -1, -6,   4},
                           { -6,   1, -8,   7},
                           { -4,   4, -8,   7},
                           { -8,   7, -8,  10},
                           {-10,  10, -6,  10},
                           {  0,   4,  2,   7},
                           {  0,   4, -2,   7},
                           { -2,   7,  2,   7}
                          };             // Diseño de la Nave
   

gforce_t gforce;
float Angulo=0;
float   Zoom=2;


   return_reset=1;                  // esto sirve para elegir el tipo de retorno en caso de pulsar RESET (1-> Homebrew Browser, 2->RESET)
   if(argc<1) return_reset=2;
   InitScreen();                       // Inicialización del Vídeo.
   SYS_SetResetCallback(reset_call);   // fija la callback para el boton RESET
   SYS_SetPowerCallback(power_call);   // fija la callback para el boton POWER


   ASND_Init();                  // Inicializa la librería de sonido
   
   WPAD_Init();                        // Inicializa el lector de pad
   WPAD_SetDataFormat(0,WPAD_FMT_BTNS_ACC_IR);
   WPAD_SetVRes(0,640,480);


   fatInit(8, false);               // Inicializa la libreria FAT
    fatSetDefaultInterface(PI_INTERNAL_SD); // fija el device "fat:" a la SD

   atexit(fun_exit);               // fija la funcion de salida (aqui se finaliza el uso de dispositivos, etc: usa exit(0); para salir del programa)
   
   ASND_Pause(0);                  // Pausa de sonido global a 0

    tabla[0]=SCR_HEIGHT;

    for(n=1;n<80;n++)
      {
      m=((rand() & 0x3f00)>>8)-32;
      if(m>-8 && m<8) m=0; // para generar planicies
      tabla[n]=tabla[n-1]+m;
      if(tabla[n]>SCR_HEIGHT) tabla[n]-=m*2;   // limite de altura
      if(tabla[n]<60) tabla[n]-=m*2;         // limite de altura
      }
   tabla[n]=tabla[n-1];


   // inicializa el modplayer en modo loop infinito
   MODPlay_Init(&mod_track);


   if (MODPlay_SetMOD (&mod_track, hybris ) < 0 ) // set the MOD song
      {
      MODPlay_Unload (&mod_track);   
      }
   else 
      {
      MODPlay_SetVolume( &mod_track, 32,32); // fix the volume to 32 (max 64)
      MODPlay_Start (&mod_track); // Play the MOD
      }


   while(1)                     // bucle principal
      {
      if(exit_by_reset) exit(0);                           // comprueba si se han pulsado RESET o POWER y sal si es asi
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);      // comprueba si se han pulsado Home en wiimote 1 y sal si es asi

      
      // dibujado de la caja

      SetTexture(NULL);

      DrawRoundFillBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 0xffafafaf); // dibuja una caja solida
      DrawRoundBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 4, 0xff00ffff); // dibuja el perimetro de la caja con borde de grosor 4
      
      letter_size(8,32); // tamaño de letra 16x64
      PX= 0; PY= 18; color= 0xff000000; bkcolor=0;
      
      SelectFontTexture(0); // selecciona font principal

      autocenter=1; // autocentrado on
      s_printf("Wiilander");
      autocenter=0;
      
      
      // configura para usar color con GX_Begin (funcion de dibujado de poligonos de GX)
      ConfigureForColor();
      
//      #if 1

      GX_Begin(GX_LINES, GX_VTXFMT0, 80*4*2); // dibuja 80*4 lineas (en matriz de 2x2) * 2 vertices
      for(n=0;n<80;n++)
         {
         AddColorVertex(n*8, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)

         AddColorVertex((n+1)*8,tabla[n+1], 1, 0xffff9000); // segundo vertice

         AddColorVertex(n*8+1, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)

         AddColorVertex((n+1)*8+1,tabla[n+1], 1, 0xffff9000); // segundo vertice
         
         AddColorVertex(n*8, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         
         AddColorVertex((n+1)*8,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
         
         AddColorVertex(n*8+1, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         
         AddColorVertex((n+1)*8+1,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
         }

      GX_End();

//
//





      WPAD_ScanPads();                  //Lee todos los mandos
      WPAD_GForce(0, &gforce);            //Lee la aceleracion del mando 1
         

      Angulo=3.1492*gforce.y;
            
      // Dibuja la Nave
            
      GX_Begin(GX_LINES, GX_VTXFMT0, 23*2); // dibuja  Nave  23x2
      for(n=0;n<23;n++)
         {
         Line_x1=Nave_x+Modelo_Nave[n][0]*cos(Angulo)/Zoom+Modelo_Nave[n][1]*sin(Angulo)/Zoom;
         Line_y1=Nave_y-Modelo_Nave[n][0]*sin(Angulo)/Zoom+Modelo_Nave[n][1]*cos(Angulo)/Zoom;
         Line_x2=Nave_x+Modelo_Nave[n][2]*cos(Angulo)/Zoom+Modelo_Nave[n][3]*sin(Angulo)/Zoom;
         Line_y2=Nave_y-Modelo_Nave[n][2]*sin(Angulo)/Zoom+Modelo_Nave[n][3]*cos(Angulo)/Zoom;
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }

      GX_End();





//      #else
//      // utiliza quads para hacer montañas solidas
//
//      GX_Begin(GX_QUADS, GX_VTXFMT0, 80*4); // dibuja 80 quads (4 vertices)
//
//      for(n=0;n<80;n++)
//         {
//         AddColorVertex(n*8, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//
//         AddColorVertex((n+1)*8,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         
//         AddColorVertex((n+1)*8, SCR_HEIGHT, 1, 0xffff9000); // tercer vertice
//
//         AddColorVertex(n*8, SCR_HEIGHT, 1, 0xffff9000);  // cuarto vertice
//         }
//         
//
//      GX_End();
//      #endif
      
      



      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) {
      Zoom=1;
      }

      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) {
      Zoom=2;
      }




      // scroll y actualizacion del mapa de alturas

      for(n=0;n<80;n++)
         {
         tabla[n]=tabla[n+1];
         }
      m=((rand() & 0x3f00)>>8)-32;

      if(m>-8 && m<8) m=0; // para generar planicies

      tabla[n]=tabla[n-1]+m;
      if(tabla[n]>SCR_HEIGHT) tabla[n]-=m*2; // limite de altura
      if(tabla[n]<50) tabla[n]-=m*2;         // limite de altura

      // borra e intercambia la pantalla, espera al retrazado vertical
      Screen_flip();
      counter++;
      }

exit(0);

}




Pulsando en el wiimote HOME se vuelve al HC, y con + y menos cambiamos el zoom.


Salu2
manny
 
Mensajes: 22
Registrado: Lunes, 1 de Diciembre de 2008 00:03

Re: Wiilander

Notapor manny » Martes, 23 de Diciembre de 2008 14:36

Detección de colisiones:

Hermes escribió:Bueno, a lo mejor te puedo echar una manita.

Veamos, tal y como yo lo veo, lo mejor sería generar el terreno montañoso por completo en una tabla mas grande como mapa de altura: así te sería mas fácil posicionar y manejar un número fijo de líneas en pantalla, puesto que sería dibujar siempre el mismo número dentro de un rango. Además, no hay ninguna regla escrita que diga que no puedas trabajar por lotes (por ejemplo dibujar 16 lineas si hay mas o igual 16 y cerrar finalmente con un "paquete" entre 1 a 15 caso de quedar un pico). Hacer este tipo de comprobaciones es sumamente sencillo.


Por otro lado, en el tema de las colisiones, pues teniendo en cuenta que la idea es aterrizar una nave y determinar si la nave se posa correctamente (con las patas) o colisiona con el suelo y todo el tema, yo creo que lo mejor es utilizar puntos de control.

Imaginemos un punto con unas coordenadas X, Y y una linea comprendida entre A y B que representa esa cresta de la "montaña". El pie de la montaña sería la parte de abajo de la pantalla, cuyo límite inferior es SCR_HEIGHT (realmente uno menos, pero importa un carajo en este caso :lol:)

Pues bien, si queremos comprobar la colisión, tendríamos que conocer si el punto queda por encima, o por debajo de la montaña. Es decir si la Y de nuestro punto de control es igual o mayor a un punto de cruce con la línea comprendida entre A y B, es que el punto está colisionando.

Así que lo primero que vamos a hacer, es comprobar si la línea se siente atraída sexualmente por el punto :lol:. Para ello, vamos a comprobar la X.

Imaginemos que Ax es menor que Bx, lo cual sucede teniendo en cuenta que usamos un mapa de altura donde programamos el paso X con un valor fijo (que en mi ejemplo, vamos incrementando de izquierda a derecha con la cantidad de 8). Pues bien, si pillamos la X de nuestro punto, resulta que: Si X>=Ax && X<=Bx) hay atracción sexual. Con esto sabemos que en esa dimensión X, el punto puede pertenecer a la línea. Si no hay atracción sexual, ya sabemos que nuestro punto de control no está colisionando con el terreno representado por esa línea directamente.

En caso de que "se gusten" nos queda por determinar si Y pertenece o queda por debajo de esa línea para saber si hay o no sexo ésta noche ¿como lo podemos averiguar? Pues muy sencillo: ¿te acuerdas de la regla de tres?

Pues teniendo en cuenta que X pertenece a la linea (cosa que sabemos al comprobar la atracción sexual) solo tenemos que averiguar que valor Y le corresponde a ese valor X en la línea.

Teniendo en cuenta que Ax<=Bx y que si hay atracción sexual, Ax<=X:

Factor=(X-Ax)/(Bx-Ax); // restamos Ax para referenciar a 0 y así obtener un factor de distancia

Aquí tenemos que cuidar dos cosas: comprobar que Bx-Ax no es igual a 0. Si lo es, en este caso podríamos mirar cual de los dos valores Ay o By es menor y tomarlo como resultado final. Podriamos asignarlo a la variable Yr (Y relativa)

Y por otro lado, si la división es de enteros, nuestro factor no sirve pues el valor devuelto, estará comprendido entre 0 y 1. Puedes hacer dos cosas: pasar a float o multiplicar por un factor de escala, para provocar lo que se conoce cómo coma fija.

Imaginemos que lo usamos como float, para no liarnos:

float Factor=((float) (X-Ax)) / ((float) (Bx-Ax));


Pues bien, nuestra Y relativa, sería: Yr= ((int) (((float) (By-Ay))*Factor))+Ay;

Nota como restamos Ay a By, para obtener la referencia a 0 y después de multiplicar por el factor, sumamos Ay para volver a la referencia original.

Vale ¿Y ahora que? Pues que si la Y de nuestro punto de control, es mayor o igual que Yr, el punto está colisionando, puesto que está entre la cresta y el pié de la montaña (teniendo en cuenta la representación en pantalla que estamos usando, obviamente)

La idea entonces sería utilizar varios puntos de control para cubrir los pies de la nave y rodeándola, para determinar si aterrizamos correcta o incorrectamente y como el filtro sexual X>=Ax && X<=Bx es muy rápido y como mucho afectaría a 3 líneas, pues no tienes porque tener problemas al comprobar unos cuantos.



El que estoy usando, en vez de usar puntos de control, busca cruces entre lineas es poco poco eficiente... pero no se le escapa nada. . ya que verifico en un bucle que ninguna linea de la nave, toca ninguna linea del mapa, funciona perfecto para las lineas con angulo, pero para las lineas paralelas .. nada de na.. este es el código (que saque de san google).. luego lo cuelgo completo funcionando con el mapa.

Código: Seleccionar todo
// funcion lineCollide detecta si dos lineas AB BC se tocan.

int lineCollide(float ax,float ay, float bx, float by, float cx, float cy, float dx, float dy)
   {
      float tarray[4][2]; //<===== Find the inner bounding of rect ABCD
      if (ax<bx){
               tarray[0][0]=ax;
               tarray[1][0]=bx;
      } else {
               tarray[0][0]=bx;
               tarray[1][0]=ax;
               }
      if (ay<by){
               tarray[0][1]=ay;
               tarray[1][1]=by;
      } else {
               tarray[0][1]=by;
               tarray[1][1]=ay;
   }
      if (cx<dx){
               tarray[2][0]=cx;
               tarray[3][0]=dx;
      } else {
               tarray[2][0]=dx;
               tarray[3][0]=cx;
   }

      if (cy<dy){
               tarray[2][1]=cy;
               tarray[3][1]=dy;
      } else {
               tarray[2][1]=dy;
               tarray[3][1]=cy;
      }

   float tarray2[2][2]; //<===== Sort Section Two

      if (tarray[0][0]<tarray[2][0]) { tarray2[0][0]=tarray[2][0]; }else{ tarray2[0][0]=tarray[0][0]; } //biggest of the small ones
      if (tarray[0][1]<tarray[2][1]) { tarray2[0][1]=tarray[2][1]; }else{ tarray2[0][1]=tarray[0][1]; } //biggest of the small ones
      if (tarray[1][0]<tarray[3][0]) { tarray2[1][0]=tarray[1][0]; }else{ tarray2[1][0]=tarray[3][0]; } //biggest of the small ones
      if (tarray[1][1]<tarray[3][1]) { tarray2[1][1]=tarray[1][1]; }else{ tarray2[1][1]=tarray[3][1]; } //biggest of the small ones
      float mab=(ay-by)/(ax-bx); //<===== Find Slopes of Lines
      float mcd=(cy-dy)/(cx-dx);
      if (mab==mcd) return 0; //the lines are paralell
      float yiab=((ax-bx)*ay-ax*(ay-by))/(ax-bx); //<===== Find the y Intercept of Lines
      float yicd=((cx-dx)*cy-cx*(cy-dy))/(cx-dx);
      float x=(yicd-yiab)/(mab-mcd); //<===== Find the Intersection Points of the Line
      float y=mab*x+yiab;
      if (x>tarray2[0][0] && x<tarray2[1][0] && y>tarray2[0][1] && y<tarray2[1][1]) { return 1; }else{ return 0; }
         }





Gracias,

Manny
manny
 
Mensajes: 22
Registrado: Lunes, 1 de Diciembre de 2008 00:03

Re: Wiilander

Notapor manny » Miércoles, 24 de Diciembre de 2008 02:22

Bueno en esta versión he limpiado un pelin el código, y dibujo el mapa del juego en vez del del ejemplo de Hermes con scroll.. lo malo es que al hacer el zoom (pulsando la tecla +) no funciona.. :( me sale algo muy curioso como si no se aplicara el zoom a todos los valores solo a los negativos..)... a ver si alguien lo ve y me da alguna pista..


Código: Seleccionar todo
/* Example2: interaccion con las GX

Copyright (c) 2008 Hermes <www.entuwii.net>
Copyright (c) 2008 Manny
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of
  conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
  of conditions and the following disclaimer in the documentation and/or other
  materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#define USE_MODPLAYER 1

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <ogcsys.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

#include <fat.h>
#include <fcntl.h>
#include "unistd.h"

#include "screen.h"

#include "asndlib.h"

#ifdef USE_MODPLAYER
// MOD Player
#include "gcmodplay.h"

MODPlay mod_track;

#include "hybris.h"

#endif



int return_reset=1;

int exit_by_reset=0;

void reset_call() {exit_by_reset=return_reset;}
void power_call() {exit_by_reset=3;}



void fun_exit()
{

   ASND_End();      // finaliza el sonido
   WPAD_Shutdown();
   Screen_flip();  // espera a que acabe el GX si está en uso
   fatUnmount(PI_INTERNAL_SD); // desmonta la partición de la SD
   usleep(500);   // espera 500 ms por si hay algo que esté trabajando todavía
   if(exit_by_reset==2)
      SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
   if(exit_by_reset==3)
      SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);

exit(0);
}

int Nave_x=320,Nave_y=130;      // Posicion Inicial de la Nave, por defecto 400,240


int main(int argc, char **argv)
{

int n;


short Line_x1,Line_y1,Line_x2,Line_y2;
int  Modelo_Nave[24][4]= {
                           { -2,   7,  0,  10},
                           {  0,  10,  2,   7},
                           { -3, -10,  3, -10},
                           {  3, -10,  6,  -7},
                           {  6,  -7,  6,  -4},
                           {  6,  -4,  3,  -1},
                           { -3,  -1, -6,  -4},
                           { -6,  -4, -6,  -7},
                           { -6,  -7, -3, -10},
                           { -6,  -1,  6,  -1},
                           {  6,  -1,  6,   4},
                           {  6,   1,  8,   7},
                           {  4,   4,  8,   7},
                           {  8,   7,  8,  10},
                           {  6,  10, 10,  10},
                           {  6,   4, -6,   4},
                           { -6,  -1, -6,   4},
                           { -6,   1, -8,   7},
                           { -4,   4, -8,   7},
                           { -8,   7, -8,  10},
                           {-10,  10, -6,  10},
                           {  0,   4,  2,   7},
                           {  0,   4, -2,   7},
                           { -2,   7,  2,   7}
                          };             // Diseño de la Nave
   



int Mapa[66][4];                     // Mapa que se puede dibujar
int lineas_mapa;                     // Numero de lineas del mapa que se pueden dibujar



// Mapa Fase 1 la tabla define las lineas, que forman el mapa (posicion X1, altura1, posicion x2, altura2)
int  Mapa_Fase1[66][4]= {
{  -320,  245,  -305,  240}, 
{  -305,  240,  -295,  230}, 
{  -295,  230,  -290,  225}, 
{  -290,  225,  -275,  215}, 
{  -275,  215,  -270,  205}, 
{  -270,  205,  -265,  190}, 
{  -265,  190,  -255,  185}, 
{  -255,  185,  -245,  185}, 
{  -245,  185,  -230,  190}, 
{  -230,  190,  -225,  200}, 
{  -225,  200,  -210,  180}, 
{  -210,  180,  -205,  205}, 
{  -205,  205,  -195,  220}, 
{  -195,  220,  -185,  220}, 
{  -185,  220,  -180,  215}, 
{  -180,  215,  -175,  195}, 
{  -175,  195,  -165,  190}, 
{  -165,  190,  -155,  180}, 
{  -155,  180,  -145,  175}, 
{  -145,  175,  -140,  155}, 
{  -140,  155,  -135,  150}, 
{  -135,  150,  -125,  140}, 
{  -125,  140,  -115,  115}, 
{  -115,  115,  -110,  85}, 
{  -110,  85,  -105,  70}, 
{  -105,  70,  -90,  55}, 
{  -90,  55,  -75,  50}, 
{  -75,  50,  -70,  45}, 
{  -70,  45,  -60,  45}, 
{  -60,  45,  -50,  55}, 
{  -50,  55,  -45,  70}, 
{  -45,  70,  -55,  85}, 
{  -55,  85,  -60,  100}, 
{  -60,  100,  -50,  125}, 
{  -50,  125,  -35,  135}, 
{  -35,  135,  -25,  155}, 
{  -25,  155,  -10,  160}, 
{  -10,  160,  5,  140}, 
{  5,  140,  10,  115}, 
{  10,  115,  5,  95}, 
{  5,  95,  20,  80}, 
{  20,  80,  30,  50}, 
{  30,  50,  45,  45}, 
{  45,  45,  55,  45}, 
{  55,  45,  65,  115}, 
{  65,  115,  75,  130}, 
{  75,  130,  85,  105}, 
{  85,  105,  105,  80}, 
{  105,  80,  120,  35}, 
{  120,  35,  140,  25}, 
{  140,  25,  150,  25}, 
{  150,  25,  160,  60}, 
{  160,  60,  190,  145}, 
{  190,  145,  205,  45}, 
{  205,  45,  220,  30}, 
{  220,  30,  235,  10}, 
{  235,  10,  245,  5}, 
{  245,  5,  255,  5}, 
{  255,  5,  260,  25}, 
{  260,  25,  275,  205}, 
{  275,  205,  290,  275}, 
{  290,  275,  300,  195}, 
{  300,  195,  305,  190}, 
{  305,  190,  315,  190}, 
{  315,  190,  320,  245}, 
                  };             // Mapa Fase 1


gforce_t gforce;
float Angulo=0;
float   Zoom=1;


   return_reset=1;                  // esto sirve para elegir el tipo de retorno en caso de pulsar RESET (1-> Homebrew Browser, 2->RESET)
   if(argc<1) return_reset=2;
   InitScreen();                       // Inicialización del Vídeo.
   SYS_SetResetCallback(reset_call);   // fija la callback para el boton RESET
   SYS_SetPowerCallback(power_call);   // fija la callback para el boton POWER


   ASND_Init();                  // Inicializa la librería de sonido
   
   WPAD_Init();                        // Inicializa el lector de pad
   WPAD_SetDataFormat(0,WPAD_FMT_BTNS_ACC_IR);
   WPAD_SetVRes(0,640,480);


   fatInit(8, false);               // Inicializa la libreria FAT
    fatSetDefaultInterface(PI_INTERNAL_SD); // fija el device "fat:" a la SD

   atexit(fun_exit);               // fija la funcion de salida (aqui se finaliza el uso de dispositivos, etc: usa exit(0); para salir del programa)
   
   ASND_Pause(0);                  // Pausa de sonido global a 0


   // inicializa el modplayer en modo loop infinito
   MODPlay_Init(&mod_track);


   if (MODPlay_SetMOD (&mod_track, hybris ) < 0 ) // set the MOD song
      {
      MODPlay_Unload (&mod_track);   
      }
   else 
      {
      MODPlay_SetVolume( &mod_track, 32,32); // fix the volume to 32 (max 64)
      MODPlay_Start (&mod_track); // Play the MOD
      }


   while(1)                     // bucle principal
      {
      if(exit_by_reset) exit(0);                           // comprueba si se han pulsado RESET o POWER y sal si es asi
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);      // comprueba si se han pulsado Home en wiimote 1 y sal si es asi

      
      // dibujado de la caja

      SetTexture(NULL);

      DrawRoundFillBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 0xffafafaf); // dibuja una caja solida
      DrawRoundBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 4, 0xff00ffff); // dibuja el perimetro de la caja con borde de grosor 4
      
      letter_size(8,32); // tamaño de letra 16x64
      PX= 0; PY= 18; color= 0xff000000; bkcolor=0;
      
      SelectFontTexture(0); // selecciona font principal

      autocenter=1; // autocentrado on
      s_printf("Wiilander %d %d\n",SCR_WIDTH,SCR_HEIGHT);
      autocenter=0;
      
      
      // configura para usar color con GX_Begin (funcion de dibujado de poligonos de GX)
      ConfigureForColor();
      
//      #if 1
//      GX_Begin(GX_LINES, GX_VTXFMT0, 80*4*2); // dibuja 80*4 lineas (en matriz de 2x2) * 2 vertices
//      for(n=0;n<80;n++)
//         {
//         AddColorVertex(n*8, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         }
//      GX_End();
//
//



      WPAD_ScanPads();                  //Lee todos los mandos
      WPAD_GForce(0, &gforce);            //Lee la aceleracion del mando 1
         

      Angulo=3.1492*gforce.y;
            

      // Dibuja la Nave
      GX_Begin(GX_LINES, GX_VTXFMT0, 23*2); // dibuja  Nave  23x2
      for(n=0;n<23;n++)
         {
         Line_x1=Nave_x+Modelo_Nave[n][0]*cos(Angulo)*Zoom+Modelo_Nave[n][1]*sin(Angulo)*Zoom;
         Line_y1=Nave_y-Modelo_Nave[n][0]*sin(Angulo)*Zoom+Modelo_Nave[n][1]*cos(Angulo)*Zoom;
         Line_x2=Nave_x+Modelo_Nave[n][2]*cos(Angulo)*Zoom+Modelo_Nave[n][3]*sin(Angulo)*Zoom;
         Line_y2=Nave_y-Modelo_Nave[n][2]*sin(Angulo)*Zoom+Modelo_Nave[n][3]*cos(Angulo)*Zoom;
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();



      // Dibuja el Mapa
      // Creamos una Tabla con el mapa que se puede dibujar, es decir que esta X ( 0:640) e y (0:480)
      
      lineas_mapa=0;
      for(n=0;n<65;n++)
         {
            Line_x1=(Zoom*Mapa_Fase1[n][0])+320;
            Line_y1=SCR_HEIGHT-(Zoom*Mapa_Fase1[n][1]);
            Line_x2=(Zoom*Mapa_Fase1[n][2])+320;
            Line_y2=SCR_HEIGHT-(Zoom*Mapa_Fase1[n][3]);
            if ((Line_x1>-1 && Line_x1<SCR_WIDTH) && (Line_x2>-1 && Line_x2<SCR_WIDTH) && (Line_y1>-1 && Line_y1<SCR_HEIGHT) && (Line_y2>-1 && Line_y2<SCR_HEIGHT)) {
               lineas_mapa++;
               Mapa[n][0]=Line_x1;
               Mapa[n][1]=Line_y1;
               Mapa[n][2]=Line_x2;
               Mapa[n][3]=Line_y2;
                              }
         }
      
      
      GX_Begin(GX_LINES, GX_VTXFMT0, lineas_mapa*2); // dibuja  mapa
      for(n=0;n<lineas_mapa;n++)
         {
         Line_x1=Mapa[n][0];
         Line_y1=Mapa[n][1];
         Line_x2=Mapa[n][2];
         Line_y2=Mapa[n][3];
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();
         
   
      
         

      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) {
      Zoom=2;
      }
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) {
      Zoom=1;
      }

      // borra e intercambia la pantalla, espera al retrazado vertical
      Screen_flip();
      }

exit(0);

}




GRACIAS
manny
 
Mensajes: 22
Registrado: Lunes, 1 de Diciembre de 2008 00:03

Re: Wiilander

Notapor manny » Miércoles, 24 de Diciembre de 2008 18:19

Bueno .. ya esta arreglado lo del zoom.. era una chorrada.. la tabla que se alimentaba con los vértices que si están dentro de pantalla, tenia el indice mal...
Código: Seleccionar todo
               Mapa[n][0]=Line_x1;  >>correcto>> Mapa[lineas_mapa][0]=Line_x1;
               Mapa[n][1]=Line_y1;  >>correcto>> Mapa[lineas_mapa][1]=Line_y1;
               Mapa[n][2]=Line_x2;  >>correcto>> Mapa[lineas_mapa][2]=Line_x2;
               Mapa[n][3]=Line_y2;  >>correcto>> Mapa[lineas_mapa][3]=Line_y2;


Aquí esta la última versión con gestión de tiempo, y con control de la nave.. ya se puede navegar por todo el mapa, con el wiimote en posición vertical, le damos angulo a la nave inclinandolo hacia los lados, y si realizamos una torsión hacia delante, le damos aceleración.. el zoom por ahora se sigue controlando de forma manual, pulsando las teclas + y -

Código: Seleccionar todo
/* Example2: interaccion con las GX

Copyright (c) 2008 Hermes <www.entuwii.net>
Copyright (c) 2008 Manny
All rights reserved.

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of
  conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
  of conditions and the following disclaimer in the documentation and/or other
  materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#define USE_MODPLAYER 1

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <ogcsys.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

#include <fat.h>
#include <fcntl.h>
#include "unistd.h"
#include <ogc/lwp_watchdog.h>

#include "screen.h"

#include "asndlib.h"

#ifdef USE_MODPLAYER
// MOD Player
#include "gcmodplay.h"

MODPlay mod_track;

#include "hybris.h"

#endif






// Gestion de tiempo.  funciones para crear una pausa de x milisegundos
u64 ini_milisegundos, fin_milisegundos, frametime;

void ResetTimeBase() {
  ini_milisegundos=ticks_to_millisecs(gettime());
}

int CurrentTime() {
  fin_milisegundos=ticks_to_millisecs(gettime());
  return fin_milisegundos-ini_milisegundos;
}



// Gestion de salida
int return_reset=1;
int exit_by_reset=0;

void reset_call() {exit_by_reset=return_reset;}
void power_call() {exit_by_reset=3;}

void fun_exit()
{
   ASND_End();      // finaliza el sonido
   WPAD_Shutdown();
   Screen_flip();  // espera a que acabe el GX si está en uso
   fatUnmount(PI_INTERNAL_SD); // desmonta la partición de la SD
   usleep(500);   // espera 500 ms por si hay algo que esté trabajando todavía
   if(exit_by_reset==2)
      SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
   if(exit_by_reset==3)
      SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);

exit(0);

}

// Informacion de graficos
int  Modelo_Nave[24][4]= {
                           { -2,   7,  0,  10},
                           {  0,  10,  2,   7},
                           { -3, -10,  3, -10},
                           {  3, -10,  6,  -7},
                           {  6,  -7,  6,  -4},
                           {  6,  -4,  3,  -1},
                           { -3,  -1, -6,  -4},
                           { -6,  -4, -6,  -7},
                           { -6,  -7, -3, -10},
                           { -6,  -1,  6,  -1},
                           {  6,  -1,  6,   4},
                           {  6,   1,  8,   7},
                           {  4,   4,  8,   7},
                           {  8,   7,  8,  10},
                           {  6,  10, 10,  10},
                           {  6,   4, -6,   4},
                           { -6,  -1, -6,   4},
                           { -6,   1, -8,   7},
                           { -4,   4, -8,   7},
                           { -8,   7, -8,  10},
                           {-10,  10, -6,  10},
                           {  0,   4,  2,   7},
                           {  0,   4, -2,   7},
                           { -2,   7,  2,   7}
                          };             // Diseño de la Nave
   


// Mapa Fase 1 la tabla define las lineas, que forman el mapa (posicion X1, altura1, posicion x2, altura2)
int  Mapa_Fase1[66][4]= {
{  -320,  245,  -305,  240}, 
{  -305,  240,  -295,  230}, 
{  -295,  230,  -290,  225}, 
{  -290,  225,  -275,  215}, 
{  -275,  215,  -270,  205}, 
{  -270,  205,  -265,  190}, 
{  -265,  190,  -255,  185}, 
{  -255,  185,  -245,  185}, 
{  -245,  185,  -230,  190}, 
{  -230,  190,  -225,  200}, 
{  -225,  200,  -210,  180}, 
{  -210,  180,  -205,  205}, 
{  -205,  205,  -195,  220}, 
{  -195,  220,  -185,  220}, 
{  -185,  220,  -180,  215}, 
{  -180,  215,  -175,  195}, 
{  -175,  195,  -165,  190}, 
{  -165,  190,  -155,  180}, 
{  -155,  180,  -145,  175}, 
{  -145,  175,  -140,  155}, 
{  -140,  155,  -135,  150}, 
{  -135,  150,  -125,  140}, 
{  -125,  140,  -115,  115}, 
{  -115,  115,  -110,  85}, 
{  -110,  85,  -105,  70}, 
{  -105,  70,  -90,  55}, 
{  -90,  55,  -75,  50}, 
{  -75,  50,  -70,  45}, 
{  -70,  45,  -60,  45}, 
{  -60,  45,  -50,  55}, 
{  -50,  55,  -45,  70}, 
{  -45,  70,  -55,  85}, 
{  -55,  85,  -60,  100}, 
{  -60,  100,  -50,  125}, 
{  -50,  125,  -35,  135}, 
{  -35,  135,  -25,  155}, 
{  -25,  155,  -10,  160}, 
{  -10,  160,  5,  140}, 
{  5,  140,  10,  115}, 
{  10,  115,  5,  95}, 
{  5,  95,  20,  80}, 
{  20,  80,  30,  50}, 
{  30,  50,  45,  45}, 
{  45,  45,  55,  45}, 
{  55,  45,  65,  115}, 
{  65,  115,  75,  130}, 
{  75,  130,  85,  105}, 
{  85,  105,  105,  80}, 
{  105,  80,  120,  35}, 
{  120,  35,  140,  25}, 
{  140,  25,  150,  25}, 
{  150,  25,  160,  60}, 
{  160,  60,  190,  145}, 
{  190,  145,  205,  45}, 
{  205,  45,  220,  30}, 
{  220,  30,  235,  10}, 
{  235,  10,  245,  5}, 
{  245,  5,  255,  5}, 
{  255,  5,  260,  25}, 
{  260,  25,  275,  205}, 
{  275,  205,  290,  275}, 
{  290,  275,  300,  195}, 
{  300,  195,  305,  190}, 
{  305,  190,  315,  190}, 
{  315,  190,  320,  245}, 
                  };             // Mapa Fase 1
 




int Nave_x=320,Nave_y=130;                  // Posicion Inicial de la Nave, por defecto 400,240
float Angulo=0;
int   Zoom=1;
float   Vx_init=0, Vy_init=0, Vx=0, Vy=0;      // control de velocidad
int    Fuel_Nave= 10000;                  // combstible de la nave
int    Potencia_Nave=12;                  // Potencia de los motores
float    G=3;                           // G
float    delta= 0.1;
float    Acx=0,Acy=0;                     // Aceleracion.
int   posx_init, posy_init;





int main(int argc, char **argv)
{

int n;


short Line_x1,Line_y1,Line_x2,Line_y2;



int Mapa[66][4];                     // Mapa que se puede dibujar
int lineas_mapa=0;                     // Numero de lineas del mapa que se pueden dibujar



gforce_t gforce;


   return_reset=1;                  // esto sirve para elegir el tipo de retorno en caso de pulsar RESET (1-> Homebrew Browser, 2->RESET)
   if(argc<1) return_reset=2;
   InitScreen();                       // Inicialización del Vídeo.
   SYS_SetResetCallback(reset_call);   // fija la callback para el boton RESET
   SYS_SetPowerCallback(power_call);   // fija la callback para el boton POWER


   ASND_Init();                  // Inicializa la librería de sonido
   
   WPAD_Init();                        // Inicializa el lector de pad
   WPAD_SetDataFormat(0,WPAD_FMT_BTNS_ACC_IR);
   WPAD_SetVRes(0,640,480);


   fatInit(8, false);               // Inicializa la libreria FAT
    fatSetDefaultInterface(PI_INTERNAL_SD); // fija el device "fat:" a la SD

   atexit(fun_exit);               // fija la funcion de salida (aqui se finaliza el uso de dispositivos, etc: usa exit(0); para salir del programa)
   
   ASND_Pause(0);                  // Pausa de sonido global a 0


   // inicializa el modplayer en modo loop infinito
   MODPlay_Init(&mod_track);


   if (MODPlay_SetMOD (&mod_track, hybris ) < 0 ) // set the MOD song
      {
      MODPlay_Unload (&mod_track);   
      }
   else 
      {
      MODPlay_SetVolume( &mod_track, 32,32); // fix the volume to 32 (max 64)
      MODPlay_Start (&mod_track); // Play the MOD
      }


   while(1)                     // bucle principal
      {
      ResetTimeBase();            //r

      if(exit_by_reset) exit(0);                           // comprueba si se han pulsado RESET o POWER y sal si es asi
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);      // comprueba si se han pulsado Home en wiimote 1 y sal si es asi
      
      // dibujado de la caja

      SetTexture(NULL);

      DrawRoundFillBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 0xffafafaf); // dibuja una caja solida
      DrawRoundBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 4, 0xff00ffff); // dibuja el perimetro de la caja con borde de grosor 4
      
      letter_size(8,32); // tamaño de letra 16x64
      PX= 0; PY= 18; color= 0xff000000; bkcolor=0;
      
      SelectFontTexture(0); // selecciona font principal

      autocenter=1; // autocentrado on
      s_printf("Wiilander %d %d %d\n",SCR_WIDTH,SCR_HEIGHT,lineas_mapa);
      autocenter=0;
      
      
      // configura para usar color con GX_Begin (funcion de dibujado de poligonos de GX)
      ConfigureForColor();
      
//      #if 1
//      GX_Begin(GX_LINES, GX_VTXFMT0, 80*4*2); // dibuja 80*4 lineas (en matriz de 2x2) * 2 vertices
//      for(n=0;n<80;n++)
//         {
//         AddColorVertex(n*8, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         }
//      GX_End();
//
//



      WPAD_ScanPads();                  //Lee todos los mandos
      WPAD_GForce(0, &gforce);            //Lee la aceleracion del mando 1
         

      

      // Calculo de cinematica
      
         Angulo=3.14159*gforce.y;
         
         Vx_init=Vx;
         Vy_init=Vy;
         
         
   if (Fuel_Nave>0){
      if (gforce.x>0){
         Fuel_Nave=Fuel_Nave-(gforce.x*Potencia_Nave);         
         
         Acx=sin(-Angulo)*gforce.x*Potencia_Nave;
         Acy=G-(cos(Angulo)*gforce.x*Potencia_Nave);
   }   else    {
         Acy=G;
            }   
      }
         
         Vx= (Acx*delta)+Vx_init;
         Vy= (Acy*delta)+Vy_init;

         posx_init=Nave_x;
         posy_init=Nave_y;

         Nave_x=(Vx*delta)+posx_init;
         Nave_y=(Vy*delta)+posy_init;





      // Dibuja la Nave
      GX_Begin(GX_LINES, GX_VTXFMT0, 23*2); // dibuja  Nave  23x2
      for(n=0;n<23;n++)
         {
         Line_x1=Nave_x+Modelo_Nave[n][0]*cos(Angulo)*Zoom/2+Modelo_Nave[n][1]*sin(Angulo)*Zoom/2;
         Line_y1=Nave_y-Modelo_Nave[n][0]*sin(Angulo)*Zoom/2+Modelo_Nave[n][1]*cos(Angulo)*Zoom/2;
         Line_x2=Nave_x+Modelo_Nave[n][2]*cos(Angulo)*Zoom/2+Modelo_Nave[n][3]*sin(Angulo)*Zoom/2;
         Line_y2=Nave_y-Modelo_Nave[n][2]*sin(Angulo)*Zoom/2+Modelo_Nave[n][3]*cos(Angulo)*Zoom/2;
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();



      // Dibuja el Mapa
      // Creamos una Tabla con el mapa que se puede dibujar, es decir que esta X ( 0:640) e y (0:480)
      
      lineas_mapa=0;
      for(n=0;n<65;n++)
         {
            Line_x1=(Zoom*Mapa_Fase1[n][0])+320;
            Line_y1=SCR_HEIGHT-(Zoom*Mapa_Fase1[n][1]);
            Line_x2=(Zoom*Mapa_Fase1[n][2])+320;
            Line_y2=SCR_HEIGHT-(Zoom*Mapa_Fase1[n][3]);
            if ((Line_x1>-1-50 && Line_x1<SCR_WIDTH+50) && (Line_x2>-1-50 && Line_x2<SCR_WIDTH+50) && (Line_y1>-1-50 && Line_y1<SCR_HEIGHT+50) && (Line_y2>-1-50 && Line_y2<SCR_HEIGHT+50)) {
               Mapa[lineas_mapa][0]=Line_x1;
               Mapa[lineas_mapa][1]=Line_y1;
               Mapa[lineas_mapa][2]=Line_x2;
               Mapa[lineas_mapa][3]=Line_y2;
               lineas_mapa++;
                              }
         }
      
      
      GX_Begin(GX_LINES, GX_VTXFMT0, lineas_mapa*2); // dibuja  mapa
      for(n=0;n<lineas_mapa;n++)
         {
         Line_x1=Mapa[n][0];
         Line_y1=Mapa[n][1];
         Line_x2=Mapa[n][2];
         Line_y2=Mapa[n][3];
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();
         
   
      
         

      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) {
      Zoom=2;
      }
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) {
      Zoom=1;
      }

      // borra e intercambia la pantalla, espera al retrazado vertical
      Screen_flip();
      
      
      // entra en un  bucle y no sale hasta que llegue a los 40 milisegundos
      do {
            frametime=CurrentTime();
         } while (frametime<40);
               
      }
   
exit(0);

}



Salu2,

Manny
manny
 
Mensajes: 22
Registrado: Lunes, 1 de Diciembre de 2008 00:03

Re: Wiilander

Notapor Hermes » Viernes, 26 de Diciembre de 2008 11:15

manny escribió:Bueno .. ya esta arreglado lo del zoom.. era una chorrada.. la tabla que se alimentaba con los vértices que si están dentro de pantalla, tenia el indice mal...


Me alegro de que lo hayas solucionado y de ver que le está metiendo caña :)

Dos cosas:

1) Perdona que no esté por aquí comentando, pero es que... bueno digamos que a mi me pasa lo contrario que a ti: estoy cansado del año, y que éste año he dedicado bastante tiempo a hacer cosas y en estos días no me apetece absolutamente nada programar, ni estar dándole vueltas al coco :lol: (estoy en esa fase de bajón y tierra de nadie de la que muchas veces he vuelto haciendo algo interesante :lol: ). De hecho, he dejado muchas cosas en el tintero a causa de mi desgana y espero que lo sepáis comprender ;)

En cambio a ti seguro que te pasa lo contrario: que ahora es cuando puedes aprovechar para hacer cosas y vas lanzado a por ello. Por cierto el marika del marcan no aparece por ningún lado y no lo he visto ni en el MSN y ya no creo que le vea este año (porque se va a Alemania con sus amiguitos juakers del Continente a dar una conferencia).

2) Sobre los ejemplos de mi cursillo y el tema de las licencias: La licencia que incluyo, es valida para esos ejemplos y restringida a esos ejemplos, pero vosotros podéis modificaros y añadirles la licencia que queráis, sin problemas y no es necesario que en éste caso, me añadáis como coautor o autor originario si construis un programa partiendo de uno de esos ejemplos.

Si queréis mencionarme como muestra de agradecimiento, adelante, pero la intención de los ejemplos es mostraros un poco el camino de cómo hacer ciertas cosas, no supeditar vuestro trabajo al mío, ni que parezca que yo he intervenido en la creación de vuestro programa.

Esa "gloria" es vuestra y la intención es que vosotros brilléis por vuestra cuenta y no al contrario.

Es decir: si alguien modifica la screenlib o un programa mío (Guitarfun, Wiireader, Wiiengine), en ese caso, ésto es correcto:

Copyright (c) 2008 Hermes <www.entuwii.net>
Copyright (c) 2008 Manny
All rights reserved.


Porque el autor originario soy yo y Manny puede haber introducido algunos cambios a la librería/programas y es coautor.

Pero si te basas en uno de mis ejemplos para hacer un programa, ésto es "ofensivo":

Copyright (c) 2008 Hermes <www.entuwii.net>
Copyright (c) 2008 Manny
All rights reserved.


Por que da a entender que Hermes es el creador de VUESTRO programa y no es así: yo solo os muestro como hacerlo, una especie de tutorial en forma de programa que podéis usar como base y ya está.

Si lo pones así:

Copyright (c) 2008 Manny
Copyright (c) 2008 Hermes <www.entuwii.net>
All rights reserved.


Parece que Manny hizo el programa y yo lo modifiqué y que por tanto, parte de los derechos ("gloria") es mía :lol:

Queda mejor:

Copyright (c) 2008 Manny
All rights reserved.


o eso con una cita de agradecimiento por mi ayuda, si queréis.

Y en éste caso, yo no me voy a sentir ofendido de forma alguna, porque vuestro trabajo no "continúa" el mio, si no que es algo nuevo que comparte unos cuantos procedimientos "chorras" que os he enseñado en esos ejemplos, para que VOSOTROS publiquéis vuestros trabajos. El programa es de Manny y no mío y tiene derecho a todo el reconocimiento por él, aunque yo pueda haber contribuido a facilitarle las cosas en forma de librería y enseñar cuatro "chorradas". ¿OK? ;)

Yo estaré orgulloso sabiendo que hay gente que utiliza la screenlib (que lleva mi (c) ) para hacer un programa o la asndlib (que también lleva mi (c) ) y que mi cursillo contribuye a que otra gente derribe las barreras que le separa de hacer cosas interesantes en Wii ¿Que más puedo pedir? :lol:

Saludos.
Hermes
Sargento Moderador
 
Mensajes: 130
Registrado: Lunes, 26 de Mayo de 2008 19:41

Re: Wiilander

Notapor manny » Viernes, 26 de Diciembre de 2008 19:07

Hermes, gracias por la aclaración y animo, que la inspiración ya sabes que tiene altibajos.. y la Navidad, no es precisamente la época mas alegre para todo el mundo.. yo tengo que aprovechar ahora que puedo, además ya sabes como son las cosas en mundo de la programación de estas cosillas, suele ser binario.. o le das caña.. o lo dejas abandonado 'sine die'..

La versión anterior tenia un pequeño descuadre en la posición de la nave, cuando se hacia el zoom, en esta ya esta corregido, para el siguiente post espero añadir, detección de colisiones, y scroll horizontal.

Código: Seleccionar todo
/* Wiilander

Copyright (c) 2008 Manny
All rights reserved.
http://www.entuwii.net/foro/viewtopic.php?f=14&t=102

Use the fantastic ;) screenlib, library  Copyright (c) 2008 Hermes, and the wii programation training from Hermes:
http://www.entuwii.net/foro/viewtopic.php?f=6&t=94

Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of
  conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
  of conditions and the following disclaimer in the documentation and/or other
  materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#define USE_MODPLAYER 1

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <ogcsys.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

#include <fat.h>
#include <fcntl.h>
#include "unistd.h"
#include <ogc/lwp_watchdog.h>

#include "screen.h"

#include "asndlib.h"

#ifdef USE_MODPLAYER
// MOD Player
#include "gcmodplay.h"

MODPlay mod_track;

#include "hybris.h"

#endif






// Gestion de tiempo.  funciones para crear una pausa de x milisegundos
u64 ini_milisegundos, fin_milisegundos, frametime;

void ResetTimeBase() {
  ini_milisegundos=ticks_to_millisecs(gettime());
}

int CurrentTime() {
  fin_milisegundos=ticks_to_millisecs(gettime());
  return fin_milisegundos-ini_milisegundos;
}



// Gestion de salida
int return_reset=1;
int exit_by_reset=0;

void reset_call() {exit_by_reset=return_reset;}
void power_call() {exit_by_reset=3;}

void fun_exit()
{
   ASND_End();      // finaliza el sonido
   WPAD_Shutdown();
   Screen_flip();  // espera a que acabe el GX si está en uso
   fatUnmount(PI_INTERNAL_SD); // desmonta la partición de la SD
   usleep(500);   // espera 500 ms por si hay algo que esté trabajando todavía
   if(exit_by_reset==2)
      SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
   if(exit_by_reset==3)
      SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);

exit(0);

}

// Informacion de graficos

// El modelo de la nave esta refenciado en coordenadas 0.0 (es decir 0.0 es el centro de la nave) lo hago asi para poder aplicar los zooms,
// y la trigonometria necesaria para girar la nave.

int  Modelo_Nave[24][4]= {
                           { -2,   7,  0,  10},
                           {  0,  10,  2,   7},
                           { -3, -10,  3, -10},
                           {  3, -10,  6,  -7},
                           {  6,  -7,  6,  -4},
                           {  6,  -4,  3,  -1},
                           { -3,  -1, -6,  -4},
                           { -6,  -4, -6,  -7},
                           { -6,  -7, -3, -10},
                           { -6,  -1,  6,  -1},
                           {  6,  -1,  6,   4},
                           {  6,   1,  8,   7},
                           {  4,   4,  8,   7},
                           {  8,   7,  8,  10},
                           {  6,  10, 10,  10},
                           {  6,   4, -6,   4},
                           { -6,  -1, -6,   4},
                           { -6,   1, -8,   7},
                           { -4,   4, -8,   7},
                           { -8,   7, -8,  10},
                           {-10,  10, -6,  10},
                           {  0,   4,  2,   7},
                           {  0,   4, -2,   7},
                           { -2,   7,  2,   7}
                          };             // Diseño de la Nave
   


// Mapa Fase 1 la tabla define las lineas, que forman el mapa (posicion X1, altura1, posicion x2, altura2)
int  Mapa_Fase1[66][4]= {
{  -320,  245,  -305,  240}, 
{  -305,  240,  -295,  230}, 
{  -295,  230,  -290,  225}, 
{  -290,  225,  -275,  215}, 
{  -275,  215,  -270,  205}, 
{  -270,  205,  -265,  190}, 
{  -265,  190,  -255,  185}, 
{  -255,  185,  -245,  185}, 
{  -245,  185,  -230,  190}, 
{  -230,  190,  -225,  200}, 
{  -225,  200,  -210,  180}, 
{  -210,  180,  -205,  205}, 
{  -205,  205,  -195,  220}, 
{  -195,  220,  -185,  220}, 
{  -185,  220,  -180,  215}, 
{  -180,  215,  -175,  195}, 
{  -175,  195,  -165,  190}, 
{  -165,  190,  -155,  180}, 
{  -155,  180,  -145,  175}, 
{  -145,  175,  -140,  155}, 
{  -140,  155,  -135,  150}, 
{  -135,  150,  -125,  140}, 
{  -125,  140,  -115,  115}, 
{  -115,  115,  -110,  85}, 
{  -110,  85,  -105,  70}, 
{  -105,  70,  -90,  55}, 
{  -90,  55,  -75,  50}, 
{  -75,  50,  -70,  45}, 
{  -70,  45,  -60,  45}, 
{  -60,  45,  -50,  55}, 
{  -50,  55,  -45,  70}, 
{  -45,  70,  -55,  85}, 
{  -55,  85,  -60,  100}, 
{  -60,  100,  -50,  125}, 
{  -50,  125,  -35,  135}, 
{  -35,  135,  -25,  155}, 
{  -25,  155,  -10,  160}, 
{  -10,  160,  5,  140}, 
{  5,  140,  10,  115}, 
{  10,  115,  5,  95}, 
{  5,  95,  20,  80}, 
{  20,  80,  30,  50}, 
{  30,  50,  45,  45}, 
{  45,  45,  55,  45}, 
{  55,  45,  65,  115}, 
{  65,  115,  75,  130}, 
{  75,  130,  85,  105}, 
{  85,  105,  105,  80}, 
{  105,  80,  120,  35}, 
{  120,  35,  140,  25}, 
{  140,  25,  150,  25}, 
{  150,  25,  160,  60}, 
{  160,  60,  190,  145}, 
{  190,  145,  205,  45}, 
{  205,  45,  220,  30}, 
{  220,  30,  235,  10}, 
{  235,  10,  245,  5}, 
{  245,  5,  255,  5}, 
{  255,  5,  260,  25}, 
{  260,  25,  275,  205}, 
{  275,  205,  290,  275}, 
{  290,  275,  300,  195}, 
{  300,  195,  305,  190}, 
{  305,  190,  315,  190}, 
{  315,  190,  320,  245}, 
                  };             // Mapa Fase 1
 




int Nave_x=320,Nave_y=264;                  // Posicion Inicial de la Nave, por defecto 400,240
float Angulo=0;
int   Zoom=1;
float   Vx_init=0, Vy_init=0, Vx=0, Vy=0;      // control de velocidad
int    Fuel_Nave= 100000;                  // combstible de la nave
int    Potencia_Nave=12;                  // Potencia de los motores
float    G=3;                           // G
float    delta= 0.1;
float    Acx=0,Acy=0;                     // Aceleracion.
int   posx_init, posy_init;





int main(int argc, char **argv)
{

int n;


short Line_x1,Line_y1,Line_x2,Line_y2;



int Mapa[66][4];                     // Mapa que se puede dibujar
int lineas_mapa=0;                     // Numero de lineas del mapa que se pueden dibujar



gforce_t gforce;


   return_reset=1;                  // esto sirve para elegir el tipo de retorno en caso de pulsar RESET (1-> Homebrew Browser, 2->RESET)
   if(argc<1) return_reset=2;
   InitScreen();                       // Inicialización del Vídeo.
   SYS_SetResetCallback(reset_call);   // fija la callback para el boton RESET
   SYS_SetPowerCallback(power_call);   // fija la callback para el boton POWER


   ASND_Init();                  // Inicializa la librería de sonido
   
   WPAD_Init();                        // Inicializa el lector de pad
   WPAD_SetDataFormat(0,WPAD_FMT_BTNS_ACC_IR);
   WPAD_SetVRes(0,640,480);


   fatInit(8, false);               // Inicializa la libreria FAT
    fatSetDefaultInterface(PI_INTERNAL_SD); // fija el device "fat:" a la SD

   atexit(fun_exit);               // fija la funcion de salida (aqui se finaliza el uso de dispositivos, etc: usa exit(0); para salir del programa)
   
   ASND_Pause(0);                  // Pausa de sonido global a 0


   // inicializa el modplayer en modo loop infinito
   MODPlay_Init(&mod_track);


   if (MODPlay_SetMOD (&mod_track, hybris ) < 0 ) // set the MOD song
      {
      MODPlay_Unload (&mod_track);   
      }
   else 
      {
      MODPlay_SetVolume( &mod_track, 32,32); // fix the volume to 32 (max 64)
      MODPlay_Start (&mod_track); // Play the MOD
      }


   while(1)                     // bucle principal
      {
      ResetTimeBase();            //r

      if(exit_by_reset) exit(0);                           // comprueba si se han pulsado RESET o POWER y sal si es asi
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);      // comprueba si se han pulsado Home en wiimote 1 y sal si es asi
      
      // dibujado de la caja

      SetTexture(NULL);

      DrawRoundFillBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 0xffafafaf); // dibuja una caja solida
      DrawRoundBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 4, 0xff00ffff); // dibuja el perimetro de la caja con borde de grosor 4
      
      letter_size(8,32); // tamaño de letra 16x64
      PX= 0; PY= 18; color= 0xff000000; bkcolor=0;
      
      SelectFontTexture(0); // selecciona font principal

      autocenter=1; // autocentrado on
      s_printf("Wiilander %d %d %d\n",SCR_WIDTH,SCR_HEIGHT,lineas_mapa);
      autocenter=0;
      
      
      // configura para usar color con GX_Begin (funcion de dibujado de poligonos de GX)
      ConfigureForColor();
      
//      #if 1
//      GX_Begin(GX_LINES, GX_VTXFMT0, 80*4*2); // dibuja 80*4 lineas (en matriz de 2x2) * 2 vertices
//      for(n=0;n<80;n++)
//         {
//         AddColorVertex(n*8, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         }
//      GX_End();
//
//


   // Controles de entrada

      WPAD_ScanPads();                  //Lee todos los mandos
      WPAD_GForce(0, &gforce);            //Lee la aceleracion del mando 1

      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) {
      Zoom=2;
      }
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) {
      Zoom=1;
      }

         

      

      // Calculo de cinematica
   // la cinematica por ahora esta hecha a ojo.. la idea, es poner una cinematica mas seria, que incluso tenga en cuenta el peso del combustible
   // que queda en el tanque.. ¿Alguien se anima?
   
      
         Angulo=3.14159*gforce.y;
         
         Vx_init=Vx;
         Vy_init=Vy;
         
         
   if (Fuel_Nave>0){
      if (gforce.x>0){
         Fuel_Nave=Fuel_Nave-(gforce.x*Potencia_Nave);         
         
         Acx=sin(-Angulo)*gforce.x*Potencia_Nave;
         Acy=G-(cos(Angulo)*gforce.x*Potencia_Nave);
   }   else    {
         Acy=G;
            }   
      }
         
         Vx= (Acx*delta)+Vx_init;
         Vy= (Acy*delta)+Vy_init;

         posx_init=Nave_x;
         posy_init=Nave_y;

         Nave_x=(Vx*delta)+posx_init;
         Nave_y=(Vy*delta)+posy_init;





      // Dibuja la Nave
      // Aparte de tener que usar trigonometria, para girar la nave.. al hacer un zoom, tengo que transladar las coordenadas, para poder aplicar el zoom,
      // y luego volver a transladarlas.. en la coordenada y se ve mejor.. lo que hago es calcular la altura hasta el cero, aplicar el zoom, y volver a
      // usar las coordenadas que maneja la wii de 0 a 528.. siendo 528 altura =0, se podria hacer de una manera mas eficaz.. pero la Wii puede con esto
      // sin problemas.. lo del (Zoom/2) que aplico a la nave lo hago porque sino salia muy grande.. ya lo modificare en la versión final.
      GX_Begin(GX_LINES, GX_VTXFMT0, 23*2); // dibuja  Nave  23x2
      for(n=0;n<23;n++)
         {
         Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom/2+Modelo_Nave[n][1]*sin(Angulo)*Zoom/2;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom/2+Modelo_Nave[n][1]*cos(Angulo)*Zoom/2;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom/2+Modelo_Nave[n][3]*sin(Angulo)*Zoom/2;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom/2+Modelo_Nave[n][3]*cos(Angulo)*Zoom/2;
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();



      // Dibuja el Mapa
      // Creamos una Tabla con el mapa que se puede dibujar, es decir que esta X ( 0:640) e y (0:528)
      
      lineas_mapa=0;
      for(n=0;n<65;n++)
         {
            Line_x1=(Zoom*Mapa_Fase1[n][0])+320;
            Line_y1=SCR_HEIGHT-(Zoom*Mapa_Fase1[n][1]);
            Line_x2=(Zoom*Mapa_Fase1[n][2])+320;
            Line_y2=SCR_HEIGHT-(Zoom*Mapa_Fase1[n][3]);
            if ((Line_x1>-1-50 && Line_x1<SCR_WIDTH+50) && (Line_x2>-1-50 && Line_x2<SCR_WIDTH+50) && (Line_y1>-1-50 && Line_y1<SCR_HEIGHT+50) && (Line_y2>-1-50 && Line_y2<SCR_HEIGHT+50)) {
               Mapa[lineas_mapa][0]=Line_x1;
               Mapa[lineas_mapa][1]=Line_y1;
               Mapa[lineas_mapa][2]=Line_x2;
               Mapa[lineas_mapa][3]=Line_y2;
               lineas_mapa++;
                              }
         }
      
      
      GX_Begin(GX_LINES, GX_VTXFMT0, lineas_mapa*2); // dibuja  mapa
      for(n=0;n<lineas_mapa;n++)
         {
         Line_x1=Mapa[n][0];
         Line_y1=Mapa[n][1];
         Line_x2=Mapa[n][2];
         Line_y2=Mapa[n][3];
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();
         
   
            
      // borra e intercambia la pantalla, espera al retrazado vertical
      Screen_flip();
      
      
      // entra en un  bucle y no sale hasta que llegue a los 30 milisegundos
      do {
            frametime=CurrentTime();
         } while (frametime<40);
               
      }
   
      

exit(0);

}



Salu2,

Manny
manny
 
Mensajes: 22
Registrado: Lunes, 1 de Diciembre de 2008 00:03

Re: Wiilander

Notapor manny » Lunes, 29 de Diciembre de 2008 01:05

Esta versión ya tiene scroll horizontal y vertical, (cuando se hace un zoom.. el scroll sale descentrado.. es algo que tengo que corregir), pero por lo demás se puede navegar por todo el mapa.. he añadido, la opción de "debug" de pulsar la A que nos reinicia los valores de scroll y posición de la nave.. tengo un par de dudillas :?: :?: pero estas las publico, en la parte de programación general..

Con respecto a la rutina de detención de colisión, ya la estoy usando.. pero por ahora solo para calcular la altura de la nave, trazando una linea que se va haciendo mas larga desde la nave hasta el suelo.. si os fijáis al moveros cuando pasáis por las zonas de aterrizaje que son planas.. no calcula bien la altura y pone 2000.. porque no encuentra la colisión con este tipo de lineas.

Código: Seleccionar todo
/* Wiilander

Copyright (c) 2008 Manny
All rights reserved.
http://www.entuwii.net/foro/viewtopic.php?f=14&t=102

Use the fantastics ;) screenlib and asndlib, libraries  Copyright (c) 2008 Hermes, and the Wii programation training from Hermes:
http://www.entuwii.net/foro/viewtopic.php?f=6&t=94


Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of
  conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
  of conditions and the following disclaimer in the documentation and/or other
  materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#define USE_MODPLAYER 1

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <ogcsys.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

#include <fat.h>
#include <fcntl.h>
#include "unistd.h"
#include <ogc/lwp_watchdog.h>

#include "screen.h"

#include "asndlib.h"

#ifdef USE_MODPLAYER
// MOD Player
#include "gcmodplay.h"

MODPlay mod_track;

#include "hybris.h"

#endif






// Gestion de tiempo.  funciones para crear una pausa de x milisegundos
u64 ini_milisegundos, fin_milisegundos, frametime;

void ResetTimeBase() {
  ini_milisegundos=ticks_to_millisecs(gettime());
}

int CurrentTime() {
  fin_milisegundos=ticks_to_millisecs(gettime());
  return fin_milisegundos-ini_milisegundos;
}



// Gestion de salida
int return_reset=1;
int exit_by_reset=0;

void reset_call() {exit_by_reset=return_reset;}
void power_call() {exit_by_reset=3;}

void fun_exit()
{
   ASND_End();      // finaliza el sonido
   WPAD_Shutdown();
   Screen_flip();  // espera a que acabe el GX si está en uso
   fatUnmount(PI_INTERNAL_SD); // desmonta la partición de la SD
   usleep(500);   // espera 500 ms por si hay algo que esté trabajando todavía
   if(exit_by_reset==2)
      SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
   if(exit_by_reset==3)
      SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);

exit(0);

}


// funcion lineCollide detecta si dos lineas AB BC se tocan.

int lineCollide(float ax,float ay, float bx, float by, float cx, float cy, float dx, float dy)
   {
      float tarray[4][2]; //<===== Find the inner bounding of rect ABCD
      if (ax<bx){
               tarray[0][0]=ax;
               tarray[1][0]=bx;
      } else {
               tarray[0][0]=bx;
               tarray[1][0]=ax;
               }
      if (ay<by){
               tarray[0][1]=ay;
               tarray[1][1]=by;
      } else {
               tarray[0][1]=by;
               tarray[1][1]=ay;
   }
      if (cx<dx){
               tarray[2][0]=cx;
               tarray[3][0]=dx;
      } else {
               tarray[2][0]=dx;
               tarray[3][0]=cx;
   }

      if (cy<dy){
               tarray[2][1]=cy;
               tarray[3][1]=dy;
      } else {
               tarray[2][1]=dy;
               tarray[3][1]=cy;
      }

   float tarray2[2][2]; //<===== Sort Section Two

      if (tarray[0][0]<tarray[2][0]) { tarray2[0][0]=tarray[2][0]; }else{ tarray2[0][0]=tarray[0][0]; } //biggest of the small ones
      if (tarray[0][1]<tarray[2][1]) { tarray2[0][1]=tarray[2][1]; }else{ tarray2[0][1]=tarray[0][1]; } //biggest of the small ones
      if (tarray[1][0]<tarray[3][0]) { tarray2[1][0]=tarray[1][0]; }else{ tarray2[1][0]=tarray[3][0]; } //biggest of the small ones
      if (tarray[1][1]<tarray[3][1]) { tarray2[1][1]=tarray[1][1]; }else{ tarray2[1][1]=tarray[3][1]; } //biggest of the small ones
      float mab=(ay-by)/(ax-bx); //<===== Find Slopes of Lines
      float mcd=(cy-dy)/(cx-dx);
      if (mab==mcd) return 0; //the lines are paralell
      float yiab=((ax-bx)*ay-ax*(ay-by))/(ax-bx); //<===== Find the y Intercept of Lines
      float yicd=((cx-dx)*cy-cx*(cy-dy))/(cx-dx);
      float x=(yicd-yiab)/(mab-mcd); //<===== Find the Intersection Points of the Line
      float y=mab*x+yiab;
      if (x>tarray2[0][0] && x<tarray2[1][0] && y>tarray2[0][1] && y<tarray2[1][1]) { return 1; }else{ return 0; }
         }



// Informacion de graficos

// El modelo de la nave esta refenciado en coordenadas 0.0 (es decir 0.0 es el centro de la nave) lo hago asi para poder aplicar los zooms,
// y la trigonometria necesaria para girar la nave.

int  Modelo_Nave[24][4]= {
                           { -2,   7,  0,  10},
                           {  0,  10,  2,   7},
                           { -3, -10,  3, -10},
                           {  3, -10,  6,  -7},
                           {  6,  -7,  6,  -4},
                           {  6,  -4,  3,  -1},
                           { -3,  -1, -6,  -4},
                           { -6,  -4, -6,  -7},
                           { -6,  -7, -3, -10},
                           { -6,  -1,  6,  -1},
                           {  6,  -1,  6,   4},
                           {  6,   1,  8,   7},
                           {  4,   4,  8,   7},
                           {  8,   7,  8,  10},
                           {  6,  10, 10,  10},
                           {  6,   4, -6,   4},
                           { -6,  -1, -6,   4},
                           { -6,   1, -8,   7},
                           { -4,   4, -8,   7},
                           { -8,   7, -8,  10},
                           {-10,  10, -6,  10},
                           {  0,   4,  2,   7},
                           {  0,   4, -2,   7},
                           { -2,   7,  2,   7}
                          };             // Diseño de la Nave
   


// Mapa Fase 1 la tabla define las lineas, que forman el mapa (posicion X1, altura1, posicion x2, altura2)
int  Mapa_Fase1[66][4]= {
{  -640,  243,  -610,  238}, 
{  -610,  238,  -590,  228}, 
{  -590,  228,  -580,  223}, 
{  -580,  223,  -550,  213}, 
{  -550,  213,  -540,  203}, 
{  -540,  203,  -530,  188}, 
{  -530,  188,  -510,  183}, 
{  -510,  183,  -490,  183}, 
{  -490,  183,  -460,  188}, 
{  -460,  188,  -450,  198}, 
{  -450,  198,  -420,  178}, 
{  -420,  178,  -410,  203}, 
{  -410,  203,  -390,  218}, 
{  -390,  218,  -370,  218}, 
{  -370,  218,  -360,  213}, 
{  -360,  213,  -350,  193}, 
{  -350,  193,  -330,  188}, 
{  -330,  188,  -310,  178}, 
{  -310,  178,  -290,  173}, 
{  -290,  173,  -280,  153}, 
{  -280,  153,  -270,  148}, 
{  -270,  148,  -250,  138}, 
{  -250,  138,  -230,  113}, 
{  -230,  113,  -220,  83}, 
{  -220,  83,  -210,  68}, 
{  -210,  68,  -180,  53}, 
{  -180,  53,  -150,  48}, 
{  -150,  48,  -140,  43}, 
{  -140,  43,  -120,  43}, 
{  -120,  43,  -100,  53}, 
{  -100,  53,  -90,  68}, 
{  -90,  68,  -110,  83}, 
{  -110,  83,  -120,  98}, 
{  -120,  98,  -100,  123}, 
{  -100,  123,  -70,  133}, 
{  -70,  133,  -50,  153}, 
{  -50,  153,  -20,  158}, 
{  -20,  158,  10,  138}, 
{  10,  138,  20,  113}, 
{  20,  113,  10,  93}, 
{  10,  93,  40,  78}, 
{  40,  78,  60,  48}, 
{  60,  48,  90,  43}, 
{  90,  43,  110,  43}, 
{  110,  43,  130,  113}, 
{  130,  113,  150,  128}, 
{  150,  128,  170,  103}, 
{  170,  103,  210,  78}, 
{  210,  78,  240,  33}, 
{  240,  33,  280,  23}, 
{  280,  23,  300,  23}, 
{  300,  23,  320,  58}, 
{  320,  58,  380,  143}, 
{  380,  143,  410,  43}, 
{  410,  43,  440,  28}, 
{  440,  28,  470,  8}, 
{  470,  8,  490,  3}, 
{  490,  3,  510,  3}, 
{  510,  3,  520,  23}, 
{  520,  23,  550,  203}, 
{  550,  203,  580,  273}, 
{  580,  273,  600,  193}, 
{  600,  193,  610,  188}, 
{  610,  188,  630,  188}, 
{  630,  188,  640,  243}, 
{  640,  243,  660,  473} 
                  };             // Mapa Fase 1
 




int Nave_x=320,Nave_y=264,scroll_x=0,scroll_y=0;                  // Posicion Inicial de la Nave, por defecto 400,240
float Angulo=0;
int   Zoom=1;
float   Vx_init=0, Vy_init=0, Vx=0, Vy=0;      // control de velocidad
int    Fuel_Nave= 100000;                  // combstible de la nave
int    Potencia_Nave=12;                  // Potencia de los motores
float    G=3;                           // G
float    delta= 0.1;
float    Acx=0,Acy=0;                     // Aceleracion.
int   posx_init, posy_init;


int Altura=0;
int n=0, nn=0;
int colision=0;


void Calculo_de_Altura() {
         Altura=0;
          while (Altura < 2000){
         n=0;
         while (n < 65){
         colision=lineCollide(((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)-1,(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))+Altura,((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+1,(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-1,(Zoom*Mapa_Fase1[n][0])+320,SCR_HEIGHT-(Zoom*Mapa_Fase1[n][1]),(Zoom*Mapa_Fase1[n][2])+320,SCR_HEIGHT-(Zoom*Mapa_Fase1[n][3]));
      //AQUI
         if    (colision == 1){
                           return;   }
         n += 1;   }   
         Altura += 1;
          }
         }






int main(int argc, char **argv)
{

int n;


short Line_x1,Line_y1,Line_x2,Line_y2;



int Mapa[66][4];                     // Mapa que se puede dibujar
int lineas_mapa=0;                     // Numero de lineas del mapa que se pueden dibujar



gforce_t gforce;


   return_reset=1;                  // esto sirve para elegir el tipo de retorno en caso de pulsar RESET (1-> Homebrew Browser, 2->RESET)
   if(argc<1) return_reset=2;
   InitScreen();                       // Inicialización del Vídeo.
   SYS_SetResetCallback(reset_call);   // fija la callback para el boton RESET
   SYS_SetPowerCallback(power_call);   // fija la callback para el boton POWER


   ASND_Init();                  // Inicializa la librería de sonido
   
   WPAD_Init();                        // Inicializa el lector de pad
   WPAD_SetDataFormat(0,WPAD_FMT_BTNS_ACC_IR);
   WPAD_SetVRes(0,640,480);


   fatInit(8, false);               // Inicializa la libreria FAT
    fatSetDefaultInterface(PI_INTERNAL_SD); // fija el device "fat:" a la SD

   atexit(fun_exit);               // fija la funcion de salida (aqui se finaliza el uso de dispositivos, etc: usa exit(0); para salir del programa)
   
   ASND_Pause(0);                  // Pausa de sonido global a 0


   // inicializa el modplayer en modo loop infinito
   MODPlay_Init(&mod_track);


   if (MODPlay_SetMOD (&mod_track, hybris ) < 0 ) // set the MOD song
      {
      MODPlay_Unload (&mod_track);   
      }
   else 
      {
      MODPlay_SetVolume( &mod_track, 32,32); // fix the volume to 32 (max 64)
      MODPlay_Start (&mod_track); // Play the MOD
      }


   while(1)                     // bucle principal
      {
      ResetTimeBase();            //r

      if(exit_by_reset) exit(0);                           // comprueba si se han pulsado RESET o POWER y sal si es asi
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);      // comprueba si se han pulsado Home en wiimote 1 y sal si es asi
      
      // dibujado de la caja

      SetTexture(NULL);

      DrawRoundFillBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 0xffafafaf); // dibuja una caja solida
      DrawRoundBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 4, 0xff00ffff); // dibuja el perimetro de la caja con borde de grosor 4
      
      letter_size(8,32); // tamaño de letra 16x64
      PX= 0; PY= 18; color= 0xff000000; bkcolor=0;
      
      SelectFontTexture(0); // selecciona font principal

      Calculo_de_Altura();
      
      autocenter=1; // autocentrado on
      s_printf("Wiilander %d %d %d\n",SCR_WIDTH,SCR_HEIGHT,Altura);
      autocenter=0;
      
      
      // configura para usar color con GX_Begin (funcion de dibujado de poligonos de GX)
      ConfigureForColor();
      
//      #if 1
//      GX_Begin(GX_LINES, GX_VTXFMT0, 80*4*2); // dibuja 80*4 lineas (en matriz de 2x2) * 2 vertices
//      for(n=0;n<80;n++)
//         {
//         AddColorVertex(n*8, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         }
//      GX_End();
//
//


   // Controles de entrada

      WPAD_ScanPads();                  //Lee todos los mandos
      WPAD_GForce(0, &gforce);            //Lee la aceleracion del mando 1

      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) {
      Zoom=2;
      }
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) {
      Zoom=1;
      }

   //Solo para test...
      if ( WPAD_ButtonsHeld(0) & WPAD_BUTTON_A ){
         WPAD_Rumble(0,1);
         Nave_x=320;
         Nave_y=264;
         Vx=Vy=scroll_y=scroll_x=0;
         Fuel_Nave=10000;
         
      } else{
         WPAD_Rumble(0,0);      
      }
            
         
         

      

   // Calculo de cinematica
   // la cinematica por ahora esta hecha a ojo.. la idea, es poner una cinematica mas seria, que incluso tenga en cuenta el peso del combustible
   // que queda en el tanque.. ¿Alguien se anima?
   
      
         Angulo=3.14159*gforce.y;
         
         Vx_init=Vx;
         Vy_init=Vy;
         
         
   if (Fuel_Nave>0){
      if (gforce.x>0){
         Fuel_Nave=Fuel_Nave-(gforce.x*Potencia_Nave);         
         
         Acx=sin(-Angulo)*gforce.x*Potencia_Nave;
         Acy=G-(cos(Angulo)*gforce.x*Potencia_Nave);
   }   else    {
         Acy=G;
            }   
      }
         
         Vx= (Acx*delta)+Vx_init;
         Vy= (Acy*delta)+Vy_init;

         posx_init=Nave_x;
         posy_init=Nave_y;

           
         
         
         if (((Vx*delta)+posx_init>160) && ((Vx*delta)+posx_init<480)) {
         Nave_x=(Vx*delta)+posx_init;
               }
         if ((Vx*delta)+posx_init<160) {
         scroll_x-=(Vx*delta);
               }
         if ((Vx*delta)+posx_init>480) {
         scroll_x-=(Vx*delta);
               }
   
         if (((Vy*delta)+posy_init>132) && ((Vy*delta)+posy_init<396)) {
         Nave_y=(Vy*delta)+posy_init;
               }
         if ((Vy*delta)+posy_init<132) {
         scroll_y-=(Vy*delta);
               }
         if ((Vy*delta)+posy_init>396) {
         scroll_y-=(Vy*delta);
               }


   

//         Nave_x=(Vx*delta)+posx_init;
//         Nave_y=(Vy*delta)+posy_init;





      // Dibuja la Nave
      // Aparte de tener que usar trigonometria, para girar la nave.. al hacer un zoom, tengo que transladar las coordenadas, para poder aplicar el zoom,
      // y luego volver a transladarlas.. en la coordenada y se ve mejor.. lo que hago es calcular la altura hasta el cero, aplicar el zoom, y volver a
      // usar las coordenadas que maneja la wii de 0 a 528.. siendo 528 altura =0, se podria hacer de una manera mas eficaz.. pero la Wii puede con esto
      // sin problemas.. lo del (Zoom/2) que aplico a la nave lo hago porque sino salia muy grande.. ya lo modificare en la versión final.
      GX_Begin(GX_LINES, GX_VTXFMT0, 23*2); // dibuja  Nave  23x2
      for(n=0;n<23;n++)
         {
         Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom/2+Modelo_Nave[n][1]*sin(Angulo)*Zoom/2;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom/2+Modelo_Nave[n][1]*cos(Angulo)*Zoom/2;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom/2+Modelo_Nave[n][3]*sin(Angulo)*Zoom/2;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom/2+Modelo_Nave[n][3]*cos(Angulo)*Zoom/2;
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();



      // Dibuja el Mapa
      // Creamos una Tabla con el mapa que se puede dibujar, es decir que esta X ( 0:640) e y (0:528)
      
      lineas_mapa=0;
      for(n=0;n<65;n++)
         {
            Line_x1=(Zoom*Mapa_Fase1[n][0])+320+scroll_x*Zoom;
            Line_y1=SCR_HEIGHT-(Zoom*(Mapa_Fase1[n][1]))+scroll_y;
            Line_x2=(Zoom*Mapa_Fase1[n][2])+320+scroll_x*Zoom;
            Line_y2=SCR_HEIGHT-(Zoom*(Mapa_Fase1[n][3]))+scroll_y;
            if ((Line_x1>-1-50 && Line_x1<SCR_WIDTH+50) && (Line_x2>-1-50 && Line_x2<SCR_WIDTH+50) && (Line_y1>-1-50 && Line_y1<SCR_HEIGHT+50) && (Line_y2>-1-50 && Line_y2<SCR_HEIGHT+50)) {
               Mapa[lineas_mapa][0]=Line_x1;
               Mapa[lineas_mapa][1]=Line_y1;
               Mapa[lineas_mapa][2]=Line_x2;
               Mapa[lineas_mapa][3]=Line_y2;
               lineas_mapa++;
                              }
         }
      
      
      GX_Begin(GX_LINES, GX_VTXFMT0, lineas_mapa*2); // dibuja  mapa
      for(n=0;n<lineas_mapa;n++)
         {
         Line_x1=Mapa[n][0];
         Line_y1=Mapa[n][1];
         Line_x2=Mapa[n][2];
         Line_y2=Mapa[n][3];
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();
         
   
      Calculo_de_Altura();

       // Calculo de colision


/*
            n=0;
            while (n < 23){
         nn=0;
         while (nn < 65){
      
          Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom/2+Modelo_Nave[n][1]*sin(Angulo)*Zoom/2;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom/2+Modelo_Nave[n][1]*cos(Angulo)*Zoom/2;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom/2+Modelo_Nave[n][3]*sin(Angulo)*Zoom/2;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom/2+Modelo_Nave[n][3]*cos(Angulo)*Zoom/2;
          colision=lineCollide(Line_x1,Line_y1,Line_x2,Line_y2,(Zoom*Mapa_Fase1[nn][0])+320,SCR_HEIGHT-(Zoom*Mapa_Fase1[nn][1]),(Zoom*Mapa_Fase1[nn][2])+320,SCR_HEIGHT-(Zoom*Mapa_Fase1[nn][3]));
      //AQUI
         if    (colision == 1){
                           Nave_x=320;
                           Nave_y=130;
                            Vx=Vy=0;}
   
         n += 1;   }   
         nn += 1;
          }
        
*/
         



      // borra e intercambia la pantalla, espera al retrazado vertical
      Screen_flip();
      
      
      // entra en un  bucle y no sale hasta que llegue a los 40 milisegundos
      do {
            frametime=CurrentTime();
         } while (frametime<40);
               
      }
   
      

exit(0);

}



Salu2,

Manny
manny
 
Mensajes: 22
Registrado: Lunes, 1 de Diciembre de 2008 00:03

Re: Wiilander

Notapor manny » Martes, 30 de Diciembre de 2008 02:34

Ya funciona casi todo :!: :!: :!:
La parte mas difícil ya esta hecha!! ;)

Se puede navegar, :D se dibuja el fuego de la nave, los zoom son automáticos, y funciona a la perfección la rutina de colisiones (el problema era el típico 0/0), solo me falta poner el mapa de zonas de aterrizaje y ponerme con el sonido de los motores..

Ademas si intentas subir mucho.. la nave pierde potencia y empieza a caer.. como si cayera en barrena.

Código: Seleccionar todo
/* Wiilander

Copyright (c) 2008 Manny
All rights reserved.
http://www.entuwii.net/foro/viewtopic.php?f=14&t=102

Use the fantastics ;) screenlib and asndlib, libraries  Copyright (c) 2008 Hermes, and the Wii programation training from Hermes:
http://www.entuwii.net/foro/viewtopic.php?f=6&t=94


Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of
  conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
  of conditions and the following disclaimer in the documentation and/or other
  materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#define USE_MODPLAYER 1

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <ogcsys.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

#include <fat.h>
#include <fcntl.h>
#include "unistd.h"
#include <ogc/lwp_watchdog.h>

#include "screen.h"

#include "asndlib.h"

#ifdef USE_MODPLAYER
// MOD Player
#include "gcmodplay.h"

MODPlay mod_track;

#include "hybris.h"

#endif






// Gestion de tiempo.  funciones para crear una pausa de x milisegundos
u64 ini_milisegundos, fin_milisegundos, frametime;

void ResetTimeBase() {
  ini_milisegundos=ticks_to_millisecs(gettime());
}

int CurrentTime() {
  fin_milisegundos=ticks_to_millisecs(gettime());
  return fin_milisegundos-ini_milisegundos;
}



// Gestion de salida
int return_reset=1;
int exit_by_reset=0;

void reset_call() {exit_by_reset=return_reset;}
void power_call() {exit_by_reset=3;}

void fun_exit()
{
   ASND_End();      // finaliza el sonido
   WPAD_Shutdown();
   Screen_flip();  // espera a que acabe el GX si está en uso
   fatUnmount(PI_INTERNAL_SD); // desmonta la partición de la SD
   usleep(500);   // espera 500 ms por si hay algo que esté trabajando todavía
   if(exit_by_reset==2)
      SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
   if(exit_by_reset==3)
      SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);

exit(0);

}


// funcion lineCollide detecta si dos lineas AB BC se tocan.

int lineCollide(float ax,float ay, float bx, float by, float cx, float cy, float dx, float dy)
   {
   
      ax+=0.01;
      ay+=0.02;
      bx+=0.03;
      by+=0.04;
      cx+=0.05;
      cy+=0.06;
      dx+=0.07;
      dy+=0.08;
      
      float tarray[4][2]; //<===== Find the inner bounding of rect ABCD
      if (ax<bx){
               tarray[0][0]=ax;
               tarray[1][0]=bx;
      } else {
               tarray[0][0]=bx;
               tarray[1][0]=ax;
               }
      if (ay<by){
               tarray[0][1]=ay;
               tarray[1][1]=by;
      } else {
               tarray[0][1]=by;
               tarray[1][1]=ay;
   }
      if (cx<dx){
               tarray[2][0]=cx;
               tarray[3][0]=dx;
      } else {
               tarray[2][0]=dx;
               tarray[3][0]=cx;
   }

      if (cy<dy){
               tarray[2][1]=cy;
               tarray[3][1]=dy;
      } else {
               tarray[2][1]=dy;
               tarray[3][1]=cy;
      }

   float tarray2[2][2]; //<===== Sort Section Two

      if (tarray[0][0]<tarray[2][0]) { tarray2[0][0]=tarray[2][0]; }else{ tarray2[0][0]=tarray[0][0]; } //biggest of the small ones
      if (tarray[0][1]<tarray[2][1]) { tarray2[0][1]=tarray[2][1]; }else{ tarray2[0][1]=tarray[0][1]; } //biggest of the small ones
      if (tarray[1][0]<tarray[3][0]) { tarray2[1][0]=tarray[1][0]; }else{ tarray2[1][0]=tarray[3][0]; } //biggest of the small ones
      if (tarray[1][1]<tarray[3][1]) { tarray2[1][1]=tarray[1][1]; }else{ tarray2[1][1]=tarray[3][1]; } //biggest of the small ones
      float mab=(ay-by)/(ax-bx); //<===== Find Slopes of Lines
      float mcd=(cy-dy)/(cx-dx);
      if (mab==mcd) return 0; //the lines are paralell
      float yiab=((ax-bx)*ay-ax*(ay-by))/(ax-bx); //<===== Find the y Intercept of Lines
      float yicd=((cx-dx)*cy-cx*(cy-dy))/(cx-dx);
      float x=(yicd-yiab)/(mab-mcd); //<===== Find the Intersection Points of the Line
      float y=mab*x+yiab;
      if (x>tarray2[0][0] && x<tarray2[1][0] && y>tarray2[0][1] && y<tarray2[1][1]) { return 1; }else{ return 0; }
         }



// Informacion de graficos

// El modelo de la nave esta refenciado en coordenadas 0.0 (es decir 0.0 es el centro de la nave) lo hago asi para poder aplicar los zooms,
// y la trigonometria necesaria para girar la nave.

int  Modelo_Nave[22][4]= {
                           { -3, -10,  3, -10},
                           {  3, -10,  6,  -7},
                           {  6,  -7,  6,  -4},
                           {  6,  -4,  3,  -1},
                           { -3,  -1, -6,  -4},
                           { -6,  -4, -6,  -7},
                           { -6,  -7, -3, -10},
                           { -6,  -1,  6,  -1},
                           {  6,  -1,  6,   4},
                           {  6,   1,  8,   7},
                           {  4,   4,  8,   7},
                           {  8,   7,  8,  10},
                           {  6,  10, 10,  10},
                           {  6,   4, -6,   4},
                           { -6,  -1, -6,   4},
                           { -6,   1, -8,   7},
                           { -4,   4, -8,   7},
                           { -8,   7, -8,  10},
                           {-10,  10, -6,  10},
                           {  0,   4,  2,   7},
                           {  0,   4, -2,   7},
                           { -2,   7,  2,   7}
                          };             // Diseño de la Nave
   


// Mapa Fase 1 la tabla define las lineas, que forman el mapa (posicion X1, altura1, posicion x2, altura2)
int  Mapa_Fase1[71][4]= {
{  -650,  950,  -680,  650}, 
{  -680,  650,  -650,  400}, 
{  -650,  400,  -640,  243}, 
{  -640,  243,  -610,  238}, 
{  -610,  238,  -590,  228}, 
{  -590,  228,  -580,  223}, 
{  -580,  223,  -550,  213}, 
{  -550,  213,  -540,  203}, 
{  -540,  203,  -530,  188}, 
{  -530,  188,  -510,  183}, 
{  -510,  183,  -490,  183}, 
{  -490,  183,  -460,  188}, 
{  -460,  188,  -450,  198}, 
{  -450,  198,  -420,  178}, 
{  -420,  178,  -410,  203}, 
{  -410,  203,  -390,  218}, 
{  -390,  218,  -370,  218}, 
{  -370,  218,  -360,  213}, 
{  -360,  213,  -350,  193}, 
{  -350,  193,  -330,  188}, 
{  -330,  188,  -310,  178}, 
{  -310,  178,  -290,  173}, 
{  -290,  173,  -280,  153}, 
{  -280,  153,  -270,  148}, 
{  -270,  148,  -250,  138}, 
{  -250,  138,  -230,  113}, 
{  -230,  113,  -220,  83}, 
{  -220,  83,  -210,  68}, 
{  -210,  68,  -180,  53}, 
{  -180,  53,  -150,  48}, 
{  -150,  48,  -140,  43}, 
{  -140,  43,  -120,  43}, 
{  -120,  43,  -100,  53}, 
{  -100,  53,  -90,  68}, 
{  -90,  68,  -110,  83}, 
{  -110,  83,  -120,  98}, 
{  -120,  98,  -100,  123}, 
{  -100,  123,  -70,  133}, 
{  -70,  133,  -50,  153}, 
{  -50,  153,  -20,  158}, 
{  -20,  158,  10,  138}, 
{  10,  138,  20,  113}, 
{  20,  113,  10,  93}, 
{  10,  93,  40,  78}, 
{  40,  78,  60,  48}, 
{  60,  48,  90,  43}, 
{  90,  43,  110,  43}, 
{  110,  43,  130,  113}, 
{  130,  113,  150,  128}, 
{  150,  128,  170,  103}, 
{  170,  103,  210,  78}, 
{  210,  78,  240,  33}, 
{  240,  33,  280,  23}, 
{  280,  23,  300,  23}, 
{  300,  23,  320,  58}, 
{  320,  58,  380,  143}, 
{  380,  143,  410,  43}, 
{  410,  43,  440,  28}, 
{  440,  28,  470,  8}, 
{  470,  8,  490,  3}, 
{  490,  3,  510,  3}, 
{  510,  3,  520,  23}, 
{  520,  23,  550,  203}, 
{  550,  203,  580,  273}, 
{  580,  273,  600,  193}, 
{  600,  193,  610,  188}, 
{  610,  188,  630,  188}, 
{  630,  188,  640,  243}, 
{  640,  243,  660,  473}, 
{  660,  473,  675,  650}, 
{  675,  650,  660,  950} 
                  };             // Mapa Fase 1
 




int Nave_x=320,Nave_y=264,scroll_x=0,scroll_y=0;                  // Posicion Inicial de la Nave, por defecto 400,240
float Angulo=0;
float   Zoom=1;
float   Vx_init=0, Vy_init=0, Vx=0, Vy=0;      // control de velocidad
int    Fuel_Nave= 100000;                  // combstible de la nave
int    Potencia_Nave=12;                  // Potencia de los motores
float    G=3;                           // G
float    delta= 0.1;
float    Acx=0,Acy=0;                     // Aceleracion.
int   posx_init, posy_init;


int Altura=0;
int n=0, nn=0;
int colision=0;


void Calculo_de_Altura() {
         Altura=0;
          while (Altura < 500){
         n=0;
         while (n < 71){
            if    (lineCollide(((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x))-1,(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)))+Altura+10,((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x))+1,(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)))-1,(Mapa_Fase1[n][0])+320+scroll_x,SCR_HEIGHT-((Mapa_Fase1[n][1]))+scroll_y,(Mapa_Fase1[n][2])+320+scroll_x,SCR_HEIGHT-((Mapa_Fase1[n][3]))+scroll_y)== 1){
                           return;   }
         n += 1;   }   
         Altura += 1;
          }
         }





int main(int argc, char **argv)
{

int n;


short Line_x1,Line_y1,Line_x2,Line_y2;



int Mapa[71][4];                     // Mapa que se puede dibujar
int lineas_mapa=0;                     // Numero de lineas del mapa que se pueden dibujar



gforce_t gforce;


   return_reset=1;                  // esto sirve para elegir el tipo de retorno en caso de pulsar RESET (1-> Homebrew Browser, 2->RESET)
   if(argc<1) return_reset=2;
   InitScreen();                       // Inicialización del Vídeo.
   SYS_SetResetCallback(reset_call);   // fija la callback para el boton RESET
   SYS_SetPowerCallback(power_call);   // fija la callback para el boton POWER


   ASND_Init();                  // Inicializa la librería de sonido
   
   WPAD_Init();                        // Inicializa el lector de pad
   WPAD_SetDataFormat(0,WPAD_FMT_BTNS_ACC_IR);
   WPAD_SetVRes(0,640,480);


   fatInit(8, false);               // Inicializa la libreria FAT
    fatSetDefaultInterface(PI_INTERNAL_SD); // fija el device "fat:" a la SD

   atexit(fun_exit);               // fija la funcion de salida (aqui se finaliza el uso de dispositivos, etc: usa exit(0); para salir del programa)
   
   ASND_Pause(0);                  // Pausa de sonido global a 0


   // inicializa el modplayer en modo loop infinito
   MODPlay_Init(&mod_track);


   if (MODPlay_SetMOD (&mod_track, hybris ) < 0 ) // set the MOD song
      {
      MODPlay_Unload (&mod_track);   
      }
   else 
      {
      MODPlay_SetVolume( &mod_track, 32,32); // fix the volume to 32 (max 64)
      MODPlay_Start (&mod_track); // Play the MOD
      }


   while(1)                     // bucle principal
      {
      ResetTimeBase();            //ponemos el contador de tiempo a cero.

      if(exit_by_reset) exit(0);                           // comprueba si se han pulsado RESET o POWER y sal si es asi
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);      // comprueba si se han pulsado Home en wiimote 1 y sal si es asi
      
      // dibujado de la caja

      SetTexture(NULL);

      DrawRoundFillBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 0xffafafaf); // dibuja una caja solida
      DrawRoundBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 4, 0xff00ffff); // dibuja el perimetro de la caja con borde de grosor 4
      
      letter_size(8,32); // tamaño de letra 16x64
      PX= 0; PY= 18; color= 0xff000000; bkcolor=0;
      
      SelectFontTexture(0); // selecciona font principal

      Calculo_de_Altura();
      
      autocenter=1; // autocentrado on
//      s_printf("Altura %d %d %d\n",SCR_WIDTH,SCR_HEIGHT,Altura);
      s_printf("Wiilander: Altura: %dm Vx: %3.2f  Vy: %3.2f\n",Altura,Vx,gforce.x);

      autocenter=0;
      
      
      // configura para usar color con GX_Begin (funcion de dibujado de poligonos de GX)
      ConfigureForColor();
      
//      #if 1
//      GX_Begin(GX_LINES, GX_VTXFMT0, 80*4*2); // dibuja 80*4 lineas (en matriz de 2x2) * 2 vertices
//      for(n=0;n<80;n++)
//         {
//         AddColorVertex(n*8, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         }
//      GX_End();
//
//


   // Controles de entrada

      WPAD_ScanPads();                  //Lee todos los mandos
      WPAD_GForce(0, &gforce);            //Lee la aceleracion del mando 1

      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) {
      Zoom=2;
      }
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) {
      Zoom=1;
            }


   //Solo para test...
      if ( WPAD_ButtonsHeld(0) & WPAD_BUTTON_A ){
         WPAD_Rumble(0,1);
         Nave_x=320;
         Nave_y=264;
         Vx=Vy=scroll_y=scroll_x=0;
         Fuel_Nave=10000;
         
      } else{
         WPAD_Rumble(0,0);      
      }
            
         
         

      

   // Calculo de cinematica
   // la cinematica por ahora esta hecha a ojo.. la idea, es poner una cinematica mas seria, que incluso tenga en cuenta el peso del combustible
   // que queda en el tanque.. ¿Alguien se anima?
   
      
         Angulo=3.14159*gforce.y;
         
         Vx_init=Vx;
         Vy_init=Vy;
         
         
         
   
   
         
         
   if (Fuel_Nave>0){
      if (gforce.x>0){
         
            // Dibuja el fuego de la nave
      GX_Begin(GX_LINES, GX_VTXFMT0, 2*2);
         Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)-2*cos(Angulo)*Zoom+7*sin(Angulo)*Zoom;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))+2*sin(Angulo)*Zoom+7*cos(Angulo)*Zoom-264+264*Zoom;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+0*cos(Angulo)*Zoom+25*gforce.x*sin(Angulo)*Zoom;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-0*sin(Angulo)*Zoom+25*gforce.x*cos(Angulo)*Zoom-264+264*Zoom;
         
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         
         Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+2*cos(Angulo)*Zoom+7*sin(Angulo)*Zoom;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-2*sin(Angulo)*Zoom+7*cos(Angulo)*Zoom-264+264*Zoom;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+0*cos(Angulo)*Zoom+25*gforce.x*sin(Angulo)*Zoom;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-0*sin(Angulo)*Zoom+25*gforce.x*cos(Angulo)*Zoom-264+264*Zoom;
         
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         
      GX_End();
   
      
         Fuel_Nave=Fuel_Nave-(gforce.x*Potencia_Nave);         
         Acx=sin(-Angulo)*gforce.x*Potencia_Nave;
         Acy=G-(cos(Angulo)*gforce.x*Potencia_Nave);
   }   else    {
         Acy=G;
            }   
      }
   
// no deja subir mas de 400m

   
   if (Altura>400) {
         Acy=4.5*G;
            }
         
         Vx= (Acx*delta)+Vx_init;
         Vy= (Acy*delta)+Vy_init;

         posx_init=Nave_x;
         posy_init=Nave_y;

             
         if (((Vx*delta)+posx_init>240) && ((Vx*delta)+posx_init<400)) {
         Nave_x=(Vx*delta)+posx_init;
               }
         if ((Vx*delta)+posx_init<240) {
         scroll_x-=(Vx*delta);
               }
         if ((Vx*delta)+posx_init>400) {
         scroll_x-=(Vx*delta);
               }
   
         if (((Vy*delta)+posy_init>198) && ((Vy*delta)+posy_init<330)) {
         Nave_y=(Vy*delta)+posy_init;
               }
         if ((Vy*delta)+posy_init<198) {
         scroll_y-=(Vy*delta);
               }
         if ((Vy*delta)+posy_init>330) {
         scroll_y-=(Vy*delta);
               }

   

//         Nave_x=(Vx*delta)+posx_init;
//         Nave_y=(Vy*delta)+posy_init;





      // Dibuja la Nave
      // Aparte de tener que usar trigonometria, para girar la nave.. al hacer un zoom, tengo que transladar las coordenadas, para poder aplicar el zoom,
      // y luego volver a transladarlas.. En la coordenada y, se ve mejor.. lo que hago es calcular la altura hasta el cero, aplicar el zoom, y volver a
      // usar las coordenadas que maneja la wii de 0 a 528.. siendo 528 altura =0, se podria hacer de una manera mas eficaz.. pero la Wii puede con esto
      // sin problemas.. lo del (Zoom/2) que aplico a la nave lo hago porque sino salia muy grande.. ya lo modificare en la versión final.
      GX_Begin(GX_LINES, GX_VTXFMT0, 21*2); // dibuja  Nave  23x2
      for(n=0;n<21;n++)
         {
         Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom+Modelo_Nave[n][1]*sin(Angulo)*Zoom;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom+Modelo_Nave[n][1]*cos(Angulo)*Zoom-264+264*Zoom;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom+Modelo_Nave[n][3]*sin(Angulo)*Zoom;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom+Modelo_Nave[n][3]*cos(Angulo)*Zoom-264+264*Zoom;
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();

   

      // Dibuja el Mapa
      // Creamos una Tabla con el mapa que se puede dibujar, es decir que esta X ( 0:640) e y (0:528)
      
      lineas_mapa=0;
      for(n=0;n<71;n++)
         {
            Line_x1=(Zoom*Mapa_Fase1[n][0])+320+scroll_x*Zoom;
            Line_y1=SCR_HEIGHT-(Zoom*(Mapa_Fase1[n][1]))+scroll_y*Zoom-264+264*Zoom;
            Line_x2=(Zoom*Mapa_Fase1[n][2])+320+scroll_x*Zoom;
            Line_y2=SCR_HEIGHT-(Zoom*(Mapa_Fase1[n][3]))+scroll_y*Zoom-264+264*Zoom;
            
            if ((Line_x1>-1-80 && Line_x1<SCR_WIDTH+80) && (Line_x2>-1-80 && Line_x2<SCR_WIDTH+80) && (Line_y1>-1-80 && Line_y1<SCR_HEIGHT+180) && (Line_y2>-1-80 && Line_y2<SCR_HEIGHT+180)) {
               Mapa[lineas_mapa][0]=Line_x1;
               Mapa[lineas_mapa][1]=Line_y1;
               Mapa[lineas_mapa][2]=Line_x2;
               Mapa[lineas_mapa][3]=Line_y2;
               lineas_mapa++;
                              }
         }
      
      
      GX_Begin(GX_LINES, GX_VTXFMT0, lineas_mapa*2); // dibuja  mapa
      for(n=0;n<lineas_mapa;n++)
         {
         Line_x1=Mapa[n][0];
         Line_y1=Mapa[n][1];
         Line_x2=Mapa[n][2];
         Line_y2=Mapa[n][3];
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();
         
         

      // calculo de colision, si hay una colision ponemos la variable colision a uno.. testeamos todas la lineas de la nave, con todas las lineas que dibujan
      // el mapa.

      for(nn=0;nn<lineas_mapa;nn++)
         {
         
         for(n=0;n<21;n++)
            {
            Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom+Modelo_Nave[n][1]*sin(Angulo)*Zoom;
            Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom+Modelo_Nave[n][1]*cos(Angulo)*Zoom-264+264*Zoom;
            Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom+Modelo_Nave[n][3]*sin(Angulo)*Zoom;
            Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom+Modelo_Nave[n][3]*cos(Angulo)*Zoom-264+264*Zoom;
      if (lineCollide(Mapa[nn][0],Mapa[nn][1],Mapa[nn][2],Mapa[nn][3],Line_x1,Line_y1,Line_x2,Line_y2)){
         colision = 1;
      }

   
            }
   
         }


      // por ahora si tenemos una colision, volvemos al principio.

      if ( colision == 1 ){
         WPAD_Rumble(0,1);
         Nave_x=320;
         Nave_y=264;
         Vx=Vy=scroll_y=scroll_x=0;
         Fuel_Nave=10000;
         colision=0;
         
      }


      Calculo_de_Altura();

      if (Altura<70){
      Zoom=2;
      }
      
      
      if (Altura>72) {
      Zoom=1;
      }

      if (Altura>200) {
      Zoom=0.5;
      }





      // borra e intercambia la pantalla, espera al retrazado vertical
      Screen_flip();
      
      
      // entra en un  bucle y no sale hasta que llegue a los 40 milisegundos contando desde que se hizo el resetimebase()
      do {
            frametime=CurrentTime();
         } while (frametime<40);
               
      }
   
      

exit(0);

}



Salu2,

Manny
manny
 
Mensajes: 22
Registrado: Lunes, 1 de Diciembre de 2008 00:03

Re: Wiilander

Notapor manny » Domingo, 11 de Enero de 2009 20:10

Nueva version.. con bastantes mejoras:

---> La nave explota
---> Marcadores
---> Zonas de aterrizaje..

Salu2,

Manny



Código: Seleccionar todo
/* Wiilander

Copyright (c) 2008 Manny
All rights reserved.
http://www.entuwii.net/foro/viewtopic.php?f=14&t=102

Use the fantastics ;) screenlib and asndlib, libraries  Copyright (c) 2008 Hermes,
and the Wii programation training from Hermes:
      http://www.entuwii.net/foro/viewtopic.php?f=6&t=94


Redistribution and use in source and binary forms, with or without modification, are
permitted provided that the following conditions are met:

- Redistributions of source code must retain the above copyright notice, this list of
  conditions and the following disclaimer.
- Redistributions in binary form must reproduce the above copyright notice, this list
  of conditions and the following disclaimer in the documentation and/or other
  materials provided with the distribution.
- The names of the contributors may not be used to endorse or promote products derived
  from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

#define USE_MODPLAYER 1

#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <math.h>
#include <ogcsys.h>
#include <gccore.h>
#include <wiiuse/wpad.h>

#include <fat.h>
#include <fcntl.h>
#include "unistd.h"
#include <ogc/lwp_watchdog.h>

#include "screen.h"

#include "asndlib.h"

#ifdef USE_MODPLAYER
// MOD Player
#include "gcmodplay.h"

MODPlay mod_track;

#include "hybris.h"

#endif






// Gestion de tiempo.  funciones para crear una pausa de x milisegundos
u64 ini_milisegundos, fin_milisegundos, frametime;

void ResetTimeBase() {
  ini_milisegundos=ticks_to_millisecs(gettime());
}

int CurrentTime() {
  fin_milisegundos=ticks_to_millisecs(gettime());
  return fin_milisegundos-ini_milisegundos;
}



// Gestion de salida
int return_reset=1;
int exit_by_reset=0;

void reset_call() {exit_by_reset=return_reset;}
void power_call() {exit_by_reset=3;}

void fun_exit()
{
   ASND_End();      // finaliza el sonido
   WPAD_Shutdown();
   Screen_flip();  // espera a que acabe el GX si está en uso
   fatUnmount(PI_INTERNAL_SD); // desmonta la partición de la SD
   usleep(500);   // espera 500 ms por si hay algo que esté trabajando todavía
   if(exit_by_reset==2)
      SYS_ResetSystem(SYS_RETURNTOMENU, 0, 0);
   if(exit_by_reset==3)
      SYS_ResetSystem(SYS_POWEROFF_STANDBY, 0, 0);

exit(0);

}


// funcion lineCollide detecta si dos lineas AB BC se tocan.

int lineCollide(float ax,float ay, float bx, float by, float cx, float cy, float dx, float dy)
   {
   
      ax+=0.01;
      ay+=0.02;
      bx+=0.03;
      by+=0.04;
      cx+=0.05;
      cy+=0.06;
      dx+=0.07;
      dy+=0.08;
      
      float tarray[4][2]; //<===== Find the inner bounding of rect ABCD
      if (ax<bx){
               tarray[0][0]=ax;
               tarray[1][0]=bx;
      } else {
               tarray[0][0]=bx;
               tarray[1][0]=ax;
               }
      if (ay<by){
               tarray[0][1]=ay;
               tarray[1][1]=by;
      } else {
               tarray[0][1]=by;
               tarray[1][1]=ay;
   }
      if (cx<dx){
               tarray[2][0]=cx;
               tarray[3][0]=dx;
      } else {
               tarray[2][0]=dx;
               tarray[3][0]=cx;
   }

      if (cy<dy){
               tarray[2][1]=cy;
               tarray[3][1]=dy;
      } else {
               tarray[2][1]=dy;
               tarray[3][1]=cy;
      }

   float tarray2[2][2]; //<===== Sort Section Two

      if (tarray[0][0]<tarray[2][0]) { tarray2[0][0]=tarray[2][0]; }else{ tarray2[0][0]=tarray[0][0]; } //biggest of the small ones
      if (tarray[0][1]<tarray[2][1]) { tarray2[0][1]=tarray[2][1]; }else{ tarray2[0][1]=tarray[0][1]; } //biggest of the small ones
      if (tarray[1][0]<tarray[3][0]) { tarray2[1][0]=tarray[1][0]; }else{ tarray2[1][0]=tarray[3][0]; } //biggest of the small ones
      if (tarray[1][1]<tarray[3][1]) { tarray2[1][1]=tarray[1][1]; }else{ tarray2[1][1]=tarray[3][1]; } //biggest of the small ones
      float mab=(ay-by)/(ax-bx); //<===== Find Slopes of Lines
      float mcd=(cy-dy)/(cx-dx);
      if (mab==mcd) return 0; //the lines are paralell
      float yiab=((ax-bx)*ay-ax*(ay-by))/(ax-bx); //<===== Find the y Intercept of Lines
      float yicd=((cx-dx)*cy-cx*(cy-dy))/(cx-dx);
      float x=(yicd-yiab)/(mab-mcd); //<===== Find the Intersection Points of the Line
      float y=mab*x+yiab;
      if (x>tarray2[0][0] && x<tarray2[1][0] && y>tarray2[0][1] && y<tarray2[1][1]) { return 1; }else{ return 0; }
         }



// Informacion de graficos

// El modelo de la nave esta refenciado en coordenadas 0.0 (es decir 0.0 es el centro de la nave) lo hago asi para poder aplicar los zooms,
// y la trigonometria necesaria para girar la nave.

int  Modelo_Nave[22][4]= {
                           { -3, -10,  3, -10},
                           {  3, -10,  6,  -7},
                           {  6,  -7,  6,  -4},
                           {  6,  -4,  3,  -1},
                           { -3,  -1, -6,  -4},
                           { -6,  -4, -6,  -7},
                           { -6,  -7, -3, -10},
                           { -6,  -1,  6,  -1},
                           {  6,  -1,  6,   4},
                           {  6,   1,  8,   7},
                           {  4,   4,  8,   7},
                           {  8,   7,  8,  10},
                           {  6,  10, 10,  10},
                           {  6,   4, -6,   4},
                           { -6,  -1, -6,   4},
                           { -6,   1, -8,   7},
                           { -4,   4, -8,   7},
                           { -8,   7, -8,  10},
                           {-10,  10, -6,  10},
                           {  0,   4,  2,   7},
                           {  0,   4, -2,   7},
                           { -2,   7,  2,   7}
                          };             // Diseño de la Nave
   


// Mapa Fase 1 la tabla define las lineas, que forman el mapa (posicion X1, altura1, posicion x2, altura2)
int  Mapa_Fase1[71][4]= {
{  -650,  950,  -680,  650}, 
{  -680,  650,  -650,  400}, 
{  -650,  400,  -640,  243}, 
{  -640,  243,  -610,  238}, 
{  -610,  238,  -590,  228}, 
{  -590,  228,  -580,  223}, 
{  -580,  223,  -550,  213}, 
{  -550,  213,  -540,  203}, 
{  -540,  203,  -530,  188}, 
{  -530,  188,  -520,  183}, 
{  -520,  183,  -480,  183}, 
{  -480,  183,  -460,  188}, 
{  -460,  188,  -450,  198}, 
{  -450,  198,  -420,  178}, 
{  -420,  178,  -410,  203}, 
{  -410,  203,  -400,  218}, 
{  -400,  218,  -365,  218}, 
{  -365,  218,  -360,  213}, 
{  -360,  213,  -350,  193}, 
{  -350,  193,  -330,  188}, 
{  -330,  188,  -310,  178}, 
{  -310,  178,  -290,  173}, 
{  -290,  173,  -280,  153}, 
{  -280,  153,  -270,  148}, 
{  -270,  148,  -250,  138}, 
{  -250,  138,  -230,  113}, 
{  -230,  113,  -220,  83}, 
{  -220,  83,  -210,  68}, 
{  -210,  68,  -180,  53}, 
{  -180,  53,  -150,  48}, 
{  -150,  48,  -140,  43}, 
{  -140,  43,  -120,  43}, 
{  -120,  43,  -100,  53}, 
{  -100,  53,  -90,  68}, 
{  -90,  68,  -110,  83}, 
{  -110,  83,  -120,  98}, 
{  -120,  98,  -100,  123}, 
{  -100,  123,  -70,  133}, 
{  -70,  133,  -50,  153}, 
{  -50,  153,  -20,  158}, 
{  -20,  158,  10,  138}, 
{  10,  138,  20,  113}, 
{  20,  113,  10,  93}, 
{  10,  93,  40,  78}, 
{  40,  78,  60,  48}, 
{  60,  48,  90,  43}, 
{  90,  43,  110,  43}, 
{  110,  43,  130,  113}, 
{  130,  113,  150,  128}, 
{  150,  128,  170,  103}, 
{  170,  103,  210,  78}, 
{  210,  78,  240,  33}, 
{  240,  33,  280,  23}, 
{  280,  23,  300,  23}, 
{  300,  23,  320,  58}, 
{  320,  58,  380,  143}, 
{  380,  143,  410,  43}, 
{  410,  43,  440,  28}, 
{  440,  28,  470,  8}, 
{  470,  8,  490,  3}, 
{  490,  3,  510,  3}, 
{  510,  3,  520,  23}, 
{  520,  23,  550,  203}, 
{  550,  203,  580,  273}, 
{  580,  273,  600,  193}, 
{  600,  193,  610,  188}, 
{  610,  188,  630,  188}, 
{  630,  188,  640,  243}, 
{  640,  243,  660,  473}, 
{  660,  473,  675,  650}, 
{  675,  650,  660,  950} 
                  };             // Mapa Fase 1
 

int  Mapa_Pistas_Fase1[2][4]= {
{  -520,  185,  -480,  185}, 
{  -400,  220,  -365,  220}
                     };



int Nave_x=320,Nave_y=264,scroll_x=120,scroll_y=160;                  // Posicion Inicial de la Nave, por defecto 400,240
float Angulo=0;
float   Zoom=1;
float   Vx_init=0, Vy_init=0, Vx=0, Vy=0;      // control de velocidad
int    Fuel_Nave= 100000;                  // combstible de la nave
int    Potencia_Nave=12;                  // Potencia de los motores
float    G=3;                           // G
float    delta= 0.05;
float    Acx=0,Acy=0;                     // Aceleracion.
int   posx_init, posy_init;


int Altura=0;
int n=0, nn=0;
int colision=0;


void Calculo_de_Altura() {
         Altura=0;
          while (Altura < 500){
         n=0;
         while (n < 71){
            if    (lineCollide(((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x))-1,(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)))+Altura+7,((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x))+1,(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)))-1,(Mapa_Fase1[n][0])+320+scroll_x,SCR_HEIGHT-((Mapa_Fase1[n][1]))+scroll_y,(Mapa_Fase1[n][2])+320+scroll_x,SCR_HEIGHT-((Mapa_Fase1[n][3]))+scroll_y)== 1){
                           return;   }
         n += 1;   }   
         Altura += 1;
          }
         }





int main(int argc, char **argv)
{

int n;


short Line_x1,Line_y1,Line_x2,Line_y2;



int Mapa[71][4];                     // Mapa que se puede dibujar
int lineas_mapa=0;                     // Numero de lineas del mapa que se pueden dibujar

int Pistas[10][4];                        // Pistas que se puede dibujar
int lineas_pistas=0;                     // Numero de lineas de pistas que se pueden dibujar


int explosion[22][2]={ { 12, 0},         // velocididad de la particula, angulo de la particula
                  { 12, 1},
                  { 11, 2},
                  { 9, 3},
                  { 7, 4},
                  { 8, 5},
                  { 14, 6},
                  { 16, 7},
                  { 9, 8},
                  { 8, 9},
                  { 9, 10},
                  { 7, 11},
                  { 11, 12},
                  { 13, 13},
                  { 14, 14},
                  { 16, 15},
                  { 11, 16},
                  { 9, 17},
                  { 8, 18},
                  { 9, 19},
                  { 7, 20},
                  { 6, 21}
               };
float t_explosion=0;

gforce_t gforce;


   return_reset=1;                  // esto sirve para elegir el tipo de retorno en caso de pulsar RESET (1-> Homebrew Browser, 2->RESET)
   if(argc<1) return_reset=2;
   InitScreen();                       // Inicialización del Vídeo.
   SYS_SetResetCallback(reset_call);   // fija la callback para el boton RESET
   SYS_SetPowerCallback(power_call);   // fija la callback para el boton POWER

   ASND_Init();                  // Inicializa la librería de sonido
   
   WPAD_Init();                        // Inicializa el lector de pad
   WPAD_SetDataFormat(0,WPAD_FMT_BTNS_ACC_IR);
   WPAD_SetVRes(0,640,480);

   fatInit(8, false);               // Inicializa la libreria FAT
    fatSetDefaultInterface(PI_INTERNAL_SD); // fija el device "fat:" a la SD

   atexit(fun_exit);               // fija la funcion de salida (aqui se finaliza el uso de dispositivos, etc: usa exit(0); para salir del programa)
   
   ASND_Pause(0);                  // Pausa de sonido global a 0

   // inicializa el modplayer en modo loop infinito
   MODPlay_Init(&mod_track);

   if (MODPlay_SetMOD (&mod_track, hybris ) < 0 ) // set the MOD song
      {
      MODPlay_Unload (&mod_track);   
      }
   else 
      {
      MODPlay_SetVolume( &mod_track, 32,32); // fix the volume to 32 (max 64)
      MODPlay_Start (&mod_track); // Play the MOD
      }


   while(1)                     // bucle principal
      {
      ResetTimeBase();            //ponemos el contador de tiempo a cero.

      if(exit_by_reset) exit(0);                           // comprueba si se han pulsado RESET o POWER y sal si es asi
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_HOME) exit(0);      // comprueba si se han pulsado Home en wiimote 1 y sal si es asi
      
      // dibujado de la caja

      SetTexture(NULL);

//      DrawRoundFillBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 0xffafafaf); // dibuja una caja solida
//      DrawRoundBox2(SCR_WIDTH/2-200, 16, 400, 40, 0, 4, 0xff00ffff); // dibuja el perimetro de la caja con borde de grosor 4
      
      letter_size(8,32); // tamaño de letra 16x64
//      PX= 0; PY= 18; color= 0xff000000; bkcolor=0;

      
      SelectFontTexture(0); // selecciona font principal
      Calculo_de_Altura();

      autocenter=0; // autocentrado off

      PX= SCR_WIDTH/16;PY= SCR_HEIGHT/64;color= 0xffafafaf;bkcolor= 0;
      s_printf("Score:  ");
      
         PX= SCR_WIDTH/16;PY= SCR_HEIGHT/64+24;color= 0xffafafaf;bkcolor= 0;
      s_printf("Fuel:  %d",Fuel_Nave);
      
            PX= SCR_WIDTH/16;PY= SCR_HEIGHT/64+48;color= 0xffafafaf;bkcolor= 0;
      s_printf("TIME:   %d",0);
            
      PX= SCR_WIDTH-(SCR_WIDTH/4);PY= SCR_HEIGHT/64;color= 0xffafafaf;bkcolor= 0;
      s_printf("Altitude: %d",Altura);
            
      PX= SCR_WIDTH-(SCR_WIDTH/4);PY= SCR_HEIGHT/64+24;color= 0xffafafaf;bkcolor= 0;
      s_printf("H Speed: %3.2f",Vx);
            
      PX= SCR_WIDTH-(SCR_WIDTH/4);PY= SCR_HEIGHT/64+48;color= 0xffafafaf;bkcolor= 0;
      s_printf("V Speed: %3.2f",Vy);


//      autocenter=1; // autocentrado on

//      s_printf("Altura %d %d %d\n",Nave_x,Nave_y,scroll_y);
//      s_printf("Wiilander: Altura: %dm Vx: %3.2f  Vy: %3.2f\n",Altura,Vx,Vy);

      autocenter=0;
   


      // configura para usar color con GX_Begin (funcion de dibujado de poligonos de GX)
      ConfigureForColor();
      
//      #if 1
//      GX_Begin(GX_LINES, GX_VTXFMT0, 80*4*2); // dibuja 80*4 lineas (en matriz de 2x2) * 2 vertices
//      for(n=0;n<80;n++)
//         {
//         AddColorVertex(n*8, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n], 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1], 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         AddColorVertex(n*8+1, tabla[n]+1, 1, 0xffff9000);  // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
//         AddColorVertex((n+1)*8+1,tabla[n+1]+1, 1, 0xffff9000); // segundo vertice
//         }
//      GX_End();
//
//


   // Controles de entrada

      WPAD_ScanPads();                  //Lee todos los mandos
      WPAD_GForce(0, &gforce);            //Lee la aceleracion del mando 1

      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_PLUS) {
      Zoom=2;
      }
      if (WPAD_ButtonsDown(0) & WPAD_BUTTON_MINUS) {
      Zoom=1;
            }

   //Solo para test...
      if ( WPAD_ButtonsHeld(0) & WPAD_BUTTON_A ){
         WPAD_Rumble(0,1);
         Nave_x=320;
         Nave_y=264;
         Vx=Vy=0;
         scroll_y=scroll_x=160;
         Fuel_Nave=10000;
         
      } else{
         WPAD_Rumble(0,0);      
      }
            
         
         

      // Dibuja el Mapa
      // Creamos una Tabla con el mapa que se puede dibujar, es decir que esta X ( 0:640) e y (0:528)
      
      lineas_mapa=0;
      for(n=0;n<71;n++)
         {
            Line_x1=(Zoom*Mapa_Fase1[n][0])+320+scroll_x*Zoom;
            Line_y1=SCR_HEIGHT-(Zoom*(Mapa_Fase1[n][1]))+scroll_y*Zoom-264+264*Zoom;
            Line_x2=(Zoom*Mapa_Fase1[n][2])+320+scroll_x*Zoom;
            Line_y2=SCR_HEIGHT-(Zoom*(Mapa_Fase1[n][3]))+scroll_y*Zoom-264+264*Zoom;
            
            if ((Line_x1>-1-80 && Line_x1<SCR_WIDTH+80) && (Line_x2>-1-80 && Line_x2<SCR_WIDTH+80) && (Line_y1>-1-80 && Line_y1<SCR_HEIGHT+180) && (Line_y2>-1-80 && Line_y2<SCR_HEIGHT+180)) {
               Mapa[lineas_mapa][0]=Line_x1;
               Mapa[lineas_mapa][1]=Line_y1;
               Mapa[lineas_mapa][2]=Line_x2;
               Mapa[lineas_mapa][3]=Line_y2;
               lineas_mapa++;
                              }
         }
      
      
      GX_Begin(GX_LINES, GX_VTXFMT0, lineas_mapa*2); // dibuja  mapa
      for(n=0;n<lineas_mapa;n++)
         {
         Line_x1=Mapa[n][0];
         Line_y1=Mapa[n][1];
         Line_x2=Mapa[n][2];
         Line_y2=Mapa[n][3];
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();
         
         
      // Dibuja el pistas
      // Creamos una Tabla con el mapa que se puede dibujar, es decir que esta X ( 0:640) e y (0:528)
      
      lineas_pistas=0;
      for(n=0;n<2;n++)
         {
            Line_x1=(Zoom*Mapa_Pistas_Fase1[n][0])+320+scroll_x*Zoom;
            Line_y1=SCR_HEIGHT-(Zoom*(Mapa_Pistas_Fase1[n][1]))+scroll_y*Zoom-264+264*Zoom;
            Line_x2=(Zoom*Mapa_Pistas_Fase1[n][2])+320+scroll_x*Zoom;
            Line_y2=SCR_HEIGHT-(Zoom*(Mapa_Pistas_Fase1[n][3]))+scroll_y*Zoom-264+264*Zoom;
            
            if ((Line_x1>-1-80 && Line_x1<SCR_WIDTH+80) && (Line_x2>-1-80 && Line_x2<SCR_WIDTH+80) && (Line_y1>-1-80 && Line_y1<SCR_HEIGHT+180) && (Line_y2>-1-80 && Line_y2<SCR_HEIGHT+180)) {
               Pistas[lineas_pistas][0]=Line_x1;
               Pistas[lineas_pistas][1]=Line_y1;
               Pistas[lineas_pistas][2]=Line_x2;
               Pistas[lineas_pistas][3]=Line_y2;
               lineas_pistas++;
                              }
         }
      
      
      GX_Begin(GX_LINES, GX_VTXFMT0, lineas_pistas*8); // dibuja  mapa
      for(n=0;n<lineas_pistas;n++)
         {
         Line_x1=Pistas[n][0];
         Line_y1=Pistas[n][1];
         Line_x2=Pistas[n][2];
         Line_y2=Pistas[n][3];
         AddColorVertex(Line_x1,Line_y1, 1, 0xff00ff00);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xff00ff00);    // segundo vertice

         AddColorVertex(Line_x1,Line_y1-1, 1, 0xff00ff00);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xff00ff00);    // segundo vertice
         
         AddColorVertex(Line_x1,Line_y1, 1, 0xff00ff00);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2-1, 1, 0xff00ff00);    // segundo vertice
         
         AddColorVertex(Line_x1,Line_y1-1, 1, 0xff00ff00);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2-1, 1, 0xff00ff00);    // segundo vertice

         }
      GX_End();



      // calculo de contacto con las pistas de aterrizaje

      for(nn=0;nn<lineas_pistas;nn++)
         {
         
         for(n=0;n<21;n++)
            {
            Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom+Modelo_Nave[n][1]*sin(Angulo)*Zoom;
            Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom+Modelo_Nave[n][1]*cos(Angulo)*Zoom-264+264*Zoom;
            Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom+Modelo_Nave[n][3]*sin(Angulo)*Zoom;
            Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom+Modelo_Nave[n][3]*cos(Angulo)*Zoom-264+264*Zoom;
               if (lineCollide(Pistas[nn][0],Pistas[nn][1],Pistas[nn][2],Pistas[nn][3],Line_x1,Line_y1,Line_x2,Line_y2)){
      
//               colision = 100;
               Nave_x=320;
               Nave_y=264;
               Vx=Vy=0;
               scroll_y=scroll_x=160;
               Fuel_Nave=10000;

                  }
            }
         }





   if (colision==0){


   // Calculo de cinematica
   // la cinematica por ahora esta hecha a ojo.. la idea, es poner una cinematica mas seria, que incluso tenga en cuenta el peso del combustible
   // que queda en el tanque.. ¿Alguien se anima?
   
      
         Angulo=3.14159*gforce.y;
         Vx_init=Vx;
         Vy_init=Vy;
   
         if (Altura>400) {   Acy=4.5*G; }      // no deja subir mas de 400m
         
         Vx= (Acx*delta)+Vx_init;
         Vy= (Acy*delta)+Vy_init;

         posx_init=Nave_x;
         posy_init=Nave_y;

             
         if (((Vx*delta)+posx_init>240) && ((Vx*delta)+posx_init<400)) {
         Nave_x=(Vx*delta)+posx_init;
               }
         if ((Vx*delta)+posx_init<240) {
         scroll_x-=(Vx*delta);
               }
         if ((Vx*delta)+posx_init>400) {
         scroll_x-=(Vx*delta);
               }
   
         if (((Vy*delta)+posy_init>198) && ((Vy*delta)+posy_init<330)) {
         Nave_y=(Vy*delta)+posy_init;
               }
         if ((Vy*delta)+posy_init<198) {
         scroll_y-=(Vy*delta);
               }
         if ((Vy*delta)+posy_init>330) {
         scroll_y-=(Vy*delta);
               }
   

      // calculo de colision, si hay una colision ponemos la variable colision a uno.. testeamos todas la lineas de la nave, con todas las lineas que dibujan
      // el mapa.

      for(nn=0;nn<lineas_mapa;nn++)
         {
         
         for(n=0;n<21;n++)
            {
            Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom+Modelo_Nave[n][1]*sin(Angulo)*Zoom;
            Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom+Modelo_Nave[n][1]*cos(Angulo)*Zoom-264+264*Zoom;
            Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom+Modelo_Nave[n][3]*sin(Angulo)*Zoom;
            Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom+Modelo_Nave[n][3]*cos(Angulo)*Zoom-264+264*Zoom;
      if (lineCollide(Mapa[nn][0],Mapa[nn][1],Mapa[nn][2],Mapa[nn][3],Line_x1,Line_y1,Line_x2,Line_y2)){
         colision = 100;
      }
            }
         }
         









      // Dibuja la Nave
      // Aparte de tener que usar trigonometria, para girar la nave.. al hacer un zoom, tengo que transladar las coordenadas, para poder aplicar el zoom,
      // y luego volver a transladarlas.. En la coordenada y, se ve mejor.. lo que hago es calcular la altura hasta el cero, aplicar el zoom, y volver a
      // usar las coordenadas que maneja la wii de 0 a 528.. siendo 528 altura =0, se podria hacer de una manera mas eficaz.. pero la Wii puede con esto
      // sin problemas.. lo del (Zoom/2) que aplico a la nave lo hago porque sino salia muy grande.. ya lo modificare en la versión final.
      GX_Begin(GX_LINES, GX_VTXFMT0, 21*2); // dibuja  Nave  23x2
      for(n=0;n<21;n++)
         {
         Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom+Modelo_Nave[n][1]*sin(Angulo)*Zoom;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom+Modelo_Nave[n][1]*cos(Angulo)*Zoom-264+264*Zoom;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom+Modelo_Nave[n][3]*sin(Angulo)*Zoom;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom+Modelo_Nave[n][3]*cos(Angulo)*Zoom-264+264*Zoom;
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         }
      GX_End();
      
      // Sin la nave tiene combustible, y giramos el mando dibuja la llamarada del motor.
      Acy=G;
      
      if (Fuel_Nave>0){
         if (gforce.x>0){
         
            // Dibuja el fuego de la nave
      GX_Begin(GX_LINES, GX_VTXFMT0, 2*2);
         Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)-2*cos(Angulo)*Zoom+7*sin(Angulo)*Zoom;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))+2*sin(Angulo)*Zoom+7*cos(Angulo)*Zoom-264+264*Zoom;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+0*cos(Angulo)*Zoom+(25*gforce.x+7)*sin(Angulo)*Zoom;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-0*sin(Angulo)*Zoom+(25*gforce.x+7)*cos(Angulo)*Zoom-264+264*Zoom;
         
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         
         Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+2*cos(Angulo)*Zoom+7*sin(Angulo)*Zoom;
         Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-2*sin(Angulo)*Zoom+7*cos(Angulo)*Zoom-264+264*Zoom;
         Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+0*cos(Angulo)*Zoom+(25*gforce.x+7)*sin(Angulo)*Zoom;
         Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-0*sin(Angulo)*Zoom+(25*gforce.x+7)*cos(Angulo)*Zoom-264+264*Zoom;
         
         AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
         AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
         
      GX_End();
   
         Fuel_Nave=Fuel_Nave-(gforce.x*Potencia_Nave);         
         Acx=sin(-Angulo)*gforce.x*Potencia_Nave;
         Acy=G-(cos(Angulo)*gforce.x*Potencia_Nave);
                     }
   }   
   
}


   




      // Si hay una colision, explotamos la nave usando la formula tipica de un proyectil
      // x = v*cos(a)*t ; y = v * sin(a)*t - 0.5 g * t *t
      // Creamos una matriz con 21 velocidades diferentes y con 21 angulos diferentes
      //

      if (colision>1){
         colision-=1;
         
         
         //   Angulo+=0.25;    // con esto conseguimos que los cachitos de nave roten... pero queda un pelin mal.. para arrglarlo tengo que crear
                        // otra matriz de la nave, con todos los segmentos referenciados en cero.. para una futura versión.
         GX_Begin(GX_LINES, GX_VTXFMT0, 21*2); // dibuja  Nave  23x2
         for(n=0;n<21;n++)
               {
                  Line_x1=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][0]*cos(Angulo)*Zoom+Modelo_Nave[n][1]*sin(Angulo)*Zoom;
                  Line_y1=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][0]*sin(Angulo)*Zoom+Modelo_Nave[n][1]*cos(Angulo)*Zoom-264+264*Zoom;
                  Line_x2=((SCR_WIDTH/2)-((SCR_WIDTH/2)-Nave_x)*Zoom)+Modelo_Nave[n][2]*cos(Angulo)*Zoom+Modelo_Nave[n][3]*sin(Angulo)*Zoom;
                  Line_y2=(SCR_HEIGHT-((SCR_HEIGHT-Nave_y)*Zoom))-Modelo_Nave[n][2]*sin(Angulo)*Zoom+Modelo_Nave[n][3]*cos(Angulo)*Zoom-264+264*Zoom;
      
                  Line_x1+=explosion[n][0]*cos(explosion[n][1])*t_explosion;
                  Line_y1-=explosion[n][0]*sin(explosion[n][1])*t_explosion-(0.5 *t_explosion *t_explosion);
                  Line_x2+=explosion[n][0]*cos(explosion[n][1])*t_explosion;
                  Line_y2-=explosion[n][0]*sin(explosion[n][1])*t_explosion-(0.5 *t_explosion *t_explosion);
         
         
                  AddColorVertex(Line_x1,Line_y1, 1, 0xffff9000);     // primer vertice  (recuerda que x1,y1 y z1 son enteros con signo de 16 bits)
                  AddColorVertex(Line_x2,Line_y2, 1, 0xffff9000);    // segundo vertice
               }
         
         GX_End();
         t_explosion+=0.5;
         
                  }



      if (colision==1){
         WPAD_Rumble(0,1);
         Nave_x=320;
         Nave_y=264;
         Vx=Vy=scroll_y=scroll_x=0;
         Fuel_Nave=10000;
         colision=0;
         t_explosion=0;
         }



      Calculo_de_Altura();

      if (Altura<70){
      Zoom=2;
      }
      
      
      if (Altura>72) {
      Zoom=1;
      }

      if (Altura>200) {
      Zoom=0.5;
      }





      // borra e intercambia la pantalla, espera al retrazado vertical
      Screen_flip();
      
      
      // entra en un  bucle y no sale hasta que llegue a los 40 milisegundos contando desde que se hizo el resetimebase()
      do {
            frametime=CurrentTime();
         } while (frametime<40);
               
      }
   
      

exit(0);

}

manny
 
Mensajes: 22
Registrado: Lunes, 1 de Diciembre de 2008 00:03

Re: Wiilander

Notapor suloku » Viernes, 16 de Enero de 2009 11:58

Esta ultima es la 0.3?
suloku
 
Mensajes: 8
Registrado: Jueves, 8 de Mayo de 2008 15:42

Siguiente

Volver a Aplicaciones

¿Quién está conectado?

Usuarios navegando por este Foro: No hay usuarios registrados visitando el Foro y 1 invitado

cron