CPCWiki forum

General Category => Programming => Topic started by: redbox on 16:00, 06 March 11

Title: Mode 3
Post by: redbox on 16:00, 06 March 11
Can anyone help explain to me how Mode 3 works (as described on Grim's website here (http://www.grimware.org/doku.php/documentations/devices/gatearray#rmr))?


I see it's basically Mode 0 with only a 4 colour depth.  I have an effect I'm working on (which suits a 4 colours and 2 pixels per byte setup), but was wondering if using Mode 3 would give me any benefits over Mode 0 - for example, can you shrink the VRAM space?  Does it make double buffering any easier etc.?
Title: Re: Mode 3
Post by: Optimus on 16:32, 06 March 11

I think mode 3 is 4 colours in Mode 0 but without the advantages of such a mode. The screen is not 8kb as I'd expect but still 16kb. The bit permutations for the unused colours don't have any effect or maybe they cycle again over the 4 first colours, I don't remember. Now, if this would be an 8kb vram mode it would be great but unfortunatelly I don't see any usefuleness in it. I was told there is no use in Mode 3 but I'd like to hear otherwise.
Title: Re: Mode 3
Post by: Devilmarkus on 18:28, 06 March 11
It's also 16k screen ram but you can theoretically keep 2 screen contents in the same ram area and toggle them by byte shifting.
For more info, ask Kevin Thacker.
He did a little mode 3 test program, where you can toggle between 2 screens.
Title: Re: Mode 3
Post by: redbox on 18:42, 06 March 11
Quote from: Devilmarkus on 18:28, 06 March 11
It's also 16k screen ram but you can theoretically keep 2 screen contents in the same ram area and toggle them by byte shifting.
For more info, ask Kevin Thacker.
He did a little mode 3 test program, where you can toggle between 2 screens.


Now this sounds very interesting.  Do you have any links for the test program?
Title: Re: Mode 3
Post by: Devilmarkus on 19:48, 06 March 11
Here you go.

(no palette is set... pure test!)

Use space key to toggle images
Title: Re: Mode 3
Post by: redbox on 21:12, 06 March 11
Quote from: Devilmarkus on 19:48, 06 March 11
Use space key to toggle images


Thanks for the demo. 


Do you mean the here the data is just stored in half bytes, which means two pictures are in 16kb?  It looks like from this demo data still has to be copied to the screen...?  If so, you could also do this sort of thing with normal Mode 0 (albeit with only 4 colours) by also storing the data in this way.


I was hoping Mode 3 gave you some little advantage in some way because Grim's website says it's "a bit weird but may be useful in some very special cases".
Title: Re: Mode 3
Post by: Devilmarkus on 23:44, 06 March 11
Sure it needs to be copied to screen ram.
But both screens are in the 16k file!
It's done by byte shifting.
Title: Re: Mode 3
Post by: andycadley on 00:28, 07 March 11
Quote from: redbox on 21:12, 06 March 11
I was hoping Mode 3 gave you some little advantage in some way because Grim's website says it's "a bit weird but may be useful in some very special cases".
Nothing that couldn't be equally accomplished by Mode 0 with careful palette selection. Mode 3 is basically just a quirk of the way the hardware is wired up and not actually useful in any practical sense.
Title: Re: Mode 3
Post by: arnoldemu on 11:15, 07 March 11
Quote from: redbox on 21:12, 06 March 11
I was hoping Mode 3 gave you some little advantage in some way because Grim's website says it's "a bit weird but may be useful in some very special cases".
Andy is correct, mode 3 gives you nothing.
No advantage, and still takes 16k, just some bits are not used in each byte.
Title: Re: Mode 3
Post by: ssg on 03:48, 08 March 11
how about saving collision mask for the game screen? although that game would have sucked with such wide pixels and only 4 colors :)
Title: Re: Mode 3
Post by: redbox on 10:52, 08 March 11
Thanks for the help guys.

Thought Mode 3 was like this, but worth asking.  :)
Title: Re: Mode 3
Post by: steve on 14:23, 08 March 11
Maybe you could generate a 3D display?, two screens switched 50 times a second, using coloured glasses as they do with 3D TV/Films.
Title: Re: Mode 3
Post by: redbox on 16:07, 08 March 11
Quote from: steve on 14:23, 08 March 11
Maybe you could generate a 3D display?, two screens switched 50 times a second, using coloured glasses as they do with 3D TV/Films.

Problem is there isn't a way of accessing the data for the 2nd screen directly.

You have to shift the bytes and this takes a long time, way longer than is possible using 50hz.  :(
Title: Re: Mode 3
Post by: steve on 17:43, 08 March 11
Could you use double buffering so the processor can write to one 16k ram block while the other block is being displayed?, I don't know if 3D is possible with the CPC, but it would be great if it was.
Title: Re: Mode 3
Post by: steve on 18:16, 08 March 11
@redbox, are you saying the machine cannot access the second screen data directly, so it must be moved by the cpu to be displayed?
Title: Re: Mode 3
Post by: andycadley on 19:02, 08 March 11
@steve, yes exactly. However if you do the same thing with Mode 0 you should be able to switch between 4 colour screens with just a palette change.
Title: Re: Mode 3
Post by: redbox on 20:55, 08 March 11
Quote from: steve on 18:16, 08 March 11
@redbox, are you saying the machine cannot access the second screen data directly, so it must be moved by the cpu to be displayed?

As Andy said, you're completely right.

It's a shame, because Mode 3 stores the a byte of data as 11XX11XX, with X being unused.  If you could switch to XX11XX11 using the hardware then some good effects could be made (maybe such as you described) but alas it appears it's not possible.
Title: Re: Mode 3
Post by: AMSDOS on 10:25, 04 April 11
This has me stumped. According to Video Modes (http://cpcwiki.eu/index.php/Video_modes) MODE 3 uses the same Bits per Pixel (BPP) as Mode 1 and yet it's only 160x200!  ???  Does this mean it's sort of limited to a Spectrum Sized screen? (which a number of games used anyway to allow for more coding?).

I simply interpret it as a quirky mode. Pity the CPC cannot have 80x100 with all 27 colours anywhere on screen (not the split screen effect kind!  8) )
Title: Re: Mode 3
Post by: arnoldemu on 11:39, 04 April 11
Quote from: CP/M User on 10:25, 04 April 11
This has me stumped. According to Video Modes (http://cpcwiki.eu/index.php/Video_modes) MODE 3 uses the same Bits per Pixel (BPP) as Mode 1 and yet it's only 160x200!  ???  Does this mean it's sort of limited to a Spectrum Sized screen? (which a number of games used anyway to allow for more coding?).

I simply interpret it as a quirky mode. Pity the CPC cannot have 80x100 with all 27 colours anywhere on screen (not the split screen effect kind!  8) )
Yes it uses the same BPP, and yes it's 160x200. But some other bits are ignored.
It's just how the video hardware creates it.

Think like this:

every microsecond, the gate-array reads 2 bytes of data into it's internal memory.
Then using mode information it decodes the pixels in a certain way.
Then also, depending on mode it then "shifts" the pixels out to the monitor until all are done.
It happens that it shifts at mode 0 rate, but decodes like mode 1.

The screen size is the same as mode 0/mode 1/mode 2 in terms of border size, chars per screen, just looks different, and the other bits in the byte are ignored.
Is it useful, well, not really, I've not found something it can be an advantage for.
Title: Re: Mode 3
Post by: AMSDOS on 14:06, 04 April 11
I had a look at Markus' example which seems to suggest that it can incorporate 2 screens within a 17k program, so perhaps that's the only good thing about Mode 3, otherwise it's an unusual example.
Title: Re: Mode 3
Post by: arnoldemu on 14:24, 04 April 11
Quote from: CP/M User on 14:06, 04 April 11
I had a look at Markus' example which seems to suggest that it can incorporate 2 screens within a 17k program, so perhaps that's the only good thing about Mode 3, otherwise it's an unusual example.
That was actually my test program.

The test was 1) to check mode 3 was decoded correctly in emus, 2) to test on cpc clones to see if they were compatible in this respect, or if they decoded it different.

Yes you can hold 2 screens within the same 17k, but the only way to switch between them is to use a software loop to shift the bits up and down. You can't switch in hardware.
Title: Re: Mode 3
Post by: sigh on 15:22, 04 April 11
Are we talking split screen?
Title: Re: Mode 3
Post by: arnoldemu on 15:39, 04 April 11
Quote from: sigh on 15:22, 04 April 11
Are we talking split screen?
no

Mode 3 is an artifact of the cpc's design. It's almost useless because it is same resolution as mode 0 but with 4 colours, some bits in each byte are ignored, so it doesn't take any less ram than normal mode 0.
Title: Re: Mode 3
Post by: TFM on 04:20, 05 April 11
Well, there is a use for Mode 3 ... think about SHADDOWS ;-)

And as second hint... think about switching between Mode 0 and 3 ;-)

Got it ;-)
Title: Re: Mode 3
Post by: AMSDOS on 13:36, 05 April 11
Quote from: arnoldemu on 14:24, 04 April 11
That was actually my test program.

Sorry!  :-[

QuoteThe test was 1) to check mode 3 was decoded correctly in emus, 2) to test on cpc clones to see if they were compatible in this respect, or if they decoded it different.

QuoteYes you can hold 2 screens within the same 17k, but the only way to switch between them is to use a software loop to shift the bits up and down. You can't switch in hardware.

So that means it won't work with SCR SET BASE or LDIR (or simular instructions).
Title: Re: Mode 3
Post by: sigh on 15:21, 05 April 11
Quote from: TFM/FS on 04:20, 05 April 11
Well, there is a use for Mode 3 ... think about SHADDOWS ;-)

And as second hint... think about switching between Mode 0 and 3 ;-)

Got it ;-)

Could you elaborate on these?

What do you mean by shadows?
Also, why would you want to switch modes?
Title: Re: Mode 3
Post by: TFM on 03:02, 06 April 11
Quote from: sigh on 15:21, 05 April 11
Could you elaborate on these?

What do you mean by shadows?
Also, why would you want to switch modes?

When you switch between Mode 0 and 3 then you literally switch between 4 and 16 colors. And you switch between watch it all (Mode 0) and watch half of it (Mode 3). Sorry can't tell it better in english words...

