Thread Rating:
  • 0 Vote(s) - 0 Average
  • 1
  • 2
  • 3
  • 4
  • 5
sprites like MJ's Trabajo Basura (not unregr. Fourspriter)
#1
not unregretting that awesome Fourspriter, what about that technique used on MojonTwin's Trabajo Basura? <!-- m --><a class="postlink" href="http://www.mojontwins.com/juegos_mojonos/trabajo-basura-dire-job/">http://www.mojontwins.com/juegos_mojono ... -dire-job/</a><!-- m -->
it seems to be very similar to most of the sprites used on zx-spectrum games - how would we use this kind of sprites from a zxbasic-compiler library?
Reply
#2
The easiest way may well be to integrate sp1 from z88dk into Boriel's Basic; but it's something I haven't got my head around at all, that.

<!-- m --><a class="postlink" href="http://www.z88dk.org/forum/">http://www.z88dk.org/forum/</a><!-- m -->
<!-- m --><a class="postlink" href="http://www.z88dk.org/wiki/doku.php?id=library:sprites:sp1">http://www.z88dk.org/wiki/doku.php?id=l ... pritesConfusedp1</a><!-- m -->

Specifically this source:
<!-- m --><a class="postlink" href="http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/sprites/software/sp1/spectrum/sprites/">http://z88dk.cvs.sourceforge.net/viewvc ... m/sprites/</a><!-- m -->
Reply
#3
these sources looks confusing, specially for me
i were taking a look at some old magazines, and found this: http://www.worldofspectrum.org/infoseek.cgi?regexp=^Sprite+Designer+[2]$
when disassembled, i think the code looks like this: http://pastebin.com/6Wpeb7tT - but i couldn't understand a thing of this - maybe sp1 from z88dk were based from an 'engine' like this?
Reply
#4
It is a sprite engine - I don't think it was based on an older one specifically, but it does have quite a few similarities, such as its own screen copy that it updates before refreshing the screen. It's not surprising - a screen buffer is a very common way of doing flicker free sprites - you can update off screen, and then update to screen when done.
Reply
#5
We use Alcoholics Anonymous' splib2 library, a precursor to SP1. The library divides the screen in a 32x24 characters grid. Each cell can be printed with a background tile (256 in total). On top, you can define some sprites. In each update, sprites invalidate those cells they touch, making them "dirty". The libary just redraws such cells from bottom to top, starting with the background tile, then each corresponding 8x8 section of each sprite on top (which the library pre-rotates in a buffer).

There's not a full screen, 6912 bytes buffer. It's just a tile buffer. When an 8x8 cell needs to be redrawn, it is redrawn in a small buffer off-screen then blit to screen.

It works like hardware tile and sprite based displays such as those in the C64 or the MSX, but it's, of course, software driven.

splib2 is not so integrated into z88dk when compared to SP1, so porting it to a ZX Basic library would be posible, albeit painstakingly laborious, as the assembly syntaxes are not compatible and lots of things should be made by hand.

Besides, ZX Basic binaries aren't as fast as z88dk binaries (for obvious reasons: C is much lower level than BASIC).
Reply
#6
na_th_an Wrote:splib2 is not so integrated into z88dk when compared to SP1, so porting it to a ZX Basic library would be posible, albeit painstakingly laborious, as the assembly syntaxes are not compatible and lots of things should be made by hand.
I would like to have a look at these asm code. Where can I get the src code of sp1?
na_th_an Wrote:Besides, ZX Basic binaries aren't as fast as z88dk binaries (for obvious reasons: C is much lower level than BASIC).
A note on this claim: it's is only *partially true*. It's true that higher level languages add more overhead to programs (that's the trade-off). But keep in mind the idea behind ZX BASIC is that it performs heavy optimizations so it tries to be as fast as C while maintaining high level syntax (that's why I don't add many features people are asking for, like a true VAL routine, a richer PRINT one, or a GOTO 3 * n, DATA or whatever). Of course, benchmarking (thanks to Britlion) is necessary (e.g. compare ZX BASIC vs C vs ASM) to study possible optimizations by the compiler.

If you want you can push it further and use FastCALL routines (which are faster than __STDCALL__ ones), and even inline asm. A FASTCALLed + inline ASM routine is exactly the same as a normal ASM one (no overhead added).

I'm writting an extensive documentation (I think I've already mentioned before), that might even become a little manual. This manual is *really* advanced, and document things like: ASM Inlining, calling conventions and parameter passing, graph tables for the speccy, optimizations the compiler does (according to its optimization level), and much much more.

