Thread Rating:
  • 1 Vote(s) - 5 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Fucking Awesome Spectrum Engine (FASE)
#1
Hi

We are writing an engine (sprites, tiles, maps) and I would like to interface with ZX Basic. The main thread is here (sorry, it's in spanish)

http://www.mojontwins.com/mojoniaplus/vi...f=9&t=1461

Now the engine is in alpha stage and there is a SDCC working demo. This is the code:

Code:
#include "bunuelera.h" const unsigned char data[32]= { 0x00, 0x42, 0x11, 0, 0x08, 0x60, 0x60, 2, 0x09, 0xa8, 0x48, 3, 0x0a, 0x22, 0x02, 1, 0x0b, 0xd0, 0x6e, 2, 0x0c, 0xb6, 0x34, 3, 0x0d, 0x32, 0x32, 1, 0x04, 0x52, 0x5e, 0}; int main(){ // variables int i, x= 0, y= 0; // pasar personajes a sprites for ( i = 0; i < 32; i++ ) sprites[i>>2][i&3]= data[i]; // inicializar engine INIT; // mostrar la primera pantalla al comienzo screen= 0; while(1){ // esto hace que el engine procese un frame generando el escenario FRAME; // movimiento de los enemigos for ( i = 1; i < 8; i++ ){ if( sprites[i][3]&1 ) if( sprites[i][2] ) sprites[i][2]--; else sprites[i][3]^= 1; else if( sprites[i][2]<0x90 ) sprites[i][2]++; else sprites[i][3]^= 1; if( sprites[i][3]&2 ) if( sprites[i][1]>0x08 ) sprites[i][1]--; else sprites[i][3]^= 2; else if( sprites[i][1]<0xe8 ) sprites[i][1]++; else sprites[i][3]^= 2; } // movimiento del protagonista if( ~KeybYUIOP & 0x01 ){ // P if( sprites[0][1]<0xee ) sprites[0][1]++; else if( x < 11 ) sprites[0][1]= 0x02, screen= y*12 + ++x; } else if( ~KeybYUIOP & 0x02 ){ // O if( sprites[0][1]>0x02 ) sprites[0][1]--; else if( x ) sprites[0][1]= 0xee, screen= y*12 + --x; } if( ~KeybGFDSA & 0x01 ){ // A if( sprites[0][2]<0xa0 ) sprites[0][2]++; else if( y < 1 ) sprites[0][2]= 0x01, screen= ++y*12 + x; } else if( ~KeybTREWQ & 0x01 ){ // Q if( sprites[0][2]>0x01 ) sprites[0][2]--; else if( y ) sprites[0][2]= 0xa0, screen= --y*12 + x; } } }

My idea is to traslate this code to ZX Basic. The engine set ups a runtime enviroment that leave between 24K and 30K bytes free from $8000 address. Basically there are 2 routines to call: INIT to initialize the engine and FRAME, that put all the stuff in the screen every frame. With this engine you can move between 8 and 16 sprites flicker free at 50fps in 48K and all 128K models. The engine has diferent implementation for each machine (floating bus in 48K, shadow screen in 128K) so the comunication is done by accessing to next memory locations:

Code:
5b00 number of screen to paint 5b01-5b96 tiles codes of actual screen 5bfe-5bff set to repaint a rectangular area of tiles 5c00-5c3f sprite info, where 5c00-5c02 first sprite 5c00 sprite number, set high bit to disable 5c01 X coord 5c02 Y coord 5c04-5c06 second sprite ...

More info in the first message of the linked thread

Regards

-----------

Buenas, estamos escribiendo un engine de sprites, tiles y mapas y me gustaría poder usar dicho engine con ZX Basic. En el hilo que enlazo arriba está todo explicado en español. No tengo mucha idea sobre ZX Basic, pero veo que hay una comunidad detrás y me gustaría que me ayudaran a traducir la demo de C a Basic.

Saludos
Reply
#2
Hi, Antonio!

This is, in fact, *fucking awesome* :!:
Please, stand by me Smile
Cuenta conmigo!! Smile
Reply
#3
Thank you very much

I am looking the bitfrost engine interface. The main 2 calls can be easy done by:

Code:
#define INIT \ asm \ call $fffc \ end asm #define FRAME \ asm \ call $fff1 \ end asm

But in the rest of the code I don't know if make a subroutine or a #define with a POKE.
Reply
#4
antoniovillena Wrote:Thank you very much

I am looking the bitfrost engine interface. The main 2 calls can be easy done by:

Code:
#define INIT \ asm \ call $fffc \ end asm #define FRAME \ asm \ call $fff1 \ end asm

But in the rest of the code I don't know if make a subroutine or a #define with a POKE.
For a single Poke, #define is MUCH faster, because it acts as an inline function.
You can also use SUB/Function FASCALL <name>(param) for asm functions, if they are a bit more complicated.
Reply
#5
Hi

I have made some advances in the BASIC code. The demo is functional but not complete, I don't know how to manage the keyboard.

I uploaded a file with all necessary files except SjAsmPlus.exe (download it from http://sourceforge.net/projects/sjasmplus/) because 256K file size restriction in the forum. Also change "set _lang=c" to "set _lang=basic" in the second line on makeBu.bat and correct the path of some utilities.

When you execute makeBu.bat and all works correctly you have the generated file "game.tap", try it on any ZX Spectrum emulator.


Attached Files
.zip   FASE.0.10.zip (Size: 253.17 KB / Downloads: 1,749)
Reply
#6
Wow! How fast! Confusedhock:
There is already a simple IN (multikeyboard) library management in the standard /library/ directory (see https://github.com/boriel/zxbasic/blob/v...y/keys.bas).

You can use it with:
Code:
#include <keys.bas> While 1 Do IF multikeys(KEYB) THEN PRINT "B Pressed" : End IF IF multikeys(KEYA) THEN PRINT "A Pressed" : End IF REM etc... etc... End While
These routine detects several keys pressed at once (beware, there are some hardware limitations on the ZX Spectrum keyboard).
KEYB, KEYA, etc... are constants defined in the previous source code.
Reply
#7
Thank you. Now it's almost done.

Unfortunately the demo only shows 6 of the 7 enemies, so I have debugged the Z80 code and found a word write to $5c0b. This position is the DEFADD variable of the 48 ROM. So, is there any way of disable writing to internal variables?

Code:
#include <keys.bas> #include "fase.bas" DisableInt DIM datos(31) as UBYTE = { _ $00, $42, $11, 0, _ $08, $60, $60, 2, _ $09, $a8, $48, 3, _ $0a, $22, $02, 1, _ $0b, $d0, $6e, 2, _ $0c, $b6, $34, 3, _ $0d, $32, $32, 1, _ $04, $52, $5e, 0 } DIM i, x, y AS UBYTE FOR i = 0 TO 31 SETSPRITE(i>>2, i&3, datos(i)) NEXT i INIT SETSCREEN(0) WHILE 1 FRAME FOR i = 1 TO 8 IF GETSPRITE(i, 3) & 1 THEN IF GETSPRITE(i, 2) > 0 THEN SETSPRITE(i, 2, GETSPRITE(i, 2)-1) ELSE SETSPRITE(i, 3, GETSPRITE(i, 3) bXOR 1) END IF ELSE IF GETSPRITE(i, 2) < $90 THEN SETSPRITE(i, 2, GETSPRITE(i, 2)+1) ELSE SETSPRITE(i, 3, GETSPRITE(i, 3) bXOR 1) END IF END IF IF GETSPRITE(i, 3) & 2 THEN IF GETSPRITE(i, 1) > $08 THEN SETSPRITE(i, 1, GETSPRITE(i, 1)-1) ELSE SETSPRITE(i, 3, GETSPRITE(i, 3) bXOR 2) END IF ELSE IF GETSPRITE(i, 1) < $e8 THEN SETSPRITE(i, 1, GETSPRITE(i, 1)+1) ELSE SETSPRITE(i, 3, GETSPRITE(i, 3) bXOR 2) END IF END IF NEXT i IF multikeys(KEYP) THEN IF GETSPRITE(0, 1) < $ee THEN SETSPRITE(0, 1, GETSPRITE(0, 1)+1) ELSEIF x < 11 THEN SETSPRITE(0, 1, $02) x= x + 1 SETSCREEN(y*12 + x) END IF END IF IF multikeys(KEYO) THEN IF GETSPRITE(0, 1) > $02 THEN SETSPRITE(0, 1, GETSPRITE(0, 1)-1) ELSEIF x > 0 THEN SETSPRITE(0, 1, $ee) x= x - 1 SETSCREEN(y*12 + x) END IF END IF IF multikeys(KEYA) THEN IF GETSPRITE(0, 2) < $a0 THEN SETSPRITE(0, 2, GETSPRITE(0, 2)+1) ELSEIF y < 1 THEN SETSPRITE(0, 2, $01) y= y + 1 SETSCREEN(y*12 + x) END IF END IF IF multikeys(KEYQ) THEN IF GETSPRITE(0, 2) > $01 THEN SETSPRITE(0, 2, GETSPRITE(0, 2)-1) ELSEIF y > 0 THEN SETSPRITE(0, 2, $a0) y= y - 1 SETSCREEN(y*12 + x) END IF END IF END WHILE
Reply
#8
antoniovillena Wrote:Thank you. Now it's almost done.

Unfortunately the demo only shows 6 of the 7 enemies, so I have debugged the Z80 code and found a word write to $5c0b. This position is the DEFADD variable of the 48 ROM. So, is there any way of disable writing to internal variables?
Not yet, but will be available as an option, as many others.
I put it in the TODO queue.
Reply
#9
Please help. I have this code in C:

Code:
void *Input; // function pointer declare ... /* function pointer assign */ while ( 1 ){ i= inp(0xf7fe) & 0x1f; if( i==0x1e ){ Input= Joystick; break; } else if( i==0x1d ){ Input= Cursors; break; } else if( i==0x1b ){ Input= Keyboard; break; } else if( i==0x17 ){ Redefine(); } } ... if( Input() & RIGHT ) // function pointer call ax= vx<maxvx ? 40 : 0;

I want to do something similar in ZX Basic. I know that ZX Basic has not function pointers, but I think that you can find another good solution.
Reply
#10
Awesome !!

It will be fantastic to use FASE with Zx basic !! Big Grin Big Grin
Reply
#11
JBGV Wrote:Awesome !!

It will be fantastic to use FASE with Zx basic !!  Big Grin  Big Grin

Now It's done. Download package here:

http://www.mojontwins.com/mojoniaplus/do...hp?id=5144
Reply
#12
Wow! Confusedhock: Confusedhock:

I have to study this to see how to use it in a game.


Enhorabuena por el trabajo tan enorme !!
Reply


Forum Jump:


Users browsing this thread: 1 Guest(s)