Title: Re: Mode 3
Post by: FatAgnus on 03:20, 06 April 11
POST EDITED:
Sorry, bad test. Yes, colour depth changes without distorting gfx.
Some flickering effects could be archieved (it's faster than changing entire palette for "flashing" effects, i.e.)
Title: Re: Mode 3
Post by: sigh on 03:38, 06 April 11
Quote from: TFM/FS on 03:02, 06 April 11

When you switch between Mode 0 and 3 then you literally switch between 4 and 16 colors. And you switch between watch it all (Mode 0) and watch half of it (Mode 3). Sorry can't tell it better in english words...

Do you have any control of the colours that it is switching too? For instance, if you wanted to change a 16 colour pic to a black, grey and white etc.
Would it be the whole scene/pic or could you allocate it to certain areas or sprites?

I would also still like to know what you mean by shadows.
Title: Re: Mode 3
Post by: TFM on 06:07, 06 April 11
Well, shaddows in the sense of other colors. Here a link, that is a bit related, but not completly what I mean:

http://www.youtube.com/watch?v=ztf7pacNf6A (http://www.youtube.com/watch?v=ztf7pacNf6A)

You surely can define the colors. But you usually use the whole screen.

Just play a bit around and switch between 0 and 3 (  LD BC,&7F80 or 83 : OUT (C),C   )

In case you work under basic you have to switch the interrupts off.

Go assembler, in Basic you can't do that properly.
Title: Re: Mode 3
Post by: arnoldemu on 11:20, 06 April 11
Quote from: TFM/FS on 06:07, 06 April 11
Well, shaddows in the sense of other colors. Here a link, that is a bit related, but not completly what I mean:

http://www.youtube.com/watch?v=ztf7pacNf6A (http://www.youtube.com/watch?v=ztf7pacNf6A)

You surely can define the colors. But you usually use the whole screen.

Just play a bit around and switch between 0 and 3 (  LD BC,&7F80 or 83 : OUT (C),C   )

In case you work under basic you have to switch the interrupts off.

Go assembler, in Basic you can't do that properly.
Nice effect. I see now.
Title: Re: Mode 3
Post by: sigh on 00:03, 07 April 11
Thats a very interesting effect. Thanks for showing.
This could be used for some lighting effects in games such sprites walk under light rays etc.
Title: Re: Mode 3
Post by: TFM on 23:21, 07 April 11
If you can wait 10 years more... then our RPG will please you :-)
Title: Re: Mode 3
Post by: sigh on 12:19, 09 April 11
Question on the 4 modes:

1) If you were to take each of the 4 modes and make them 160x200, in order(the fastest first) , which would be the faster mode to use for a sprite fest of a vertical scrolling bullet hell shooter game?

2) Also, are there any examples of games done in mode 2?

Quote from: TFM/FS on 23:21, 07 April 11
If you can wait 10 years more... then our RPG will please you :-)

A very ambitious project indeed! Roll on 2021 :) !
Title: Re: Mode 3
Post by: AMSDOS on 12:30, 09 April 11
Quote from: sigh on 12:19, 09 April 11
Question on the 4 modes:

1) If you were to take each of the 4 modes and make them 160x200, in order(the fastest first) , which would be the faster mode to use for a sprite fest of a vertical scrolling bullet hell shooter game?

2) Also, are there any examples of games done in mode 2?

I'm also interested to know if there were any graphical games done in Mode 2, my feeling is most of them are Text Adventures. At one time though I thought SWIV might have been since the main playing field is two colours, sadly it isn't, though my feeling is it's seems as if it could be done by simply having 3 quarters of the playing screen in Mode 2 and the Bottom quarter in Mode 1 for the Control Pannel.
Title: Re: Mode 3
Post by: TFM on 09:29, 10 April 11
Quote from: sigh on 12:19, 09 April 11
Question on the 4 modes:

1) If you were to take each of the 4 modes and make them 160x200, in order(the fastest first) , which would be the faster mode to use for a sprite fest of a vertical scrolling bullet hell shooter game?

2) Also, are there any examples of games done in mode 2?

1) The fastest mode is Mode 2. For examples see some of Bollwares Mode 2 games. Sprites are very easy to handle in Mode 2. Mode 1 and 0 need more complex (and therefore slower) routines.
But... it all depends if you work with or without background. Without background it doesn't matter much.

2) Err... yes... see: http://www.bollaware.de/ (http://www.bollaware.de/)

Hope that helps a bit...
Title: Re: Mode 3
Post by: sigh on 23:58, 10 April 11
Quote from: TFM/FS on 09:29, 10 April 11

1) The fastest mode is Mode 2. For examples see some of Bollwares Mode 2 games. Sprites are very easy to handle in Mode 2. Mode 1 and 0 need more complex (and therefore slower) routines.
But... it all depends if you work with or without background. Without background it doesn't matter much.

2) Err... yes... see: http://www.bollaware.de/ (http://www.bollaware.de/)

Hope that helps a bit...

Mode 2 - Fres attack game by Bollwares. That really is an incredible game. Smooth horizontal scrolling(is it pixel scrolling? It looks incredibly smooth) - just wow!

It's the only mode 2 game I've seen on their site. Are there others?

(..and it is 2 player...)
Title: Re: Mode 3
Post by: arnoldemu on 11:23, 11 April 11
Quote from: sigh on 23:58, 10 April 11
Mode 2 - Fres attack game by Bollwares. That really is an incredible game. Smooth horizontal scrolling(is it pixel scrolling? It looks incredibly smooth) - just wow!

It's the only mode 2 game I've seen on their site. Are there others?

(..and it is 2 player...)
I thought the mastertronic game transmuter was in mode 2.
Or was it just the title screen?
Title: Re: Mode 3
Post by: sigh on 15:30, 11 April 11
Quote from: arnoldemu on 11:23, 11 April 11
I thought the mastertronic game transmuter was in mode 2.
Or was it just the title screen?

Looking at the screen shots on transmuter it seems to be mode 1 as there are 4 colours: http://www.cpcgamereviews.com/t/index9.html (http://www.cpcgamereviews.com/t/index9.html)

So, would a bullet hell shoot em up be possible with Mode 2 graphics seeing that the sprites are quicker to handle? Also, with that huge sheet of 640x200 only taking up 16kb, you could most likely have some interesting graphical effects and huge end of level bosses.
Title: Re: Mode 3
Post by: andycadley on 21:48, 11 April 11
Quote from: sigh on 15:30, 11 April 11
So, would a bullet hell shoot em up be possible with Mode 2 graphics seeing that the sprites are quicker to handle? Also, with that huge sheet of 640x200 only taking up 16kb, you could most likely have some interesting graphical effects and huge end of level bosses.

I seriously doubt that Mode 2 sprites will be faster, if anything I'd expect them to work out slower. Whilst it's true that a sprite of equal dimensions uses less memory, you end up needing the sprites to be twice as wide for them to be physically the same size - so no memory savings there. Furthermore, since they're only monochrome, you have to maintain a seperate mask unless you want very primitive looking mono sprites. That effectively means you've doubled the memory requirement over Mode 1 sprites and gained very little in the process.
Title: Re: Mode 3
Post by: sigh on 23:31, 11 April 11
Quote from: andycadley on 21:48, 11 April 11

I seriously doubt that Mode 2 sprites will be faster, if anything I'd expect them to work out slower. Whilst it's true that a sprite of equal dimensions uses less memory, you end up needing the sprites to be twice as wide for them to be physically the same size - so no memory savings there. Furthermore, since they're only monochrome, you have to maintain a seperate mask unless you want very primitive looking mono sprites. That effectively means you've doubled the memory requirement over Mode 1 sprites and gained very little in the process.

I was wondering about the masking. Some interesting and different points made by both you and TFM/MS.
Title: Re: Mode 3
Post by: TFM on 01:00, 12 April 11
Exactly right! Andy Cadley is wrong here (probably he never made sprite routines...). In Mode 2 it's totally easy to connect Sprites with a background, because a pixel can be set or not. That's so simple. But in Mode 1 and 0 you have more colors, and every pixel uses different bits of a byte. In addition - depending in the pen - a set pixel can consist out of ones and zeroes. So the fast and easy Z80 instructions can't be used any longer.
What was 1-step in Mode 2 becomes at least 2-steps in Mode 1 and 0. If Andy Cadley still thinks he is right, then let him proove it.
Title: Re: Mode 3
Post by: andycadley on 02:06, 12 April 11
LOL, I can assure you I've written a great many sprite routines on both the CPC and the Spectrum (which has a very Mode 2 like display) so I do have a clue what I'm talking about here. I can see where the assumption it must be faster comes from, because it seems inherently obvious at first. It's only when you start to consider the details of how it has to be done that the rather more surprising truth becomes self evident.

Unless your sprites are going to be solid blocks of one colour that never pass over background (or, if they do you just allow some parts to appear incorrectly transparent) you have to use a seperate mask layer to first clear the relevant area of the display under the sprite. Doing this ends up being just as much work as masking a Mode 1 sprite but uses more memory overall (since Mode 1 sprites usually just sacrifice 1 colour to act as a mask, which you can't do in Mode 2).

As odd as it may seem, you're usually much better off working in Mode 0 from a performance point of view as it both minimizes the amount of masking needed and reduces the amount of memory needed for pre-shifting frames. From a gaming perspective Mode 2 doesn't really make much sense at all.
Title: Re: Mode 3
Post by: arnoldemu on 11:50, 12 April 11
I too have written some sprite routines for all the modes.

Really there is not much in them, but perhaps I need to make a demo program to show what you need and the resulting speed so we can settle this.

In all modes, it comes down to do you sacrific one pen for transparency. If you do, you can have a 256 byte mask table. If you don't you need extra mask bytes.

Now in mode 2, Andy is correct, you *must* have a mask, you've got no choice.

So then it comes down to, do you store pre-shifted sprites or do you store a shift table and compute at runtime.

For mode 2, this is approx 3.5K of shift table, for mode 1 it's half this, for mode 0, it's 512 bytes i think.

The actual code is almost the same regardless of the mode, it just depends on how wide and tall the sprite is.

The way you can make sprite drawing faster is to reduce the width of the screen to be 32 chars wide (64 bytes), because then you can use more 8-bit arithmetic to move around the screen compared to being forced to use 16-bit.

So which mode is best? I would say, go for mode 1 if you need resolution and detail in your sprites.
Go for mode 0 if you want colour.
Mode 2 is not really that great for games, but could be used in a stylised way to create something interesting and different from the norm. Here I am more thinking of using mode 2 with some interrupts to have more than 2 colours on the screen, and produce some interesting colour mixes.

EDIT:
For those who are not sure of the terms I used here, go to:

www.cpctech.org.uk/

Look under "source" and here you will find examples for drawing masked sprites, pre-shifted sprites, sprites in mode 1 and mode 2.

So you can get an idea of how to draw a sprite on the cpc.
Title: Re: Mode 3
Post by: sigh on 15:22, 12 April 11
I see.

While I've been working on the beatem up game, I've been toying with the idea of trying out a different mode for the next game I want to create (football) but first want to test on something less animation heavy like a vertical shooter, so I can have a better understanding of the different modes and what's capable with each one. (I'll eventually will be doing something using mode 2). I now am even more impressed at how quickly Fres Attack plays with all these other variables!
Title: Re: Mode 3
Post by: TFM on 07:32, 13 April 11
In Mode 2 the Sprite itself is the mask and the quick Z80 command OR can be used to lay the Sprite over the background. This is the most efficient way, and it can't be used in Mode 1 and 0.

