News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu
avatar_Fabrizio Radica

Simple Engine Game in Basic

Started by Fabrizio Radica, 15:48, 29 July 16

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

AMSDOS

#50
Quote from: Executioner on 02:36, 05 August 16
By the looks of the graphics, you could simple POKE the overlay pixels into screen memory (that's not machine code). POKE &C000+X%*2+y%*80,255 for example should be much quicker than using transparent character overlay.


I'm interested in having a look at this, though I recall @ervin posting this program in this thread which was replacing the PRINT with POKE, but was saying the POKE was slower in that situation until the program was compiled, though the POKE is arranged a little bit differently within a FOR loop, so your suggested approach may have advantages, and then with that POKE you can use the Encoded pen. I made a crude BASIC Sprite Driver which did that (in the Silly Thread).


FURTHER EDIT: Okay, I had a look at that formula, so it works based on Character Position, 0 being the first for Row/Column, but I think the xpos might need to say x%*4 rather than x%*2 for MODE 0, so when x%=19 &4C is the result and 4 bytes will take that to &4F. So for y% that can be range 0 to 19 and a loop that increments itself by &800 will fill in the rest from that position.



Quote from: Morri on 23:38, 04 August 16
No, the BASIC submissions must be one file (no multi-loading) and all interpreted BASIC 1.0 (no machine code pokes). My game CoolBox was going to be an entry but I couldn't get my code to work on Basic 1.0, the control code bug got me.


Was somewhat tempted to do a program as a BASIC stub file, but the judges would only have to take a look at the source code to find M/C  embedded in there with it.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

arnoldemu

The following code is in assembler but you may be able to use a similar idea in basic:

http://cpctech.cpc-live.com/source/charspr.asm

The code sets the mode to 2. Then using the firmware you pretend it's in the mode of your choice (1 or 0).

At this point the character matrices will be plotted direct to the screen as bytes (char matrices copyed directly byte by byte to the screen in mode 2, in other modes they are translated).

So for mode 0, each char matrix is now 2x8. Mode 1 is 4x8 etc.

Redefine your char matrices as if they are encoded pixel data that can be poked to the screen and put them side by side and use print to display them.

Now plot them in the normal way and instant sprites!

in basic you may be able to do this for mode 0:

mode 2: call &bd1c

and this for mode 1:

mode 2: call &bd1c,1

If it works, full colour sprites! :)

But of course you need to redefine the charset too so you can't just do print"Hello" or print score% :(

You would probably need to use CHR$ to print OR ctrl+letter in the string.



AMSDOS

Quote from: Fabrizio Radica on 15:49, 04 August 16
many thanks to all, really.


Now my tiny engine is near to be completed.
I have also implemented enemies and levels from disc (or tape)

Soon, i'll be ready to release the source code full commented, if you want :)




Hmm, guessing you noticed, your little red character wiped out some of those background blocks when they went through them.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Fabrizio Radica

Quote from: AMSDOS on 10:23, 05 August 16

Hmm, guessing you noticed, your little red character wiped out some of those background blocks when they went through them.


Yes little bug i've fixed last night. :)
I've also rewritten that part and now is more fast and light.

Morri

#54
Quote from: arnoldemu on 09:17, 05 August 16The following code is in assembler but you may be able to use a similar idea in basic: http://cpctech.cpc-live.com/source/charspr.asm The code sets the mode to 2. Then using the firmware you pretend it's in the mode of your choice (1 or 0). At this point the character matrices will be plotted direct to the screen as bytes (char matrices copyed directly byte by byte to the screen in mode 2, in other modes they are translated). So for mode 0, each char matrix is now 2x8. Mode 1 is 4x8 etc. Redefine your char matrices as if they are encoded pixel data that can be poked to the screen and put them side by side and use print to display them. Now plot them in the normal way and instant sprites! in basic you may be able to do this for mode 0: mode 2: call &bd1c and this for mode 1: mode 2: call &bd1c,1 If it works, full colour sprites! :) But of course you need to redefine the charset too so you can't just do print"Hello" or print score% :( You would probably need to use CHR$ to print OR ctrl+letter in the string.

I have seen the possibilities of this technique in a previous thread, it really is impressive and very fast compact code for BASIC.
Keeping it Kiwi since 1977

Fabrizio Radica

