News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_bluestar

Smooth movement in Basic for CPC

Started by bluestar, 13:38, 08 February 23

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

bluestar

Hi everybody,

Sorry if this is a recurrent subject but I wasn't able to find a similar post in the forum.

After 37 years of got my CPC 472 I'm now learning how to code games for Amstrad. I'm a programmer so coding itself is not a problem for me.

Currently I've the idea of develop a couple of games in Basic, and then move to a framework like CPCtelera and use C and assembly code. Just for fun.

Anyway... I've created a prototype of Oh Mummy! in Basic wich works quite fine and now I'm trying to improve some parts of the program. One is the movement of course. I'm using a 16x16 character but it blinks too much when moving.

I've tested different variations in order to improve results but there is no much difference (adding FRAME instruction, playing with transparent colors, using TAG/TAGOFF, erasing just a part of the track, etc.). Best way currently is deleting and drawing at the same PRINT instruction (a different PRINT instruction is call based on player direction with empty characters in the previous position).

Nevertheless... Is there any particular trick/procedure using pure Basic to get an acceptable smooth movement? Other solution adding machine code to Basic?

I know I'll getting better results with other languages but the idea is develop an acceptabale game and then code the same game in C in order to compare.

Thanks in advance (and excuse my English).

andycadley

I think you've probably tried most of them, at some point BASIC just isn't great for this kind of thing.

Probably the only other option left is to handle screen updates by palette switching so you can draw to the screen without it being visible, and make the change near instantaneous. It's similar to the colour plane techniques described in the manual.

It's all to do with bitwise operations and careful arrangement of the palette, it easiest to describe in Mode 1 but the principle applies to Mode 0 too. Because of the way it works, it does limit the number of colours on screen however.

Start with a screen entirely in PEN 0, which will be our background colour. Draw something on the screen using PEN 1 using an OR operation, it'll all appear in PEN 1. So far, so simple. Now draw something over the top of it using OR and PEN 2. Every pixel that was in both drawings will end up in PEN 3, the others will either be 1 or 2 depending on which drawing they were part of.

Now the clever bit, change the palette entries as follows:

0 - background colour
1 - foreground colour
2 - background colour
3 - foreground colour

And the second drawing will mysteriously disappear, even though the pixels are still in place. Change the palette to:

0 - background colour
1 - background colour
2 - foreground colour 
3 - foreground colour

And the second image instantly replaces the first. What's more if you draw the first image again, only this time using an AND operation and PEN 2, all of the pixels that were set to PEN 1 will become PEN 0 and all those in PEN 3 become PEN 2, effectively erasing the background image ready to start over.

By cycling between drawing in PEN 1 &2 like this, switching palette each time you've finished you can get almost instant updates to the screen. But you have sacrificed the colour depth to just 2 colours in Mode 1 (or 8 in Mode 0)

Sykobee (Briggsy)

I think you are finding out why sprite RSXes were common :)

In terms of BASIC RSXes used today there is the 8BP library that might be enough to solve your BASIC issues, and I think it has a C/asm version too which would help later on. It does have its limitations (I haven't used it however). Sprites Alive! and Laser Basic were other solutions back in the day.

TAG is a very slow way to get multicoloured pixel-perfect sprites.

bluestar

Quote from: andycadley on 14:56, 08 February 23I think you've probably tried most of them, at some point BASIC just isn't great for this kind of thing.

Probably the only other option left is to handle screen updates by palette switching so you can draw to the screen without it being visible, and make the change near instantaneous. It's similar to the colour plane techniques described in the manual.

It's all to do with bitwise operations and careful arrangement of the palette, it easiest to describe in Mode 1 but the principle applies to Mode 0 too. Because of the way it works, it does limit the number of colours on screen however.

Start with a screen entirely in PEN 0, which will be our background colour. Draw something on the screen using PEN 1 using an OR operation, it'll all appear in PEN 1. So far, so simple. Now draw something over the top of it using OR and PEN 2. Every pixel that was in both drawings will end up in PEN 3, the others will either be 1 or 2 depending on which drawing they were part of.

Now the clever bit, change the palette entries as follows:

0 - background colour
1 - foreground colour
2 - background colour
3 - foreground colour

And the second drawing will mysteriously disappear, even though the pixels are still in place. Change the palette to:

0 - background colour
1 - background colour
2 - foreground colour
3 - foreground colour

And the second image instantly replaces the first. What's more if you draw the first image again, only this time using an AND operation and PEN 2, all of the pixels that were set to PEN 1 will become PEN 0 and all those in PEN 3 become PEN 2, effectively erasing the background image ready to start over.

By cycling between drawing in PEN 1 &2 like this, switching palette each time you've finished you can get almost instant updates to the screen. But you have sacrificed the colour depth to just 2 colours in Mode 1 (or 8 in Mode 0)
Thanks! I'll try this method. Colour depth is a problem as I'm working in Mode 1 but is fine with a GT65 monitor... :) I'll code a test and maybe I'll consider develop a 2 colours version of the game at the end. 