So Mode 2 is the winner! ;D


EDIT: Maybe we should do some Sprite-Routine benchmarks here, but you guys will really start to hate me if I'm right at the end - because I'm usually right (ok, you can start to hate me now).

Title: Re: Mode 3
Post by: ssg on 09:50, 13 April 11
Quote from: TFM/FS on 07:32, 13 April 11
In Mode 2 the Sprite itself is the mask


That's not true. You'd want to have opaque black color in your sprites, for dithering or detailing etc.
Title: Re: Mode 3
Post by: arnoldemu on 11:17, 13 April 11
Quote from: TFM/FS on 07:32, 13 April 11
In Mode 2 the Sprite itself is the mask and the quick Z80 command OR can be used to lay the Sprite over the background. This is the most efficient way, and it can't be used in Mode 1 and 0.

So Mode 2 is the winner! ;D


EDIT: Maybe we should do some Sprite-Routine benchmarks here, but you guys will really start to hate me if I'm right at the end - because I'm usually right (ok, you can start to hate me now).
a fast sprite drawing challenge!
this will be fun.
If you're correct, I'll not hate you ;)

EDIT: Mission genocide uses OR to draw the sprites and AND to remove them, but then you loose some colours ;)
I already made a sprite example that shows this one ;)
Title: Re: Mode 3
Post by: FatAgnus on 11:49, 13 April 11
Ssg is right.
You need 3 colours in mode2, "ink"+"black"+"transparent", so you can't simply "OR it" (if you want a USEFUL routine, of course)

Title: Re: Mode 3
Post by: TFM on 21:16, 13 April 11
Quote from: ssg on 09:50, 13 April 11

That's not true. You'd want to have opaque black color in your sprites, for dithering or detailing etc.

Well, in Mode 2 you have only 2 colors (pixel set or pixel not set). The dittering must be done to the background, so the sprite remains as it is.

Or do you want to dither that sprite? Then it would be like a shaddow, nice effect but not wanted for most sprites I guess.
Title: Re: Mode 3
Post by: TFM on 21:17, 13 April 11
Quote from: FatAgnus on 11:49, 13 April 11
Ssg is right.
You need 3 colours in mode2, "ink"+"black"+"transparent", so you can't simply "OR it" (if you want a USEFUL routine, of course)

But Mode 2 _HAS_ only two colors. A mask is senseless there. Look at Bollawares prods.
Title: Re: Mode 3
Post by: TFM on 21:20, 13 April 11
Quote from: arnoldemu on 11:17, 13 April 11
a fast sprite drawing challenge!
this will be fun.

Think so. Now let's define some parameters... Screen format... sprites size.... how to measure time (100 moves of the sprite?).... background or no backgound?   

Tell me what you want ... I don't care.
Title: Re: Mode 3
Post by: andycadley on 21:57, 13 April 11
Quote from: TFM/FS on 21:17, 13 April 11

But Mode 2 _HAS_ only two colors. A mask is senseless there. Look at Bollawares prods.

That's exactly why you need a mask, two colours isn't enough.

Let's consider a very simple example, a sprite like Dizzy who is basically a big blob with eyes. If you use ink 0 as transparent and ink 1 as white there is no way you can draw him without making his eyes transparent, which is going to look exceptionally ugly as he wanders around the world. You need a seperate mask so that you can make his eyes black, his body white and the space around him transparent. It's basically essential for all but a handful of limited scenarios.

The two key cases where you could avoid masking are where the entire background is ink 0, but then you could equally well OR a Mode 0 or Mode 1 sprite, or for extremely simple sprites which are just a solid block of colour. Now that is handy for bullets, but you can use the same optimisation of just ORing onto the display in Mode 1 or 0 by just drawing your bullets entirely in ink 3 or 15 respectively.
Title: Re: Mode 3
Post by: FatAgnus on 22:00, 13 April 11
Quote from: TFM/FS on 21:17, 13 April 11

But Mode 2 _HAS_ only two colors. A mask is senseless there. Look at Bollawares prods.


Sorry, you are wrong: the mask does the job.

EDIT: Oooops, Andycadley was faster and better.
Title: Re: Mode 3
Post by: TFM on 22:31, 13 April 11
Quote from: andycadley on 21:57, 13 April 11
Let's consider a very simple example, a sprite like Dizzy who is basically a big blob with eyes. If you use ink 0 as transparent and ink 1 as white there is no way you can draw him without making his eyes transparent, which is going to look exceptionally ugly as he wanders around the world.

You are absolutely right in this case.

But solid tanks and jets don't have eyes  ;D  Ok, I'm always taking space games as reference in mind. For Sprites with two colors you can do something else. Just directly draw them. Routines will be a bit more complex, but really quick.
Title: Re: Mode 3
Post by: TFM on 22:33, 13 April 11
Quote from: FatAgnus on 22:00, 13 April 11

Sorry, you are wrong: the mask does the job.

EDIT: Oooops, Andycadley was faster and better.

No, I'm not.

Andy is right with Dizzy.

But I'm right with SpaceWars.

It depends on the final application, the way you like to use them.

Look f. e. at the FutureOS mousepointer, no mask is needed, and I guess it get's the job done. I have no better example, because I don't consider Mode 2 (at the moment) for games.
Title: Re: Mode 3
Post by: FatAgnus on 22:36, 13 April 11
Yes, you are.
If you want to win "because I was talking about this game, not about this other", nice then.
Nice to meet yourself.


Title: Re: Mode 3
Post by: andycadley on 23:00, 13 April 11
Well except for the fact that in something like Spacewar you can just OR (probably even XOR) the sprites regardless of the mode, so it's definitely not faster in that case.
Title: Re: Mode 3
Post by: TFM on 23:18, 13 April 11
Quote from: FatAgnus on 22:36, 13 April 11
Yes, you are.
If you want to win "because I was talking about this game, not about this other", nice then.
Nice to meet yourself.

You miss the point! It's not about a particular game. It's just in which way you want to use the sprites. Again look at Bollawares prods f.e. and then it may be nice to meet yourself - or whatever :-\

Quote from: andycadley on 23:00, 13 April 11
Well except for the fact that in something like Spacewar you can just OR (probably even XOR) the sprites regardless of the mode, so it's definitely not faster in that case.

If you OR them it's way faster... that brings us back to the sprite benchmark.  8)
Title: Re: Mode 3
Post by: FatAgnus on 23:29, 13 April 11
Sorry again, but "THE POINT" is obvious here, very very obvious.

EDIT: I feel BANHAMMER over my head, so, "oh yes, you are right, thanx!". Ok?
Title: Re: Mode 3
Post by: TFM on 03:11, 14 April 11
Quote from: FatAgnus on 23:29, 13 April 11
Sorry again, but "THE POINT" is obvious here, very very obvious.

EDIT: I feel BANHAMMER over my head, so, "oh yes, you are right, thanx!". Ok?

What's your problem? Afraid of a discussion? Do you like to make a personal problem out of it?

Ok, I leave this thread now. Have fun alltogether. :P 8)
Title: Re: Mode 3
Post by: Xyphoe on 04:06, 14 April 11
Please don't fall out guys! This could be (and was/is) an interesting topic and very useful ... even if I don't really quite understand large parts of the technical discussions!  :-*
Title: Re: Mode 3
Post by: redbox on 11:22, 14 April 11
Quote from: TFM/FS on 03:11, 14 April 11
Ok, I leave this thread now. Have fun alltogether. :P 8)


Ah, don't go - I was hoping to see that you might finally admit you were wrong for once...?


Was an interesting topic too.  :)
Title: Re: Mode 3
Post by: arnoldemu on 11:27, 14 April 11
Quote from: TFM/FS on 22:33, 13 April 11
It depends on the final application, the way you like to use them.
Yes I agree. It does depend on application.

So the way to solve this would be to define various scenarios, and then each person can implement a method that works in that scenario.

to me the ultimate timing would be to see the timing of the raster bars in the border. If we define how the timing is done, we can also then compare and find the fastest.

I think it would be a interesting way to look at how sprites can be drawn.



Title: Re: Mode 3
Post by: sigh on 12:14, 14 April 11
This is a fantastic idea!!

It's also very likely to create new thoughts and techniques that may not have yet been discovered.
Title: Re: Mode 3
Post by: FatAgnus on 12:45, 14 April 11
Quote from: Xyphoe on 04:06, 14 April 11
Please don't fall out guys! This could be (and was/is) an interesting topic and very useful ... even if I don't really quite understand large parts of the technical discussions!  :-*


Yes, you are right Xyphoe. You are cent per cent right.
About the "contest", as long as Executioner can be considered winner (why wasting time? :-X ), it would be very interesting to know who gets the second place.
My bet is for Syx.
Title: Re: Mode 3
Post by: andycadley on 14:14, 14 April 11
Quote from: FatAgnus on 12:45, 14 April 11
About the "contest", as long as Executioner can be considered winner (why wasting time? :-X ), it would be very interesting to know who gets the second place.

If we end up with a library of fast sprite routines that can be used, everyones a winner!  ;)
Title: Re: Mode 3
Post by: FatAgnus on 14:31, 14 April 11
QuoteIf we end up with a library of fast sprite routines that can be used, everyones a winner! 

Yes, you are right too.  ;) :laugh:
Title: Re: Mode 3
Post by: SyX on 14:48, 14 April 11
Niño que sepas que te aprecio mucho y que tengo que invitarte a unas birras ó lo que prefieras, pero me vas a poner gordo con tanto halago  :laugh:
Title: Re: Mode 3
Post by: FatAgnus on 14:53, 14 April 11
Quote from: SyX on 14:48, 14 April 11
Niño que sepas que te aprecio mucho y que tengo que invitarte a unas birras ó lo que prefieras, pero me vas a poner gordo con tanto halago  :laugh:


Why?
I give you THE SECOND pos, not the first one!  :laugh:
A Executioner-Grim-Rhino duel could be mythical! but, of course, they don't need to prove anything ;) 
...wait... if so, then you are fourth! Sorry about that!  ::)
Title: Re: Mode 3
Post by: SyX on 15:12, 14 April 11
xDDDDDD
Title: Re: Mode 3
Post by: sigh on 15:33, 14 April 11
Quote from: andycadley on 14:14, 14 April 11

If we end up with a library of fast sprite routines that can be used, everyones a winner!  ;)

So very true.
Title: Re: Mode 3
Post by: TFM on 17:23, 14 April 11
Quote from: redbox on 11:22, 14 April 11

Ah, don't go - I was hoping to see that you might finally admit you were wrong for once...?


Was an interesting topic too.  :)

Nice! And Thanks! So if you want to see me wrong, that's easy - just let's make the sprite benchmark contest. I already said, you can define all parameters. If I do it, then maybe some guy would call it ballenced. So all paramerters free for you to define. But seeminly nobody wants that. Give it a try, proove me wrong  ;)
Title: Re: Mode 3
Post by: TFM on 17:25, 14 April 11
Quote from: arnoldemu on 11:27, 14 April 11
Yes I agree. It does depend on application.

So the way to solve this would be to define various scenarios, and then each person can implement a method that works in that scenario.

to me the ultimate timing would be to see the timing of the raster bars in the border. If we define how the timing is done, we can also then compare and find the fastest.

I think it would be a interesting way to look at how sprites can be drawn.

Aehm... if I get you right... then you suggest the following:
- switch border to different color
- move sprite (or just draw sprite, or??)
- switch border again to other color

Right?

Ok, can somebody define the other paramertes (size, screen format, background)?
Title: Re: Mode 3
Post by: sigh on 23:14, 15 April 11
A weekend start? (Not to sure how long it takes to do these things...)

Really am interested in these results!
Title: Re: Mode 3
Post by: TFM on 23:55, 15 April 11
Quote from: sigh on 23:14, 15 April 11
A weekend start? (Not to sure how long it takes to do these things...)

Really am interested in these results!

Why don't you do a favour for us. Just define:

- Sprite size in X and Y
- Screen format (chars per line, number of lines)
- Use background of not?
- other things you have in mind...

And then we can start  :)
Title: Re: Mode 3
Post by: andycadley on 00:48, 16 April 11
How about:

Anything I've missed?
Title: Re: Mode 3
Post by: sigh on 01:29, 16 April 11
Quote from: andycadley on 00:48, 16 April 11
How about:


       
  • 24*21 Mode 1 pixels or equivalent (the size of a C64 hardware sprite, which seems like an unbiased point of reference)
  • Background composed of 16*16 Mode 1 (or equivalent) tiles that sprite can pass in front of.
  • Sprites, background and tiles can be stored however is appropriate for the routine.
  • No need to support hardware scrolling.
  • Sprites and tile drawing should be generic enough that they can reasonably be used in a 64K game
Anything I've missed?

But isn't it mode 2 thats under investigation and was the reason for this friendly contest?
Title: Re: Mode 3
Post by: andycadley on 01:54, 16 April 11
Well it was a case of Mode 2 is the fastest for drawing sprites in, so you need some submissions from all different modes to see for sure. Of course people can always submit multiple different routines for different modes (or one routine that works in all modes if they'd like).

Probably should add that everyone will share their code as as they go or at least at the end (somewhere on the wiki?) so that we can all learn some new tricks. At the end of the day, the "contest" is less interesting than getting everyone to do a bit of cpc coding, even if they've never really tried before.
Title: Re: Mode 3
Post by: TFM on 03:02, 16 April 11
Quote from: andycadley on 00:48, 16 April 11
How about:   

         
  • 28*21 Mode 2 pixels (an unbiased point of reference)
  • Background composed of 32*16 Mode 2 tiles that sprite can pass in front of.
  • Sprites, background and tiles can be stored however is appropriate for the routine.
  • No scrolling.
  • Sprites and tile drawing must be generic
Anything I've missed?

Nope! All defined! Ok, let's take that parameters.

Yes, sure we've been talking about MODE 2! So I adjusted (in your quote) the pixel to Mode 2, ok?

Title: Re: Mode 3
Post by: andycadley on 09:20, 16 April 11
Quote from: TFM/FS on 03:02, 16 April 11
Yes, sure we've been talking about MODE 2! So I adjusted (in your quote) the pixel to Mode 2, ok?
Well the sprite size should be 48*21 Mode 2 pixels, but I think that was probably a typo. Other than that all sounds good to me.  :)
Title: Re: Mode 3
Post by: TFM on 09:25, 16 April 11
Quote from: andycadley on 09:20, 16 April 11
Well the sprite size should be 48*21 Mode 2 pixels, but I think that was probably a typo. Other than that all sounds good to me.  :)

Yes, right :-) ...was a long day! Let's get it started... :-)
Title: Re: Mode 3
Post by: sigh on 16:18, 18 April 11
So how is it all going for you programmers out there? Any news?
Title: Re: Mode 3
Post by: redbox on 16:43, 18 April 11
Quote from: sigh on 16:18, 18 April 11
So how is it all going for you programmers out there? Any news?


Fast sprites are easy:


1) 'Compile' them
2) Set your screen to 32x32 chars - can use 8-bit INC/DEC for next byte
3) Use faster LD instructions where possible - LD (HL),C is faster then LD (HL),&40 etc
4) ANDing the byte and ORing it with what you want is a quick way to mask
5) Use SET and RES to go up and down screen lines


What I'm really interested in is what TFM will do to make his MODE 2 masked sprites faster than anything else  :)
Title: Re: Mode 3
Post by: TFM on 19:41, 18 April 11
Quote from: redbox on 16:43, 18 April 11

Fast sprites are easy:


1) 'Compile' them
2) Set your screen to 32x32 chars - can use 8-bit INC/DEC for next byte
3) Use faster LD instructions where possible - LD (HL),C is faster then LD (HL),&40 etc
4) ANDing the byte and ORing it with what you want is a quick way to mask
5) Use SET and RES to go up and down screen lines


What I'm really interested in is what TFM will do to make his MODE 2 masked sprites faster than anything else  :)

Well, leave point 3 away. Sprites have been defined as generic. BTW: I'm not goint to present too quick here.
Title: Re: Mode 3
Post by: Axelay on 14:38, 19 April 11
This discussion got me thinking about how to do the lookup table method I've been using, but how to do it without being restricted to even lines, so I thought I'd give it a go.  I'm including the result, though it is slower by some margin.  62 scan lines to be precise.  It would be faster with the screen width reduced and height increased, and interupts disabled, but I guess that wouldnt be very generic.

Anyway, it's mode 1, but uses a method that would be identical in any mode, using a sprite with the mask included in it.  That lets the sprite use the entire palatte, no colour being used for transparent, but the end sprite is huge at 252 bytes.  I've included a disk image with the graphics and basic programs used to get the graphics into asm format.

With the source code, you can uncomment the two 'halts' to move the code execution down the screen so you can see how many scan lines each part of the code takes, the background block has the left edge designed just for this purpose.

org &8000
nolist
run start
SpriteAddr equ &200+16
BGSave equ &300
SpriteData equ &400
.SpritesYX
   defb 115,46
.SpritesYXMv
   defb 1,1
.Mode1Pal
defb &55,&5f,&4e,&54

.start
di      ;; disable interrupts
im 1     ;; interrupt mode 1 (CPU will jump to &0038 when a interrupt occrs)
ld hl,&c9fb    ;; C9 FB are the bytes for the Z80 opcodes EI:RET
ld (&0038),hl   ;; setup interrupt handler
ei      ;; re-enable interrupts
; set colours 0-3
    ld a,3
    ld hl,Mode1Pal
    call SetColours
; fill the screen with the background block
call PrintBlocks
; copy the Y address table to &100
ld hl,YTable
ld de,&100
ld bc,232
ldir
; copy the sprite to &400. Sprite is 6 bytes by 21 = 126 bytes, but contains mask data
; which doubles it's size
ld hl,Sprite
ld de,SpriteData
ld bc,252
ldir
; fill the sprite address list with dummy values for first frame
ld hl,&cfd0
ld (SpriteAddr),hl
ld hl,SpriteAddr
ld de,SpriteAddr+2
ld bc,21*2-2
ldir
.main
; wait for vsync
call FrameFlyB
; wait to start code at same time every frame
; un-comment additional halts to see entire execution
; time, though sprite will disappear during this time
halt
;halt
;halt
; set border to different blues for each stage
ld bc,&7f10
out (c),c
ld bc,&7f55
out (c),c
; restore the background from last frame
; (requires the dummy addresses for the first frame, set previously)
call RestoreBlock
ld bc,&7f10
out (c),c
ld bc,&7f44
out (c),c
; generate a new list of screen addresses based on current XY coord (in bytes)
call CalcSpriteAddr
ld bc,&7f10
out (c),c
ld bc,&7f5d
out (c),c
; save the background for the new position of the sprite
call SaveBlock
ld bc,&7f10
out (c),c
ld bc,&7f5b
out (c),c
; finaly...
call PrintSprite
; and now set border back to black
ld bc,&7f10
out (c),c
ld bc,&7f54
out (c),c
; now move the sprite about
call MoveSprite
; repeat
jr main
.RestoreBlock
; is the last time the address list is used, so SP can be used to pop the addresses
    ld (SaveSP+1),sp
    ld sp,SpriteAddr ; load SP with top of address list
    ld bc,21*&100+&ff ; ld b with 21 and c with dummy to stop ldi corrupting b
    ld hl,BGsave ; load hl with saved background data
.ResBlkLp
; restore each line by popping address of screen to de and copying back the screen data
    pop de
    ldi
    ldi
    ldi
    ldi
    ldi
    ldi
    djnz ResBlkLp
.SaveSP
    ld sp,0
    ret

.SaveBlock
; with interrupts enabled, is generally not possible unless writing code with fixed
; execution times to assume can still use SP to pop the address list without an interupt
; corrupting the address list if it happens along while reading it
; so for this example a much lousier (slower) method is used
    ld hl,SpriteAddr ; ld hl with pointer to screen address list of sprite
    ld b,21 ; height of sprite
    exx
    ld de,BGsave ; load de' with destination to back up screen data to
    exx
.SavBlkLp
; instead of pop, ugly code using a and a' to get (hl) into hl'
    ld a,(hl)
    inc l
    ex af,af'
    ld a,(hl)
    inc l
    exx
    ld h,a
    ex af,af'
    ld l,a
    ldi
    ldi
    ldi
    ldi
    ldi
    ldi
    exx
    djnz SavBlkLp
    ret
