News:

Printed Amstrad Addict magazine announced, check it out here!

Main Menu

Another Basic Demo

Started by Bytebreaker, 13:18, 14 February 17

Previous topic - Next topic

0 Members and 1 Guest are viewing this topic.

Bytebreaker

Hello,


this demo uses code snippets from the pattern maker and char rotation tools I posted here earlier.
The focus this time was on exporting precalculated data on disk in order to speed up effects.


The "HF" logo consists of ca. 450 real numbers, 225 each for x and y coordinates which makes up 6kb on disk.
The flower pattern was originally 68k big, because I had 2912 dots, and for each dots an x and an y coordinate value as real numbers stored on disk. Changing the filetype to integer shrinked the exported table to 29k. The breakthrough came when I tought of whatr SRS taught me about making fast circles. I crunched the number of dots down to 224 and found a way to connect them correctly with lines drawn. This made the exported data table 4k big, which led to a fast drawing of effects and bearable loading times. The original preloading time was +1 minute, now we are at <10 seconds.


I am as always open for hints or improvement tips. The source is unprotected as always.




Gryzor

Really charming, made me think of the Amsoft tape (of course). Though I've got to admit at first I thought it was drawing a swastika :D

Bytebreaker

@ Gryzor


*ouch*


My wife said the same when I showed it to her.  :doh:
Being German it might be natural for me to like orthogonality, but not when it gets into the wrong shape, I can assure you this.  ;)


Sykobee (Briggsy)

#3
Ditto the Swastika thought!


I wonder if pre-calcing a sine table, and switching to ints, could do it in 'real time'.


Instead of Plot, you could Poke into screen memory for the first part, as long as the dots are 4 or 8 pixels apart.

arnoldemu

#4
I looked at your source. Your scroller is nice, and it is scrolling it at a whole char at a time??
Your code seemed like it was doing a lot of work? It is possible I misunderstood what you wanted to make.

Here is a char based scroller that works fast:

5 cls
10 a$="This is a really long scroller. to test printing in basic"
20 p%=1:l%=len(a$)
30 b$=mid$(a$,p%,8):p%=p%+1:if p%>(l%-8) then p%=1
40 locate 1,1:print b$:goto 30


in fact it's too fast to read LOL. 8 is the number of chars visible at one time.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

arnoldemu

@Bytebreaker:  I like your demo. :)

Your scroller is using TAG ("Text as graphics"), MOVE and PRINT so it is using graphics functions in the OS for drawing each character. These functions are slow because to draw each character it is done pixel-by-pixel and code always checks that the pixel is inside the graphics window. In addition to draw each pixel the screen memory address is calculated and then a pixel is AND/OR to place it to the screen. This method is perfect for your message which follows a curve because it allows it's placement where you need.

My scroller is faster because I am using the text functions. These are faster because the text location is checked if it is inside the text window and then the whole char is drawn line-by-line. Also my scroller is faster because I think I am doing the logic for displaying the string differently. My scroller will not wrap, so the best way to solve that is to add extra spaces at the end equal to the width of the scroll and print up to the end of the string.