Quote from: Executioner on 02:36, 05 August 16
By the looks of the graphics, you could simple POKE the overlay pixels into screen memory (that's not machine code). POKE &C000+X%*2+y%*80,255 for example should be much quicker than using transparent character overlay.

Hi :)
Can you explain me better? i'm interested (and curious)
&c000 is the video address?
so i can draw much quicker the player? how?

I've to study the memory addresses. :(

arnoldemu

Quote from: Morri on 15:51, 05 August 16
I have seen the possibilities of this technique in a previous thread, it really is impressive and very fast compact code for BASIC.
I missed that post.

Example for "sprites":


5 symbol after 240
6 symbol 241,&aa,&f3,&cc,&33,&aa,&55,&cc,&33
7 symbol 242,&34,&66,&33,&66,&33,&66,&33,&66
10 mode 2:call &bd1c
20 locate 2,1:print chr$(241);chr$(242);


Use mode 2 text coordinates to move.

EDIT: The values for symbol are the bytes you need to POKE to memory to draw the same pixels.

So you could create some sprites on the screen using PLOT, then peek the memory address to fetch them for symbol.


arnoldemu

Quote from: Fabrizio Radica on 18:42, 05 August 16
Hi :)
Can you explain me better? i'm interested (and curious)
&c000 is the video address?
so i can draw much quicker the player? how?

I've to study the memory addresses. :(

Example:

1 mode 0
5 addr=(x*2)+(y*80)+&c000
6 restore 60
7 for i=0 to 7:read d:poke addr+(i*&800),d:next
8 restore 70
9 addr=(x*2)+1+(y*80)+&c000
10 for i=0 to 7:read d:poke addr+(i*&800),d:next
60 data &aa,&f3,&cc,&33,&aa,&55,&cc,&33
70 data &34,&66,&33,&66,&33,&66,&33,&66


The data has the bytes to poke. The data is organised as a column, 2 pixels wide and 8 pixels tall.

Restore is used to choose which data to use.

There are two for loops which are almost the same. These draw line by line.

The address is calculated based on mode 2 char coordinates.

The code becomes a little more complex if you want to move more smoothly.

arnoldemu

Screen coordinates:

You need to use mode to reset the screen location because it will change if it is scrolled by basic.

Use "mode" to do that.

&c000 is top-left. &c001 is one byte to right. &c002 is 2 bytes to right up to &c000+79 which is the byte on the right on the top line.

Next scanline down is +&800. &c800 is under &c000.
Pattern repeats for 8 scanlines:

&c000
&c800
&d000
&d800
&e000
&e800
&f000
&f800

This is the first column.

The next line is then &c000+80.

&f800
&c000+&80
&c000+&80+&800
&c000+&80+&1000 etc

Try with poke values and you will see.


Fabrizio Radica

Quote from: arnoldemu on 18:58, 05 August 16
Screen coordinates:

You need to use mode to reset the screen location because it will change if it is scrolled by basic.

Use "mode" to do that.

&c000 is top-left. &c001 is one byte to right. &c002 is 2 bytes to right up to &c000+79 which is the byte on the right on the top line.

Next scanline down is +&800. &c800 is under &c000.
Pattern repeats for 8 scanlines:

&c000
&c800
&d000
&d800
&e000
&e800
&f000
&f800

This is the first column.

The next line is then &c000+80.

&f800
&c000+&80
&c000+&80+&800
&c000+&80+&1000 etc

Try with poke values and you will see.


ok, i've understand.
it's similar to c64.

i've added this line and is really simple get a value from the memory.. for collisions... for example

15 print hex$(peek(&c000+&800+1))



thank's :)

AMSDOS

I've mapped out the whole screen here if you were wondering.


@arnoldemu made a little blue, the 1st bit is correct - adding 80, but has then added &80, which is 128 bytes, instead of adding &50 which is 80!
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS


This is what I knocked up, but I'm unsure if this is the approach @Executioner had in mind when suggesting to POKE to screen, rather than using Transparent Mode.


So in this situation I've taken your platform, converted it to bytes, line 2000..2060 pokes it to memory, and then use the main nested loop 140..190 to draw that all over the screen, 1000..1090 draws the image.