.PrintSprite
    ld ix,SpriteAddr ; use ix register to read address list this time
    ld hl,SpriteData ; hl points to sprite data, which includes the mask byte
                     ; mask precedes the data byte it relates to
    ld b,21 ; pixel lines to print
.PrnSprLp
; normally I'd use the alternate registers to work out what frame to print
; so assuming the alt registers are not available, IX is used to read address
; list instead
    ld e,(ix+0)
    inc ixl
    ld d,(ix+0)
    inc ixl ; de now has screen address for this row
; for each byte, read the screen data from (de), 'and' with (hl) and 'or' with (hl+1)
; then write back to (de)
; 1
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc de
; 2
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc de
; 3
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc de
; 4
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc de
; 5
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc de
; 6
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    djnz PrnSprLp
    ret
; YTable contains only the odd address lines, so the table fits in one 256 byte page
; however, both odd and even addresses are determined from this table
.CalcSpriteAddr
; write screen addresses with SP, possible interrupts are no problem as they are being
; written, not read
    ld (SaveSPCalc+1),sp
    ld sp,SpriteAddr+42 ; set SP to 'bottom' of address list
    ld hl,SpritesYX+1 ; set hl to point to sprite co-ord, stored y first
    exx
    ld h,1 ; base ytable is at &100, so preload h' with 1
    exx
    ld b,1 ; only 1 sprite to print
.CalcSprLoop
    ld a,(hl) ; ld x co-ord into a
    dec l
    ex af,af'
    ld a,(hl) ; ld y co-ord into a'
    add a,20 ; start from bottom of y and work up
    dec l
    exx
    ld l,a ; ld l with y co-ord
    ex af,af'
    ld b,&c0 ; if screen flipping, this value would change to base of current screen
    ld c,a   ; ld c' with x co-ord
             ; now bc' contains what needs to be added to the base screen address
    bit 0,l ; if y address is even, need to start with single address
    jr z,EvenYAddr
    ld iy,OddAddrExit
    jr OddYAddr
.EvenYAddr
    ld iy,EvenAddrExit
    inc l ; need to bump up to high byte from address table
    ld d,(hl) ; get contents of (hl), add bc, and put result in de
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    res 3,d ; only want even address
    push de
    dec l
.OddYAddr
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de ; de contains odd address, so push
    res 3,d ; move to even line above it
    push de ; and push that as well
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    res 3,d
    push de
    jp (iy) ; skip the last line if y co-ord was even
.OddAddrExit ; if y co-ord was odd, get one last address line
    dec l
    ld d,(hl)
    dec l
    ld a,(hl)
    add a,c
    ld e,a
    ld a,b
    adc a,d
    ld d,a
    push de
    dec l
.EvenAddrExit
    exx
    dec b
    jp nz,CalcSprLoop
;
.SaveSPCalc
    ld sp,0
    ret
.MoveSprite
    ld hl,SpritesYXMv+1
; x first
    ld a,(hl)
    res 1,l
    add a,(hl)
    ld (hl),a
    set 1,l
    cp a,0
    jr z,SwapXDir
    cp a,74
    jr nz,DontSwapXDir
.SwapXDir
    ld a,(hl)
    neg
    ld (hl),a
.DontSwapXDir
    dec l
; now y move
    ld a,(hl)
    res 1,l
    add a,(hl)
    ld (hl),a
    set 1,l
    cp a,16
    jr z,SwapYDir
    cp a,195
    jr nz,DontSwapYDir
.SwapYDir
    ld a,(hl)
    neg
    ld (hl),a
.DontSwapYDir
    ret
.FrameFlyB
    ld b,&f5    ;; B = I/O address of PPI port B
.vsync
    in a,(c)    ;; read PPI port B input
    rra      ;; transfer bit 0 into carry
    jr nc,vsync    ;; if carry=0 then vsync= 0 (inactive),
      ;; if carry=1 then vsync=1 (active).
    ret
list
.SetColours
nolist
; HL points to list, A holds 15 or 3
    ld b,&7f
    ld c,(hl)
    out (c),a
    out (c),c
    inc hl
    or a
    jr z,SetColEnd
    dec a
    jr SetColours
.SetColEnd
    ld a,&10 ; set border same as ink 0
    out (c),a
    out (c),c
    ret
.PrintBlocks
    ld de,&c000
    ld c,20
.PBsLpOuter
    push de
    ld b,13
.PBsLLpInner
    push bc
    ld a,1
    cp a,b
    jr nz,PrintBlock
    jr PrintHalfBlock
.PrintBlockReturn
    pop bc
    djnz PBsLLpInner
    pop de
    inc de
    inc de
    inc de
    inc de
    dec c
    jr nz,PBsLpOuter
    ret
PrintHalfBlock
    ld c,1+32
    jr PrnBlkCommon
PrintBlock
    ld c,2+64
.PrnBlkCommon
    ld hl,BackGndBlock
.PBLpO
    ld b,8
.PBLpI
    ldi
    ldi
    ldi
    ldi
    ex de,hl
    push de
    ld de,&800-4
    add hl,de
    pop de
    ex de,hl
    djnz PBLpI
    ex de,hl
    push de
    ld de,&c000+&50
    add hl,de
    pop de
    ex de,hl
    dec c
    jr nz,PBLpO
    jr PrintBlockReturn
.BackGndBlock
    defb 143,15,15,15
    defb 71,15,15,15
    defb 239,175,175,143
    defb 119,95,95,79
    defb 239,143,15,143
    defb 119,95,79,79
    defb 239,239,175,143
    defb 119,95,79,79
    defb 239,239,175,143
    defb 119,95,79,79
    defb 239,255,239,143
    defb 119,95,95,79
    defb 239,175,175,143
    defb 119,255,255,207
    defb 255,255,255,239
    defb 85,85,85,85
.Sprite
    defb 238,0,119,0,0,240,0,240,238,0,119,0
    defb 204,1,0,56,0,75,0,30,0,193,51,8
    defb 136,19,0,60,0,225,0,135,0,211,17,12
    defb 0,103,0,158,0,210,0,90,0,167,0,142
    defb 0,87,0,79,0,240,0,180,0,223,0,78
    defb 136,51,0,175,0,240,0,224,0,175,17,172
    defb 136,64,0,222,0,240,0,240,0,119,17,96
    defb 0,176,0,48,0,240,0,240,0,128,0,240
    defb 0,208,0,240,0,195,0,60,0,240,0,180
    defb 0,160,0,240,0,167,0,30,0,240,0,30
    defb 0,144,0,112,0,71,0,30,0,225,0,150
    defb 0,160,0,176,0,39,0,158,0,240,0,90
    defb 0,144,0,80,0,147,0,124,0,240,0,180
    defb 0,128,0,176,0,192,0,112,0,240,0,210
    defb 136,64,0,6,0,240,0,240,0,150,17,224
    defb 136,99,0,175,0,176,0,224,0,207,17,44
    defb 0,87,0,79,0,80,0,96,0,175,0,142
    defb 0,103,0,174,0,32,0,176,0,87,0,78
    defb 136,51,0,76,0,0,0,80,0,35,17,140
    defb 204,17,0,184,0,0,0,32,0,209,51,8
    defb 238,0,119,0,0,240,0,240,238,0,119,0
.YTable
    defw &fd0,&1fd0,&2fd0,&3fd0
    defw &fd0,&1fd0,&2fd0,&3fd0
;
    defw &800,&1800,&2800,&3800
    defw &850,&1850,&2850,&3850
    defw &8a0,&18a0,&28a0,&38a0
    defw &8f0,&18f0,&28f0,&38f0
;
    defw &940,&1940,&2940,&3940
    defw &990,&1990,&2990,&3990
    defw &9e0,&19e0,&29e0,&39e0
    defw &a30,&1a30,&2a30,&3a30
;
    defw &a80,&1a80,&2a80,&3a80
    defw &ad0,&1ad0,&2ad0,&3ad0
    defw &b20,&1b20,&2b20,&3b20
    defw &b70,&1b70,&2b70,&3b70
;
    defw &bc0,&1bc0,&2bc0,&3bc0
    defw &c10,&1c10,&2c10,&3c10
    defw &c60,&1c60,&2c60,&3c60
    defw &cb0,&1cb0,&2cb0,&3cb0
;
    defw &d00,&1d00,&2d00,&3d00
    defw &d50,&1d50,&2d50,&3d50
    defw &da0,&1da0,&2da0,&3da0
    defw &df0,&1df0,&2df0,&3df0
;
    defw &e40,&1e40,&2e40,&3e40
    defw &e90,&1e90,&2e90,&3e90
    defw &ee0,&1ee0,&2ee0,&3ee0
    defw &f30,&1f30,&2f30,&3f30
;
    defw &f80,&1f80,&2f80,&3f80
;
    defw &fd0,&1fd0,&2fd0,&3fd0
    defw &fd0,&1fd0,&2fd0,&3fd0




