What I did today

vsim 2.0 lmao

I finally finished (at least I hope so…) a Commodore BASIC V2 (https://www.c64-wiki.com/index.php/BASIC) compiler thingy. It takes any C64 BASIC program, compiles it into a kind of object tree (not directly into machine- or p-code) and executes the results. It’s not an emulator, i.e it doesn’t try to mimic the original hardware. It just runs the programs. If they are using actual hardware features, the results look strange sometimes but they run nonetheless.
The purpose of all this has still to be discovered. I guess one could use it as a scripting language for Java if one really wants to…
Execution time is around 10% of compiled Java code, but 10 times faster than similar (albeit more limited) BASIC interpreters that I tried.

Example program:


10 FOR B=99 TO 1 STEP -1
20 GOSUB 100
30 T$=T$+" OF BEER ON THE WALL"
40 PRINT T$;", ";T$
50 PRINT "TAKE ONE DOWN AND PASS IT AROUND, "
60 IF B-1<=0 THEN PRINT "NO MORE BOTTLES OF BEER ON THE WALL":GOTO 80
70 GOSUB 200:PRINT " OF BEER ON THE WALL"
80 PRINT:NEXT
91 PRINT "GO TO THE STORE AND BUY SOME MORE, 99 BOTTLES OF BEER ON THE WALL"
92 END
100 T$=STR$(B)+" BOTTLE":IF B>1 THEN T$=T$+"S"
110 RETURN
200 A=B-1:PRINT STR$(A)+" BOTTLE";
210 IF A>1 THEN PRINT "S";
220 RETURN

…or a more condensed version:


10 FORB=99TO1STEP-1:GOSUB100
20 T$=T$+" OF BEER ON THE WALL":PRINTT$;", ";T$:PRINT"TAKE ONE DOWN AND PASS IT AROUND, "
30 IFB-1<=0THENPRINT"NO MORE BOTTLES OF BEER ON THE WALL":GOTO50
40 GOSUB200:PRINT" OF BEER ON THE WALL"
50 PRINT:NEXT
60 PRINT"GO TO THE STORE AND BUY SOME MORE, 99 BOTTLES OF BEER ON THE WALL":END
100 T$=STR$(B)+" BOTTLE":IFB>1THENT$=T$+"S"
110 RETURN
200 A=B-1:PRINTSTR$(A)+" BOTTLE";:IFA>1THENPRINT"S";
210 RETURN

Edit: Some other valid program for your enjoyment (three FORs, but only one NEXT…)


10 FORI=0TO10:FORX=0TO20:FORY=5TO30
20 PRINTI,X,Y
100 NEXT
110 IFI<>10ORX<>20GOTO100

Always amuses me how CBM BASIC can we written without any whitespace.

Cas :slight_smile:

Yes. That makes parsing it quite different from modern languages. Simply because variable names combined with commands can lead to things that actually look like keywords. Like


10 LE=1
15 R=20
20 FORI=LETOR

…merges LE and TO into the LET keyword (edit: and TO and R into OR)…or…


10 T=4
20 IFTAND5THEN

…merges T and AND into the function call TAN.

Some BASIC compilers had issues with this in the past and treated these cases as syntax errors, which they aren’t.

I made this cool hotbar just now after testers requested it.

It turned out pretty cool, I think.

Sunday/Tuesday worked out the kinks of converting a Yamaha DX7 patch called ā€œCHROMA 5Bā€ to Java. I want to use it in a game design I am currently working on. The interesting feature of this synth patch is that the shorter the amount of time before the release is triggered, the brighter the decay. In other words, when you play it on a keyboard by holding the key down, the tone color quickly becomes damped, but if you play super staccato (releasing very quickly) the tone color is quite bright, with qualities of a hammered metal string.

The last kink to work out was implementing ā€œfrequency scaling,ā€ so that the harmonic content of the higher frequency notes would balance with that of the lower notes. I hadn’t yet added this to my synth as a general feature, and was worried it would be tricky. But it turned out to be easier than expected. A nice sounding roll off to the ā€œmodulation indexā€ (a factor that determines the amplitude of the modulation) was achieved with a simple Math.log10(frequency) function.

Late Tuesday and most of Wednesday was spent working on getting a queue of sequences to run. I had previously gotten multiple instances of what I call PulseMotif to play in the ā€œCircleSoundsā€ demo, where multiple sequences loop concurrently and have their pan and volume altered by the position of circles on the screen. But I hadn’t done the thing of having a new sequence start when another ends. The bigger goal is to have not only sequences possible, but real-time branching in the selection of which sequence to play next.

Anyway, I got a simple chain of three sequences to run smoothly yesterday. It is a bit clunky, but I think the key idea is a good one. Instead of focusing on various Sequence queueing/handling objects, I wrote a PulseMotifListener interface, and the player-code for the PulseMotif objects now sends out messages marking the beginning, looping and ending of a sequence to registered Listeners of that PulseMotif. (A similar thing happens with individual Notes played by my FM Synth implementation.) The testing code had an inner class that implemented PulseMotifListener, and it handled the removal of the finished sequence and the start of the next within the implementation of its pulseMotifDone() method. And it ran successfully, as far as I can tell.

Today, I plan to work out the logic where instead of a simple chain, I have a pool of options and state variables are used to select a sequence from the pool to chain when a given sequence ends. I’ll try and get a demo of this up soon if it works.

Added rain effects to TF, and continued playing with the Sky settings.
It almost feels like my graphics are a lot better than the actual game they present.
It doesn’t say much, but I mean this game looks like much more than it actually is IMO.

In that case you just have to improve the actual game :wink:

Ran across a pixel art program: https://dunin.itch.io/ptop

good old dx7, owned one back when ;D

sounds like a straight forward state machine creating responsive sounds, looking forward to it :slight_smile:

Got my first paycheck for my summer internship :slight_smile: 3rd year coding with this company.
Also randomly working on a genetic algorithm thing for cars. Randomly generates a chassis and wheels + terrain, then pits the cars against one another. I have all the simulation stuff done, now I just need to concatenate all the varying info into a ā€œgeneā€ to use for breeding.

Check out the code here if you want: https://github.com/CMatri/CarGenetics

Written last exam in this semester… And got accepted on summer internship I wanted literally hour later (first in my life as well)! :slight_smile:

Bought my dream car, the Subaru WRX! She’s a 2017 WRX in the base trim with a manual transmission in Lapis Pearl Blue. I really have to thank some of the members here for putting up with me in the beginning, if I had been turned off of programming I would have never been hired as a software developer and I wouldn’t be the proud owner of my favorite car. I truly have to accredit the beginning of my career to this site. So thank you everyone!

Have a picture taken with a potato!

I’ve been working on my 2D OGL rendering wrapper, I think I can now see what I’d like to make. My ideas are still a bit foggy, so I’ll talk about them a little later on.
Anyway, I now have a solid way to display strings in any font: about 250ms for the first font’s initialization, about 30-50ms for the next fonts, followed by 0-1ms to reinit them each time the OpenGL context is destroyed and reopened. Unfortunately I have to instantiate a same font twice if I want to change its size.
Text can then be rendered in any colour, skipping lines after words that would make the line width go off-limits, etc.

J0 :slight_smile:

I decided to redo TritonForge’s terrain generation system and so far, the results are amazing. Worlds can be much bigger and they generate like 3x as fast as before! Mountains are higher, valleys are lower. There are also plains generated every once in a while, so worlds are very different now from seed to seed. The caves also use a vein-esque system to generate now and I like it more than when it was just straight perlin noise.

(A 3500x2000 world or 2.275km x 1.3km when you take into account the character’s size. The character is ~0.6m x ~1.3m)
It is not done yet, but it shouldnt take long to add ores and stuff back in.

The generation uses a Java port of the C++ Accidental Noise Library, and it can be found here: http://www.java-gaming.org/index.php?topic=29439.0

Spent a couple hours changing most of my rendering code to fit zooming; however, whilst zooming onto the origin (the center of the display in my case) works fine, trying to zoom onto something else is kinda tricky… I’d really appreciate it if someone could provide me with a good paper about that :slight_smile:

J0

Zooming out/into a specific position (such as under the mouse cursor) is really simple and just like rotating around a given position.
When you use OpenGL, for example, then you first apply a translation to translate to the scaling origin, then apply the scaling, and then you translate back (by negating the first translation). You then pre-multiply this transformation to your modelview matrix. Done. :slight_smile:
Working example with LWJGL 3 and JOML here

EDIT:
the latest development version 1.8.2-SNAPSHOT of JOML contains new convenience methods to scale and rotate the view/camera around a given position: [icode]Matrix4f.rotateAroundLocal/scaleAroundLocal(…, position)[/icode], which is shorthand for:
[icode]modelview.translateLocal(-position).scaleLocal/rotateLocal(…).translateLocal(position)[/icode], which performs pre-multiplication and is itself a more efficient way of doing: [icode]tmpMatrix.translation(position).scale/rotate(…).translate(-position).mul(modelview, modelview)[/icode]
When wanting to scale/rotate an object and not the camera around a given point, omit the ā€œLocalā€ at the end of the method names.

@KaiHH Thanks a lot I didn’t know about that at all! I was trying to manually adapt the positions at which I was drawing every single element… :persecutioncomplex:

Added video scaling and real time dithering just for some retro fun :slight_smile:

Technically I did this 27 days ago, but who cares!

I was bored and ported the ā€˜par easings’ one-header library from here to Java. The code can be found here (Warning: No documentation): https://gist.github.com/Longor1996/e6f0c0c7f6208859917b7fe992e0045c