100 ' Setup Image & Display across screen
110 MODE 0:INK 0,0
120 GOSUB 2010
130 addr%=&8000
140 FOR y%=0 TO 24
150   FOR x%=0 TO 19
160     GOSUB 1020
170     addr%=&8000
180   NEXT x%
190 NEXT y%
200 CALL &BB18:CALL &BC02:MODE 2:END
1000 ' Poke Sprite to Screen
1010 ' On Entry - x% = XPOS (0..19), y% = YPOS (0..24), addr% = sprite location
1020 scradr%=&C000+(x%*4)+(y%*80)
1030 FOR v%=0 TO 7
1040   FOR h%=0 TO 3
1050     IF PEEK(addr%)<>0 THEN POKE scradr%+h%+(v%*&800),PEEK(addr%)
1060     addr%=addr%+1
1070   NEXT h%
1080 NEXT v%
1090 RETURN
2000 ' Poke Image to Memory
2010 RESTORE 2070
2020 FOR addr%=&8000 TO &801F
2030   READ a$
2040   POKE addr%,VAL("&"+a$)
2050 NEXT addr%
2060 RETURN
2070 DATA 30,c3,c3,82
2080 DATA c3,c3,c3,82
2090 DATA c3,c3,c3,82
2100 DATA c3,c3,c3,82
2110 DATA c3,c3,c3,82
2120 DATA c3,c3,c3,00
2130 DATA 00,00,00,00
2140 DATA 00,00,00,00



I mention @Executioner because in interpreted BASIC it takes a while (a few minutes) to draw up, and I think this is what @ervin was trying to tell me earlier. Though I think the situation changes when something like this has been compiled.


This was the outcome for interpreted BASIC:


[attachimg=1]


If your wondering how I got that DATA for your platform block from the SYMBOL data I did this:


mode 0:print chr$(22);chr$(1);:locate 1,1:pen 9:print chr$(245);:pen 4:locate 1,1:print chr$(248);:print chr$(22);chr$(0);:locate 1,10


To print the Object Top Left Corner of the screen.


I can just get the data with this:



1000 scradr%=&C000 : for loop=1 to 8 : gosub 1020 : print : scradr%=scradr%+&800 : NEXT loop
1010 end
1020 for addr=scradr to scradr+3 : print hex$(peek(addr));" ";:next addr : return
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Executioner

Well, the idea wasn't to POKE the whole tile into screen memory, but to print the character as normal and POKE a single byte for the two white pixels in the top corner. You gain the advantage of using a firmware print to display the tile without using transparency (which is slow). For example, a single tile in the tope corner could be something like

LOCATE x,y:PRINT CHR$(254);:POKE &C000+x*4+y*80,255

This wouldn't work particularly well if you had lots of different colour pixels in the character tile, but for just one in the corner it's fine. You could also define an array containing one (or maybe more) offsets and values to poke. So for example:

20 DATA &C000,&D801,&C800,&F800:'Address offsets
30 DATA &FF,&55,&AA,&22:'Values

Read these into variables (eg. A% and V%), then

LOCATE x,y:PRINT CHR$(tile + 252):POKE A%(tile),V%(tile)

AMSDOS

Quote from: Executioner on 09:12, 06 August 16
Well, the idea wasn't to POKE the whole tile into screen memory, but to print the character as normal and POKE a single byte for the two white pixels in the top corner. You gain the advantage of using a firmware print to display the tile without using transparency (which is slow). For example, a single tile in the tope corner could be something like

LOCATE x,y:PRINT CHR$(254);:POKE &C000+x*4+y*80,255

This wouldn't work particularly well if you had lots of different colour pixels in the character tile, but for just one in the corner it's fine. You could also define an array containing one (or maybe more) offsets and values to poke. So for example:

20 DATA &C000,&D801,&C800,&F800:'Address offsets
30 DATA &FF,&55,&AA,&22:'Values

Read these into variables (eg. A% and V%), then

LOCATE x,y:PRINT CHR$(tile + 252):POKE A%(tile),V%(tile)