Looking at your code then I would advise to use integers as much as possible (the BASIC interpreter has to do a conversion from 5-byte REAL number to 2 byte int and it's slow doing that a lot).

I don't think the drawing of the dot pattern could be speeded up with normal PLOT, other than to use ints and to not read it from data statements.

Another way would be define chars and change pen colours for drawing. You can turn on XOR, OR and AND plot modes so that your pixels are not removed when you write new chars.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Bytebreaker

#6
@ sykobee


I like your suggestion.
Before releasing the demo here I made different attempts with precalculations during runtime of the demo. If I take every nth value to calculate, and link the dot coordinates with lines, this might be as fast or even faster than reading from disk. At that time I had not found out the proper way to link the dots in the right manner, since the flower is not a continuous spiral and there is no clear number pattern telling me after n dots, that the there is a "line break".


Now I know by trial and error that I have to take every 13th dot coordinate of this particular pattern to maintain it's structure while reducing redundant coordinate information massively. While drawing lines from dot position to dot position (move:draw and so on) in a loop I check if the distance between the current x value and the next one is >90 or the distance of the current y value and the coming one is > 90. I use ABS function for it to avoid dealing with the sign (+/-). If the distance is >90, I skip the drawing process, so no diagonal lines will be drawn from the outer perimeter to the center (which looks really shitty).


In theory, I could adapt this concept to work without any preloading from disc, but with generating the table in realtime and then draw lines coordinate-wise to avoid slow plotting of single dots. I think here we might have equal speed or even a little speed advantage of the realtime version. I will try this in one of my next projects. 


@ arnoldemu


Thank you very much for the insights you give me regarding possible optimizations. In fact, the "HF" dot logo consists of floats while the flower structure consists of integers. I also tried ASCII upfront when trying to shrink the flower structure, but that was no real advantage. 2-bye Integers indeed take the fewest space. I feared loss of precision when switching from floats to integers but I can see no visual flaws with my bare eye.


In fact it is very comfortable to generate custom chars on CPC, so I will do more experiments with that in the future combined with bool operators. Actually, I am supposed to learn 6502 assembler to do stuff for my C64 scene group, but the CPC has become my hidden champion and I can't let go of that fabulous Basic. :-) That whole Amstrad package is British computer engineering at it's best.


Edit:
The credits for the tag-based scroller go to Morri here in the forum. He taught it to me and I just modified length and position of the scrolled text. Indeed I need that "tag softening" for smoothness and slowdown.

AMSDOS

#7
I'm just wondering if MASK could be used for the dotted effect, though you're at risk of making it BASIC 1.1 only. The best example I can think of where MASK is used is the Pyramids game from AA66 Type-ins, the board is drawn up with a MASK in place fairly quickly, so quick I think it was even faster than my Assembly PLOT loop routine to create the same effect on the 464 (though PLOT is a slow one no matter the language being used).
* Using the old Amstrad Languages :D   * with 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

I wanted to try a pixel by pixel mode 1 scroller in basic:


5 cls
10 a$="This is a really long scroller. to test printing in basic"
20 origin 0,0,16,128,399,380
30 tag:p%=1:l%=len(a$)
40 b$=MID$(a$,p%,9)
50 for b%=0 to 7
60 move 16-(b%*2),399:print b$;
70 next
80 p%=p%+1:if p%>(l%-8) then p%=1
90 goto 30


Window size is 8 chars wide.
I use origin to define the graphics window
I get *9* characters from the string at a time. I do this so that when I scroll at line 60 there is no empty pixels at the end.
b%*2 is used because all graphics coordinates are in mode 2 resolution and mode 1 has pixels twice the width.
16 is the starting draw position defined by the graphics window, I then draw at 16,14,12,etc to move the pixels to the left.


:)
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Xifos

Line 90, you wanted to write goto 40, not goto 30.
;)

AMSDOS

Quote from: arnoldemu on 14:54, 14 February 17
I looked at your source. Your scroller is nice, and it is scrolling it at a whole char at a time??
Your code seemed like it was doing a lot of work? It is possible I misunderstood what you wanted to make.

Here is a char based scroller that works fast:

5 cls
10 a$="This is a really long scroller. to test printing in basic"
20 p%=1:l%=len(a$)
30 b$=mid$(a$,p%,8):p%=p%+1:if p%>(l%-8) then p%=1
40 locate 1,1:print b$:goto 30


in fact it's too fast to read LOL. 8 is the number of chars visible at one time.


Sorry for taking another topic of discussion elsewhere and bringing it here. I had in mind another game for the 10 Liner compo using a BASIC form of Horizontal Scrolling, though it would involve multiple lines, so I'm unsure if this method would work. For my program I was thinking of storing a number in the character string so that could be used to add or deduct from a set area and then print a block in that position.




* Using the old Amstrad Languages :D   * with 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

Quote from: Xifos on 22:48, 16 February 17
Line 90, you wanted to write goto 40, not goto 30.
;)
yes. good find.
My games. My Games
My website with coding examples: Unofficial Amstrad WWW Resource

Bytebreaker

#12
@ amsdos


Oh I really enjoy reading. Scrollers are something essential, and it is great to see different creative approaches how to realize this in readable form without machine language.


On C64, I invented a hard scroll routine in v2 basic that works with easily editable datas and uses print commands. The concept behind it might work on CPC, too:


------------------------------------



5 print chr$(147)  : rem clear screen


38 for i=1to40     : rem load empty spaces (code 32)
39 read q


40 v$=v$+chr$(q)
41 next i