Regarding people asking more and more features: some (wanted!) features are slowly being added (one by one), but preserving the current performance or adding overhead *only* when such feature is used by the programmer, because I think if people want a slow fully-compatible Sinclair BASIC they better stick to the BASIC already included in the Speccy's ROM. :roll:

The most important feature missing at the moment (IMHO) is passing arrays as parameters to functions and subs.

Update: I've already had a look to the sp1 src above (about a year ago). The main problem there is I don't know how to use that library in C (to convert it to basic).
Reply
#7
I ran into similar problems. I understand the concepts behind it, I just can't work out

a) where the actual assembly is
b) how it's called
c) where it's documented.

I don't speak C, which doesn't help.
Reply
#8
boriel Wrote:
na_th_an Wrote:splib2 is not so integrated into z88dk when compared to SP1, so porting it to a ZX Basic library would be posible, albeit painstakingly laborious, as the assembly syntaxes are not compatible and lots of things should be made by hand.
I would like to have a look at these asm code. Where can I get the src code of sp1?

Again, not SP1, but splib2. SP1 is very heavily integrated into z88dk so the amount of things you have to port is huge. splib2 was conceived as a standalone library you could use from assembly or C - it just happens to include an "interface" z88dk-compatible, but could just be called using assembly "call"s. I'm quite sure that if you took the assembly files, modified the syntax, and embedded them in BASIC Subs and Functions, it would work.

You can find splib2 here: <!-- m --><a class="postlink" href="http://www.timexsinclair.org/alvin/spritepack/programmer-intro.htm">http://www.timexsinclair.org/alvin/spri ... -intro.htm</a><!-- m --> The documentation is for the programmer who's going to use it, but if you need asistance you can always ask Alvin, he's quite supportive.

Of course SP1 is faster and more feature rich, but splib2's memory footprint is much smaller. Besides, most of our games use it, it can't be that bad Big Grin Anyways, the source codes of SP1 come with the z88dk source distribution, as SP1 is part of z88dk.
Reply
#9
britlion Wrote:I ran into similar problems. I understand the concepts behind it, I just can't work out

a) where the actual assembly is
b) how it's called
c) where it's documented.

I don't speak C, which doesn't help.

You are welcome to adapt whatever of sp1 you would like to. The library works pretty much as nathan mentioned and is the successor to splib2. These are original libraries not based on anything else and are more sophisticated than anything you will find in magazines or the stuff they sold in the day Smile

The source is everything in this directory: <!-- m --><a class="postlink" href="http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/libsrc/sprites/software/sp1/spectrum/">http://z88dk.cvs.sourceforge.net/viewvc ... /spectrum/</a><!-- m --> and below. You can ignore the collision directory as that was never implemented properly. The code is standalone except for the dynamic memory allocation/deallocation done by sp1_CreateSpr and sp1_DeleteSpr. These two functions call to an external user-supplied function that does memory allocation. Typically, a C program simply uses standard malloc and free to satisfy the requests.

The library can be configured by editing the file 'spectrum-cusomize.asm' (customize.asm is a backup copy of the defaults) before generating the sp1 library. Customization allows configuration of the screen size and the memory map. A reduced screen size means less memory used by the library. The defaults set up a full size 32x24 screen and set the memory map detailed at the end of that file.

