| |
Chase That Feeling [2009] |
Released At :
Syntax 2009
Achievements :
Mixed Demo Competition at Syntax 2009 : #1
Credits :
SIDs used in this release :
Download :
Look for downloads on external sites:
Pokefinder.org
Production Info Submitted by A Life in Hell on 2 November 2009
I was going to write a c64 note for this, but conjuror uploaded it before I got the chance :). So I'm gonna throw the text I had written for the note up here for all of your curio's sake :). I cut out the personal stuff, tho, since that really belongs in a c64 notefile and not csdb :).
General Stuff
-------------
Most of the work on this demo was done between 2am friday night and 7pm saturday afternoon. I had the idea in my head for a while, and I had a couple of things coded (the non-transparent kefrens bars, the circle plotter and of course the rotozoom stuff).
The music is a cover of Hoobastank's "My Turn" from the album For(n)ever. I always loved JCH's "Give it up" and Agemixer's "Freestyler", and wanted to do something similar, but never gort around to working it out. So this is my first attempt at that, and obviously.... it has some problems that I will get to in a little while. But first some theory about how it works.
So if you read the articles in the HVSC 10 years collection, you'll know the basic theory of how you do speech sounds on a c64 - one channel is the carrier, which is the frequency of the speaking voice, and one is the modulator, which is a ring modulation, sync, or both. If you're Agemixer, filter banks are also involved :).
In any case, the codec used here works kind of like that. I use a phase vocoder (that I suspect has an occasional bug!) to get the base pitch of the tone, and then try different modulation frequences until I find the closest match (based on the magnatude portion of an FFT calculation). If people are interested, I will release this tool at some point.
I have a parameter in that which controls how often the sid is updated. I did 25fps to make everything fit into ram. In retrospect, I suspect given more time I could have free'd up a little more ram and made 50fps work, given the changes to the loader that I made after I'd made the 25fps decision, which sounds a bit better. Cest la vie - I thought about doing a 100% version of this with a bunch of bugs fixed, and maybe including that one, but I don't think anyone cares enough :).
But back on point. So in order to get intelligable output, I ended up dealing with five parameters - two voice frequencies of eight bits each, two volumes of four bits each, a waveform of three bits ($11,$21,$41,$81) for the carrier channel and a modulation type of two bits (1 bit ring, 1 bit sync) for the modulator channel. This gets compressed into four bytes per updated frame.
The instrumental part of the song was done in a single track in ninjatracker 1.02 (I think 1.02), then patched the player to only play a sid channel, mostly because the rotozoom part relies on a music player of no more than 12 rasterlines to achieve 50fps. Ninja takes 4 rasterlines, and voice player takes 7. There really is no excuse for it taking 7 rasterlines other than some shitty, shitty code on my part.
The replayer code has a couple of major points of shittiness, the most obvious one being the classic problem for anyone who does sid programming - you'll notice that I said that I needed to set two volumes.... so obviously you can't fucking do that :). Quick sid theory lesson for those not initiated: there is a "feature" in the sid where you can change teh sustain _down_, but not _up_ without a retrigger. You can do this after having the ADSR at zero for three cycles or so (might have been five, i forget now), which is pretty inaudable. But, the fastest attack is 12ms or so, which is half a frame, whcih causes a nice audable click. I originally had the filters turned on to attempt to deal with that, but I actually _forgot_ to turn them back on after turning them off for testing reasons. I don't know if it's really much/at all better though.....
So anyhow, the net result is that you end up with something that is vaugely in the right direction of there, but obviously not acutally totally brilliant, due to a combination of bugs and stupidity on my part. But I still thought it sounded cool, and some of the other people I showed it to thought that it sounded cool, and besides, I was already committed ;). I think it's one of those like/hate things again. One day I will learn not to do that.... but today is not that day :).
But back on topic, once I've turned the sample data into sid data, i cut it up into blocks and stream it from the disk into a 4k ring buffer from the loader routine. So you end up with code that looks like:
loadPart:
while ringBuffer needs data:
loadMusic
loadPart
while ringBuffer needs data:
loadMusic
in an effort to try and keep that buffer nice and full. And it mostly works... i mean, for obviously small values of "works". But it also puts some stress on the loading times, which is not something I considered until I wrote the ringbuffer code at 5am on satuday morning, and realised that all of my loading times doubled. But of course they did... duh, any fucking moron could have seen that coming!
Rotozoomers
-----------
The rotozoomers run at 50fps, and are an enhanced version of the routine I used in the syntax party invite (primarily, with many of the carry errors fixed), which was an enhanced version of the one used in still not a scener (but that one was limited to 16x16 textures, which suck, and it ran at 25fps), which was a trick that was invented by Axis and AEG in any case.
The second rotozoomer actually does correct interlacing/dithering by having the rotozoomer defined as four bitplanes, and applying the dither/interlace at plot time rather than just having a dithered image. Also, I stole the texture for that from TRSI's DTV demo "Misery 3", which was pretty much the entire reason I coded this version of the rotozoom. The "WOW" texture was drawn by _V_, who also helped a lot with sinuses and stuff :)
Kefrens Bars
------------
The kefrens bars use exactly the same trick that Crossbow used in Demus Interruptus, and that HCL used more in Interruptus Retriggerus. I just did some automatic cycle counting speedcode in order to increase the number of them per frame (264 of them, despite the typo in the demo claiming 263 :)). I'm actually quite happy with the routine, it came out pretty well and surprisingly smoothly.
But what I really wanted to code, was transparent ones like Radiantx did in Faux Visage, but I sort of figured this wasn't going to happen until Icycool goaded me into it at 5:30pm - so I had the routine working using the python (/home/jaymz/c64/genRadiantx.py) code generator by 6:00pm, and got the c64 speedcode generator half working by 6:30pm (I always prototype speedcode on the PC, and then write it on the c64 later. I have a plan to actually write an assembler that does this for me....). Honsetly, I think these are the best looking routines in the demo, which is ironic because they were the easiest to code. That said, the code is completly fucking terrible (in particular, it does at least one more R/W cycle than it needs to, at least some of the time), and from the next day perspective of sobriety, I already know how to speed it up a _lot_. It's 163 bars, btw, but they're only 4 pixels wide like the ones in faux visage. I realise now how to make them wider, but I was too fucked up to manage this on the day :).
Interference
------------
So if you saw the mac classic demo "3 inches is enough" by Unreal Voodoo, you'll recognise the look of the interference circles - I coded this after seeing that demo. Anyone who saw beertime iva from dekadence will recognise where the technique came from, or at least would work it out when the filename internally is britelite.ass :). The trick is, each charblock has exactly 8 pixels defined within it - using the standard 2x2 resolution with every second pixel being dead, as made famous by Real/Resource+Dreams. You then just eor together entire charblocks at a time, meaning you can do a full screen interference in 1 frame. So I'm interlacing this to calculate every pixel, but only half of them are drawn per frame, so you know. I have a version of this which deons't need the interlace (or can have colour with interlacing), due to using a 4fli mode, but unfortuatly it currently takes 130% of a frame, which is completly not acceptable - interference is an effect that rarely works at less than 50fps. But hey, that's what optimization is for, right? :)
Circle Picture
--------------
All the credit for circle picture goes to _V_, who did the actual picture (the routine imports SVG files) and presented the idea - I'm just a humble codeslave :). The circle drawing routine is not the best.... I have a version which draws less, but it ironically cannot draw laerge circles as fast for a bunch of dumb reasons. But since everyone liked the look of this, I didn't worry about it too much :). The original idea comes from an amiga aga demo, btw, with a name that I cannot spell right now.
Static Graphics
---------------
Okay, in order:
Picture #1 - Girl with glasses. Hires Bitmap, is a cheap party convert of my friend Kate. I needed to hide some loading.... I didn't touch this one up at all, just convered it with my command line conversion tool
Picture #2 - Title Picture. Interlaced AFLI/ECI, made in Truecolour Trip again, which I have since kind of broken. For those who remember, it's my PC based editor that is basically a hacked up gimp that hooks to a a c64 via ethernet and does realtime wiring of the image you're working on and allows you to tweak parts of the image for astetic reasons, essentuially because I wanted photoshop for c64, because I suck at graphics but am a multimediot, as Deekay put it years ago :). The girl in the picture is my friend (exgirlfriend, whatever) Jenn, who is the same girl that I used in Fuck the Scene. The occasional interlace judder seems to be either loader or packer related, but I don't know which...
Picture #3 - Girl with tear. Hires Bitmap, this is a copy of a picture from the PC demo "Forever Dreaming" by acme in 1997. This was the first thing done in the version of TruecolourTrip that handles non-interlaced and non-fli modes. I originally did it as an interlaced non-fli, but I needed to save another 8k of ram, so I moved back to non-interlaced at the last minute. A shame, the interlaced version looks better, but I'm acutally really happy with how this came out. Hires being a pain in the ass mode that I am growing to love...
I know a lot of you out there find code-assisted graphics to be offensive on a personal level, and, well, I guess all I can say to that is that I know and respect how much work it is to hand pixel something, but I'm a coder, and coding is how I look at the world... but then, I'm not entering a graphics contest, either. But still, I know. You don't like it. I get that. But I find the challenge interesting, so, uhm, yeah, I suck.
Hidden Part
-----------
It's hidden. So of course I'm not gonna write about it in the note :)
|
|
|
|
| Search CSDb |
| Navigate | |
|
| Detailed Info | |
|
| Fun Stuff | |
· Goofs · Hidden Parts · Trivia
|
|
| Forum | |
|
| Support CSDb | |
|
| |
|