47 d1=peek(63)      : rem c64 workaround to achieve a data restore effect
48 d2=peek(64)      : rem save restore point
49 d3=peek(65)
50 d4=peek(66)


53 print v$
54 for k=1 to 100:next k : rem retardation
55 if c=173 then 170


160 v$=right$(v$,39)
161 read q$
162 v$=v$+q$
163 print chr$(145)chr$(145)chr$(145) : rem crsr up
164 c=c+1
169 goto 53


170 poke 63,d1      : rem restore saved restore points for data
171 poke 64,d2
172 poke 65,d3
173 poke 66,d4
175 v$="                                        "
180 c=0
185 goto 160






790 data 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32
791 data 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32


903 data "h","a","l","l","o"," ","w","i","e"," ","g","e","h","t","s","?"
904 data " ","e","s"," ","i","s","t"," ","i","m","m","e","r","n","o","c"
905 data "h"," ","u","m","s","t","a","e","n","d","l","i","c","h",","," "
906 data "t","e","x","t"," ","z","u"," ","v","e","r","f","a","s","s","e"
907 data "n"," ","a","b","e","r"," ","w","e","n","i","g","s","t","e","n"
908 data "s"," ","i","s","t"," ","e","s"," ","d","a","t","a"," ","k","l"
909 data "a","r","t","e","x","t","."," ","(","c",")"," ","b","y","t","e"
910 data "b","r","e","a","k","e","r"," ","2","0","1","6"," "," "," "," "
911 data " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
912 data " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
913 data " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "


-----------------------------------------------


I also did a sinus hard scroller on c64 in v2 basic but this could only be achieved be poking screen pokes directly into screen ram while a precalculated array contained the screen addresses to poke to.


You find attached c64 prg files that show what happens. Just drag and drop them into VICE emulator or any other c64 emulator you have at hand. C64 basic is shitty and not elegant compared to the noble loco basic, but like McGuyver you can make bazookas with little wooden matches if you try hard enough. :-)



Bytebreaker

#13
I quickly adapted my c64 hard scroll code to cpc and it works fine. You can copy and paste it into WinCPC and it works.
(edit 22:03h - fixed restore bug)

---------------------



5 cls


38 for i=1 to 40     : rem load empty spaces (code 32)
39 read q


40 v$=v$+chr$(q)
41 next i


53 print v$
54 for k=1 to 50:next k : rem retardation
55 if c=173 then 170


160 v$=right$(v$,39)
161 read q$
162 v$=v$+q$
163 locate 1,1
164 c=c+1
169 goto 53


170 restore
175 v$="                                        "
180 c=0
185 goto 38




790 data 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32
791 data 32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32,32




903 data "h","a","l","l","o"," ","w","i","e"," ","g","e","h","t","s","?"
904 data " ","e","s"," ","i","s","t"," ","i","m","m","e","r","n","o","c"
905 data "h"," ","u","m","s","t","a","e","n","d","l","i","c","h",","," "
906 data "t","e","x","t"," ","z","u"," ","v","e","r","f","a","s","s","e"
907 data "n"," ","a","b","e","r"," ","w","e","n","i","g","s","t","e","n"
908 data "s"," ","i","s","t"," ","e","s"," ","d","a","t","a"," ","k","l"
909 data "a","r","t","e","x","t","."," ","(","c",")"," ","b","y","t","e"
910 data "b","r","e","a","k","e","r"," ","2","0","1","6"," "," "," "," "
911 data " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
912 data " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "
913 data " "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "




AMSDOS

Well I've tried having a go at what I was suggesting, though haven't got the effect right, the 1st example just sets up to show what I had in mind which is to draw a Horizontal Tunnel and the 2nd example is me trying to pipe through the rest of the data unsuccessfully, though it looks like from the look of it it's going to be quite slow, though I have set a$ to a string size of 250, to allow for the multiple line to work each character from mid$ needs to be a length of 1 and it's just a matter of looping through the positions.


5 MODE 0
10 a$=STRING$(250,CHR$(143))
11 c$="0000000000112233322344433322111111110000"
20 p%=1
25 FOR x%=1 TO 16
30 GOSUB 1000:p%=p%+1:IF p%>39 THEN p%=1
40 LOCATE x%,10+VAL(MID$(c$,p%,1)):PRINT b$;:LOCATE x%,20-VAL(MID$(c$,p%,1)):PRINT b$;
50 NEXT x%:END
1000 b$=MID$(a$,p%,1):RETURN