Sorry I got confused when you started asking about having a small Sprite Driver in a BASIC game for the Compo. After @Morri explained M/C wasn't allowed, you posted that POKE with formula, which I thought was interesting, but got caught up in the formula and didn't realise you were suggesting merely Poking the corner of the Wall Sprite.  :( 


But I appreciate the explanation and agree that would be a better approach instead of using Transparent Mode to Display one small bit of the Wall Tile.


The program I posted yesterday was out of my own curiosity, I didn't mean to imply this was what you were suggesting, though I remember @ervin saying that Poking was quite slow when using BASIC, though whatever was written got translated with CPC BASIC 3, with interesting results. So I ended up writing that program to have a look.


I'll post an attachment of the program in due course.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

ZbyniuR

Fabrizio - In my opinion to appear whole screen fast (in about 3 sec), you can use just few PRINT, instead hundreds PRINT, CHR$, READ... etc. in FOR-NEXT loop.
Just use for tiles narrow fonts 4x8 pixels in 4 colors, which I explained here:
BASIC programming tips

And to check tiles on map use TEST color of pixel, instead DIM and DATA. Thats should be much shorter and faster program. Narrow font show at once 4 colors of tiles or sprites. Example of small sprite I did here:
BASIC programming tips
And this method let make quite fluent animation without assembler:
BASIC programming tips

In STARS, TREK is better than WARS.

AMSDOS

A bit late with my post given @ZbyniuR probably has the best advice on Control Codes!  :D


The program I posted earlier has to be modified a little bit to work in CPC BASIC 3, so now it looks like this:




100 ' Setup Image & Display across screen
110 MODE 0:INK 0,0
130 addr=&8000
140 FOR y=0 TO 24
150   FOR x=0 TO 19
160     GOSUB 1020
170     addr=&8000
180   NEXT x
190 NEXT y
200 CALL &BB18:CALL &BC02:MODE 2:END
1000 ' Poke Sprite to Screen
1010 ' On Entry - x = XPOS (0..19), y = YPOS (0..24), addr = sprite location
1020 scradr=&C000+(x*4)+(y*80)
1030 FOR v=0 TO 7
1040   FOR h=0 TO 3
1050     IF PEEK(addr)<>0 THEN POKE scradr+h+(v*&800),PEEK(addr)
1060     addr=addr+1
1070   NEXT h
1080 NEXT v
1090 RETURN





The data from Line 2000 gets saved into a file "wall.spr" which is on my attach disk image, so then that routine is removed line 120 also goes. CPC BASIC 3 handles variables a little bit differently from Locomotive BASIC, so the "%" is removed. That program can then be compiled in CPC BASIC 3. Which I've attached.


Performance wise, the program draws around the same pace as the BASIC version, but it's drawing 20x25, so it might be a touch faster. The only advantage in this is all the Sprite Drawing is kept within the program, so no 3rd party software, the approach @arnoldemu discussed earlier would also keep the sprite drawing within the program, I reckon would be faster, my early version of Get the Cash used a similar approach, though I was surprised what the final result was after compiling it with CPC BASIC 3, which seemed a bit slow. 3rd party sprite drivers seem to change that, but present the problem of submitting to the Games Compo.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Fabrizio Radica

Quote from: AMSDOS on 04:38, 07 August 16
A bit late with my post given @ZbyniuR probably has the best advice on Control Codes!  :D


The program I posted earlier has to be modified a little bit to work in CPC BASIC 3, so now it looks like this:




100 ' Setup Image & Display across screen
110 MODE 0:INK 0,0
130 addr=&8000
140 FOR y=0 TO 24
150   FOR x=0 TO 19
160     GOSUB 1020
170     addr=&8000
180   NEXT x
190 NEXT y
200 CALL &BB18:CALL &BC02:MODE 2:END
1000 ' Poke Sprite to Screen
1010 ' On Entry - x = XPOS (0..19), y = YPOS (0..24), addr = sprite location
1020 scradr=&C000+(x*4)+(y*80)
1030 FOR v=0 TO 7
1040   FOR h=0 TO 3
1050     IF PEEK(addr)<>0 THEN POKE scradr+h+(v*&800),PEEK(addr)
1060     addr=addr+1
1070   NEXT h
1080 NEXT v
1090 RETURN





The data from Line 2000 gets saved into a file "wall.spr" which is on my attach disk image, so then that routine is removed line 120 also goes. CPC BASIC 3 handles variables a little bit differently from Locomotive BASIC, so the "%" is removed. That program can then be compiled in CPC BASIC 3. Which I've attached.


Performance wise, the program draws around the same pace as the BASIC version, but it's drawing 20x25, so it might be a touch faster. The only advantage in this is all the Sprite Drawing is kept within the program, so no 3rd party software, the approach @arnoldemu discussed earlier would also keep the sprite drawing within the program, I reckon would be faster, my early version of Get the Cash used a similar approach, though I was surprised what the final result was after compiling it with CPC BASIC 3, which seemed a bit slow. 3rd party sprite drivers seem to change that, but present the problem of submitting to the Games Compo.

wow!
Now I have to learn and understand what you're writing.
aargh!! i would like to code it with CPC Basic 3 but doesn't work in OSX El Capitan and Wine :(


Fabrizio Radica

Quote from: AMSDOS on 05:07, 06 August 16
This is what I knocked up, but I'm unsure if this is the approach @Executioner had in mind when suggesting to POKE to screen, rather than using Transparent Mode.


So in this situation I've taken your platform, converted it to bytes, line 2000..2060 pokes it to memory, and then use the main nested loop 140..190 to draw that all over the screen, 1000..1090 draws the image.

100 ' Setup Image & Display across screen
110 MODE 0:INK 0,0
120 GOSUB 2010
130 addr%=&8000
140 FOR y%=0 TO 24
150   FOR x%=0 TO 19
160     GOSUB 1020
170     addr%=&8000
180   NEXT x%
190 NEXT y%
200 CALL &BB18:CALL &BC02:MODE 2:END
1000 ' Poke Sprite to Screen
1010 ' On Entry - x% = XPOS (0..19), y% = YPOS (0..24), addr% = sprite location
1020 scradr%=&C000+(x%*4)+(y%*80)
1030 FOR v%=0 TO 7
1040   FOR h%=0 TO 3
1050     IF PEEK(addr%)<>0 THEN POKE scradr%+h%+(v%*&800),PEEK(addr%)
1060     addr%=addr%+1
1070   NEXT h%
1080 NEXT v%
1090 RETURN
2000 ' Poke Image to Memory
2010 RESTORE 2070
2020 FOR addr%=&8000 TO &801F
2030   READ a$
2040   POKE addr%,VAL("&"+a$)
2050 NEXT addr%
2060 RETURN
2070 DATA 30,c3,c3,82
2080 DATA c3,c3,c3,82
2090 DATA c3,c3,c3,82
2100 DATA c3,c3,c3,82
2110 DATA c3,c3,c3,82
2120 DATA c3,c3,c3,00
2130 DATA 00,00,00,00
2140 DATA 00,00,00,00



I mention @Executioner because in interpreted BASIC it takes a while (a few minutes) to draw up, and I think this is what @ervin was trying to tell me earlier. Though I think the situation changes when something like this has been compiled.


This was the outcome for interpreted BASIC:


[attachimg=1]


If your wondering how I got that DATA for your platform block from the SYMBOL data I did this:


mode 0:print chr$(22);chr$(1);:locate 1,1:pen 9:print chr$(245);:pen 4:locate 1,1:print chr$(248);:print chr$(22);chr$(0);:locate 1,10


To print the Object Top Left Corner of the screen.


I can just get the data with this:



1000 scradr%=&C000 : for loop=1 to 8 : gosub 1020 : print : scradr%=scradr%+&800 : NEXT loop
1010 end
1020 for addr=scradr to scradr+3 : print hex$(peek(addr));" ";:next addr : return




I don't understund how to draw my tiles in your data.
I see (correct me if i wrong) 4 colums and 8 row (sprite 4x8) and is ok
But, how is it subdivided?


When i draw my SYMBOL CHR, i only put one pixel color per chr$
like this:

160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
168 SYMBOL 248,&X11000000,&X0,&X0,&X0,&X0,&X0,&X0,&X0 'wall color



Thank'you :)

rk last

I doubt this method is worth while on the CPC, but here goes.

When I code, lets say a platformer on a PC, I READ the DATA as normal and then store the X and Y of anything solid into another array.  This often means that certain screens/levels have smaller content inside this other array. (can read it faster)

I then then do a FOR/NEXT match from that array against the players X&Y position. 
maRK

AMSDOS

Quote from: rk last on 21:45, 07 August 16
I doubt this method is worth while on the CPC, but here goes.

When I code, lets say a platformer on a PC, I READ the DATA as normal and then store the X and Y of anything solid into another array.  This often means that certain screens/levels have smaller content inside this other array. (can read it faster)

I then then do a FOR/NEXT match from that array against the players X&Y position.


A while ago (May last year), I was writing up some simple demonstration for a platform game and had @ronaldo help with the Jumping process. The data from those examples gets stored into an Array, so when my character falls onto it, it doesn't fall any further, I think pretty much any platform game has to operate like that, some platform games would definitely have a larger array (for the whole level), so as you move through it, each sector of that larger array is stored to the smaller array (which is the playing field), but the examples I have in that thread only deals in a single screen array.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS


Quote from: Fabrizio Radica on 13:44, 07 August 16
wow!
Now I have to learn and understand what you're writing.
aargh!! i would like to code it with CPC Basic 3 but doesn't work in OSX El Capitan and Wine


Unfortunately that's one of the limitations with CPC BASIC 3 (requires Windows). Some other CPC Based BASIC Compilers were mentioned earlier, Fabacom might be able to do what you need, which all runs on the CPC!


Quote from: Fabrizio Radica on 15:45, 07 August 16




I don't understund how to draw my tiles in your data.
I see (correct me if i wrong) 4 colums and 8 row (sprite 4x8) and is ok
But, how is it subdivided?


I'll try and explain, though it's somewhat complicated.


Each byte can hold a certain amount of pixel data, this varies depending on the screen mode you're in, in MODE 0 in your case it can hold a left most pixel and a right most pixel, if we were using MODE 1, that number would be 4 pixels for each byte - so an 8x8 image would only take 2 bytes. In MODE 2 a single byte will hold 8 pixels! So just getting back to my example in MODE 0, because a Byte can hold 2 Pixels, a whole column (of 8 pixels), only needs 4 Bytes. But for rows it never changes. So for MODE 0,1 or 2, 8 Bytes is always required if the Tile is 8 pixels in height. So naturally this will change if the Tile was bigger.


Quote
When i draw my SYMBOL CHR, i only put one pixel color per chr$
like this:

160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
168 SYMBOL 248,&X11000000,&X0,&X0,&X0,&X0,&X0,&X0,&X0 'wall color





Thank'you


In your examples you're using Symbol to redefine the character set, which is always 8x8, it's possible to use multiple SYMBOL  definitions to make up a larger image, or in this example above it's using Transparent Mode - PRINT CHR$(22)+CHR(1) to PRINT CHR$(245) and then PRINT CHR$(248) to PRINT another Colour on top of the main graphic, this is due to these SYMBOL definitions only allowing 2 Colours, but one of those Colours is the background, so you only have 1 colour for your character.


Earlier @Executioner was suggesting replacing PRINT CHR$(248) with the POKE would be faster than using the Transparent Mode approach. For the purpose of enhancing your game in Interpreted BASIC, it's worth checking that out. What I published is merely a curiosity, gone to the point of poking a sprite to the screen. As you would notice the Locomotive BASIC version is terribly slow, the screenshot shows that. After compiling it with CPC BASIC 3, I think it's about the same speed as your game, so I think removing the Transparent Mode from it and using the POKE Executioner posted should make your program run faster than my Compiled.


It might be easier to do a screenshot of drawing the image to screen and getting the Byte information of it:


[attachimg=1]


I Used a small little program I posted earlier to get the Information, it simply works by having the Image at the top left of the screen (1,1), but works out the Bytes across and down, to let me come up with my data, the program I posted earlier looks like this:



1000 scradr=&C000:FOR loop=1 TO 8:GOSUB 1020:PRINT:scradr=scradr+&800:NEXT loop
1010 END
1020 FOR addr=scradr TO scradr+3:PRINT HEX$(PEEK(addr));" ";:NEXT addr:RETURN
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

AMSDOS

So this is what I came up with, based on @Executioner suggestion. In this example I've removed the Transparent Mode along with the Background SYMBOLs being defined - CHR$(248) & CHR$(249), which are no longer needed. I've taken the 464 version of the game and have modified Lines 30011 & 30021 so they are now using POKEs to Poke the White Pixel, into the Wall Block and Bonus. The Bonus one was a bit harder given it wasn't on the top of the line, so cheated and calculated it based on the Row it was on - which gets me to &D000. x% is multiplied by 4, which takes it past the spot in question, so subtracted 2 to get the right spot. Also both the formula's have been altered slightly based on Executioner's formula, mainly because their 0 based, so 1 is subtracted to get the right Row.


1 'A (simple) GAME Routine BY FABRIZIO RADICA - 2016 Retroacademy.it
10 DEFINT A-Z:MODE 0:transpOn$=CHR$(22)+CHR$(1):transpOff$=CHR$(22)+CHR$(0)
11 ON BREAK GOSUB 50000
20 BORDER 0:INK 0,0:maxx%=20:maxy%=20:lev%=0:isDown%=0:SYMBOL AFTER 240
160 SYMBOL 245,&X11111110,&X11111110,&X11111110,&X11111110,&X11111110,&X11111100,&X0,&X0 'wall
165 SYMBOL 246,&X1111110,&X10000000,&X10000000,&X10000000,&X10000000,&X10000000,&X0,&X0 'background
166 SYMBOL 247,&X111100,&X1111110,&X11111011,&X11111111,&X11111111,&X11111111,&X1111110,&X111100 'bonus
170 SYMBOL 240,&X111100,&X1111110,&X11101011,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player right
171 SYMBOL 250,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111,&X10000001,&X11111111 'ladders
172 SYMBOL 251,&X111100,&X1111110,&X11010111,&X11111111,&X11111111,&X11000011,&X1100110,&X111100 'player left
180 wa1$=CHR$(245):bg$=CHR$(246):bo1$=CHR$(247):wa2$=CHR$(248):bo2$=CHR$(249):plyr$=CHR$(240):plyl$=CHR$(251):lad$=CHR$(250)
200 DIM map%(maxy%,maxx%)
240 CLS:LOCATE 1,24:INK 1,3:PRINT "Loading"
250 ' FOR i%=2 TO 15:INK i%,0:NEXT i%
292 lev%=lev%+1
295 IF (lev%>3) THEN CLS: PRINT "YOU WIN!!" : END
310 fpen$=CHR$(15):green$=fpen$+CHR$(12):white$=fpen$+CHR$(4):bgcolor$=fpen$+CHR$(8):bgr$=bgcolor$+bg$
340 wall$=fpen$+CHR$(9)+wa1$+curLeft$+white$+wa2$:bonus$=fpen$+CHR$(7)+bo1$+curLeft$+white$+bo2$:playerr$=fpen$+CHR$(3)+plyr$:playerl$=fpen$+CHR$(3)+plyl$:ladders$=white$+lad$
345 DIM obj$(10),playerFrame$(10)
350 obj$(1)=wall$:obj$(2)=bonus$:obj$(3)=ladders$
354 frcount=1
355 pframe$(1)=CHR$(240)
356 pframe$(2)=CHR$(251)
400 FOR y%=1 TO maxy%
410 FOR x%=1 TO maxx%
420 READ a%:map%(y%,x%)=a%:LOCATE x%,y%
430 ON map%(y%,x%) GOSUB 30010,30020,30030,30000
440 NEXT x%:NEXT y%
660 CALL &BC02:BORDER 0:INK 0,0:INK 1,26:x%=2:y%=4:v%=1:sc%=0:p%=0
700 LOCATE 1,24:PRINT "Score 0  - Lev ";lev%
720 'memory &7fff:load"music.bin",&8000:call &8000
740 LOCATE 1,1 : PRINT CHR$(15);CHR$(3); : LOCATE x%,y% : PRINT pframe$(frcount):CALL &BD19
750 IF map%(y%,x%)=2 THEN map%(y%,x%)=0:LOCATE 6,24:sc%=sc%+1:PRINT sc%
780 IF NOT(INKEY(8)) AND NOT(map%(y%,x%-v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=2: GOSUB 40000: x%=x%-v%
800 IF NOT(INKEY(1)) AND NOT(map%(y%,x%+v%)=1) AND NOT(map%(y%+v%,x%)=0) THEN frcount=1: GOSUB 40000: x%=x%+v%
850 IF NOT(INKEY(0)) AND NOT(map%(y%-v%,x%)=1) AND map%(y%-v%,x%)=3 THEN GOSUB 40000:y%=y%-v%
860 IF NOT(INKEY(2)) AND NOT(map%(y%+v%,x%)=1) AND map%(y%+v%,x%)=3 THEN GOSUB 40000:y%=y%+v%
880 IF map%(y%+v%,x%)=0 OR map%(y%+v%,x%)=2 THEN GOSUB 40000:y%=y%+v%
900 'if sc%>=9 then cls: goto 240
990 GOTO 740
1000 DATA 0,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,1,0,0
1100 DATA 0,1,4,4,0,0,0,0,4,1,1,1,1,1,0,0,0,1,1,0
1200 DATA 1,0,0,0,0,0,0,0,0,0,0,0,0,0,2,0,0,3,0,1
1300 DATA 1,0,0,0,0,0,4,4,0,0,0,1,1,1,1,1,1,3,0,1
1400 DATA 1,1,1,0,3,0,0,0,0,2,0,0,0,0,0,3,0,3,0,1
1500 DATA 1,0,0,1,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1600 DATA 1,0,0,0,3,0,0,0,0,1,1,1,1,1,0,3,1,1,1,1
1700 DATA 1,0,0,0,3,1,2,0,0,0,0,4,4,0,0,3,0,4,4,1
1800 DATA 1,0,0,0,3,1,1,1,0,0,3,0,2,0,0,3,0,0,0,1
1900 DATA 1,2,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,1,0
2000 DATA 1,0,1,1,3,1,0,0,1,0,3,1,1,1,1,1,1,1,0,0
2100 DATA 1,0,0,0,3,3,1,1,1,1,3,1,1,1,0,4,4,1,1,0
2200 DATA 1,0,0,0,1,3,3,0,0,0,3,0,2,0,0,0,0,0,0,1
2300 DATA 1,0,1,1,1,1,3,0,0,1,1,1,1,1,0,0,2,0,0,1
2400 DATA 1,0,3,0,3,0,3,0,3,0,0,0,0,0,1,1,1,0,0,1
2500 DATA 1,0,3,1,3,1,1,0,3,1,1,1,1,1,1,1,1,1,0,1
2600 DATA 1,0,3,0,3,4,1,0,3,1,1,1,1,1,0,0,1,1,0,1
2700 DATA 0,1,1,0,3,0,1,0,3,1,0,4,4,0,0,0,0,0,0,1
2800 DATA 0,0,1,0,3,0,0,0,3,0,0,0,0,0,2,0,2,0,0,1
2900 DATA 0,0,0,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0
30000 LOCATE 1,1 : PRINT CHR$(15);CHR$(8); : LOCATE x%,y% : PRINT CHR$(246);:RETURN
30010 LOCATE 1,1:PRINT CHR$(15);CHR$(9); : LOCATE x%,y% : PRINT CHR$(245);
30011 POKE &C000+(x%-1)*4+(y%-1)*80,&30:RETURN
30020 LOCATE 1,1 : PRINT CHR$(15);CHR$(7); : LOCATE x%,y% : PRINT CHR$(247);
30021 POKE &D000+x%*4-2+(y%-1)*80,&B8:RETURN
30030 LOCATE 1,1 : PRINT CHR$(15);CHR$(4); : LOCATE x%,y% : PRINT CHR$(250);:RETURN
40000 LOCATE x%,y%:PRINT" ";:LOCATE x%,y%:PRINT obj$(map%(y%,x%));:RETURN
50000 CLEAR : CALL &BC02 : PEN 1 : MODE 2 : END             
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Gryzor

Just dropping by to say welcome, @Fabrizio Radica -  great to see new guys trying stuff! I really like this thread :)

Executioner

Quote from: AMSDOS on 04:33, 08 August 16
Also both the formula's have been altered slightly based on Executioner's formula, mainly because their 0 based, so 1 is subtracted to get the right Row.

How about subtracting 80 and 1 from &C000 or &D000 then you don't make BASIC have to do it. ie.

&C000 becomes &BFAF and &D000 (+2) becomes &CFB1.

I don't think you need the LOCATE 1,1 and extra LOCATE x%,y% either, eg. You can just do

PRINT CHR$(15);CHR$(8);CHR$(246);

AMSDOS

Quote from: Executioner on 14:14, 09 August 16
How about subtracting 80 and 1 from &C000 or &D000 then you don't make BASIC have to do it. ie.

&C000 becomes &BFAF and &D000 (+2) becomes &CFB1.


I know what you mean, unfortunately I've tried this and it just wouldn't work. But feel free to make adjustments.

Quote
I don't think you need the LOCATE 1,1 and extra LOCATE x%,y% either, eg. You can just do

PRINT CHR$(15);CHR$( 8) ;CHR$(246);


Call it a precaution, I wasn't sure if it would work on a 464, though the program I posted earlier with the LOCATE Control Code demonstrates the PEN Control Code doesn't interfere, it all seems to be occurring when people are using BackSpace Control code that problems emerge on the 464.
* Using the old Amstrad Languages :D * And create my own ;)
* Incorporating the Firmware :P
* I also like to problem solve code in BASIC :)   * And type-in Type-Ins! :D

Home Computing Weekly Programs
Popular Computing Weekly Programs
Your Computer Programs
Updated Other Program Links on Profile Page (Update April 16/15 phew!)
Programs for Turbo Pascal 3

Powered by SMFPacks Menu Editor Mod