The C header file 'spectrum-sp1.h' lists all the sp1 functions and data structure definitions. I am not sure if Boriel's basic has the equivalent of a struct or pointer to a struct? but something like that is necessary.

* The section 'DATA STRUCTURES' lists all the struct definitions used by the library. The sub-section under 'SPRITES' containing all that SP1_DRAW_* stuff exposes the sprite draw primitives as function pointer addresses so that the draw primitives can be specified while creating sprites (see sprites/draw). That way you can choose between MASK, OR, XOR sprites, etc. The programmer doesn't do anything with them except pass them as values (memory addresses) to the creation functions.

* Lines 209 to 225 are the sprite related functions

* Lines 230 to 232 are sprite character functions -- these are character squares not attached to sprites than can be placed on the display to act like middle-ground elements (background elements that can be in front of some sprites as they have a z value associated with them).

* Lines 314 to 329 deal with background tiles (ie background character squares). Basically you PRINT AT characters to the background.

* Lines 370 to 389 are functions that deal with updating the screen.

The associated asm code is in the subdirectories; all implementations will be in *callee.asm files except for fastcall functions which will have no callee suffix. All callee files will also have a non-callee version that only jumps into the callee file. These are only there to be used by function pointers and can be ignored.


So the idea is the user configures the library by editing 'spectrum-cusomize.asm' and then creates the library by assembling it. This generates a standalone sp1.lib library and sp1.h header. The C program includes the header file so the compiler knows how to call the functions and the user adds '-lsp1' to the compile line so the linker looks for functions in sp1.lib.

One thing you do not want to do is have all the sp1 code always included in a project. This will reduce the amount of memory to the program. For example, a program that only uses MASK sprites does not need to include all the code for OR, XOR, LOAD, etc sprites in the project. z88dk has a linker that only pulls in functions that are actually called so this is how it's done in z88dk. I don't know if Boriel's compiler has a linker feature.
Reply
#10
AlcoholicsAnonymous Wrote:One thing you do not want to do is have all the sp1 code always included in a project. This will reduce the amount of memory to the program. For example, a program that only uses MASK sprites does not need to include all the code for OR, XOR, LOAD, etc sprites in the project. z88dk has a linker that only pulls in functions that are actually called so this is how it's done in z88dk. I don't know if Boriel's compiler has a linker feature.
Unfortunately not: I don't neither know the format of the object files z88dk uses nor know where to start. :oops:
I read they're based in .elf format or the like, but other than that, I have no clue of how they are created, linked etc...
Currently, zxbasic dumps everything to assembler which is finally converted to machine code.
Reply
#11
AlcoholicsAnonymous Wrote:The C header file 'spectrum-sp1.h' lists all the sp1 functions and data structure definitions. I am not sure if Boriel's basic has the equivalent of a struct or pointer to a struct? but something like that is necessary.

Nope. Not even that much of proto-object oriented programming. More or less Sinclair Basic and raw assembly only - or any library subroutines that can be made from that.
Reply
#12
boriel Wrote:
AlcoholicsAnonymous Wrote:Unfortunately not: I don't neither know the format of the object files z88dk uses nor know where to start. :oops:
I read they're based in .elf format or the like, but other than that, I have no clue of how they are created, linked etc...
Currently, zxbasic dumps everything to assembler which is finally converted to machine code.

Paulo recently updated the documentation <!-- m --><a class="postlink" href="http://z88dk.cvs.sourceforge.net/viewvc/z88dk/z88dk/doc/z80asm.html?revision=1.3">http://z88dk.cvs.sourceforge.net/viewvc ... vision=1.3</a><!-- m --> (at the end) but honestly I don't think I would reverse engineer anything... I think I would just either write an asm/linker myself (if that is what you want to do) or make use of an existing assembler that already does it for you. If the output of zxbasic is asm, perhaps the last stage could be assembled by 3rd party assembler / linker? sdcc does it that way and z88dk does it that way -- the compilers output asm code and the last linking stage is done by a separate linker / assembler. I think it would solve all your problems with only pulling in code the programs actually uses with little effort. Subroutines could then be assembled into libraries which would be pulled into the project by the linker as needed.