Title: Re: Mode 3
Post by: Devilmarkus on 19:48, 19 April 11
nice example, Axelay!
The result looks fine!
I captured it for all who dont know how to handle assembler ;)
(http://cpc-live.com/examplecapture.gif)

I hope it's accurate...
On real CPC its of course much smoother and faster!
Title: Re: Mode 3
Post by: TFM on 22:43, 19 April 11
Sprite size for sprite with mask is ok.

Switching INTs off would bother nobody IMHO.

If I use Maxam to assemble it, then it looks quite different from the pic above. Which assembler do you use?

@all
EDIT: Just to remember, it was more about fast sprite routines for Mode 2. But nice to see some Mode 1 examples too.
Title: Re: Mode 3
Post by: andycadley on 23:57, 19 April 11
Quote from: TFM/FS on 22:43, 19 April 11
Switching INTs off would bother nobody IMHO.

If I use Maxam to assemble it, then it looks quite different from the pic above. Which assembler do you use?

@all
EDIT: Just to remember, it was more about fast sprite routines for Mode 2. But nice to see some Mode 1 examples too.
Looks fine to me using WinAPE's assembler, though pasting straight code out of the forum goes all broken in IE.  >:(

For the sake of keeping routines generic, it'd be preferable to keep interrupts enabled I think. At the very least, bonus points for not being restricted to turning them off. Shouldn't be a problem to use the alternate registers though, which might speed that code up a bit.

And, as I said originally, the point was to determine if Mode 2 really is the fastest for drawing sprites. Can't really answer that question if the only routines written are all for Mode 2. So all modes are welcome, double bonus points if you can find a way to write a routine which is fastest in Mode 3, bringing this whole thread full circle.
Title: Re: Mode 3
Post by: TFM on 00:10, 20 April 11
Quote from: andycadley on 23:57, 19 April 11
For the sake of keeping routines generic, it'd be preferable to keep interrupts enabled I think. At the very least, bonus points for not being restricted to turning them off. Shouldn't be a problem to use the alternate registers though, which might speed that code up a bit.

Agree in other things. But no commercial game uses interrupts enable. Yes, they use their own routines, but not the slow firmware interrupt. So I think, switching them OFF or to an own routine will be fine.
Leaving them switched on takes so much time, that it may double the used time to display a sprite, in you add it to an interrrupt (0-5). And this is what must be done to omit flickering.

Title: Re: Mode 3
Post by: andycadley on 00:33, 20 April 11
Point taken, the firmware routine is incredibly slow. I think switching them off is ok, as long as you don't then write the sprite routine such that it abuses the stack pointer in a way that would break if interrupts were on. It can be a very powerful trick, but makes everything a lot less reusable.
Title: Re: Mode 3
Post by: sigh on 11:07, 20 April 11
Quote from: Axelay on 14:38, 19 April 11
It would be faster with the screen width reduced and height increased, and interupts disabled, but I guess that wouldnt be very generic.

Are you going to try a mode 2? It would be interesting to see the sprite on a similar background.
Title: Re: Mode 3
Post by: arnoldemu on 11:51, 20 April 11
Quote from: TFM/FS on 00:10, 20 April 11

Agree in other things. But no commercial game uses interrupts enable. Yes, they use their own routines, but not the slow firmware interrupt. So I think, switching them OFF or to an own routine will be fine.
Leaving them switched on takes so much time, that it may double the used time to display a sprite, in you add it to an interrrupt (0-5). And this is what must be done to omit flickering.
Well I think this would be ok for "interrupts enabled":

di
ld hl,&c9fb
ld (&0038),hl
ei

A dummy interrupt, but interrupts are executing ;)

Title: Re: Mode 3
Post by: Axelay on 14:16, 20 April 11
Quote from: TFM/FS on 22:43, 19 April 11
If I use Maxam to assemble it, then it looks quite different from the pic above. Which assembler do you use?

Maxam, in Winape.

Quote from: andycadley on 23:57, 19 April 11
So all modes are welcome, double bonus points if you can find a way to write a routine which is fastest in Mode 3, bringing this whole thread full circle.

Damn your crazy suggestsions, you got me trying to *think* of something now!  Happily I havent thought of anygthing that wouldnt be faster and more colourful in mode 0 with 2 bit colour yet.  Could always do 1 bit colour in mode 3 for laughs  :laugh:

Quote from: sigh on 11:07, 20 April 11
Are you going to try a mode 2? It would be interesting to see the sprite on a similar background.

It wouldnt be faster in mode 2, I wrote it with any mode in mind.  I guess I could do a mode 2 version with the screen dimensions altered like I mentioned for fun  ;)


On the interrupts, I have disabled the firmware, so that isnt impacting the speed.
Title: Re: Mode 3
Post by: sigh on 15:21, 20 April 11
Quote from: Axelay on 14:16, 20 April 11


Maxam, in Winape.
 

Damn your crazy suggestsions, you got me trying to *think* of something now!  Happily I havent thought of anygthing that wouldnt be faster and more colourful in mode 0 with 2 bit colour yet.  Could always do 1 bit colour in mode 3 for laughs  :laugh:
 

It wouldnt be faster in mode 2, I wrote it with any mode in mind.  I guess I could do a mode 2 version with the screen dimensions altered like I mentioned for fun  ;)


On the interrupts, I have disabled the firmware, so that isnt impacting the speed.

So just to clarify - in your demonstration, a mode 2 sprite wouldn't draw any faster? All the modes would draw at the same speed? Sorry if I'm repeating myself (I'm not a programmer  ;D )
Title: Re: Mode 3
Post by: andycadley on 15:36, 20 April 11
Quote from: sigh on 15:21, 20 April 11
So just to clarify - in your demonstration, a mode 2 sprite wouldn't draw any faster? All the modes would draw at the same speed? Sorry if I'm repeating myself (I'm not a programmer  ;D )
Yes, he's using a classic sprite with a saved background and seperate mask technique, so the only difference in another screen mode is the values held in the mask.
Title: Re: Mode 3
Post by: TFM on 20:52, 20 April 11
Quote from: andycadley on 00:33, 20 April 11
Point taken, the firmware routine is incredibly slow. I think switching them off is ok, as long as you don't then write the sprite routine such that it abuses the stack pointer in a way that would break if interrupts were on. It can be a very powerful trick, but makes everything a lot less reusable.

Agree! Sprites should be generic.
Title: Re: Mode 3
Post by: TFM on 20:58, 20 April 11
Quote from: arnoldemu on 11:51, 20 April 11
Well I think this would be ok for "interrupts enabled":

di
ld hl,&c9fb
ld (&0038),hl
ei

A dummy interrupt, but interrupts are executing ;)

Hmm. In this case I see not a real difference from DI.

However, doesn't matter for me, since I use another OS for my routines. But they still stay generic. Commercial games usually kick out the firmware for good reasons (gain memory). So the OS of choice will not matter.

BTW: The idea of making the circle round and present something in Mode 3 is good. But 3 comes after 2 ;-)
Title: Re: Mode 3
Post by: Axelay on 04:21, 21 April 11
Argh!  My eyes!  I mean, here's the mode 2 example.  ;)


org &8000
nolist
run start
SpriteAddr equ &200+16
BGSave equ &300
SpriteData equ &400
.SpritesYX
   defb 115,46
.SpritesYXMv
   defb 1,1
.Mode1Pal
defb &4e,&5f,&5f,&54

.start
di      ;; disable interrupts
im 1     ;; interrupt mode 1 (CPU will jump to &0038 when a interrupt occrs)
ld hl,&c9fb    ;; C9 FB are the bytes for the Z80 opcodes EI:RET
ld (&0038),hl   ;; setup interrupt handler
ei      ;; re-enable interrupts
; set colours 0-3
    ld a,3
    ld hl,Mode1Pal
    call SetColours
    ld bc,&7F8e
    out (c),c ; set mode 2
    call SetupGameScr
; fill the screen with the background block
call PrintBlocks
; copy the Y address table to &100
ld hl,YTable
ld de,&100
ld bc,256
ldir
; copy the sprite to &400. Sprite is 6 bytes by 21 = 126 bytes, but contains mask data
; which doubles it's size
ld hl,Sprite
ld de,SpriteData
ld bc,252
ldir
; fill the sprite address list with dummy values for first frame
ld hl,&cfc0
ld (SpriteAddr),hl
ld hl,SpriteAddr
ld de,SpriteAddr+2
ld bc,21*2-2
ldir
.main
; wait for vsync
call FrameFlyB
; wait to start code at same time every frame
; un-comment additional halts to see entire execution
; time, though sprite will disappear during this time
halt
;halt
;halt
; set border to different blues for each stage
ld bc,&7f10
out (c),c
ld bc,&7f55
out (c),c
; restore the background from last frame
; (requires the dummy addresses for the first frame, set previously)
call RestoreBlock
ld bc,&7f10
out (c),c
ld bc,&7f44
out (c),c
; generate a new list of screen addresses based on current XY coord (in bytes)
call CalcSpriteAddr
ld bc,&7f10
out (c),c
ld bc,&7f5d
out (c),c
; save the background for the new position of the sprite
call SaveBlock
ld bc,&7f10
out (c),c
ld bc,&7f5b
out (c),c
; finaly...
call PrintSprite
; and now set border back to black
ld bc,&7f10
out (c),c
ld bc,&7f54
out (c),c
; now move the sprite about
call MoveSprite
; repeat
jr main
.RestoreBlock
; is the last time the address list is used, so SP can be used to pop the addresses
    ld (SaveSP+1),sp
    ld sp,SpriteAddr ; load SP with top of address list
    ld bc,21*&100+&ff ; ld b with 21 and c with dummy to stop ldi corrupting b
    ld hl,BGsave ; load hl with saved background data
.ResBlkLp
; restore each line by popping address of screen to de and copying back the screen data
    pop de
    ldi
    ldi
    ldi
    ldi
    ldi
    ldi
    djnz ResBlkLp
.SaveSP
    ld sp,0
    ret

.SaveBlock
; with interrupts enabled, is generally not possible unless writing code with fixed
; execution times to assume can still use SP to pop the address list without an interupt
; corrupting the address list if it happens along while reading it
; so for this example a much lousier (slower) method is used
    ld hl,SpriteAddr ; ld hl with pointer to screen address list of sprite
    ld b,21 ; height of sprite
    exx
    ld de,BGsave ; load de' with destination to back up screen data to
    exx
.SavBlkLp
; instead of pop, ugly code using a and a' to get (hl) into hl'
    ld a,(hl)
    inc l
    ex af,af'
    ld a,(hl)
    inc l
    exx
    ld h,a
    ex af,af'
    ld l,a
    ldi
    ldi
    ldi
    ldi
    ldi
    ldi
    exx
    djnz SavBlkLp
    ret
.PrintSprite
    ld ix,SpriteAddr ; use ix register to read address list this time
    ld hl,SpriteData ; hl points to sprite data, which includes the mask byte
                     ; mask precedes the data byte it relates to
    ld b,21 ; pixel lines to print
.PrnSprLp
; normally I'd use the alternate registers to work out what frame to print
; so assuming the alt registers are not available, IX is used to read address
; list instead
    ld e,(ix+0)
    inc ixl
    ld d,(ix+0)
    inc ixl ; de now has screen address for this row
; for each byte, read the screen data from (de), 'and' with (hl) and 'or' with (hl+1)
; then write back to (de)
; 1
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc e
; 2
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc e
; 3
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc e
; 4
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc e
; 5
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    inc e
; 6
    ld a,(de)
    and a,(hl)
    inc l
    or a,(hl)
    ld (de),a
    inc l
    djnz PrnSprLp
    ret
; YTable contains only the odd address lines, so the table fits in one 256 byte page
; however, both odd and even addresses are determined from this table
.CalcSpriteAddr
; write screen addresses with SP, possible interrupts are no problem as they are being
; written, not read
    ld (SaveSPCalc+1),sp
    ld sp,SpriteAddr+42 ; set SP to 'bottom' of address list
    ld hl,SpritesYX+1 ; set hl to point to sprite co-ord, stored y first
    exx
    ld h,1 ; base ytable is at &100, so preload h' with 1
           ; in this example the whole of the most significant byte is in the table
           ; as it is never altered by the sprite x co-ord, so to screen flip would
           ; require a second table and loading h with a different pointer
    exx
    ld b,1 ; only 1 sprite to print
