Page 2 of 3

Re: Bubble Universe Demo

Posted: Fri Mar 24, 2023 7:08 pm
by desertfish
There's no "dynamic allocation" in Prog8. The compiler gathers all variables and writes them into the assembly file where they simply reserve a byte or word in memory wherever the assembler decides to put them.

The only thing that could make a difference is if the variable's declaration includes an initialization value. If so, prog8 will make sure the variable is set to that value every time the flow of control comes around the variable declaration again. If there is no initialization value, nothing happens at all

Re: Bubble Universe Demo

Posted: Fri Mar 24, 2023 7:09 pm
by desertfish
Here is a Python version of the program, it animates super silky smooth

import math import os import sys import pygame as pg os.environ["SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"] = "0" pg.init() screen = pg.display.set_mode([640, 512]) pg.display.set_caption("Bubble Universe") clock = pg.time.Clock() r = math.tau / 235.0 t = 0.0 num_curves = 255 iteration_length = 512 while True: clock.tick(60) for event in pg.event.get(): if event.type == pg.QUIT: sys.exit(0) screen.fill(0) for i in range(0, num_curves, 4): ang1_start = i + t ang2_start = i * r + t v = 0.0 u = 0.0 for j in range(iteration_length): ang1 = ang1_start + v ang2 = ang2_start + u u = math.sin(ang1) + math.sin(ang2) v = math.cos(ang1) + math.cos(ang2) red = int(i / num_curves * 255) green = int(j / iteration_length * 255) blue = int(255 - (i / num_curves + j / iteration_length) * 128) px = int((2 + u) * 128) + 60 py = int((v + 2) * 128) screen.set_at((px, py), (red, green, blue)) pg.display.flip() t += 0.025/4

Re: Bubble Universe Demo

Posted: Sat Mar 25, 2023 4:30 pm
by CX16UserSteveC
desertfish wrote: Fri Mar 24, 2023 7:09 pm Here is a Python version of the program, it animates super silky smooth

import math import os import sys import pygame as pg os.environ["SDL_VIDEO_X11_NET_WM_BYPASS_COMPOSITOR"] = "0" pg.init() screen = pg.display.set_mode([640, 512]) pg.display.set_caption("Bubble Universe") clock = pg.time.Clock() r = math.tau / 235.0 t = 0.0 num_curves = 255 iteration_length = 512 while True: clock.tick(60) for event in pg.event.get(): if event.type == pg.QUIT: sys.exit(0) screen.fill(0) for i in range(0, num_curves, 4): ang1_start = i + t ang2_start = i * r + t v = 0.0 u = 0.0 for j in range(iteration_length): ang1 = ang1_start + v ang2 = ang2_start + u u = math.sin(ang1) + math.sin(ang2) v = math.cos(ang1) + math.cos(ang2) red = int(i / num_curves * 255) green = int(j / iteration_length * 255) blue = int(255 - (i / num_curves + j / iteration_length) * 128) px = int((2 + u) * 128) + 60 py = int((v + 2) * 128) screen.set_at((px, py), (red, green, blue)) pg.display.flip() t += 0.025/4
The Python version is much more impressive. Unfortunately I don't think a Commander X16 implementation can ever come close to emulating the performance of the Python version running on a PC.

Re: Bubble Universe Demo

Posted: Sat Mar 25, 2023 5:05 pm
by desertfish
Ah no, ofcourse not, but I was so mesmerized by your original program that I wanted to reproduce the faster versions that they discussed on that linked website!

Re: Bubble Universe Demo

Posted: Sun Mar 26, 2023 12:25 am
by rje
Would the demo run slightly faster if all the variables were floating point? I.E. no A% N% S% and so on?

Re: Bubble Universe Demo

Posted: Sun Mar 26, 2023 12:58 am
by grml
rje wrote: Sun Mar 26, 2023 12:25 am Would the demo run slightly faster if all the variables were floating point? I.E. no A% N% S% and so on?
It would indeed! It wouldn't matter much in this example, but using the % suffix in BASIC V2 is actually a bad idea that makes the program run slower; the suffix is recognized but ultimately ignored because every number is a floating point number in BASIC.

Re: Bubble Universe Demo

Posted: Sun Mar 26, 2023 1:07 am
by rje
So I got a small execution speedup by removing the % and the two calls to INT().
I also created a couple of indexes to determine the pixel color, but I didn't use anything sophisticated.

Code: Select all

10 PA=$FA00
20 VPOKE 1,PA+ 0,0      :VPOKE 1,PA+ 1,  0
30 VPOKE 1,PA+ 2,0      :VPOKE 1,PA+ 3,  0
40 VPOKE 1,PA+ 4,0  +$0F:VPOKE 1,PA+ 5,  0
50 VPOKE 1,PA+ 6,0  +$0F:VPOKE 1,PA+ 7,$0F
60 VPOKE 1,PA+ 8,$F0+$0F:VPOKE 1,PA+ 9,  0
70 VPOKE 1,PA+10,$F0+$0F:VPOKE 1,PA+11,$0F
100 GOSUB 1000 :REM COLOR ADJUSTERS
110 N=200
120 R=ÿ*2/235
130 X=0:Y=0:V=0:T=0
140 S=60
150 SCREEN $80
160 CLS
210 FORI=0TON:FORJ=0TON
230 U=SIN(I+V)+SIN(R*I+X)
240 V=COS(I+V)+COS(R*I+X)
260 X=U+T:A=40+((2+U)*S):B=((2-V)*S)
280 C=2+CI(I)+CJ(J)
300 PSET A,B,C:NEXT:NEXT
330 GET A$:IF A$="" THEN 330
340 T=T+.025
350 GOTO 150
1000 DIM CI(256),CJ(256)
1010 FOR X = 0 TO 200
1020 CI(X) = X/28
1030 CJ(X) = X/28
1040 NEXT
1099 RETURN

