I wanted to test out my mouse/joystick driver before putting into MP128 (so I could test in a simpler environment), so I made this BASIC program which I thought was fairly simple (more about that later).
The program just models the gravitational force of n-bodies in 2 dimensions. To use it, attach the disk to unit 8 and power-up to auto boot, or you can enter RUN"PLANETS" after power-up. It doesn't need to be in disk unit 8. It should even work from cassette but I haven't tried it.
Once the program is loaded, the screen is cleared and you have 3 menu options. Plug a mouse into port 1 or a joystick into port 2 (or both, that's a fun game with a friend/enemy!) You can also use the keyboard for most operations (all except drag-n-drop).
Building a Solar SystemTo start building, click Add or press A. You get the New Body menu where you set the mass, velocity (speed), and color of the new body. I always start with a star = mass of 1000 and speed 0. Whenever you're done setting the options for the body (star / planet / comet ) click O.K. or press Return.
Your new body will be attached to the cursor and you can move anywhere on the screen you like. When you find a nice location, click on the spot set the initial position. If you gave your body a non-zero speed then it should start moving right away. Even if you gave your new body a zero speed, it should start moving soon if there are other bodies present (gravitational attraction).
Of course adding only 1 body (a star for example) is rather pointless. So you will want to Add at least one more body. If you added a star like described above, the second thing to try might be to add a planet. A large jupiter-size planet should have a mass of about 1.0. A small earth-size planet should have a mass of 0.01 or less.
Whatever mass you give to your planet/comet, be sure to give it some velocity. If you give it zero velocity, it will simply fall into the star. A good starting condition is to place the planet on the same horizontal line as the star, and give the planet an x-velocity of 0 and y velocity of non-zero (1 to 10 depending on distance). Or you can place it on the same vertical line as the star and give your planet a non-zero x-velocity and zero y-velocity. I hope that makes sense! Basically you want the planet to move perpendicular (at right angle) to the star.
It's easy to get 2 bodies to orbit. When you try adding a third, you may find it rather challenging to find an oribt that is stable for all bodies. This is the so-called n-body problem. If you don't do a good job of guessing a starting positition/speed/mass for the 3+ body, then it or one of the other bodies will likely get ejected from your solor system.
Editing and Deleting BodiesIf you see one of your planets flying off into deep space, or if you're just not happy with it, you can change or delete it. Just click on the body you're interested in, and you'll get the Edit Body menu. This works just like the Add body menu. You can change the velocity, mass, or color. You can delete the body from your solor system by clicking Delete (or press ESC). Otherwise, click O.K. when you're happy with the new settings, and you get the option to reposition the body. If you click Yes (or type Y) then you can move it anywhere, just like when you add a new body. If you click No (or type N) then body returns to it's previous location but with the new properties you just defined.
DemoHopefully you'll have some fun trying to build a nice solor system. It can be quite a challenge with multiple planets which have a large variety of mass. In fact it can be quite frustrating. To demonstrate it can be done, you can choose Demo from the main menu. Then you can select the number of bodies to model, 1 to 7. Selecting only 1 is a bit silly as you'll just have a lonely star sitting in the middle of the screen. Although the n-body problem is a challenge, I got those demo settings after playing around with it for a day. Then I went to sleep without turning off my computer by accident. The next morning I was pleasantly suprised to see all my planets were still in orbit The question is, would be it stable for 4.5 billion years? I think not.
QuitBored already? Click Quit (or press Q) from the main menu to end the program and turn off all sprites except the pointer, so you can test it outside the program (or with other programs). If you want to restore the defualt IRQ routine (disable mouse/joystick control of pointer) then type SYS DEC("B83"). Or simple press STOP+RESTORE.
TechnicalThe program was meant to test the joystick/mouse driver, so it is not very sophisticated. The most noticable thing is scaling: because VIC pixels are not square, a planet in a circular orbit will apear to be in an eliptical orbit. Another thing is no provision for collisions: bodies just pass through one another. Finally there is the issue of units. The program doesn't use standard units of mass, distance, and velocity.
All of the above could be corrected fairly easily, by employing some constants in the equations, but that would just slow the simulation down. It seems to run okay with 2 or 3 bodies, but beyond that you will notice it becomes slugish. I compiled the BASIC program to make it faster, but it didn't help much. Usually when you compile a BASIC program, it will be 10x faster (or more). However due to lots of floating-point calculations, a poor compiler, or my bad programing, it runs only about 2x faster when compiled.
I tried compiling it with Data Becker's 128 Compiler (v1.03) but it gave me lots of trouble. That compiler kept giving me errors about BEGIN/BEND. And it doesn't perform IF X correctly. That's just terrible in my opinion! I tried re-writing my program with GOTOs and IF X>0, and eventually got past those problems, but then there was a problem with STR$(). It seems if their are 8 digits after the decimal point the run-time version will crash randomly (depending on the digit before the decimal point). At this point I gave up on that compiler.
Next I tried Blitz! 128. This compiler doesn't have as many options (in particular, no native 6502 ML), but at least it works! I think maybe the speed could be improved if the variables were accessed in 1-d arrays instead of a 2-d array. However I've spent too much time on this already, so didn't investigate the possibility.
Anyway, the compiled program "PLANETS" is what is normally run. The disk image also includes "PLANETS.BAS" which is the uncompiled version. Should you want to play with it. Also on the disk, "PLANETS.SPR" are the 7 sprites (besides the pointer) used in the program. They should load to $E40~$FFF. Also on the disk is "MJ-G-DRV.BIN" which is the mouse/joystick driver with Group option (for drag-n-drop). This is the ML driver used in the program, and loads to the area $B80~$E3F (it includes the sprite pointer). Not used in the program, but also on the disk is "MJ-DRV.BIN" which is the smallest version I could make. It loads into $E00~$FFF and includes a sprite for the pointer but does no sprite grouping (no drag-n-drop); more importantly the memory used for BASIC sprites 2~7 are instead used by IRQ code.
TheoryI was suprised the compiled version was so slow considering the BASIC algorithim is simple (to me anyway). Here it is,
FOR I=1 TO N-1
AX=AX(I):AY=AY(I):M1=M(I)
FOR J=I+1 TO N
DX=PX(I)-PX(J):DY=PY(I)-PY(J):M2=M(J)
L2=DX*DX+DY*DY
F=M1*M2/L2
L=SQR(L2)
FX=F*DX/L:FY=F*DY/L
AX=AX+FX/M1:AY=AY+FY/M1
AX(J)=AX(J)-FX/M2:AY(J)=AY(J)-FY/M2
NEXT J
AX(I)=AX:AY(I)=AY
NEXT I
Well that's the theory. In the program the outer loop is DO/LOOP and not FOR/NEXT because some elements (planets) might be missing (if you deleted them) and a check of mouse/keyboard/joystick can break the loop. I also optimized away the division of L by making it a part of the F calculation. Anyway, this calculates the forces (and gravitational acceleration) between all possible pairs of bodies. The number of times this loops is related to the square of the number of bodies. Specifically
number of inner iterations = (N-1)*N/2.
So with 3 bodies, there are only 3 iterations. But with 4 bodies there are 6 iterations. With all 7 bodies, there are 21 iterations of all that code.
Finally there is more code to take the accelerations calculated above and apply them to the velocity/position of each sprite (and also reset the acceleration). So as you can see, BASIC has a lot of work to do. So maybe now you can see why it runs slugish with 4 or more bodies.
The EndWell it works for me in VICE with joystick or mouse or on my C128 with a joystick (actually a sega game pad). Unfortunately I don't have mouse any more for my C128, so if anybody with a real C128 and mouse would care to report how it works, or fails, I'd love to hear about it!
EditCorrected some typos... it seems I can spell gravitational acceleration but not solar... thanks
Naquaada