.CalcSprLoop
    ld a,(hl) ; ld x co-ord into a
    dec l
    ex af,af'
    ld a,(hl) ; ld y co-ord into a'
    add a,20 ; start from bottom of y and work up
    dec l
    exx
    ld l,a ; ld l with y co-ord
    ex af,af'
    ld c,a   ; ld c' with x co-ord for adding to base screen address
    bit 0,l ; if y address is even, need to start with single address
    jr z,EvenYAddr
    ld iy,OddAddrExit
    jr OddYAddr
.EvenYAddr
    ld iy,EvenAddrExit
    inc l ; need to bump up to high byte from address table
    ld d,(hl) ; get contents of (hl), add bc, and put result in de
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    res 3,d ; only want even address
    push de
    dec l
.OddYAddr
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de ; de contains odd address, so push
    res 3,d ; move to even line above it
    push de ; and push that as well
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    dec l
;
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    res 3,d
    push de
    jp (iy) ; skip the last line if y co-ord was even
.OddAddrExit ; if y co-ord was odd, get one last address line
    dec l
    ld d,(hl)
    dec l
    ld a,(hl)
    or a,c
    ld e,a
    push de
    dec l
.EvenAddrExit
    exx
    dec b
    jp nz,CalcSprLoop
;
.SaveSPCalc
    ld sp,0
    ret
.MoveSprite
    ld hl,SpritesYXMv+1
; x first
    ld a,(hl)
    res 1,l
    add a,(hl)
    ld (hl),a
    set 1,l
    cp a,0
    jr z,SwapXDir
    cp a,58
    jr nz,DontSwapXDir
.SwapXDir
    ld a,(hl)
    neg
    ld (hl),a
.DontSwapXDir
    dec l
; now y move
    ld a,(hl)
    res 1,l
    add a,(hl)
    ld (hl),a
    set 1,l
    cp a,8
    jr z,SwapYDir
    cp a,227
    jr nz,DontSwapYDir
.SwapYDir
    ld a,(hl)
    neg
    ld (hl),a
.DontSwapYDir
    ret
.FrameFlyB
    ld b,&f5    ;; B = I/O address of PPI port B
.vsync
    in a,(c)    ;; read PPI port B input
    rra      ;; transfer bit 0 into carry
    jr nc,vsync    ;; if carry=0 then vsync= 0 (inactive),
      ;; if carry=1 then vsync=1 (active).
    ret
list
.SetColours
nolist
; HL points to list, A holds 15 or 3
    ld b,&7f
    ld c,(hl)
    out (c),a
    out (c),c
    inc hl
    or a
    jr z,SetColEnd
    dec a
    jr SetColours
.SetColEnd
    ld a,&10 ; set border same as ink 0
    out (c),a
    out (c),c
    ret
.PrintBlocks
    ld de,&c040
    ld c,16
.PBsLpOuter
    push de
    ld b,15
.PBsLLpInner
    push bc
;    ld a,1
;    cp a,b
    jr PrintBlock
;    jr PrintHalfBlock
.PrintBlockReturn
    pop bc
    djnz PBsLLpInner
    pop de
    inc de
    inc de
    inc de
    inc de
    dec c
    jr nz,PBsLpOuter
    ret
PrintHalfBlock
    ld c,1+32
    jr PrnBlkCommon
PrintBlock
    ld c,2+64
.PrnBlkCommon
    ld hl,BackGndBlock
.PBLpO
    ld b,8
.PBLpI
    ldi
    ldi
    ldi
    ldi
    ex de,hl
    push de
    ld de,&800-4
    add hl,de
    pop de
    ex de,hl
    djnz PBLpI
    ex de,hl
    push de
    ld de,&c000+&40
    add hl,de
    pop de
    ex de,hl
    dec c
    jr nz,PBLpO
    jr PrintBlockReturn
.SetupGameScr
    ld hl,GameDimensions
    ld a,6
    ld b,&bc
.ScrDimLp
    ld c,(hl)
    inc hl
    ld e,(hl)
    inc hl
    out (c),c
    inc b
    out (c),e
    dec b
    dec a
    jr nz,ScrDimLp
    ret
.GameDimensions
    defb 2,42,1,32,7,33,6,30,12,&30,13,&20
.BackGndBlock
    defb 63,255,255,255
    defb 15,255,255,255
    defb 130,170,170,175
    defb 1,85,85,95
    defb 66,191,255,175
    defb 1,74,171,95
    defb 130,133,87,175
    defb 1,74,171,95
    defb 66,133,87,175
    defb 1,74,171,95
    defb 130,128,3,175
    defb 1,85,85,95
    defb 66,170,170,175
    defb 0,0,0,7
    defb 128,0,0,3
    defb 17,17,17,17
.Sprite
    defb 255,0,240,0,0,0,0,0,15,0,255,0
    defb 252,0,0,0,0,255,0,255,0,0,63,0
    defb 224,2,0,175,0,239,0,255,0,245,7,64
    defb 192,21,0,87,0,255,0,255,0,202,3,160
    defb 128,42,0,170,0,191,0,191,0,85,1,80
    defb 128,5,0,85,0,255,0,252,0,170,1,160
    defb 128,0,0,163,0,238,0,239,0,21,1,56
    defb 0,10,0,15,0,255,0,255,0,192,0,252
    defb 0,0,0,187,0,177,0,75,0,187,0,252
    defb 0,9,0,111,0,207,0,247,0,255,0,254
    defb 0,0,0,187,0,149,0,250,0,254,0,254
    defb 0,5,0,87,0,138,0,251,0,255,0,254
    defb 0,0,0,138,0,197,0,87,0,187,0,188
    defb 0,2,0,21,0,80,0,15,0,255,0,252
    defb 128,0,0,0,0,170,0,238,0,239,1,232
    defb 128,0,0,84,0,85,0,219,0,85,1,112
    defb 128,2,0,168,0,42,0,180,0,170,1,160
    defb 192,5,0,84,0,5,0,94,0,85,3,80
    defb 224,10,0,160,0,18,0,42,0,138,7,160
    defb 252,1,0,64,0,0,0,141,0,5,63,0
    defb 255,0,240,0,0,0,0,0,15,0,255,0
.YTable
;
    defw &c800,&d800,&e800,&f800
    defw &c840,&d840,&e840,&f840
    defw &c880,&d880,&e880,&f880
    defw &c8c0,&d8c0,&e8c0,&f8c0
;
    defw &c900,&d900,&e900,&f900
    defw &c940,&d940,&e940,&f940
    defw &c980,&d980,&e980,&f980
    defw &c9c0,&d9c0,&e9c0,&f9c0
;
    defw &ca00,&da00,&ea00,&fa00
    defw &ca40,&da40,&ea40,&fa40
    defw &ca80,&da80,&ea80,&fa80
    defw &cac0,&dac0,&eac0,&fac0
;
    defw &cb00,&db00,&eb00,&fb00
    defw &cb40,&db40,&eb40,&fb40
    defw &cb80,&db80,&eb80,&fb80
    defw &cbc0,&dbc0,&ebc0,&fbc0
;
    defw &cc00,&dc00,&ec00,&fc00
    defw &cc40,&dc40,&ec40,&fc40
    defw &cc80,&dc80,&ec80,&fc80
    defw &ccc0,&dcc0,&ecc0,&fcc0
;
    defw &cd00,&dd00,&ed00,&fd00
    defw &cd40,&dd40,&ed40,&fd40
    defw &cd80,&dd80,&ed80,&fd80
    defw &cdc0,&ddc0,&edc0,&fdc0
;
    defw &ce00,&de00,&ee00,&fe00
    defw &ce40,&de40,&ee40,&fe40
    defw &ce80,&de80,&ee80,&fe80
    defw &cec0,&dec0,&eec0,&fec0
;
    defw &cf00,&df00,&ef00,&ff00
    defw &cf40,&df40,&ef40,&ff40
    defw &cf80,&df80,&ef80,&ff80
    defw &cfc0,&dfc0,&efc0,&ffc0



Source also in the attached file.  Narrowing the screen has saved only 2 scan lines (down to 60) but it would be multiplied by the number of sprites you have in a game, so it all adds up.  Could save even more by disabling interupts, or as I have in my last two projects, restricting y co-ordinates to even addresses.
Title: Re: Mode 3
Post by: sigh on 10:51, 21 April 11
Quote from: Axelay on 04:21, 21 April 11
Argh!  My eyes!  I mean, here's the mode 2 example.  ;)

Source also in the attached file.  Narrowing the screen has saved only 2 scan lines (down to 60) but it would be multiplied by the number of sprites you have in a game, so it all adds up.  Could save even more by disabling interupts, or as I have in my last two projects, restricting y co-ordinates to even addresses.

I had at look at this in winape. So when you say that "Narrowing the screen has saved only 2 scan lines (down to 60) but it would be multiplied by the number of sprites you have in a game, so it all adds up.", 
Does this mean that that the more sprites you have in the game, the more scanlines that you save in comparison to mode 1 and mode 0?
Title: Re: Mode 3
Post by: redbox on 10:56, 21 April 11
Quote from: TFM/FS on 19:41, 18 April 11
BTW: I'm not goint to present too quick here.


Hahahahahahahahahahahahahahahaha!

Title: Re: Mode 3
Post by: arnoldemu on 11:33, 21 April 11
Quote from: TFM/FS on 20:58, 20 April 11

Hmm. In this case I see not a real difference from DI.
Try using the stack pointer and push/pop with DI and then with this code ;)
They are different.

Title: Re: Mode 3
Post by: MaV on 12:06, 21 April 11
Quote from: redbox on 10:56, 21 April 11

Hahahahahahahahahahahahahahahaha!

Now really, was this necessary? He's probably up to his ears in work and can hardly raise his eye-lids when posting here, much less code a nice piece of assembly code in that state.

Give him the benefit of the doubt and let's wait until he comes up with something.

MaV
Title: Re: Mode 3
Post by: FatAgnus on 12:32, 21 April 11
Quote from: MaV on 12:06, 21 April 11
Now really, was this necessary? He's probably up to his ears in work and can hardly raise his eye-lids when posting here, much less code a nice piece of assembly code in that state.

Give him the benefit of the doubt and let's wait until he comes up with something.

MaV