5 MODE 0
6 PRINT CHR$(23)+CHR$(1);
10 a$=STRING$(250,CHR$(143))
11 c$="0000000000112233322344433322111111110000"
20 p%=1
25 FOR x%=1 TO 16
30 GOSUB 1000:p%=p%+1
40 GOSUB 3000
50 NEXT x%
55 p%=1
56 WHILE 1
60 FOR x%=1 TO 16
70   GOSUB 2000:p%=p%+1
80   IF p%>39 THEN p%=0
90   GOSUB 4000
100 NEXT x%
110 WEND
1000 b$=MID$(a$,p%,1):RETURN
2000 b$=MID$(a$,p%+1,1):RETURN
3000 LOCATE x%,10+VAL(MID$(c$,p%,1)):PRINT b$;:LOCATE x%,20-VAL(MID$(c$,p%,1)):PRINT b$;:RETURN
4000 LOCATE x%,10+VAL(MID$(c$,p%+1,1)):PRINT " ";b$;" ";:LOCATE x%,20-VAL(MID$(c$,p%+1,1)):PRINT " ";b$;" ";:RETURN
* Using the old Amstrad Languages :D   * with 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

Following up on my 2nd example, I think the problem there is the data from c$ string needs to be converted into an array. I discovered the use of XOR mode won't work in this case, so the blocks won't get deleted when another block is printed in it's place plus I don't think it would help me in this example. The array in this case would be 10 or 11 in height & 40 in overall width (16 is only ever visible onscreen).
* Using the old Amstrad Languages :D   * with 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: Bytebreaker on 21:43, 17 February 17
@ amsdos


Oh I really enjoy reading. Scrollers are something essential, and it is great to see different creative approaches how to realize this in readable form without machine language.

I seem to be coming back to Moving Graphical Images Down the Screen thread, there are some BASIC examples of moving contents through an array, the 8x8 example in the Link is an example of passing material from one Large Array to a small one which gets displayed onscreen. All of those examples moving their pieces down the screen, though some slight adjustments it can be applied from Right to Left. My last example (which I haven't posted), while it didn't work, it didn't seem to have the appropriate for making a game with. That 8x8 example is using PRINT/LOCATE to position everything, the graphical MOVE.TAG,PRINT maybe faster using calculated text co-ordinated positions, though initially I tried this in my Hisoft Pascal game, which resulted in me using Easi-Sprite Driver to totally transform the game. So I feel that any attempt of making Horizontal like scrolling game from BASIC, is going to play a lot on the slow side.
* Using the old Amstrad Languages :D   * with 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

Bytebreaker

Regarding movement of images down (and up) the screen:


Here you find two basic programs in which I tried to move chars without tag command.
I did not use sinus calculations, instead I used ordinary variable counters.


In this current state, the code can only be used for demos, not for game mechanics. It is too slow and not generic enough. For each moving object I track individual counters. Moving any given set of objects in patterns should be done by artificial intelligence and not by micro management of each object by the coder directly. I don't know yet how to achieve this in Basic and the urge to do more stuff in Assembler becomes stronger. On the CPC, this pain comes very late due to the great Basic. On C64, you learn Assembly very soon because you get immediately sick of the bad Basic.


@ AMSDOS


I will study your Graphical Images thread and post further comments or questions here. Thanks for the valuable input.




AMSDOS

From the Amstrad CPC-464 Advanced User Guide Book by Mark Harrison there's two small programs on page 33 on Animated Effects, the 1st deals with Horizontal motion, but in their case their using CHR$(32) to clear a spot on the screen (which I don't want), followed by the character '>' and CHR$(8) which Moves the Cursor one space to the left, the 2nd part in that program they have CHR$(32) followed by 2 CHR$(8), then CHR$(60) and a CHR$(8); on the end. I should point out these are within a FOR loop & following those control code lines is another FOR loop to slow the process by the looks.

I'll have to have a look at these examples to see it they will help, but just thinking about it now I think I need to clear a spot from each of those printed squares , which was where the process was lagging in Animating the Scenery, which I think is why you don't see any pure BASIC horizontal moving games, but I'll have a look at your code.

Thanks.  :)
* Using the old Amstrad Languages :D   * with 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