DYNA/DYNA_JGD.CPP
2021-09-08 21:02:03 +02:00

992 lines
37 KiB
C++
Raw Blame History

#include <dos.h>
#include <time.h>
#include <conio.h>
#include <stdio.h>
#include <alloc.h>
#include "Dyna_tbl.h"
#include "..\libs\int_key\int_key.h"
#include "..\modex\modex.h"
#include "..\modex\c_utils.h"
#define BORRAR 0
#define REescribe 1
#define CTE_SALTO 80
extern char prt_tbl[13+1][21+1];
extern char prt_tbl2[13+1][21+1];
extern "C" void SET_VECTORES(volatile char *);
extern "C" void UNSET_VECTORES(void);
void limpia_teclado(void);
int RellanaConcursantes(void);
void ProcesaMovimientos(int Page);
void EscribeObjetos( int Accion, int Page );
void LiberaConcursantes(void);
// Establece preferencias por defecto
PREFERENCIAS Pref = { POS_BOSQUE, 4,
{
{ t_d, t_g, t_r, t_f, t_tab },
{ t_4n, t_6n, t_8n, t_2n, t_0n },
{ t_d, t_g, t_r, t_f , t_tab },
{ t_izquierda, t_derecha, t_arriba, t_abajo , t_0n }
/*
{ t_d, t_g, t_r, t_f },
{ t_d, t_g, t_r, t_f },
{ t_d, t_g, t_r, t_f },
{ t_d, t_g, t_r, t_f },
*/
}
};
volatile char mapa_teclado[512];
int RellanaConcursantes(void);
struct byte
{
int PuedeMatar : 1 ; // Informa sobre si puede matar por contacto
int PuedeMorir : 1 ; // Informa sobre si puede morir por contacto
int PuedeVolar : 1 ; // Informa sobre si puede atravezar los cuadros
int Dispara : 1 ; // Informa si el concursante puede disparar
int CaputDelTo : 1 ; // Informa si el concursante puede disparar
int Vidas : 4 ; // Vidas del concursante <= 4
};
// Esta estructura contendra todo lo que hay que procesar:
// (todo lo que se mueva) jugadores, enemigos, bombas, teleports
//
// NOTA: Las primeras estructuras deben corresponder a los HUMANOS
// tantas como participantes hubiesen...
typedef struct concursantes
{
char Tipo_de_concursante; // Quien Juega
char InfoConcursante;
int PosX, PosY; // Posicion del concursante
int old_PosX[2], old_PosY[2]; // Posiciones del concursante en cada pagina
char Direccion; // Direccion que toma el concursante
char Velocidad; // Como de rapido se mueve
char delay_time; // Tiempo de retraso por el que va
int secuencia_animada; // Secuencia de animaci<63>n por la que va
char Disparos; // # de disparos que puede poner al mismo tiempo
long DisparosP; // # de disparos ya puestos
char Longitud; // Longitud del disparo en cuadros;
struct byte Varios;
struct concursantes *poseed; // Due<75>o f<>sico de este objeto...
struct concursantes *sig; // Puntero al siguientes concursante
} CONCURSANTES;
CONCURSANTES *Concursantes;
CONCURSANTES *NuevoConcursante(struct concursantes *Concur);
//struct concursante *NuevoConcursante(struct concursantes *Concur);
void GeneraFuego( CONCURSANTES *aux );
void GeneraXYaleatorio( int *X, int *Y );
void ColocaBomba( CONCURSANTES *concursante );
CONCURSANTES *EliminaConcursante(struct concursantes *Concur);
void CompruebaCoordenadas(char incX, char incY, CONCURSANTES *objeto, char *Objeto_Caput );
void MovimientoAutomatico( CONCURSANTES *aux, char *incY, char *incX, int Page );
void ColocaFuego( int PosX, int PosY, CONCURSANTES *aux );
int jklop = 0;
extern CallBIOSHandler;
clock_t TiempoDeJuego, InicioDeJuego;
void ComienzaJuego(void)
{
int Current_Page = 0, cifraTMP;
long DTiempo;
limpia_teclado();
if ( RellanaConcursantes() == ERROR ) Error(0x30);
set_display_page( 1 );
CallBIOSHandler = 0;
InicioDeJuego = clock();
while( mapa_teclado[t_esc] == 0 )
{
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// mostramos el reloj...
TiempoDeJuego = clock();
DTiempo = ( TiempoDeJuego - InicioDeJuego ) / CLK_TCK;
// minutos
cifraTMP = ( DTiempo / 60 );
tdraw_bitmap ((char far *)( (Sprite[POS_NUMEROS].Sprite[0])+(long)16*18*( cifraTMP / 10 ) )
, 28 + 16*0, 3, 16, 11);
cifraTMP = ( cifraTMP - ( cifraTMP / 10 ) * 10 );
tdraw_bitmap ((char far *)( (Sprite[POS_NUMEROS].Sprite[0])+(long)16*18*cifraTMP )
, 28 + 16*1, 3, 16, 11);
// minutos
cifraTMP = ( DTiempo % 60 );
tdraw_bitmap ((char far *)( (Sprite[POS_NUMEROS].Sprite[0])+(long)16*18*( cifraTMP / 10 ) )
, 28 + 4 + 16*2, 3, 16, 11);
cifraTMP = ( cifraTMP - ( cifraTMP / 10 ) * 10 );
tdraw_bitmap ((char far *)( (Sprite[POS_NUMEROS].Sprite[0])+(long)16*18*( cifraTMP ) )
, 28 + 4 + 16*3, 3, 16, 11);
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if ( mapa_teclado[t_2] )
{
mapa_teclado[t_2] = 0;
set_display_page (2);
sleep(5);
}
if ( mapa_teclado[t_9] )
{
Pref.Entorno+=9; mapa_teclado[t_9] = 0;
if ( Pref.Entorno >= POS_BOSQUE + 3*9 )
Pref.Entorno = POS_BOSQUE;
}
if ( mapa_teclado[t_0] )
{
InicializaJuego(); mapa_teclado[t_0] = 0;
copy_page( 2, 1 );
copy_page( 2, 0 );
}
set_active_page (Current_Page);
EscribeObjetos( BORRAR, Current_Page );
// copy_page( 2, Current_Page );
ProcesaMovimientos( Current_Page );
EscribeObjetos( REescribe, Current_Page );
set_display_page (Current_Page);
Current_Page = Current_Page ^ 0x01;
};
LiberaConcursantes();
}
/**************************************************************************\
|* *|
|* EscribeObjetos *|
|* *|
|* Descripci<63>n: *|
|* Se encarga de escribir todos los objetos a la patalla: *|
|* a> se eliminan todos los objetos animados de la pantalla *|
|* b> se dibujan en las nuevas posiciones *|
|* *|
|* Entradas: BORRA ------> a *|
|* REescribe --> b *|
|* Salidas: (ninguna) *|
|* *|
\**************************************************************************/
void EscribeObjetos( int Accion, int Page )
{
CONCURSANTES *aux;
int Ancho, Alto;
// Empiezo por el principio
aux = Concursantes;
// Y mientras quede algo que procesar
while( aux != NULL )
{
// Obtengo las dimensiones
Ancho = InfoSprites[ aux -> InfoConcursante ].Ancho;
Alto = InfoSprites[ aux -> InfoConcursante ].Alto;
if ( Accion == BORRAR )
copy_bitmap (2, aux -> old_PosX[Page] + 12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[Page] + 20+InfoSprites[aux -> InfoConcursante].CorrY, aux -> old_PosX[Page]+12+Ancho+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[Page]+20+Alto+InfoSprites[aux -> InfoConcursante].CorrY,
Page, aux -> old_PosX[Page] + 12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[Page] + 20+InfoSprites[aux -> InfoConcursante].CorrY);
// copy_bitmap (2, aux -> old_PosX[Page] + 12, aux -> old_PosY[Page] + 20, aux -> old_PosX[Page]+12+Ancho, aux -> old_PosY[Page]+20+Alto,
// Page, aux -> old_PosX[Page] + 12, aux -> old_PosY[Page] + 20);
else
{
// Amplio la secuencia animada
// 0 Izq, 1 Der, 2 Arr, 3 Abj, Muerte
tdraw_bitmap ((char far *)( (Sprite[aux -> Tipo_de_concursante].Sprite[ aux -> InfoConcursante == SPR_BAQUERO ? 0 : aux->Direccion ])+(long)Ancho*Alto* (long)( aux->secuencia_animada ) ), aux -> PosX+12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> PosY+20+InfoSprites[aux -> InfoConcursante].CorrY, Ancho, Alto);
// tdraw_bitmap ((char far *)( (Sprite[aux -> Tipo_de_concursante].Sprite[aux->Direccion])+(long)Ancho*Alto* (long)( aux->secuencia_animada ) ), aux -> PosX+12, aux -> PosY+20, Ancho, Alto);
}
aux = aux -> sig;
};
}
/**************************************************************************\
|* *|
|* ProcesaMovimientos *|
|* *|
|* Descripci<63>n: *|
|* Genera los movimientos del HUMANO y maquina, despues *|
|* llama a la funci<63>n que los corrige... *|
|* *|
|* Entradas: Pagina de los movimientos *|
|* Salidas: (ninguna) *|
|* *|
\**************************************************************************/
void ProcesaMovimientos(int Page)
{
CONCURSANTES *aux;
char old_dir, enc;
char incX, incY, objeto_caput;
// Empiezo por el principio
aux = Concursantes;
// Y mientras quede algo que procesar
while( aux != NULL )
{
incX = incY = enc = objeto_caput = 0;
old_dir = aux -> Direccion;
// SOLO SE PROCESA SI ESTA VIVO
if ( aux -> Direccion != 4 )
{
switch( aux -> Tipo_de_concursante )
{
// Los jugadores procesan sus movimientos segun el usuario
// izq, der, arr, abj
case POS_JUGADORa:
case POS_JUGADORb:
// Izquierda
if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][0]] )
{
incX = - (aux -> Velocidad);
aux -> Direccion = 0;
enc = 1;
} else
// Derecha
if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][1]] )
{
incX = (aux -> Velocidad);
aux -> Direccion = 1;
enc = 1;
} else
// Arriba
if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][2]] )
{
incY = - (aux -> Velocidad);
aux -> Direccion = 2;
enc = 1;
} else
// Abajo
if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][3]] )
{
incY = (aux -> Velocidad);
aux -> Direccion = 3;
enc = 1;
} //else
// Bomba
if ( mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][4]] )
{
// Si puede disparar y el n<> de disparos puestos es menor al que tiene
if ( aux -> Varios.Dispara && aux -> DisparosP < aux -> Disparos )
{
mapa_teclado[Pref.Teclas[(aux -> Tipo_de_concursante)-POS_JUGADORa][4]] = 0;
ColocaBomba( aux );
}
}
break;
case POS_JUGADORd:
case POS_JUGADORc:
MovimientoAutomatico( aux, &incY, &incX, Page );
enc = 1;
break;
// La bomba no se mueve ( A menos que se encuentre en una zona deslizante
case POS_BOMBA:
// Eliminamos la bomba
if ( (clock() - (aux -> DisparosP))/CLK_TCK >= aux -> Varios.Vidas )
objeto_caput = 1;
enc = 1;
break;
case POS_BAQUERO:
MovimientoAutomatico( aux, &incY, &incX, Page );
enc = 1;
break;
// El resto sigue un algoritmo de movimiento ( actualmente ninguno );
default:
MovimientoAutomatico( aux, &incY, &incX, Page );
enc = 1;
break;
}
// Procesa las coordenadas si no esta caput ( Direccion 4 )
CompruebaCoordenadas( incX, incY, aux, &objeto_caput );
// Cambia de secuencia animada si corresponde
if ( enc )
{
// Empieza el nuevo movimiento por por 0 si es distinto
if ( aux -> Direccion != old_dir )
{
aux -> secuencia_animada = 0;
aux -> delay_time = 0;
} else
if ( (aux -> delay_time = aux -> delay_time + aux -> Velocidad) >= InfoSprites[ aux -> InfoConcursante ].PixelCambio )
{
aux -> delay_time = 0;
if ( (int)( aux -> secuencia_animada ) >= InfoSprites[ aux -> InfoConcursante ].Movimientos[ aux -> InfoConcursante == SPR_BAQUERO ? 0 : aux->Direccion] - 1 )
aux -> secuencia_animada = 0;
else
aux -> secuencia_animada = aux -> secuencia_animada + 1;
}
}
}else{
if ( aux -> secuencia_animada >= (InfoSprites[ aux -> InfoConcursante ].Movimientos[4] - 1) )
aux -> Varios.CaputDelTo = 1;
else
if ( (TiempoDeJuego/*clock()*/ - aux -> DisparosP)>>1 >= 1 )
{
aux -> DisparosP = TiempoDeJuego;//clock();
aux -> secuencia_animada = aux -> secuencia_animada + 1;
}
}
// Copia los movimientos a la pagina adecuada
aux -> old_PosX[Page] = aux -> PosX;
aux -> old_PosY[Page] = aux -> PosY;
if ( objeto_caput )
{
if ( aux -> Tipo_de_concursante == POS_BOMBA )
{
aux -> Varios.Vidas = 0;
aux -> Varios.CaputDelTo = 1;
GeneraFuego( aux );
} else {
aux -> Varios.Vidas = aux -> Varios.Vidas - 1;
aux -> Direccion = 4; // Activamos la muerte
aux -> secuencia_animada = 0;
aux -> DisparosP = TiempoDeJuego;
}
}
if ( aux -> Varios.CaputDelTo )
{
// Borramos al objeto de la pantalla
incX = InfoSprites[ aux -> InfoConcursante ].Ancho;
incY = InfoSprites[ aux -> InfoConcursante ].Alto;
if ( aux -> InfoConcursante == SPR_FUEGO )
{
set_active_page (2);
aux -> DisparosP = (Pref.Entorno+4);
draw_bitmap ((char far*)( Sprite[POS_ELEM_MAPA].Sprite[0] + /*incX * incY **/((aux -> DisparosP)<<8) ), aux -> PosX + 12 , aux -> PosY + 20, incX, incY );
set_active_page (Page);
draw_bitmap ((char far*)( Sprite[POS_ELEM_MAPA].Sprite[0] + /*incX * incY **/((aux -> DisparosP)<<8) ), aux -> PosX + 12 , aux -> PosY + 20, incX, incY );
}
copy_bitmap (2, aux -> old_PosX[!Page] + 12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[!Page] + 20+InfoSprites[aux -> InfoConcursante].CorrY, aux -> old_PosX[!Page]+12+incY+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[!Page]+20+incY+InfoSprites[aux -> InfoConcursante].CorrY,
!Page, aux -> old_PosX[!Page] + 12+InfoSprites[aux -> InfoConcursante].CorrX, aux -> old_PosY[!Page] + 20+InfoSprites[aux -> InfoConcursante].CorrY);
prt_tbl[(aux -> PosY)/16][(aux -> PosX)/16] = 0;
if ( ( aux -> poseed ) != NULL )
( ( aux -> poseed ) -> DisparosP ) --;
aux = EliminaConcursante( aux );
}
else
aux = aux -> sig;
};
}
void GeneraFuego( CONCURSANTES *concursante )
{
int x, y, inc;
CONCURSANTES *aux;
x = concursante -> PosX / 16;
y = concursante -> PosY / 16;
// Scaneamos posibiliades hacia la izquierda
for ( inc = 1; ( x - inc ) >= 0 && inc <= concursante -> Longitud; inc++ )
if ( prt_tbl[y][x-inc] != 1 && prt_tbl[y][x-inc] != 2 )
{
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Tipo_de_concursante = POS_FUEGOh;
ColocaFuego( (x-inc)*16, y*16, aux );
prt_tbl[y][x-inc] = 4;
} else {
// Si es una bomba <20><><EFBFBD> BOOM !!! ( la otra )
if ( prt_tbl2[y][x-inc] == 0 )
{
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Tipo_de_concursante = POS_FUEGOh;
ColocaFuego( (x-inc)*16, y*16, aux );
prt_tbl[y][x-inc] = 4;
}
break;
}
// Scaneamos posibiliades hacia la Derecha
for ( inc = 1; ( x + inc ) < 21 && inc <= concursante -> Longitud; inc++ )
if ( prt_tbl[y][x+inc] != 1 && prt_tbl[y][x+inc] != 2 )
{
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Tipo_de_concursante = POS_FUEGOh;
ColocaFuego( (x+inc)*16, y*16, aux );
prt_tbl[y][x+inc] = 4;
} else {
// Si es una bomba <20><><EFBFBD> BOOM !!! ( la otra )
if ( prt_tbl2[y][x+inc] == 0 )
{
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Tipo_de_concursante = POS_FUEGOh;
ColocaFuego( (x+inc)*16, y*16, aux );
prt_tbl[y][x+inc] = 4;
}
break;
}
// Scaneamos posibiliades hacia la arriba
for ( inc = 1; ( y - inc ) >= 0 && inc <= concursante -> Longitud; inc++ )
if ( prt_tbl[y-inc][x] != 1 && prt_tbl[y-inc][x] != 2 )
{
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Tipo_de_concursante = POS_FUEGOv;
ColocaFuego( x*16, (y-inc)*16, aux );
prt_tbl[y-inc][x] = 4;
} else {
// Si es una bomba <20><><EFBFBD> BOOM !!! ( la otra )
if ( prt_tbl2[y-inc][x] == 0 )
{
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Tipo_de_concursante = POS_FUEGOv;
ColocaFuego( x*16, (y-inc)*16, aux );
prt_tbl[y-inc][x] = 4;
}
break;
}
// Scaneamos posibiliades hacia la abajo
for ( inc = 1; ( y + inc ) < 13 && inc <= concursante -> Longitud; inc++ )
if ( prt_tbl[y+inc][x] != 1 && prt_tbl[y+inc][x] != 2 )
{
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Tipo_de_concursante = POS_FUEGOv;
ColocaFuego( x*16, (y+inc)*16, aux );
prt_tbl[y+inc][x] = 4;
} else {
// Si es una bomba <20><><EFBFBD> BOOM !!! ( la otra )
if ( prt_tbl2[y+inc][x] == 0 )
{
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Tipo_de_concursante = POS_FUEGOv;
ColocaFuego( x*16, (y+inc)*16, aux );
prt_tbl[y+inc][x] = 4;
}
break;
}
}
void ColocaFuego( int PosX, int PosY, CONCURSANTES *aux )
{
aux -> InfoConcursante = SPR_FUEGO;
aux -> PosX = PosX; aux -> PosY = PosY;
aux -> old_PosX[0] = aux -> old_PosX[1] = PosX;
aux -> old_PosY[0] = aux -> old_PosY[1] = PosY;
aux -> Direccion = 4;
aux -> Velocidad = 1;
aux -> delay_time = 40; aux -> secuencia_animada = 0;
aux -> poseed = NULL;
aux -> DisparosP = TiempoDeJuego;
aux -> Varios.CaputDelTo = 0;
}
void MovimientoAutomatico( CONCURSANTES *aux, char *incY, char *incX, int Page )
{
// Cambiamos de direccion
if ( aux -> old_PosX[Page] == aux -> PosX && aux -> old_PosY[Page] == aux -> PosY )
{
aux -> Direccion = (char)random_int( 4 );
}
switch( aux -> Direccion )
{
// izq, der, arr, abj
case 0:
*incX = -(aux -> Velocidad);
break;
case 1:
*incX = (aux -> Velocidad);
break;
case 2:
*incY = -(aux -> Velocidad);
break;
case 3:
*incY = (aux -> Velocidad);
break;
}
}
/**************************************************************************\
|* *|
|* CompruebaCoordenadas *|
|* *|
|* Descripci<63>n: *|
|* Comprueba que las coordenadas son correctas, en caso *|
|* contrario las corrige. Tambien procesa el caso de *|
|* encontrarse en una zona especial: teleport, flecha... *|
|* *|
|* Entradas: Punteros a las Coordenadas X , Y *|
|* Salidas: (ninguna) *|
|* *|
\**************************************************************************/
void CompruebaCoordenadas( char incX, char incY, CONCURSANTES *objeto, char *Objeto_Caput )
{
int xV, yV, xS, yS, Tmp;
// Este es el puntero donde estan los cuadros:
// prt_tbl[13][21];
//
// 1 ---> Cuadro indestructible / BOMBA
// 2 ---> Cuadro destructible ( Se puede sobrevolar )
// 3 ---> Objeto que puede matar al contacto
// ( Solo los jugadores pueden morir al contacto )
// Compruebo que no este fuera de los bordes
while ( (objeto->PosX) < 0 ) (objeto->PosX)++;
while ( (objeto->PosX) > 16*20 ) (objeto->PosX)--;
while ( (objeto->PosY) < 0 ) (objeto->PosY)++;
while ( (objeto->PosY) > 16*12 ) (objeto->PosY)--;
// xV = (*x + incX)/16; yV = (*y + incY)/16;
// Es un movimiento en el eje X
if ( incX != 0 )
{
xV = ((objeto->PosX) + (incX < 0 ? 2 : 11 ) )/16;
yV = ((objeto->PosY)+2)/16;
Tmp = ((objeto->PosY)+11)/16;
// Si no es un jugador ni una bomba ( Controlamos su c<>digo 3 )
xS = xV; yS = yV;
if ( prt_tbl[yS][xS] == 4 )
*Objeto_Caput = 1;
if ( objeto -> Varios.PuedeMatar )
{
prt_tbl[yV][xV] = 0;
}
// Si estoy pisando un cuadro ocupado seguimos una estructura distinta
if ( prt_tbl[yV][xV] == 1 ) //!= 0 )
if ( incX < 0 ) xV --; else xV ++;
else
xV = ((objeto->PosX) + (incX < 0 ? 2 : 11 ) + incX )/16;
// Cuidadin que puede morir
// if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && ( prt_tbl[yV][xV] == 3 || prt_tbl[Tmp][xV] == 3 ) )
/*
if ( prt_tbl[yS][xS] == 4 )
*Objeto_Caput = 1;
else
*/
if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && prt_tbl[yS][xS] == 3 )
*Objeto_Caput = 1;
else
if ( prt_tbl[yV][xV] == 0 && prt_tbl[Tmp][xV] == 0 || ( objeto -> Varios.PuedeVolar && prt_tbl[yV][xV] == 2 && prt_tbl[Tmp][xV] == 2 ) )
{
(objeto->PosX) = (objeto->PosX) + incX;
// Si no es un jugador ni una bomba ( Controlamos su c<>digo 3 )
if ( objeto -> Varios.PuedeMatar )
prt_tbl[yV][xV] = 3;
} else {
// Si no es un jugador ni una bomba ( Controlamos su c<>digo 3 )
if ( objeto -> Varios.PuedeMatar )
prt_tbl[yS][xS] = 3;
}
} else
// Es un movimiento en el eje Y
if ( incY != 0 )
{
yV = ((objeto->PosY) + (incY < 0 ? 2 : 11 ) )/16;
xV = ((objeto->PosX)+2)/16;
Tmp = ((objeto->PosX)+11)/16;
// Si no es un jugador ni una bomba ( Controlamos su c<>digo 3 )
xS = xV; yS = yV;
if ( prt_tbl[yS][xS] == 4 )
*Objeto_Caput = 1;
if ( objeto -> Varios.PuedeMatar )
{
prt_tbl[yV][xV] = 0;
}
// Si estoy pisando un cuadro ocupado seguimos una estructura distinta
if ( prt_tbl[yV][xV] == 1 )//!= 0 )
if ( incY < 0 ) yV --; else yV ++;
else
yV = ((objeto->PosY) + (incY < 0 ? 2 : 11 ) + incY )/16;
// Cuidadin que puede morir
// if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && ( prt_tbl[yV][xV] == 3 || prt_tbl[yV][Tmp] == 3 ) )
/*
if ( prt_tbl[yS][xS] == 4 )
*Objeto_Caput = 1;
else
*/
if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && prt_tbl[yS][xS] == 3 )
*Objeto_Caput = 1;
else
if ( prt_tbl[yV][xV] == 0 && prt_tbl[yV][Tmp] == 0 || ( objeto -> Varios.PuedeVolar && prt_tbl[yV][xV] == 2 && prt_tbl[yV][Tmp] == 2 ) )
{
(objeto->PosY) = (objeto->PosY) + incY;
// Si no es un jugador ni una bomba ( Controlamos su c<>digo 3 )
if ( objeto -> Varios.PuedeMatar )
prt_tbl[yV][xV] = 3;
} else {
// Si no es un jugador ni una bomba ( Controlamos su c<>digo 3 )
if ( objeto -> Varios.PuedeMatar )
prt_tbl[yS][xS] = 3;
}
} else {
// No se mueve, pero puede estar tocandole algo que le mate
xS = ((objeto->PosX)+2)/16;
yS = ((objeto->PosY)+2)/16;
if ( prt_tbl[yS][xS] == 4 )
*Objeto_Caput = 1;
else
if ( ( objeto -> InfoConcursante) == SPR_JUGADOR && ( objeto -> Varios.PuedeMorir ) && prt_tbl[yS][xS] == 3 )
*Objeto_Caput = 1;
}
// Por que lado del que pisa esta ocupado <20>
// | <20>
// <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ŀ
// <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <<3C> <20> _ <20>
// <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20><><EFBFBD>ij |<7C> <20>
// <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20> <20>
// <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
// <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ
// <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
// <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ
// <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
// <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ <20>Ŀ
// <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD> <20><><EFBFBD>
//
};
/**************************************************************************\
|* *|
|* limpia_teclado *|
|* *|
|* Descripci<63>n: *|
|* Limpia el buffer propio de teclado *|
|* *|
|* Entradas: (ninguna) *|
|* Salidas: (ninguna) *|
|* *|
\**************************************************************************/
void limpia_teclado(void)
{
int n;
for(n=0; n<256; n++)
mapa_teclado[n]=0;
}
void ColocaBomba( CONCURSANTES *concursante )
{
CONCURSANTES *aux;
int xV, yV;
xV = (concursante -> PosX + 8)/16;
yV = (concursante -> PosY + 8)/16;
if ( (aux = NuevoConcursante(concursante)) == NULL ) Error(-1);
aux -> Varios.PuedeMatar = 1; aux -> Varios.PuedeMorir = 1;
aux -> Varios.PuedeVolar = 1; aux -> Varios.Dispara = 1;
aux -> Varios.Vidas = 5; // Vida de la bomba == 5sg.
aux -> Tipo_de_concursante = POS_BOMBA;
aux -> InfoConcursante = SPR_BOMBA;
aux -> PosX = xV*16; aux -> PosY = yV*16;
prt_tbl[yV][xV] = 1; // Tipo 1 == indestructible
aux -> old_PosX[0] = aux -> old_PosX[1] = xV;
aux -> old_PosY[0] = aux -> old_PosY[1] = yV;
aux -> Direccion = 0;
aux -> Velocidad = 1;
aux -> delay_time = 40; aux -> secuencia_animada = 0;
aux -> poseed = concursante;
aux -> DisparosP = clock();
aux -> Longitud = concursante -> Longitud;
concursante -> DisparosP = concursante -> DisparosP + 1;
aux -> Varios.CaputDelTo = 0;
}
/**************************************************************************\
|* *|
|* RellenaConcursantes *|
|* *|
|* Descripci<63>n: *|
|* Se encarga de colocar y definir a los concursantes *|
|* *|
|* Entradas: (ninguna) *|
|* Salidas: OK todo va bien *|
|* ERROR algo va mal *|
|* *|
\**************************************************************************/
int RellanaConcursantes(void)
{
CONCURSANTES *aux;
// Jugador 1
if ( (Concursantes = aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR;
aux -> Varios.PuedeMatar = 0; aux -> Varios.PuedeMorir = 1;
aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 1;
aux -> Varios.Vidas = 1;
aux -> Tipo_de_concursante = POS_JUGADORa;
aux -> InfoConcursante = SPR_JUGADOR ;
aux -> PosX = 0; aux -> PosY = 0;
aux -> old_PosX[0] = aux -> old_PosX[1] = 0;
aux -> old_PosY[0] = aux -> old_PosY[1] = 0;
aux -> Direccion = 2; aux -> Velocidad = 1;
aux -> delay_time = 40; aux -> secuencia_animada = 0;
aux -> Disparos = 5; aux -> Longitud = 3;
aux -> DisparosP = 0;
aux -> poseed = NULL;
aux -> Varios.CaputDelTo = 0;
// Jugador 2
if ( (aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR;
aux -> Varios.PuedeMatar = 0; aux -> Varios.PuedeMorir = 1;
aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 1;
aux -> Varios.Vidas = 1;
aux -> Tipo_de_concursante = POS_JUGADORb;
aux -> InfoConcursante = SPR_JUGADOR ;
aux -> PosX = 320; aux -> PosY = 192;
aux -> old_PosX[0] = aux -> old_PosX[1] = 320;
aux -> old_PosY[0] = aux -> old_PosY[1] = 192;
aux -> Direccion = 2; aux -> Velocidad = 1;
aux -> delay_time = 40; aux -> secuencia_animada = 0;
aux -> Disparos = 3; aux -> Longitud = 3;
aux -> DisparosP = 0;
aux -> poseed = NULL;
aux -> Varios.CaputDelTo = 0;
// Jugador 3
if ( Pref.Jugadores >= 3 )
{
if ( (aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR;
aux -> Varios.PuedeMatar = 0; aux -> Varios.PuedeMorir = 1;
aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 1;
aux -> Varios.Vidas = 1;
aux -> Tipo_de_concursante = POS_JUGADORc;
aux -> InfoConcursante = SPR_JUGADOR ;
aux -> PosX = 320; aux -> PosY = 0;
aux -> old_PosX[0] = aux -> old_PosX[1] = 320;
aux -> old_PosY[0] = aux -> old_PosY[1] = 0;
aux -> Direccion = 2; aux -> Velocidad = 1;
aux -> delay_time = 40; aux -> secuencia_animada = 0;
aux -> Disparos = 1; aux -> Longitud = 1;
aux -> poseed = NULL;
aux -> Varios.CaputDelTo = 0;
}
// Jugador 4
if ( Pref.Jugadores >= 4 )
{
if ( (aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR;
aux -> Varios.PuedeMatar = 0; aux -> Varios.PuedeMorir = 1;
aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 1;
aux -> Varios.Vidas = 1;
aux -> Tipo_de_concursante = POS_JUGADORd;
aux -> InfoConcursante = SPR_JUGADOR ;
aux -> PosX = 0; aux -> PosY = 192;
aux -> old_PosX[0] = aux -> old_PosX[1] = 0;
aux -> old_PosY[0] = aux -> old_PosY[1] = 192;
aux -> Direccion = 2; aux -> Velocidad = 1;
aux -> delay_time = 40; aux -> secuencia_animada = 0;
aux -> Disparos = 1; aux -> Longitud = 1;
aux -> DisparosP = 0;
aux -> poseed = NULL;
aux -> Varios.CaputDelTo = 0;
}
// Vaquero
if ( (aux = NuevoConcursante(Concursantes)) == NULL ) return ERROR;
aux -> Varios.PuedeMatar = 1; aux -> Varios.PuedeMorir = 1;
aux -> Varios.PuedeVolar = 0; aux -> Varios.Dispara = 0;
aux -> Varios.Vidas = 1;
aux -> Tipo_de_concursante = POS_BAQUERO;
aux -> InfoConcursante = SPR_BAQUERO;
GeneraXYaleatorio( &(aux -> PosX), &(aux -> PosY) );
aux -> old_PosX[0] = aux -> old_PosX[1] = 0;
aux -> old_PosY[0] = aux -> old_PosY[1] = 192;
aux -> Direccion = 2; aux -> Velocidad = 1;
aux -> delay_time = 40; aux -> secuencia_animada = 0;
aux -> Disparos = 1; aux -> Longitud = 1;
aux -> DisparosP = 0;
aux -> poseed = NULL;
aux -> Varios.CaputDelTo = 0;
return OK;
}
void GeneraXYaleatorio( int *X, int *Y )
{
do {
*X = random_int( 17 ) + 2;
*Y = random_int( 9 ) + 2;
}while( prt_tbl[*Y][*X] == 1 );
prt_tbl[*Y][*X] = 0;
*X = *X * 16; *Y = *Y * 16;
}
/**************************************************************************\
|* *|
|* LiberaConcursantes *|
|* *|
|* Descripci<63>n: *|
|* Elimina a todos los concursantes liberando la memoria *|
|* *|
|* Entradas: (ninguna) *|
|* Salidas: (ninguna) *|
|* *|
\**************************************************************************/
void LiberaConcursantes(void)
{
CONCURSANTES *aux;
aux = Concursantes;
if ( Concursantes -> sig != NULL )
{
Concursantes = Concursantes -> sig;
LiberaConcursantes();
}
free( aux );
}
/**************************************************************************\
|* *|
|* EliminaConcursante *|
|* *|
|* Descripci<63>n: *|
|* Elimina al concursante que se le pasa como par<61>metro *|
|* *|
|* Entradas: El puntero al elemento a eliminar *|
|* Salidas: Elemento siguiente en la lista *|
|* *|
\**************************************************************************/
CONCURSANTES *EliminaConcursante(CONCURSANTES *Concur)
{
CONCURSANTES *ant;
CONCURSANTES *aux;
ant = aux = Concursantes;
// Quizas haya que eliminar al primer elemento
if ( aux == Concur )
{
Concursantes = aux -> sig;
free ( Concur );
return Concursantes;
} else {
while ( aux != Concur && aux != NULL)
{
ant = aux;
aux = aux -> sig;
};
if ( aux == NULL )
return NULL;
ant -> sig = Concur -> sig;
free( Concur );
return (ant -> sig);
}
}
/**************************************************************************\
|* *|
|* NuevoConcursante *|
|* *|
|* Descripci<63>n: *|
|* A<>ade un nuevo concursante al final *|
|* *|
|* Entradas: El puntero base donde insertar (Busca solo el final) *|
|* *|
|* Salidas: direccion del concursante a<>adido *|
|* NULL algo va mal *|
|* *|
\**************************************************************************/
CONCURSANTES *NuevoConcursante(CONCURSANTES *Concur)
{
CONCURSANTES *aux, *Concursante;
if ( (aux = (CONCURSANTES *)malloc( sizeof(CONCURSANTES) ) ) == NULL )
return NULL;
Concursante = Concur;
aux -> sig = NULL;
// Todavia no hay concursantes
if ( Concursante == NULL )
{
Concursante = aux;
} else {
while( Concursante -> sig != NULL )
Concursante = Concursante -> sig;
Concursante -> sig = aux;
}
return aux;
}