Thanks again.

bluestar

Quote from: Sykobee (Briggsy) on 15:06, 08 February 23I think you are finding out why sprite RSXes were common :)

In terms of BASIC RSXes used today there is the 8BP library that might be enough to solve your BASIC issues, and I think it has a C/asm version too which would help later on. It does have its limitations (I haven't used it however). Sprites Alive! and Laser Basic were other solutions back in the day.

TAG is a very slow way to get multicoloured pixel-perfect sprites.

RSX: another item for the TODO list  :laugh: Looks like i'm gonna make different versions of the game with different techniques. I'm 40 years late almost   :picard2:

Sykobee (Briggsy)

I remember many more advanced ACU game listings would have some form of sprite code embedded in DATA statements at the end, poked into memory, and either CALLed or RSXed for use from BASIC, with all the sprite data also encoded in more DATA statements.

(obviously some  (e.g., Space Mania) where literally BASIC loaders for DATA statements, with game logic also encoded, which wasn't what I call a BASIC game!)

MoteroV4

I think that one of the programmers who is currently publishing and innovating a lot in Amstrad BASIC would be Francesc Alcaucer. He also allows you to download his source code where you can learn his techniques. Link:

https://itch.io/profile/falcaucer
Released cpc games: Memtrainer, El Gerente (Remake)

Anthony Flack

Tag is SUPER slow.

One thing I used to do as a kid was force the CPC into mode 0 from mode 1, using

mode 1:call &bd1c

And then I could print using 3 coloured, 4x8 characters defined with the SYMBOL command. To this day I still retain the useless skill of being able to convert three coloured sprite sheets into hex in my head.

But these days I guess I would just write a small ASM routine to draw the sprite and call it from basic, unless I was trying to do something entirely in basic as a special challenge. Radzone is a nice example of a CPC game written partly in basic.

Actually these days I'd probably just write the whole thing in straight ASM but I understand that's not the exercise here. 

eto

Quote from: Anthony Flack on 03:25, 09 February 23mode 1:call &bd1c

And then I could print using 3 coloured, 4x8 characters defined with the SYMBOL command. To this day I still retain the useless skill of being able to convert three coloured sprite sheets into hex in my head.
yeah, that's a pretty clever and surprisingly fast option. The winner (in one category) of last years Basic-10-liner-competition was using this technique. It's fast and looking really good.

https://bunsen.itch.io/dokoban-by-copper-france

asertus

Quote from: bluestar on 15:38, 08 February 23
Quote from: Sykobee (Briggsy) on 15:06, 08 February 23I think you are finding out why sprite RSXes were common :)

In terms of BASIC RSXes used today there is the 8BP library that might be enough to solve your BASIC issues, and I think it has a C/asm version too which would help later on. It does have its limitations (I haven't used it however). Sprites Alive! and Laser Basic were other solutions back in the day.

TAG is a very slow way to get multicoloured pixel-perfect sprites.

RSX: another item for the TODO list  :laugh: Looks like i'm gonna make different versions of the game with different techniques. I'm 40 years late almost  :picard2:

If you have already it working in BASIC, I would look at 8BP for sure. Just improve the movement of sprites at least.. Unless you want just pure BASIC.


Anthony Flack

For a long time in the 80s that &bd1c trick was the best I could do, until I finally got some machine code sprite routines courtesy of Amstrad Computer User (thanks Chris Lawson).

Sokoban in ten lines though, that's outrageous!

bluestar

I wrote a quick program last night in order to test @andycadley suggestion. It works fine! although I've to add the player movement in order to check the speed and the smoothness of the movement.

As now I'm going to be limited to use two colours (mode 1), I'm thinking in a way to use just two colors for the character and keep 4 colours in the rest of the screen. My idea (not tested yet) is to create a window with the size of the character, and move it on the fly to the character position so I can switch between palettes just within the window...

I let you now the result.

bluestar

Quote from: asertus on 10:45, 09 February 23
Quote from: bluestar on 15:38, 08 February 23
Quote from: Sykobee (Briggsy) on 15:06, 08 February 23I think you are finding out why sprite RSXes were common :)

In terms of BASIC RSXes used today there is the 8BP library that might be enough to solve your BASIC issues, and I think it has a C/asm version too which would help later on. It does have its limitations (I haven't used it however). Sprites Alive! and Laser Basic were other solutions back in the day.

TAG is a very slow way to get multicoloured pixel-perfect sprites.

RSX: another item for the TODO list  :laugh: Looks like i'm gonna make different versions of the game with different techniques. I'm 40 years late almost  :picard2:

If you have already it working in BASIC, I would look at 8BP for sure. Just improve the movement of sprites at least.. Unless you want just pure BASIC.


Yeah after finish it in pure Basic I'll replicate it in 8BP. Looks very nice 8P and is made in Spain  :P

bluestar

Quote from: Anthony Flack on 03:25, 09 February 23Tag is SUPER slow.

One thing I used to do as a kid was force the CPC into mode 0 from mode 1, using

mode 1:call &bd1c

And then I could print using 3 coloured, 4x8 characters defined with the SYMBOL command. To this day I still retain the useless skill of being able to convert three coloured sprite sheets into hex in my head.

But these days I guess I would just write a small ASM routine to draw the sprite and call it from basic, unless I was trying to do something entirely in basic as a special challenge. Radzone is a nice example of a CPC game written partly in basic.

Actually these days I'd probably just write the whole thing in straight ASM but I understand that's not the exercise here.
OMG what is the witchcraft trick behind mode 1:call &bd1c !?  :o So I can have a coloured mode 1 with this... very cool (although I guess I need to redefine characters in order to point letters and numbers). Another item for the TODO list

I've seen the video of Dokoban (very cool how is programmed with a frew lines) and the character player is still blinking when it moves...

Anthony Flack

#14
Well, you can have 40 column text in Mode 0 if you redefine the character set, yeah. Basically call&bd1c puts the gate array into mode 0 while basic still thinks you're in mode 1. You can also do the same in Mode 1 with mode 2:call&bd1c,1

You really can't draw very much in pure basic before the frame catches up to you though. The print routines aren't designed for speed.

andycadley

Quote from: bluestar on 10:54, 09 February 23As now I'm going to be limited to use two colours (mode 1), I'm thinking in a way to use just two colors for the character and keep 4 colours in the rest of the screen. My idea (not tested yet) is to create a window with the size of the character, and move it on the fly to the character position so I can switch between palettes just within the window...

I let you now the result.
Unfortunately palette changes are for the whole screen and there is no way, in pure BASIC, to change a palette entry mid way through the screen (and even in assembly it's fairly timing specific) so you're pretty much limited on colours across the whole screen.

I'd concur that, unless you really want a pure BASIC solution, you're probably best of using some RSXs to manage sprite drawing of some kind.

skylas

Not sure if I can help, but I will share my thoughts/experiences, as I have faced also similar problems in Heart chaser 3.

If possible, maybe try to make the moving man in 1 square, not 2 or 4. It is much quicker like that, although it does not look so good.
GOSUB seems to make the program slower, especially if there are many together.
The lines that refer to the restrictions while moving (and generally that check what is happening in the game) have to be made as little as possible, maybe using mathematical ways so that you use as less characters as possible.
Web: https://amstradsakis.blogspot.com
Twitter: https://twitter.com/AmstradSakis
My programs (only BASIC):
RETRO-LOADSHEET ON AMSTRAD CPC!
PENALTY KICKS!
CAPITAL QUIZ!
CAPITAL QUIZ 2! (Reverse edition)
HEADS OR TAILS (ΚΟΡΩΝΑ/ΓΡΑΜΜΑΤΑ)
HEART CHASER 1,2,3!
BARBOUTI!
STROOPIE!
BUDRUMI!
ART WAR!
BATTLE OF LENINGRAD!
AMSTABOO!
RODOLFO SKYLARRIENTE!

Powered by SMFPacks Menu Editor Mod