FAQ  •  Register  •  Login

Fucking Awesome Spectrum Engine (FASE)

<<

antoniovillena

Posts: 7

Joined: Tue Jan 07, 2014 9:48 pm

Post Tue Jan 07, 2014 10:16 pm

Fucking Awesome Spectrum Engine (FASE)

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/v ... 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
<<

boriel

Site Admin

Posts: 1461

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Tue Jan 07, 2014 10:42 pm

Re: Fucking Awesome Spectrum Engine (FASE)

Hi, Antonio!

This is, in fact, *fucking awesome* :!:
Please, stand by me :)
Cuenta conmigo!! :)
<<

antoniovillena

Posts: 7

Joined: Tue Jan 07, 2014 9:48 pm

Post Tue Jan 07, 2014 11:07 pm

Re: Fucking Awesome Spectrum Engine (FASE)

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.
<<

boriel

Site Admin

Posts: 1461

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Tue Jan 07, 2014 11:17 pm

Re: Fucking Awesome Spectrum Engine (FASE)

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.
<<

antoniovillena

Posts: 7

Joined: Tue Jan 07, 2014 9:48 pm

Post Wed Jan 08, 2014 9:40 am

Re: Fucking Awesome Spectrum Engine (FASE)

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.
Attachments
FASE.0.10.zip
(253.17 KiB) Downloaded 303 times
<<

boriel

Site Admin

Posts: 1461

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Wed Jan 08, 2014 9:55 am

Re: Fucking Awesome Spectrum Engine (FASE)

Wow! How fast! :shock:
There is already a simple IN (multikeyboard) library management in the standard /library/ directory (see http://bit.ly/1dT2uYi).

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.
<<

antoniovillena

Posts: 7

Joined: Tue Jan 07, 2014 9:48 pm

Post Wed Jan 08, 2014 11:57 am

Re: Fucking Awesome Spectrum Engine (FASE)

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
<<

boriel

Site Admin

Posts: 1461

Joined: Wed Nov 01, 2006 6:18 pm

Location: Santa Cruz de Tenerife, Spain

Post Fri Jan 31, 2014 9:46 am

Re: Fucking Awesome Spectrum Engine (FASE)

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.
<<

antoniovillena

Posts: 7

Joined: Tue Jan 07, 2014 9:48 pm

Post Tue Jul 08, 2014 2:49 am

Re: Fucking Awesome Spectrum Engine (FASE)

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.
<<

JBGV

Posts: 65

Joined: Wed Feb 16, 2011 6:12 am

Post Tue Jul 08, 2014 4:55 am

Re: Fucking Awesome Spectrum Engine (FASE)

Awesome !!

It will be fantastic to use FASE with Zx basic !! :D :D
<<

antoniovillena

Posts: 7

Joined: Tue Jan 07, 2014 9:48 pm

Post Wed Jul 09, 2014 12:45 am

Re: Fucking Awesome Spectrum Engine (FASE)

JBGV wrote:Awesome !!

It will be fantastic to use FASE with Zx basic !! :D :D


Now It's done. Download package here:

http://www.mojontwins.com/mojoniaplus/d ... hp?id=5144
<<

JBGV

Posts: 65

Joined: Wed Feb 16, 2011 6:12 am

Post Wed Jul 09, 2014 4:54 am

Re: Fucking Awesome Spectrum Engine (FASE)

Wow! :shock: :shock:

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


Enhorabuena por el trabajo tan enorme !!

Return to ZX Basic Compiler

Who is online

Users browsing this forum: No registered users and 2 guests

cron
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group.
Designed by Vjacheslav Trushkin for Free Forums/DivisionCore.

phpBB SEO