Re: FASE (Fucking Awesome Spectrum Engine)
Publicado: Mar, 13 May 2014, 23:38
He hecho unos cambios menores para mejorar la legibilidad, están en el repositorio.
Si no entiendes algo, pregúntamelo. Si ves alguna forma de simplificar código o de hacer lo mismo pero que sea más fácil de entender, dímelo.
Estos serían los ficheros main.c y fase.h
main.c
$this->bbcode_second_pass_code('', '
#include "fase.h"
extern unsigned char *ending;
const unsigned char data[20]= {
0x00, 0x42, 0x11, 0,
0x08, 0x60, 0x60, 2,
0x09, 0x58, 0x48, 3,
0x0a, 0x22, 0x02, 1,
0x0b, 0x50, 0x6e, 2};
char i, j, killed, x, y, spacepressed, dirbul[4], num_bullets;
unsigned char tmpx, tmpy;
void remove_bullet( char k );
void update_screen();
void update_scoreboard();
main(){
start:
killed= x= y= spacepressed= num_bullets= *shadow= 0;
update_scoreboard();
// inicializar engine
INIT;
// pasar datos a sprites y balas
for ( i = 0; i < 5; i++ )
sprites[i].n= data[0 | i<<2],
sprites[i].x= data[1 | i<<2],
sprites[i].y= data[2 | i<<2],
sprites[i].f= data[3 | i<<2];
for ( i = 0; i < 4; i++ )
bullets[i].y= 255;
// mostrar la primera pantalla al comienzo y marcador
*screen= 0;
while(1){
// esto hace que el engine procese un frame generando el escenario
FRAME;
// movimiento de los enemigos
for ( i = 1; i < 5; i++ )
if( sprites[i].n<0x80 ){
for ( j= 0; j < num_bullets; j++ )
if( ( (sprites[i].x<bullets[j].x?bullets[j].x-sprites[i].x:sprites[i].x-bullets[j].x)
+ (sprites[i].y<bullets[j].y?bullets[j].y-sprites[i].y:sprites[i].y-bullets[j].y))<10 ){
sprites[i].n-= 0x80;
remove_bullet( j );
tmpx= sprites[i].x>>4;
tmpy= sprites[i].y>>4;
tiles[tmpy*scrw+tmpx]= 68;
tilepaint(tmpx, tmpy, tmpx, tmpy);
killed++;
if( killed==10 ){
EXIT;
Dzx7b((unsigned int) (&ending-1), 0x5aff);
Pause(100);
goto start;
}
*drwout= (unsigned int)update_scoreboard;
}
if( sprites[i].f&1 )
if( sprites[i].y>0 )
sprites[i].y--;
else
sprites[i].f^= 1;
else
if( sprites[i].y<scrh*16 )
sprites[i].y++;
else
sprites[i].f^= 1;
if( sprites[i].f&2 )
if( sprites[i].x>0 )
sprites[i].x--;
else
sprites[i].f^= 2;
else
if( sprites[i].x<scrw*16 )
sprites[i].x++;
else
sprites[i].f^= 2;
}
// movimiento de las balas
for ( i = 0; i < num_bullets; i++ ){
if( dirbul[i]&3 ){
if( dirbul[i]&1 ){
if( bullets[i].x<scrw*16 )
bullets[i].x+= 2;
else
remove_bullet( i );
}
else{
if( bullets[i].x>2 )
bullets[i].x-= 2;
else
remove_bullet( i );
}
}
if( dirbul[i]&12 ){
if( dirbul[i]&4 ){
if( bullets[i].y<scrh*16 )
bullets[i].y+= 2;
else
remove_bullet( i );
}
else{
if( bullets[i].y>2 )
bullets[i].y-= 2;
else
remove_bullet( i );
}
}
}
// movimiento del protagonista
if( inKey(KeybYUIOP) & 0x01 ){ // P
if( sprites[0].x<scrw*16 )
sprites[0].x++;
else if( x < mapw-1 )
sprites[0].x= 0,
x++,
update_screen();
}
else if( inKey(KeybYUIOP) & 0x02 ){ // O
if( sprites[0].x>0 )
sprites[0].x--;
else if( x )
sprites[0].x= scrw*16,
x--,
update_screen();
}
if( inKey(KeybGFDSA) & 0x01 ){ // A
if( sprites[0].y<scrh*16 )
sprites[0].y++;
else if( y < maph-1 )
sprites[0].y= 0,
y++,
update_screen();
}
else if( inKey(KeybTREWQ) & 0x01 ){ // Q
if( sprites[0].y>0 )
sprites[0].y--;
else if( y )
sprites[0].y= scrh*16,
y--,
update_screen();
}
if( inKey(KeybBNMs_) & 0x01 && !spacepressed && num_bullets<4 ){ // Space
bullets[num_bullets].x= sprites[0].x;
bullets[num_bullets].y= sprites[0].y;
i= inKey(KeybTREWQ)<<3&8 | inKey(KeybGFDSA)<<2&4 | inKey(KeybYUIOP)&3;
dirbul[num_bullets]= i ? i : 1;
num_bullets++;
}
spacepressed= inKey(KeybBNMs_) & 0x01;
}
}
void remove_bullet( char k ){
if( num_bullets ){
num_bullets--;
while ( k<num_bullets )
dirbul[k]= dirbul[k+1],
bullets[k].x= bullets[k+1].x,
bullets[k].y= bullets[++k].y;
bullets[k].y= 255;
}
}
void update_screen(){
*screen= y*mapw + x;
for ( j= 1; j < 5; j++ )
if( sprites[j].n>0x7f )
sprites[j].n-= 0x80;
}
void update_scoreboard(){
unsigned int scr, dst;
char count;
scr= 0x3d80+killed*8;
dst= 0x50de|*shadow<<8;
for ( count= 0; count<8; count++ )
zxmem[dst]= zxmem[scr++]^0xff,
dst+= 0x100;
}
#asm
BINARY "ending.rcs.zx7b"
._ending
#endasm
')
fase.h
$this->bbcode_second_pass_code('', '
#include "define.h"
#define Keyb54321 0xf7
#define KeybTREWQ 0xfb
#define KeybGFDSA 0xfd
#define KeybVCXZc 0xfe
#define Keyb67890 0xef
#define KeybYUIOP 0xdf
#define KeybHJKLe 0xbf
#define KeybBNMs_ 0x7f
#define tilepaint(from_x, from_y, to_x, to_y) *repaint= from_x|from_y<<4|to_x<<8|to_y<<12
#define INIT asm("call 0xfffc")
#define FRAME asm("call 0xfff9")
#define EXIT asm("call 0xfff6")
typedef struct {
unsigned char n;
unsigned char x;
unsigned char y;
unsigned char f;
} SPRITE;
typedef struct {
unsigned char x;
unsigned char y;
} BULLET;
SPRITE *sprites= 0x5b00;
BULLET *bullets= 0x5b30;
unsigned char *tiles= 0x5b40;
unsigned char *screen= 0x5c00;
unsigned char *shadow= 0x5c01;
unsigned int *repaint= 0x5c02;
unsigned int *drwout= 0x5c06;
unsigned char *zxmem= 0;
char __FASTCALL__ inKey ( unsigned char row ){
#asm
ld b, l
ld c, $fe
in a, (c)
cpl
ld l, a
#endasm
}
void __FASTCALL__ Pause ( unsigned int msecs ){
#asm
loop1: ld bc, 21
loop2: djnz loop2
dec c
jr nz, loop2
dec hl
ld a, l
or h
jr nz, loop1
#endasm
}
void __CALLEE__ Dzx7b ( unsigned int source, unsigned int addr ){
#asm
pop af
pop de
pop hl
push af
jp dzx7a
#endasm
}
')
Si no entiendes algo, pregúntamelo. Si ves alguna forma de simplificar código o de hacer lo mismo pero que sea más fácil de entender, dímelo.
Estos serían los ficheros main.c y fase.h
main.c
$this->bbcode_second_pass_code('', '
#include "fase.h"
extern unsigned char *ending;
const unsigned char data[20]= {
0x00, 0x42, 0x11, 0,
0x08, 0x60, 0x60, 2,
0x09, 0x58, 0x48, 3,
0x0a, 0x22, 0x02, 1,
0x0b, 0x50, 0x6e, 2};
char i, j, killed, x, y, spacepressed, dirbul[4], num_bullets;
unsigned char tmpx, tmpy;
void remove_bullet( char k );
void update_screen();
void update_scoreboard();
main(){
start:
killed= x= y= spacepressed= num_bullets= *shadow= 0;
update_scoreboard();
// inicializar engine
INIT;
// pasar datos a sprites y balas
for ( i = 0; i < 5; i++ )
sprites[i].n= data[0 | i<<2],
sprites[i].x= data[1 | i<<2],
sprites[i].y= data[2 | i<<2],
sprites[i].f= data[3 | i<<2];
for ( i = 0; i < 4; i++ )
bullets[i].y= 255;
// mostrar la primera pantalla al comienzo y marcador
*screen= 0;
while(1){
// esto hace que el engine procese un frame generando el escenario
FRAME;
// movimiento de los enemigos
for ( i = 1; i < 5; i++ )
if( sprites[i].n<0x80 ){
for ( j= 0; j < num_bullets; j++ )
if( ( (sprites[i].x<bullets[j].x?bullets[j].x-sprites[i].x:sprites[i].x-bullets[j].x)
+ (sprites[i].y<bullets[j].y?bullets[j].y-sprites[i].y:sprites[i].y-bullets[j].y))<10 ){
sprites[i].n-= 0x80;
remove_bullet( j );
tmpx= sprites[i].x>>4;
tmpy= sprites[i].y>>4;
tiles[tmpy*scrw+tmpx]= 68;
tilepaint(tmpx, tmpy, tmpx, tmpy);
killed++;
if( killed==10 ){
EXIT;
Dzx7b((unsigned int) (&ending-1), 0x5aff);
Pause(100);
goto start;
}
*drwout= (unsigned int)update_scoreboard;
}
if( sprites[i].f&1 )
if( sprites[i].y>0 )
sprites[i].y--;
else
sprites[i].f^= 1;
else
if( sprites[i].y<scrh*16 )
sprites[i].y++;
else
sprites[i].f^= 1;
if( sprites[i].f&2 )
if( sprites[i].x>0 )
sprites[i].x--;
else
sprites[i].f^= 2;
else
if( sprites[i].x<scrw*16 )
sprites[i].x++;
else
sprites[i].f^= 2;
}
// movimiento de las balas
for ( i = 0; i < num_bullets; i++ ){
if( dirbul[i]&3 ){
if( dirbul[i]&1 ){
if( bullets[i].x<scrw*16 )
bullets[i].x+= 2;
else
remove_bullet( i );
}
else{
if( bullets[i].x>2 )
bullets[i].x-= 2;
else
remove_bullet( i );
}
}
if( dirbul[i]&12 ){
if( dirbul[i]&4 ){
if( bullets[i].y<scrh*16 )
bullets[i].y+= 2;
else
remove_bullet( i );
}
else{
if( bullets[i].y>2 )
bullets[i].y-= 2;
else
remove_bullet( i );
}
}
}
// movimiento del protagonista
if( inKey(KeybYUIOP) & 0x01 ){ // P
if( sprites[0].x<scrw*16 )
sprites[0].x++;
else if( x < mapw-1 )
sprites[0].x= 0,
x++,
update_screen();
}
else if( inKey(KeybYUIOP) & 0x02 ){ // O
if( sprites[0].x>0 )
sprites[0].x--;
else if( x )
sprites[0].x= scrw*16,
x--,
update_screen();
}
if( inKey(KeybGFDSA) & 0x01 ){ // A
if( sprites[0].y<scrh*16 )
sprites[0].y++;
else if( y < maph-1 )
sprites[0].y= 0,
y++,
update_screen();
}
else if( inKey(KeybTREWQ) & 0x01 ){ // Q
if( sprites[0].y>0 )
sprites[0].y--;
else if( y )
sprites[0].y= scrh*16,
y--,
update_screen();
}
if( inKey(KeybBNMs_) & 0x01 && !spacepressed && num_bullets<4 ){ // Space
bullets[num_bullets].x= sprites[0].x;
bullets[num_bullets].y= sprites[0].y;
i= inKey(KeybTREWQ)<<3&8 | inKey(KeybGFDSA)<<2&4 | inKey(KeybYUIOP)&3;
dirbul[num_bullets]= i ? i : 1;
num_bullets++;
}
spacepressed= inKey(KeybBNMs_) & 0x01;
}
}
void remove_bullet( char k ){
if( num_bullets ){
num_bullets--;
while ( k<num_bullets )
dirbul[k]= dirbul[k+1],
bullets[k].x= bullets[k+1].x,
bullets[k].y= bullets[++k].y;
bullets[k].y= 255;
}
}
void update_screen(){
*screen= y*mapw + x;
for ( j= 1; j < 5; j++ )
if( sprites[j].n>0x7f )
sprites[j].n-= 0x80;
}
void update_scoreboard(){
unsigned int scr, dst;
char count;
scr= 0x3d80+killed*8;
dst= 0x50de|*shadow<<8;
for ( count= 0; count<8; count++ )
zxmem[dst]= zxmem[scr++]^0xff,
dst+= 0x100;
}
#asm
BINARY "ending.rcs.zx7b"
._ending
#endasm
')
fase.h
$this->bbcode_second_pass_code('', '
#include "define.h"
#define Keyb54321 0xf7
#define KeybTREWQ 0xfb
#define KeybGFDSA 0xfd
#define KeybVCXZc 0xfe
#define Keyb67890 0xef
#define KeybYUIOP 0xdf
#define KeybHJKLe 0xbf
#define KeybBNMs_ 0x7f
#define tilepaint(from_x, from_y, to_x, to_y) *repaint= from_x|from_y<<4|to_x<<8|to_y<<12
#define INIT asm("call 0xfffc")
#define FRAME asm("call 0xfff9")
#define EXIT asm("call 0xfff6")
typedef struct {
unsigned char n;
unsigned char x;
unsigned char y;
unsigned char f;
} SPRITE;
typedef struct {
unsigned char x;
unsigned char y;
} BULLET;
SPRITE *sprites= 0x5b00;
BULLET *bullets= 0x5b30;
unsigned char *tiles= 0x5b40;
unsigned char *screen= 0x5c00;
unsigned char *shadow= 0x5c01;
unsigned int *repaint= 0x5c02;
unsigned int *drwout= 0x5c06;
unsigned char *zxmem= 0;
char __FASTCALL__ inKey ( unsigned char row ){
#asm
ld b, l
ld c, $fe
in a, (c)
cpl
ld l, a
#endasm
}
void __FASTCALL__ Pause ( unsigned int msecs ){
#asm
loop1: ld bc, 21
loop2: djnz loop2
dec c
jr nz, loop2
dec hl
ld a, l
or h
jr nz, loop1
#endasm
}
void __CALLEE__ Dzx7b ( unsigned int source, unsigned int addr ){
#asm
pop af
pop de
pop hl
push af
jp dzx7a
#endasm
}
')