Hi,
I do have some .scr files that it would be great to apply to my code. Is there any easy way to load them as binary and add them so SP1 considers them as the background tiles?
I didn't found a tutorial on how to do it, is it possible?
I thought the function sp1_PutTiles might be the one for that, but unfortunatelly I didn't found any example of using it, and might not.
Thank you!!
SP1 and complex backgrounds (scr files)
Nirvana is an entirely separate game engine that supports multi-colour graphics.
In SP1, the tiles are 16-bit. If you print tiles that are only 8-bit (0-255) then the tile graphics are looked up like usual through the tile array. However, if you print 16-bit values such that the MSB is not 0, then this is taken as an address in memory where the eight bytes of tile graphics are found. So you can have an image in memory as background but the format will be different than a standard screen$. This also uses up a lot of memory, so plan on 128k from the get go
In SP1, the tiles are 16-bit. If you print tiles that are only 8-bit (0-255) then the tile graphics are looked up like usual through the tile array. However, if you print 16-bit values such that the MSB is not 0, then this is taken as an address in memory where the eight bytes of tile graphics are found. So you can have an image in memory as background but the format will be different than a standard screen$. This also uses up a lot of memory, so plan on 128k from the get go
Thanks, so putTitles do work then?alvin wrote:Nirvana is an entirely separate game engine that supports multi-colour graphics.
In SP1, the tiles are 16-bit. If you print tiles that are only 8-bit (0-255) then the tile graphics are looked up like usual through the tile array. However, if you print 16-bit values such that the MSB is not 0, then this is taken as an address in memory where the eight bytes of tile graphics are found. So you can have an image in memory as background but the format will be different than a standard screen$. This also uses up a lot of memory, so plan on 128k from the get go
I am also trying to have the minimal code possible if I create a code from scratch to have a SCREEN$ loaded into BANK2 and then load it with memcpy into memory, kind of
Code: Select all
memcpy(16384, cartoon0, 6912);
Code I tried from scratch is very stupid
Code: Select all
void page2() {
__asm
ld a,(23388) ;fetch current value
and %11111000 ;clear bits 0?2 (bank #)
or 2 ;select new bank
ld bc,32765 ;our port
di
ld (23388),a ;write new value back to sys. var
out (c),a ;and to port
ei
__endasm;
}
void page0() {
__asm
ld a,(23388) ;fetch current value
and %11111000 ;clear bits 0?2 (bank #)
or 0 ;select new bank
ld bc,32765 ;our port
di ;condom on
ld (23388),a ;write new value back to sys. var
out (c),a ;and to port
ei ;condom off
__endasm;
}
int main()
{
page2();
memcpy(16384, cartoon0, 6912);
page0();
in_wait_key();
while(1) {
}
}
Code: Select all
SECTION BANK_2_DATA
PUBLIC _cartoon0
_cartoon0:
BINARY "intro.scr"
Yes but I think I would use "sp1_IterateUpdateRect(rect,func)" for this instead. If you pass it a rectangle that covers the full screen, this function will visit all the "struct sp1_update" in the screen in left to right, top to bottom order. Each "struct sp1_update" is one character square. So you could do something like this:jordi wrote:Thanks, so putTitles do work then?
Code: Select all
unsigned char screen[6144];
unsigned char csx, csy;
unsigned char *csdst;
void copy_screen(struct sp1_update *u)
{
unsigned char *p;
// locate character square on screen
p = zx_cxy2saddr(csx, csy);
// store graphic location and colour in struct update
u->tile = (unsigned int)csdst;
u->colour = *zx_saddr2aaddr(p);
// copy screen graphics to screen buffer
for (unsigned char i = 0; i != 8; ++i)
{
*csdst++ = *p;
p += 256;
}
// next character square
if (++csx == 32)
{
csx = 0;
++csy;
}
}
...
// copy screen from memory bank
...
memcpy(16384,...);
// create screen in buffer from screen$
csx = csy = 0;
csdst = screen;
sp1_IterateUpdateRect(&fs, copy_screen); // fs = sp1_Rect covering full screen
Instead of storing your screens full size you can compress them. zx7 is included in z88dk so you can simply do "zx7 -f intro.scr" to compress the screen$ before including it as a binary. In your program:
Code: Select all
#include <compress/zx7.h>
dzx7_standard(cartoon0, 16384); // the original author made this src,dst even though c is normally dst,src
If you're paging the top 16k, you definitely have to make sure the code running, the stack and interrupt routines (if ints are enabled) are below 0xc000. By default, z88dk is going to place the stack up there and the suggested sp1 stack location is also up there so you will get a crash if you bank without moving your stack.
You can move the stack for your program with a pragma:
#pragma output REGISTER_SP = 0x8000 // or something out of the way
Another option is you move the stack to a temp location while you bank stuff.
You'll have to sketch out a rough memory map and decide where the stack should go, where your program org is, etc, keeping in mind sp1 wants to take a large chunk of the top of ram.
The paging you are doing updates the system variable BANKM. This is not needed unless you're running with basic interrupts enabled or you plan to return to basic. If not, you don't have to bother updating that system variable.
IO ports are defined in z88dk using special function registers and that port (0x7ffd) should be defined already in zx.h. So you could just write to that port from c like this:
IO_7FFD = x;
You can move the stack for your program with a pragma:
#pragma output REGISTER_SP = 0x8000 // or something out of the way
Another option is you move the stack to a temp location while you bank stuff.
You'll have to sketch out a rough memory map and decide where the stack should go, where your program org is, etc, keeping in mind sp1 wants to take a large chunk of the top of ram.
The paging you are doing updates the system variable BANKM. This is not needed unless you're running with basic interrupts enabled or you plan to return to basic. If not, you don't have to bother updating that system variable.
IO ports are defined in z88dk using special function registers and that port (0x7ffd) should be defined already in zx.h. So you could just write to that port from c like this:
IO_7FFD = x;