Possible candidates for assemblers are z80asm (used in z88dk), asz80 (used in sdcc), vasm and I know I am missing one here but I can't pin it down. You may want to look at licenses too. We are not totally satisfied with z80asm as it is missing sections which is quite important for separating data and code; however it is seeing continued development although very slowly. asz80 is better but we want to look at generating code for bankswitched systems (ie > 64k) and we are not sure yet if that can do it without modification.
Reply
#13
britlion Wrote:Nope. Not even that much of proto-object oriented programming. More or less Sinclair Basic and raw assembly only - or any library subroutines that can be made from that.

I did read in another thread some qualms about introducing pointers and struct like things but I do think this is something that has to happen in zxbasic to make it a better language -- without them it makes it difficult to do certain things. The concept of a pointer can be hidden from the programmer by using references for non-native types as is done in Java and other languages that try to insulate the programmer from the machine. Boriel will be doing exactly that with Arrays for passing Arrays to functions.

Certainly something like a struct should be in there. Just one example of why can be found in the sp1 library... each sprite has 10 variables associated with it. With 10 sprites on screen, there would be 100 variables. A call to a move sprite function would involve passing 10 parameters. This is all a bit crazy when all that is needed is a way to aggregate the data into a single piece so that all the data can be referred to with a single variable. I suppose a non-struct version might try to have 10 arrays, one for each sprite variable and indexed by a sprite number. But this is actually a much more confusing and limited approach IMO.
Reply
#14
AlcoholicsAnonymous Wrote:
britlion Wrote:Nope. Not even that much of proto-object oriented programming. More or less Sinclair Basic and raw assembly only - or any library subroutines that can be made from that.

I did read in another thread some qualms about introducing pointers and struct like things but I do think this is something that has to happen in zxbasic to make it a better language -- without them it makes it difficult to do certain things. The concept of a pointer can be hidden from the programmer by using references for non-native types as is done in Java and other languages that try to insulate the programmer from the machine. Boriel will be doing exactly that with Arrays for passing Arrays to functions.
That's the idea. I always though Basic should not mimic C (there are several threads about this topic), or we'll end up with "C with BASIC keywords" instead of a BASIC language. I use pointers for example for referenced variables (ByRef).

I also think structs should be a plus, but I haven't yet figured out how to implement them efficiently in a so limited machine: na_th_an suggested using IY+n scheme to reference struct fields, but IY is used by the TIMER interrupt routine. Sad I could disable it, but this will break compatibility with many BASIC programs which already work with the compiler: <!-- m --><a class="postlink" href="http://www.boriel.com/wiki/en/index.php/ZX_BASIC:Clock.Bas">http://www.boriel.com/wiki/en/index.php ... :Clock.Bas</a><!-- m -->
How did you implement structs?

Using IY would be nice. I'm thinking in relocating TIMER routine into RAM and free IY regs. (or just use something like PUSH IY, call DI routine, DI, POP IY, EI, RET).

Suggestions from anybody are welcome. Any ideas :?:
Reply
#15
I've been giving thought to this sort of issue for a while now - within the current constraints, and lacking object orientation, sprites are quite tough to do. I considered building an interface from subroutines and functions, such that you could call one and it would deal with the sprite for you - but the biggest issue is the local/global variable one - it would need arrays of data to keep track of sprites (or at least pointers) - and that would need to be global between the different subroutines. Tricky to program that /inside/ a sub Smile

All told, I rapidly realised it would become a messy thing to bolt on.

We do have memory allocation and de-allocation, and of course, when you ask for bytes from the pool, you get back an address. Most people would say that's a pointer, I think. The question is, how do we handle that as a general case?
Reply


Forum Jump:


Users browsing this thread: 2 Guest(s)