I wanted to write my blog in the web visual novel game engine I wrote two years ago, but I thought that it’s a hassle to maintain compared to plain old HTML files… I was too ambitious.
Anyway, while I’m back for a brief moment, I updated the following:
Well, that’s it! I hope the next update won’t take me another 2 years.
]]>The original GME library used SDL, which draws the oscillator by pixels. ZillaLib did not expose such a method, so at first I tried using DrawLine()
, but unfortunately, drawing a line 512 times per frame (the amount of samples used for this demo’s audio buffer) was too heavy – the buffer was constantly starved of audio as the canvas struggles to draw the oscillator at best ~20FPS.
I then had the clever idea of using DrawPolygon()
instead, which I believe uses a single draw call but with 512 vector points. The performance was vastly improved – almost 60FPS with very rare audio starving!
The controls this time are all available on the screen, for mobile-friendliness! However, if you want to use your keyboard:
Left / right arrow keys = Prev/next track
1/2/3/4/5/6/7/8/9 = Toggle audio channel on/off
Spacebar = Toggle pause/resume
- / + keys = Decrease/increase speed
E = Toggle echo (this probably doesn't work...)
0 = Reset audio channels and speed
At this point I’m satisfied with how easy-to-use ZillaLib is. I’ll try to make a simple game as a warm-up toward my pet project which I’ve been planning for months now… Probably an Asteroids or Flappy Bird clone.
The code for the ZillaLib GME can be found here.
]]>What better way to get started with ZillaLib, than to write a port of PixiJS’s BunnyMark to roughly gauge the performance of the framework! Somehow it performs really poorly on Chrome, but on Firefox it’s smooth as butter.
I’m not going to bother with improving the framerate or performance for now since I’m very unlikely to draw more than 100 sprites on the screen for my first few web games.
Controls:
Left/right click on screen = Add bunnies
Spacebar/Return = Reset
I love how ZillaLib is pretty easy to use! There were some initial hurdles, but the author has been very responsive and helpful in helping me resolve the bugs.
I’m a little sad to abandon Wyngine at this point, but it’s a small compromise (resisting the reinvent the wheel) in order to start creating stuff that really matters to me (web games for my blog, maybe).
The code for the ZillaLib BunnyMark can be found here.
]]>Controls:
1/2/3 = play song
spacebar = stop playback
The MIDI player I’ve written is primitive and hacky. There are some quirks/bugs which I didn’t bother to fix:
My original goal was to have a functional MIDI player which I can manually map channels to play basic sine/triangle/noise voices, to simulate 8-bit music. I discovered that MIDI file specs are deeper than I originally thought, which means I would lose a lot of subtle sound behaviour if I do not handle the MIDI events accordingly, such as Tempo, Control and Program changes.
On top of that, although parsed MIDI files are a lot smaller than WAV data, it’s ultimately less efficient. I could write additional logic to convert the MIDI events into WAV data, but I didn’t want to spend more time reinventing the wheel, especially since I know there’s other libraries which can already do what I want to achieve, and a lot better at that too.
While I was researching MIDI-related stuff (and emulator-related articles especially the NES APU), I came across ZillaLib, a 2D and 3D C++ game framework which literally does everything I have wanted to write with Wyngine.
It took me a while of contemplating. I had to accept the fact that I would never be able to write a library as feature-complete and efficient as ZillaLib within a reasonable time-frame before I can start writing games, so I’ve decided to stop working on Wyngine and just proceed to making games instead, using ZillaLib.
Wyngine was a good exercise though. The experience itself up until now (from image and ASCII font loading, to parsing MIDI files and writing playback logic) was an interesting and informative journey.
]]>Now there’s polyphony! You can play more than one note at the same time, and they’ll be mixed into the audio buffer. I never knew it was trivial to mix sounds (literally, just adding the samples).
Controls:
1/2/3/4 = change instruments
Q/A = increase/decrease frequency
E/D = increase/decrease volume
UP/DOWN = increase/decrease octave
ZSXCFVGBNJMK,L./ = piano notes (A, A#, B, ... G#)
This time I’ve added envelopes. You may notice that the sound of each instrument (I believe they’re technically called oscillators) have a softer feel now.
Controls:
1/2/3/4/5 = change oscillators
Q/A = increase/decrease frequency
E/D = increase/decrease volume
UP/DOWN = increase/decrease octave
ZSXCFVGBNJMK = piano notes (A, A#, B, ... G#)
Things I noticed while working with audio (so far):
The audio will not play if you visit the page from another domain (last I tried was Facebook). The easiest way to fix this is to visit the page manually (e.g. navigating to another page in this domain and back to this page). I’ll probably have to tweak Wyngine to initialise the audio when players click on the screen for the first time. Even better, I could even add a loading screen to show resources being loaded before the game actually players.
There is a delay between the keypress and the synthesized sound actually being audible. This is inevitable because audio only gets generated when the key is held; Thus the audio buffer needs some time to actually be filled before being sent to the device. Off the top of my head, I could try generating and storing audio samples to memory (ala loading music files), and playing the sound like an audio clip.
The audio crackles (lags) during playback sometimes. I think this is just because my browser is slow (or starved of memory). It happens when I have several tabs open in Chrome. When I open in a single tab on IE or Firefox, the sound plays fine.
Trying to loop the sample index (the point of time at which the sound sample is being played) at every second will produce a noticeable click. You can’t see it in this demo because I forgot to enable this “bug”. I thought it would be trivial to loop the samples rather than increasing the sample count indefinitely, but looks like there is something I don’t understand about why this is happening yet.
Audio synthesis is fun! But I’m not really good at maths…
I continued work on Wyngine, and reached the first milestone in audio synthesis: Generating sounds.
Controls:
1/2 = change between sine and square wave
Q/A = increase/decrease frequency
E/D = increase/decrease volume
UP/DOWN = increase/decrease octave
ZSXCFVGBNJMK = piano notes (A, A#, B, ... G#)
It’s nothing fancy, and it probably isn’t optimised (you’ll likely hear pops, clicks and stutters)… But I’m happy that I finally understand a little bit about audio playback. I went down into the emulator development rabbit hole a little, and am truly amazed by all the work that some programmers put into emulating game hardware. Perhaps someday I can try writing my own emulator, but that’s something really far off in the future.
The next milestone is to introduce load MIDI files, and after that, to implement MIDI playback. If successful, I can probably produce extremely small-sized webgames; Because web games usually have large asset sizes (audio and graphic files). It’s something nice to dream about.
]]>Above is a demo of the keyboard: I’m using a mini-ascii font sheet, so as long as the keypress is a valid character in the mini-ascii sheet, it should render above. I only implemented two non-character inputs I implemented were backspace (deletes the last character in the string) and enter (adds a \n
character to the string).
The next (and last) feature for Wyngine 1.0 shall be a music synthesizer. Since I want to make retro-like games, it makes sense to implement an NES or Gameboy-like APU. It’s going to be tough, since I’ve never done emulation before, but it’s something fun to think about for the next few weeks.
]]>