I can't believe it (again)... I agree, TFM could be right. let's wait, free time is not always so easy to obtain!
But he is wrong, THE MASK ALWAYS DO THE JOB!  :laugh: :laugh: :laugh:
Title: Re: Mode 3
Post by: redbox on 14:03, 21 April 11
Quote from: MaV on 12:06, 21 April 11
Now really, was this necessary? He's probably up to his ears in work and can hardly raise his eye-lids when posting here, much less code a nice piece of assembly code in that state.
Give him the benefit of the doubt and let's wait until he comes up with something.


I think you miss the point of my laughter; TFM was the one who said MODE 2 was fastest and he would prove it.


And now he's already making excuses before even posting anything.


I find this funny.  Very funny.   :)
Title: Re: Mode 3
Post by: MaV on 16:37, 21 April 11
Quote from: redbox on 14:03, 21 April 11
I think you miss the point of my laughter; TFM was the one who said MODE 2 was fastest and he would prove it.

And now he's already making excuses before even posting anything.

I find this funny.  Very funny.   :)

Ok. Of course, it doesn't look too good, if he claims mode 2 sprites are faster, and can't show results in time.

But still, maybe he's just got a lot of work to do right now.

MaV
Title: Re: Mode 3
Post by: Optimus on 03:01, 22 April 11
Something irrelevant but very very funny and wow. The blue background from Axelay's example creates a great optical illusion. It's like diagonal smooth shade from darker blue to brighter blue. Me, trying to find where the colour changes, but it's all the same tile. Wow! (I know I must be sounding crazy :)
Title: Re: Mode 3
Post by: Axelay on 05:02, 22 April 11
Quote from: sigh on 10:51, 21 April 11
I had at look at this in winape. So when you say that "Narrowing the screen has saved only 2 scan lines (down to 60) but it would be multiplied by the number of sprites you have in a game, so it all adds up.", 
Does this mean that that the more sprites you have in the game, the more scanlines that you save in comparison to mode 1 and mode 0?

Sorry, perhaps I should have said it too, but andycadley was exactly right, the sprite routine I am using is exactly the same speed, regardless of mode, and only the sprite data and mask bytes change.

But otherwise, yes.  This is a single sprite, so if you had 8 sprites, rather than being 2 scan lines faster than my previous example, it will be 16 (in any mode!).  Not enough for an extra sprite, but easily enough for some other required processing, such as movement, animation or collision.

tbh, I dont think any mode would be faster than another, because the fastest way of dealing with screen data is to ignore resolution and deal with it at the byte level rather than the bit level.  Not so practical with backgrounds though, you'd end up with a nasty, irregular looking ink 0 coloured border around the sprites.  Beyond that, I think any variation that could give a speed benefit in any particular mode almost certainly comes with some form of limitation, but it's balancing them out that is the fun part of software sprite code imo  ;)
Title: Re: Mode 3
Post by: TFM on 08:11, 22 April 11
Quote from: redbox on 10:56, 21 April 11

Hahahahahahahahahahahahahahahaha!

What's the problem? May some of us have a real live, and currently I'm working with 135 single living cells, and I have to process them every 75 minutes. I can put them to 8 degrees for not longer than 9 hours (during every night). I have to do this for at least 20 more days. So sorry, if I take resarch more important than my hobby.
Title: Re: Mode 3
Post by: EgoTrip on 13:44, 22 April 11
Quote from: TFM/FS on 08:11, 22 April 11

What's the problem? May some of us have a real live, and currently I'm working with 135 single living cells, and I have to process them every 75 minutes. I can put them to 8 degrees for not longer than 9 hours (during every night). I have to do this for at least 20 more days. So sorry, if I take resarch more important than my hobby.


What sort of cells? Whats the research for?
Title: Re: Mode 3
Post by: sigh on 15:18, 22 April 11
Quote from: Axelay on 05:02, 22 April 11


Sorry, perhaps I should have said it too, but andycadley was exactly right, the sprite routine I am using is exactly the same speed, regardless of mode, and only the sprite data and mask bytes change.

But otherwise, yes.  This is a single sprite, so if you had 8 sprites, rather than being 2 scan lines faster than my previous example, it will be 16 (in any mode!).  Not enough for an extra sprite, but easily enough for some other required processing, such as movement, animation or collision.

tbh, I dont think any mode would be faster than another, because the fastest way of dealing with screen data is to ignore resolution and deal with it at the byte level rather than the bit level.  Not so practical with backgrounds though, you'd end up with a nasty, irregular looking ink 0 coloured border around the sprites.  Beyond that, I think any variation that could give a speed benefit in any particular mode almost certainly comes with some form of limitation, but it's balancing them out that is the fun part of software sprite code imo  ;)

Hmmm. There seems to be less reason for using mode 2 for games apart from utilising the 640 width.
Title: Re: Mode 3
Post by: redbox on 18:36, 22 April 11
Quote from: TFM/FS on 08:11, 22 April 11
What's the problem? May some of us have a real live, and currently I'm working with 135 single living cells, and I have to process them every 75 minutes. I can put them to 8 degrees for not longer than 9 hours (during every night). I have to do this for at least 20 more days. So sorry, if I take resarch more important than my hobby.

That's not what I said, and I have already explained this.

I laughed because you are already making excuses before posting any of your code.  This is funny.

I hope you do find some time because I'm really looking forward to you proving to everyone that Mode 2 has the fastest sprites.
Title: Re: Mode 3
Post by: TFM on 19:31, 22 April 11
Quote from: EgoTrip on 13:44, 22 April 11

What sort of cells? Whats the research for?

Saccharomyces cerevisiae, Aging research.
Title: Re: Mode 3
Post by: TFM on 19:37, 22 April 11
Quote from: redbox on 18:36, 22 April 11
That's not what I said, and I have already explained this.

I laughed because you are already making excuses before posting any of your code.  This is funny.

I hope you do find some time because I'm really looking forward to you proving to everyone that Mode 2 has the fastest sprites.

Redbox, I'm not that stupid. And I made no excuse. btw. whats about 50 scanlines? Just be patient.

And BTW you said making these kinds of sprites is so easy. Now where are your routines? Can you only offend others (in a sophisticated way) or can you provide more than words?
Title: Re: Mode 3
Post by: MaV on 23:11, 22 April 11
Guys, please calm down.

Nothing was meant the way it was written down. Remember that this is written media which does not transmit facial expression and demeanor.


@TFM: So you're raising yeast? I knew a bavarian can't stand to be without his beloved beer. ;)

MaV
Title: Re: Mode 3
Post by: redbox on 00:05, 25 April 11
Quote from: TFM/FS on 19:37, 22 April 11
And BTW you said making these kinds of sprites is so easy. Now where are your routines?

No point, everything I explained is available on the wiki and these forums - fast sprites are nothing new, hence me saying they are "easy".

However, making Mode 2 sprites the fastest would be new, and I look forward to your code.
Title: Re: Mode 3
Post by: sigh on 16:00, 12 May 11
Any more examples and tests to be shown on the mode 2?
Title: Re: Mode 3
Post by: AMSDOS on 12:52, 16 December 12
Appologies for Dragging this Big Topic back onto the Spotlight. I thought it would be worth mentioning that I found an article about this ACU January 86 page 44 & 45 and it comes with a program with a series of RSXs:


http://www.cpcwiki.eu/index.php/File:AmstradComputerUser14-0186_page_0044.jpg (http://www.cpcwiki.eu/index.php/File:AmstradComputerUser14-0186_page_0044.jpg)
http://www.cpcwiki.eu/index.php/File:AmstradComputerUser14-0186_page_0045.jpg (http://www.cpcwiki.eu/index.php/File:AmstradComputerUser14-0186_page_0045.jpg)



You can check out the article though the interesting thing this article mentions is that games like Tankbusters (yeah I know bizarre coincidence I mentioned it the other day), use this particular mode for drawing and erasing is done on the back screen and then flipped to the visible screen when it's done. Looks like I should be considering this for my little scroller?  :-[
Title: Re: Mode 3
Post by: ralferoo on 15:45, 27 December 12
I still don't think there's any great advantage of using mode 3, as you simulate the same effect easily with palette switches. The only time you might want to do this is if you're swapping colour palettes line to line and don't want to change all 16 colours.

To achieve the same back and foreground effect, you just need to arrange the palette so the unused bits are ignored - and the way you achieve that is by replicating that colour for each unused bit. So for instance, for 2 4-colour mode 0 screens, you might have pens 0-3 for screen 1 and pens 0,4,8,12 for screen 2. To display screen 1, you set the palette to A0,A1,A2,A3,A0,A1,A2,A3,A0,A1,A2,A3,A0,A1,A2,A3 and to display screen 2, you set the palette to B0,B0,B0,B0,B1,B1,B1,B1,B2,B2,B2,B2,B3,B3,B3,B3. You could obviously vary this, so you could use four 2-colour mode 0 screens and flip between them.
Title: Re: Mode 3
Post by: AMSDOS on 00:02, 28 December 12
Quote from: ralferoo on 15:45, 27 December 12
I still don't think there's any great advantage of using mode 3, as you simulate the same effect easily with palette switches. The only time you might want to do this is if you're swapping colour palettes line to line and don't want to change all 16 colours.

To achieve the same back and foreground effect, you just need to arrange the palette so the unused bits are ignored - and the way you achieve that is by replicating that colour for each unused bit. So for instance, for 2 4-colour mode 0 screens, you might have pens 0-3 for screen 1 and pens 0,4,8,12 for screen 2. To display screen 1, you set the palette to A0,A1,A2,A3,A0,A1,A2,A3,A0,A1,A2,A3,A0,A1,A2,A3 and to display screen 2, you set the palette to B0,B0,B0,B0,B1,B1,B1,B1,B2,B2,B2,B2,B3,B3,B3,B3. You could obviously vary this, so you could use four 2-colour mode 0 screens and flip between them.



Yeah I was having a play around with the program which was in ACU, though when that program demonstrates the change from the back screen to the front screen and visa-versa, the process is really slow. I'm not entirely convinced games like Tankbusters is using this to simulate the movement of things like the shapes or tanks unless there's a fast technique of switching the screens over, though I don't see how given Kev's example was running at the same rate as the program in ACU.


Though your right in that palette switches could be used to simulate the same effect and would seem to be seen to produce a fast result.
Title: Re: Mode 3
Post by: Animalgril987 on 12:54, 07 November 20
Quote from: redbox on 16:43, 18 April 11Use faster LD instructions where possible - LD (HL),C is faster then LD (HL),&40 etc
4) ANDing the byte and ORing it with what you want is a quick way to mask
5) Use SET and RES to go up and down screen lines

Surely point 5 is out, as SET and RES each use an extra byte (&BC)?
Powered by SMFPacks Menu Editor Mod