Re: Bubble Universe Demo

Posted: Mon Mar 27, 2023 11:25 am
by pastblast
CX16UserSteveC wrote: Fri Mar 24, 2023 4:44 pm
desertfish wrote: Fri Mar 24, 2023 1:05 am I find it mesmerizing.
Here's the prog8 port. It runs faster, but not very much, due to the heavy use of floating point math in both cases.

bubbleuniverse.prg

%import graphics %import floats %import math %option no_sysinit ; Bubble Universe ; see: https://stardot.org.uk/forums/viewtopic ... 54&t=25833 main { sub start() { graphics.enable_bitmap_mode() const ubyte n = 200 const float r = floats.TWOPI/235 const ubyte s = 60 float t uword[] palette = [$000, $000, $00f, $f0f, $0ff, $fff] cx16.FB_set_palette(palette, 0, len(palette)) repeat { graphics.clear_screen(1,0) ubyte i for i in 0 to n { ubyte j float ang1_start = i+t float ang2_start = r*i+t float v=0 float u=0 for j in 0 to n { float ang1 = ang1_start+v float ang2 = ang2_start+u u=floats.sin(ang1)+floats.sin(ang2) v=floats.cos(ang1)+floats.cos(ang2) ubyte c=2 if i>=100 c++ if j>=100 c+=2 graphics.colors(c,0) uword a = 40 + ((2+u) * s) as uword uword b = ((v+2)*s) as uword graphics.plot(a,b) } } t+=0.025 } } }
I was thinking about porting to C, but cc65 doesn't support the floating type, and it'd be a bit of a pain to use the kernel math library. I wasn't aware of prog8 which does support the floating type, so thanks for the comment. Your pre-compiled bubbleuniverse.prg program file does seem to run a bit faster, but I was wondering if you move all of the variable declarations from the three inner loops to the beginning of start() if it would run even noticeably faster. However, when I compile the source file you posted and run the generated .prg program file I just get a blank screen rather than the output generated by the pre-compiled bubbleuniverse.prg program file you posted. I'm new to prog8 so I'm not sure if I did something wrong, but I compiled it with "java -jar prog8compiler-8.10-all.jar -target cx16 bubbleuniverse.p8". I get a couple of "integer implicitly converted to float" warnings on the two loop variables i and j, but no errors, and it does successfully generate a "bubbleuniverse.prg" file, but when I run this .prg file I just get a blank screen as I mentioned above.
Top

Some tips for speed improvements. These can be done separately or in some combinations.

In BASIC:

1. Pre-compute general sine and cosine values, and use a lookup table (array), rather than the built in math functions. This implies either loading data from DATA statements, or executing the built in functions only while loading the lookup table. Do not use those within the drawing loops.

2. Pre-compute the angles used within the program loops, excluding the "t" offset that changes (according to the Prog8 version shown). The angles can be kept in an array, and the "t" offset added, before looking up sine and cosine values.

In C, do items 1 & 2, plus:

3. Use integer math for all numbers not requiring floating point.

4. Use fixed point integers for all numbers that originally required floating point. This implies that angular fractions be in powers of 2 ( binary), not in powers of 10 ( decimal). For example, rather than incrementing "t" by 25/1000, increment "t" by 25, and assume a division by 1024. Don't actually divide. It also implies that the array of sine/cosine values be in fixed point. The number of fractional bits is up to you, but using a multiple of 8 often makes storage and retrieval easier.

5. Let two-pi be represented by a power of 2 integer, and not by a strange radians number. This makes using angles much easier, when dealing with binary numbers. For example, if $10000 means 2*pi, then $8000 is pi, and $4000 is pi/2. This implies that angles in lookup tables be based on this method, too. When adding 2 16-bit angles, rollover at 2*pi is automatic!

6. Knowing that the "t" value will eventually roll over, you might consider using mapped RAM, and pre-computing all U/V coordinates, based on "t". Then just look them up in the main loops.

Any of these tips can be done in assembly, of course.

Re: Bubble Universe Demo

Posted: Tue Aug 08, 2023 4:47 am
by voidstar
I shamelessly combined the music from CrazyLander and adjusted the code to randomly do a new sequence each iteration.
(will require the PLAY.PRG that CrazyLander uses)

Press ESC to stop the music, RETURN to resume it. Didn't think of it sooner, but could let SPACE force reset a new sequence.


And if anyone else missed it, the funny symbol on line 120 is PETSCII's version of PI that the Commodore BASIC interprets numerically. (I had forgotten it did that!)

120 R=ÿ*2/235

I'm horrible at music composition, if anyone has any other music sequence ideas?!

Re: Bubble Universe Demo

Posted: Thu Aug 24, 2023 12:20 am
by ahenry3068
voidstar wrote: Tue Aug 08, 2023 4:47 am I shamelessly combined the music from CrazyLander and adjusted the code to randomly do a new sequence each iteration.
(will require the PLAY.PRG that CrazyLander uses)

Press ESC to stop the music, RETURN to resume it. Didn't think of it sooner, but could let SPACE force reset a new sequence.


And if anyone else missed it, the funny symbol on line 120 is PETSCII's version of PI that the Commodore BASIC interprets numerically. (I had forgotten it did that!)

120 R=ÿ*2/235

I'm horrible at music composition, if anyone has any other music sequence ideas?!
I wish I had seen this previously. I've been doing my own modification that Cycles the Colors by VPOKING the VERA Pallette.
Maybe we should combine our modifications :).... I'm about to post mine in the next hour. Still tweaking the speed of the animation.