Raw source and immediate archive at http://www.icculus.org/~phaethon/plan/ Entries are currently sorted in: Newest First Syntax (time and date in UTC, my local timezone is PST/PDT): [YEAR].[MONTH].[DAY] ~[APPROX. HOUR] [SUMMARY] [CONTENT] 2006.10.08 ~07 My First (Personal) Soldering Project I applied my non-existent soldering skills to a little project trying to fix a non-working dance pad (non-mainstream brand). Lessons I learned in soldering today: * tin the damn tip. It really really helps, even if it forms a gigantic ball of solder on the tip. * shortening wires that are too long is easier than trying to extend it. * desoldering a mistake can get messy and crappy. * applying iron to a wire's end can still burn the nearby insulation because the conductive metal, of all things, gets hot. * holding onto the wire near the heated end is a bad idea. * the spent solder on the tip needs to get scraped off often. * scraping it off with a wet napkin does weird things to the iron. * breathing burnt insulation hurts. * breathing burnt flux also hurts. * using lead-free solder gives me warm fuzzies. * using rosin core doesn't. * diag cutters help with those spiky solder points. I should get some. * when measuring the resistance of a trace, it helps if the trace is not already covered in epoxy. Now I need a cheap-o USB PC gamepad to hook up this puppy. And remembering to attach the negative terminal properly so that the electrolytic capacitors can do their jobs. 2006.09.23 ~15 So like there's this trip with a student group at UCLA that was planned out three months ago, but somehow I marked Sep 29 and the date of the trip was never mentioned again since, so when mailing list chatter about the trip picked up a couple days ago, I got a bit suspicious, and got confirmation that it's for today through Monday, not next week. I seem to be really bad about synchronizing with group-known information. I may need to work on that this school year. 2006.09.13 ~13 So I was reminded that I... (a) have a .plan (b) have a dead/resurrectable Q3 mod cvs respository sitting on this server. I should do something useful about them. 2005.04.14 ~07 vidcap and 3D Well, finally, I got video-capture and accelerated 3D both working again, again. Radeon 7200 vidcard with VIVO, latest X.org from CVS, latest Mesa from CVS, latest drm from CVS, linux 2.6.11.7. X.org CVS at this point has incorporated the video-capturing stuff of gatos, so the ati.2 and ati.4.4.0 stuff from the GATOS project are not needed, and in fact break the install. A major snagging point for me was the kernel modules. Basically km_api_drv.ko and km_drv.ko have to be loaded before drm.ko and radeon.ko get loaded. Otherwise radeon.ko initializes the vidcard first, and km_drv's probe() never gets called. 3D failed, but vidcap worked, using stable Mesa 6.2.1 (mesa_6_2_1). Blindly jumping to Mesa CVS finally got 3D working. Furthermore, glxgears runs a tad faster than I remember (1400-ish now compared to what I think was around 1250-ish way back). 2005.04.07 ~05 another suspiciously scammish phone call Got another suspicious phone call, this time offering $200 in coupons for a shopping spree, mentioning enough department store names to trigger Carnivore. Also, I was told this month was Consumer Appreciation Month... but that it was really in March. When I pressed about the previous "Consumer Appreciation Month" call from January, the caller sidestepped the question quite overtly, trying to rush through a script. Quite obviously a script, since he didn't seem to want to sidetrack from his side of the conversation. The repeated words were also a giveaway of a script; I kept interrupted and he'd keep trying to resume with the exact same words. I don't know about other people, but reading off a script gives me the impression of an ulterior motive in play. The clincher was when he mentioned free movie passes in addition to the coupons, good for ANY MOVIE (no exceptions!). When pressed for names of which theaters, he listed so many theater chains, even those I know aren't even remotely close to California, that all I could do was just retort "That's bullshit!" and hung up right there. Note: free movie passes, espeically those given to the unwashed masses (me), have close to 0% chance of being honored for Super Duper Ultra Premiere Specials, such as Day 1 of the next Star Wars movie. That, and no way in hell every movie theater in the nation/world will simultaneously decide to honor a blanket movie pass, franchising notwithstanding. TANSTAAFL -- Economics 101. 2005.01.18 ~08 Content-free ads of "Million Dollar Baby" The ads for the movie "Million Dollar Baby" are fast approaching spammish. First of all, I'm hearing it all over the place (radio in car during commute). Secondly, there's nothing substantiative in the ads. It's all "this person said...", "that group nominated us for...", "these editors proclaim...", "look at how many thumbs up we got", and so on. Not even a slight hint at the plot of the movie. The closest thing to a plot hint was a comparison of its powerfulness(?) to "Mystic River". But otherwise completely content-free and based on what someone else is saying or doing. The movie makers aren't saying squat about it. All this makes me seriously doubt the value of the movie. What the hell is the movie about? No one's saying. Hrm... maybe it's a pointless movie. 2005.01.05 ~04 Gasoline vouchers? So this is the second time I got a call offering vouchers for $200 worth of gasoline. This time claiming to come from Shell Oil Company. The first time I got such a call was a few months ago, and I got really suspicious over it. I forget the details of that call, aside from that the conversation somehow degenerated into a "what? I can't hear you!" shouting match, then cussing the other end out as I hung up the phone. This time, since it was the second of such calls, I decided to make a note of it somewhere. As it only happened minutes before I started writing this entry, the details ought to be mre recallable. So, the call comes in, I answer it. First hint something was amiss, there was a lot of noise/chatter in the background. In fact, I thought the call was coming from an analog cell phone. The second thing was that the caller, unlike the more legitimate telemarketers, did not open with "is such-and-such there", but instead goes off with "Hi, my name is Charles, and I'm calling from Shell Oil Company." For some reason, the fact the guy gave his name (if that's his real name) right at the start raised a red flag as well. Thirdly, the caller mentions my phone number was selected to receive $200 in vouchers for gasoline at any Shell station. The mention of "number" rang in my head. Phone number, as opposed to name, address, or a frickin' lottery ticket. It's a really strange way of selecting a "winner", using a phone number. Most of all was the material being pushed. USD 200 of gasoline is a lot of money, a lot of gasoline, to be given away for free. With the price of gasoline around here, that represents approximately 90 gallons; for my car alone approximates to 2250 miles (um... 3500-ish km) of driving, which I think is enough to drive to the nearest Canadian border crossing and back. The sheer amount of money being given away for nothing was just staggeringly ridiculous. The other thing that got me thinking was the notion that my phone number was chosen more or less at random. If that were the case, they (the purported gasoline company) may as well just hand out gasoline lottery at the pumps (station ownership issues notwithstanding). But even that, being as random as it is, may as well be just a general price reduction of all gasoline products. In other words, there something bizarre about handing out vouchers/discounts to random people when that wouldn't be much different from just an across-the-board price reduction. The final straw was when the caller said, basically, that he needed to verify my phone number, and read back my phone number. Or the number he dialed. Something deep inside me felt very insulted by this reading back. Perhaps because he, the very caller, said this, my, phone number was selected, then asking if the number is correct. Couldn't he ask if the number was correct *first*, then start the spiel? Asking later felt like he was insulting my intelliegence (which he probably was, a google search later). My response was silence. Utter silence. The guy eventually hung up; when I hit the 'off' button, the display showed 1:05 of talk time; even if it's of minimal consolation, at least the caller's phone bill got rounded up to two minutes (or is that even a good thing in retrospect...). Now for the google result. I googled for "Shell Oil Company gasoline voucher". Lo and behold, the only hit that had all the terms in a meaningful position was a warning about an identity theft scam: http://www.wate.com/global/story.asp?s=2666657&ClientType=Printable Basically the whole spiel about gasoline and vouchers is a ruse to grease up the victim to start handing out personal information. Detailed personal information, along the lines of every damned digit on their personal check -- routing, account, everything. Now, if this caller is part of a scam ring, then someone else's money and life was used to pay his phone bill. Either directly (ID-theft phone purchase) or indirectly, such as, oh, draining someone's checking account down to, and perhaps even past ("overdraft protection"), the last penny. Which is why now I'm now wondering if it was such a good thing to deliberately crank up "his" phone bill to the next billed minute. Overall, though, my cynicism/pessimism, paranoia, and wandering thoughts had stopped a dumb, and potentially dangerous, phone call early. Now if only ATT would permit me to "reach out and strangle someone." 2004.11.27 ~08 How times change (inet). Via random perusals, I found this joke page with an mdate of 1996 Feb: http://users.vnet.net/matjohns/humor/10.ways.internet.worse.html ("Top ten ways the internet could get worse") Relevant Google searches peg a date predating mid-1995. Around this time, Microsoft Windows 95 started, Intel Pentium CPUs were clocking in at around 100 MHz and still stinging from the FDIV bug, and WWW was just starting to bloom with Mosaic and Netscape Navigator. What's scary is how much of the joke's content has come to pass. > 8. Home shopping "network". Online shopping (e.g. amazon, e-bay). 'nuff said. > 6. Sun internet servers replaced with pentiums. It's pretty clear the pentiums referred to are the original series pentium, the i586-equivalent, and not Pentium IV, but still, a good number of online servers these days are running x86-family CPUs (e.g. Xeon, Opteron, ... Celeron...). And let's not forget the vast sea of wintel machines ripe for zombification. > 5. Dan Quayle appointed head of "bandwidth expansion tiger team". I think President G.W. Bush (#43) is pushing for more spread of high-speed net connections in homes across the US. But then, so had Pres. Clinton (#42), but Quayle was VP under Pres. G.H.W. Bush (#41), which sort of compounds the eerie-ness factor. > 4. Free netcom account with purchase of big mac. I get a weird deja-vu-ish feeling that something very similar had come to pass. The following come to mind: juno, netzero, gmail, hotmail. I can't think of any in particular associated with purchase of fast food, though. On another note, the significance/meaning of "netcom" has faded with time as well; I have no idea what "netcom" is supposed to mean in this context, and a naive lookup of www.netcom.com redirects to www.earthlink.com; www.netcom.org is beyond my comprehension. > 3. Gameboy web browsers. As with the pentium bit, the referenced device is clearly the Z80-powered original Gameboy, and not the contemporary StrongARM-powered Gameboy Advance. Regardless, we now have Gameboy [Advance] web *servers*: http://www.fivemouse.com/gba/ > 1. Two words: "Microsoft Network". Indeed. www.msn.net. ph33r. 2004.11.23 ~06 my e-mailbox My mailbox has been overflowing with mostly virus payloads, and a slowly growing number of spam. Also, recently I have received a sudden flow of mail regarding the various programming projects I worked/am working on. As a result, I have determined obfuscating my e-mail address on my web pages is no longer productive, and have changed as many as I could bother to change to transparent mailto: URIs. 2004.10.25 ~16 Fujitsu Lifebook S7010 notes I'm keeping notes of my progress on my notebook at http://www.icculus.org/~phaethon/notebook/lifebooks7010.html The target audience is people seeking to get GNU/Linux running on the notebook, so I aim to minimize historical notes and journal-like rambles as I am wont to do. The link for it is already listed on http://www.linux-laptop.net/ 2004.09.28 ~22 New notebook, Fujitsu S7010, installing Linux Got a new notebook computer yesterday, a Fujitsu S7010. It's actually a refurbished machine, which may explain some of the variations from the posted specs. Intel Penium M 1.7GHz, 512M RAM, 80G HDD. WLAN is an Atheros adapter of some sort (PCI ID 168c:0013); the built-in ethernet is a Broadcomm gigabit adapter (PCI ID 14d4:165e). This machine apparently also has built-in bluetooth, a nice bonus. There's a hardware kill switch for the wireless stuff on the front bevel. I first booted this machine with Knoppix 3.2 EN, but nothing was usable, not even network. After waiting for Knoppix 3.6 EN to download and burn, I booted that. Suddenly just about everything worked: wireless, wired ethernet, bluetooth, infrared... dunno about modem. Also that SpeedStep thingy kicked in under Knoppix 3.6, whereas the CPU always went full-tilt under 3.2 (read: very very hot). First order of business was to image the hard drive. This took close to three hours, shoveling 80G through gzip then 100baseT onto a remote machine on the LAN. I want to image the hard drive so that I have a known starting point in the event of total hosing. The final archive weighed in at 4.9G, quite a bit more than a DVD+R's capacity. I may either split it into a DVD and CD pair, or just keep it on the desktop's hard drive. Next I resized the NTFS partition until it barely had enough room to breathe. It was something like 9.43G used, so I use qtparted to resize it from 77.8G down to 9.6G. There was already some sort of recovery partition on the drive as well (FAT32 labelled "DISE_BACKUP", apparently for "Disk Image Special Edition"... imo, I don't know what's so "special" about something that could be accomplished with dd(1) and bzip2(1)). After resizing the NTFS, I fell back to familiar grounds and ran cfdisk to partition the drive to my liking. I carved out a 9.6G /, 2 of 4.2G swap (one for suspend, the other for regular swapping), and another 9.6G for /home. Then I formatted them, using Knoppix. Next came about five hours trying to get from a running Knoppix system to a Debian installation. To distill it, it basically come down to this: Installing Debian sarge (testing) from a running Knoppix session. Under Knoppix, mounted what would be /home as /mnt/hda6. Downloaded debian initrd, vmlinuz, and sarge-i386-businesscard.iso to it. Then I set up grub to use this partition: "grub-install --root-directory=/mnt/hda6 /dev/hda". Rebooted off HDD. At the grub prompt, "root (hd0.5)" (which is linux's /dev/hda6), then "kernel /vmlinuz root=/dev/ram0", then "initrd /initrd", then "boot". This booted into the Debian installer, which found the relevant .iso image, then things went off from there. In the installer, I then selected the originally to-be "/" to be Debian's "/", since the installer insists on being able to mount / during the install process. At the end of installation, Debian pointed GRUB at proper new root partition. On reboot, the rest of Debian installation went smoothly. Now to pick and choose packages... 2004.09.26 ~01 Radeon 64DDR, X.Org 6.7, GATOS CVS, linux 2.6.8.1 Finally I got both 3D and vidcap simultaneously again, after I don't know how long. Prior to today, I had two sets of X installed, one that works with DRI but no vidcapping, and the other with vidcapping but no accelerated 3D. To make matters worse, I couldn't straighten out the modules mess, so using the other X install meant having to reboot into the other kernel as well (linux 2.4.26 with vidcap, linux 2.6.7 with 3D). I compiled stock X.Org 6.7. The radeon (radeon.ko) module was from the X.Org tree under programs/Xserver/hw/xfree86/os-support/linux/drm/kernel (I cd'd to there so many times I have the path memorized by heart now). The KMultimedia modules were from GATOS CVS as of 2004.09.26; these are km_api_drv.ko and km_drv.ko. I used the ati.4.4.0 drivers from GATOS cvs as well; had these installed into the XOrg tree with "make install". Upon running avview (also from GATOS cvs), the kernel module (km_drv, I think) kept complaining about the Radeon memory controller being misconfigured. Searching the GATOS mailing list, I came across a post from Jan 2003 -- http://sourceforge.net/mailarchive/forum.php?forum_id=5014&style=flat&viewday=14&viewmonth=200301 -- indicating that I may skip the check causing this error messsage if I were certain the memory controller was indeed configured properly. I assumed it was, since other posts implied that ati.4.4.0 properly configures the Radeon memory controller for linux 2.6.x. So I edited km/radeon.c so that it always returned 1. Testing avview... well, avview from CVS doesn't seem to vidcap properly, so I reverted to the older version (which has always worked before), which was from GATOS CVS 2003.03.22. Testing the recorded MPEG with xine, I was satisfied that recording actually worked. I tested 3D first with glxinfo (said Yes for Direct Rendering), then glxgears (got 1300fps, 200 if software rendered), then Blender, then finally Quake 3. Everything worked as expected. I had checked out DRI, but those drivers seem to conflict in existence with GATOS's ati.4.4.0. So no Mesa cvs either. As circumstances have it, XOrg 6.8 is already released, but someone else has tried GATOS on XOrg 6.8, without success. In summary, linux 2.6.8.1, XOrg 6.7, GATOS cvs for km and ati.4.4.0, old GATOS avview; radeon.ko from XOrg 6.7, km_api_drv.ko and km_drv.ko from GATOS km (with one-line change). On another note, km_drv.ko cannot coexist happily with fbcon. Best as I can tell, the fbcon calls dibs on the Radeon device before km_drv can get to it, so the kernel never gives km_drv a chance to probe devices. I wonder if there's a way for them to coexist. 2004.07.05 ~01 Making a fighter game On the Samurai Spirits Forever (SSF) forums, someone (else) has embarked on an attempt to create a Samurai Showdown-esque fighter game. http://samuraispirits.net/cgi-bin/ikonboard/topic.cgi?forum=5&topic=296 The general consensus seems to be against this fellow. Personally, I think it's doable. In any case, I've been working on my own fighter-type game for about a decade or so. Shortly after my introduction to Street Fighter II, I attempted to mimick it... in GW-BASIC. Well, I didn't get very far; as the years passed, I tried redoing it again and again, in Pascal, in C, and now Python (+ pygame). The forum thread on SSF essentially ends on an ultimatum to deliver something by July 25, twenty days from now. I decided to take this chance to try to finish my own version of a fighter game. I probably won't have anything decent by the 25th, but I figured I may as well build up the underlying technologies. I intend to journal my progress, to extract components reusable in other languages. If I can figure out where to start documenting... 2004.06.26 ~11 Radeon 7200 gatos, packet-cd (pktcdvd) So now I'm trying get back to online FPS gaming after a five-month hiatus due to a curious {video-capture} XOR {hardware-3d} dichotomy (long form short, I became a TV junkie). I finally managed to compile me a new X from the XOrg tree. The final stretch was finding the page of release tags, which finally got me a XOrg tree that actually compiles (fwiw, 'xorg-6_7_0'). For 3D drivers, it was the DRI tree. After some minor fiddling, it got installed, and glxinfo and glxgears seemed happy. Trying to retain video-capture, I dropped by gatos.sourceforge.net. For some reason, all the pages haven't been updated at all. And the CVS module 'ati.2' is outdated as well. Poring through the mailing list archive, I found there's a new module 'ati.4.4.0', presumably the set intended for XFree86 4.4. Well, it compiled cleanly for XOrg-6_7_0, so whatever. Haven't tried actually vidcapping since the kernel module "km" wasn't ready yet. Then I realized I was in ye olde linux 2.4. So it was time to bake a new kernel of the 2.6 variety. I got a DVD+RW burner back in late April. I've been using UDF and packet-writing for DVD+RWs. So I wanted to retain packet-writing under linux 2.6. Though packet-cd.sourceforge.net is the website for linux packet-writing, again it suffers from outdated content (it claimed latest patch targeted linux 2.4.0). Prior visits to the website and it's mailing list turned up a site that actually carries up-to-date patches, but the url is ridiculously long and complicated. On the off chance that google might be helpful, a search for "packet-cd" turned up the very site that carries the "live" packet-cd patches. 2004.05.23 ~11 Pokemon of the ancient past Oops. Forgot about my .plan. I'm not even going to bother finishing the prior post. On IRC, someone mentioned ye olde SNES game "Super 3D Noah's Ark". Fresh from a bout of Pokemon movies on Cartoon Network, my first two thoughts upon reading the game's title were "two of every creature" and "gotta catch 'em all". Early morning/very very late night being what it is, I started rambling to no one in particular on tangents. I pondered a fusion of the Pokemon "creature management" with Noah's Ark, in particular the Pokemon battles. So I started thinking of some rather ludicrous battle scenarios. Such as Kangaroo Rat vs. Blue Whale. Not only the size disparity, but environmental disparity as well (Kangaroo Rat requires to water; Blue Whale dies without copious water). Or arctic Seal (very cold temperature... on ark...) vs Komodo Dragon (mostly hot temperature... on the ark... simultaneously...). Basically, I kept runninng into pairings that would mean impossible (or at least requires space-age level technology) climate control given the ark's size. That's when a solution to this quandary hit me, courtesy of Pokemon. In the Pokemon world, captured pokemons (POcKet MONsters) are kept in Pokeballs. The Pokeballs remain a consistent size and weight, no matter the size and weight of the contained Pokemon, even when empty. Therefore, Noah may well very have had access to Pokeballs and Pokemon physics. The whole notion of getting creatures (in twos, no less) logically follows the mantra of "Gotta Catch 'Em All". All the more apt, as the entire surface of Earth was to be eradicated of all life. The environmental disparity is moot; Noah (or one authorized by such to act on his behalf) goes out and catches geographically-unique creatures (Kangaroo Rats, Kiwi, Lemur), then stores them in the ark in the form of pokeball-compressed creatures. Being self-contained environments, leaving the creatures in the pokeballs renders moot the issue of climate control in the ark (the captured penguin would not be exposed to above-freezing temperatures of the ark). A whale could easily fit within the confines of the ark, as they are (magically) reduced to something about the size and weight of a baseball. Or smaller, depending on the physics of Pokeballs (the animated cartoon seems to illustrate "unused" pokeballs as roughly the size of a marble). I don't have the dimensions of Noah's Ark off-hand, to roughly calculate the maximum potential capacity of the vessel. I imagine the number of baseballs that can fit in it would be staggering. Anyway, I find the notion of an ark filled with pokeballs to be easier to swallow than one that held orcas, desert foxes, sea lions, pirhanas, goats, and chupacabras within teeth's reach of each other. Noah lived in a Pokemon world. 2004.01.06 ~10 "The Purpose-Driven Life", by Rick Warren, Day 2 This entry is a tad late, but hey, I'm intent on recording my responses. - Point to Ponder: "I am not an accident." This chapter spends a good deal of time trying to drive home the point that one's (my) birth is not an accident, that there is a purpose (God's purpose) to it. All this presupposes the existence of God in the Christian form. I have yet to see anything that demonstrates why the Christian notion of God is any more correct than any other religion. Christianity isn't even the most dominant religion in the world (by sheer population count). Really, the only thing the Christian mythos has in Western Civilization is having been in the foothold since the Western's growth, and thereby being the dominant underpinning since. Just because it's popular doesn't make it right. I don't doubt there is a purpose to life, some obscure esoteric reason. But I don't buy into Warren's particular interpretation of life's purpose. - Verse to Remember: "I am your Creator. You were in my care even before you were born." Isaiah 44:2 (Contempory English Version translation) I don't know the context of this particular passage, but somehow I can't help but think this applies on so far as the (approx.) nine months prior to birth. But otherwise, I'm not gonna bother remembering stuff from a tertiary-(if not more)hand translation of an ancient book written in a living language (both source and destination), any more than I would bother memorizing Shakespeare ("modernized" or not). - Question to Consider: "I know that God uniquely created me. What areas of my personality, background, and physical appearance am I struggling to accept?" * my own meanderings 2004.01.04 ~06 "The Purpose Drive Life", by Rick Warren, Day 1 Well, in this book by Rick Warren, a chapter corresponds to a day, so Day 1 and Chapter 1 mean the same thing. - Point to Ponder: "It's not about me." True, it's certainly not about me. My lifespan is finite, so orienting life goals towards/around my own life is, in the long run, pointless. My mother has pointed out to me several times that my father (currently still alive, but does not participate in huggy-feely talks) has spent nearly his whole life trying to improve outcomes for my sister and me. This in and of itself has inspired me to care for children I have in the future. Children that grow up into extraordinary persons would be a meaningful legacy that I leave. Currently I subscribe to the notion that living beings strive to guarantee the continuation of their genetic line, which, in a sense, is a sort of continuation of one's life. This could perhaps be generalized to just leaving behind a memorable legacy, genetic or memetic. There are people that don't care to have children, but instead want to achieve great things. The foremost example that comes to mind is Richard M. Stallman and the GNU project. He certainly left a profound mark on computing, but had deliberately avoided having children to achieve that goal. Not something I want to emulate, but just something I ponder. Many times I've fancied the notion that all living things are all aiming towards a certain vague end-goal. That all genetic materials are trying to achive some kind of end state, something akin to the Gaia hypothesis. A twist to this idea is that all genetic material are merely trying to replicate eternally. Or that certain portions of the genetic material are trying to remain forever. In one sadisitic view, genetics could be viewed as some attempt at generating an infinite loop and seeing how long it can last. Regardless of the aforementioned views, they all point at life's purpose being beyond the current state of existence. One of the more depressing views is that the genetic material constructed my mind merely to help it (genes) propagate; it's depressing because it would tag my brain as a pawn in a game played out by strings of nucleotides. Abruptly changing subjects, many years ago I had decided one of the purposes of life was to leave behind something meaningful for society at large. A scientific breakthrough, an artistic insight, or a lasting improvement to government. To help others live better. Random fuzzy incomplete thought: perpetuation of genetic material modelled as eternal afterlife. Random fuzzy incomplete thought: the totality of quantum state transitions attributed to, or as, a supreme being. Random fuzzy incomplete thought: circular declaration... cosmos to purpose, and purpose to cosmos... life {subset} cosmos... subclassing inheritance... circular inferences?... - Verse to Remember: "Everything got started i him and finds its purpose in him." Colossians 1:16b (The Message translation) Forget it. - Question to Consider: In spite of all the advertising around e, how can I remind myself that life is really about living for God, not myself? OK, first off, I take offense at the suppositions inherent in the question. Namely, that this question places as "a priori" the very subject that is under discussion. To wit, that the purpose in life is living for God. I take offense, because the book is supposed to illustrate *why* this is so, and in the very first chapter, flings it at my face as being true from the get-go. In a more mathematical light, I see this as some hypothesis Q that is yet to be proven/explained, and before the first set of logic operations, poses a question to the reader presupossing the unproven hypothesis Q as true. For the time being, I'm just gonna gloss over this question, since it seems a very loaded question for such an early (first!) chapter. R.F.I.C.: Godel's incompleteness theorem. * my own questionings The author states the [Christian] Bible as being the Owner's Manual of life. My beef with this is why the Bible in particular. What puts it above the Jewish Torah? Or the Islamic Koran(sp?)? Or the Book of Mormonism? Bhuddist writings? Shinoism? Egyptian? The collection of Greek mythos? Wicca? What makes the Bible in particular any more "correct" of a owner's manual than other religious texts? As the first of three insights into your/my purpose, the author states "you discover your identity and purpose through a relationship with Jesus Christ". My gripe: does this mean people who lived in the B.C. years (i.e. before Christ's existence) were totally identiy-less and purposeless? What of those in more remote corners of the world who came up with their own ideals of life's purpose? Were/Are they ipso facto purposeless because their particular explicit purposeness don't involve a particular dude from Nazareth? The second of the three insights states "God was thinking of you long before you ever thought about him." Again, this raises the question of the B.C. era people. If they were so thought-of in great know-it-all scheme, then why were they born *B*.C.? This leads too easily to the idea of a a twisted master that likes to torment a limited few, like Sid in the "Toy Story" movies -- "the rest of you, get to sit on the shelves intact, but these toys.... muahahahaha!" I don't have any major beef with the third insight. Overall gripe: the general tone of the chapter makes me feel that life is one big game of... Starcraft. The author states that God has a purpose for each of us, and that we may succeed in life, and yet not fulfill our purpose. This sounds like something that could happen in a glitchy game of Starcraft: a dropship full of marines may accidently unload early and obliterate the Zergs, succeeding, but if they were originally ordered to wipe the floors with the Protoss, then they missed their purpose. The second insight of life's purpose also resonates with a game of Starcraft... any Starcraft player has in his/her mind the units desired to achieve some goal, from the very start of a game. If not, the player is thinking about the unit they're commissioning just before the resources are committed to create the unit (therefore counting as thinking of the unit before it was... erm... born). The third insight of life's purpose also rings with a game of Starcraft: "The purpose of your life fits into a much larger, cosmic purpose that God has designed for eternity." OK, so a game of Starcraft does not go on for eternity, but the engineers busy collecting resources really has no business knowing wtf the scientists in the science labs are doing, much less why marines are sitting around behind all the defensive siege tanks. IOW, each unit does not know the ultimate goal of the player, but they can carry out the orders assigned to them, which may lead to the outcome desired by the player. Each unit goes about its own business, but collectively, this can lead to a larger goal (i.e. wiping out all opposition). I'm not contesting insight #3, just that it paints life as a giant mutation of Starcraft. I haven't put down even half the thoughts floating about in my head. A good chunk of the writings above end on half-finished thoughts. I have trouble serializing my thoughts, and then there's that disturbing trend of ideas rearranging themselves *as* I'm serializing them. I just hope I've written down enough to remind me of the other things I'm thinking about right now. R.F.I.C.: (eqv relations communal-ties purposes) R.F.I.C.: sentient red blood cells questioning their purpose R.F.I.C.: Quote at chapter opening from Bertrand Russle (atheist) "Unless you assume a God, the question of life's purpose is meaningless"; think quote is taken with twisted context. Until next entry. 2004.01.04 ~05 "The Purpose Driven Life", by Rick Warren, Day 0 OK, so, for whatever reason, my mother wants me to read this book, really badly. She declared she will nag me every day for the next thirty-nine days to read through this thing. FWIW, the book is divided into 40 chapters, designed to be read 1 per day. Each chapter ends with a "Point to Ponder", a "Verse to Remember", and a "Question to Consider", to get the mental gears churning through the rest of the day. Instead of using paper, I decided to use this online journal as a place to record my responses. The forty chapters is a cutesy reference to various forty-day periods throughout the Christian Bible. From the preface material, the author's presupposition is that one's (my) purpose in life is/has been preplanned by God from the proverbial dawn of time. I don't intend to critique the book cover to cover, although I've already questioned various wordings and interpretations of the author at least four times in the first chapter. I'm not going to lay down what my thoughts are prior to finishing this book; i.e. I won't record my initial thought state. Being forced to read this book, I've already taken an adverse attitude towards it before opening the covers. I don't know how my attitude will change afterwards. In this initial entry, I've already rewritten and re-worded several otherwise-inflammatory sentences in preparation for the chance that I may completely change my opinin of the book in the end (i.e. I don't want to regret what I've written). For the actual responses to the chapters, however, I shall be using my then-current state of mind. In a way, I'm using these electronic entries to monitor my progress and journey through the book. 2003.11.25 ~10 UT2003, day 2 (weaponry) Well, after ravaging various CVS repositories, I got UT2003 running in a tolerable manner. There is no way I can play it online as it is now (let's just say certain polygons randomly decide to turn transparent...) but it still suffices to get a feel of ut2003. Day 1, I set up movement keys. I use ESDF for movement for FPS games. As a touch typist, I insist on my left index finger resting on 'F'. Day 2, after experience with all the weapons (yay cheat codes), I set up weapon binds (weapon-switching keys) based on my "feel" of the weapons. As I set up the keys, I noticed a certain... vague resemblance to Quake 3 weapons. Key - Quake 3 - UT2003 Q - BFG10K - Super Weapon (Ion Painter/Redeemer) W - Lighting Gun - Lightning Gun E - Forward - Forward R - Plasma Gun - Link Gun A - Rocket Launcher - Rocket Launcher S - Left strafe - Left strafe D - Backward - Backward F - Right strafe - Right strafe G - Grenade Launcher - Biorifle Z - Railgun - Shock Rifle X - use item - Translocator C - crouch - crouch V - gesture - voice menu B - Shotgun - Flak Cannon 1 - Gauntlet - Shield Gun 2 - Machine Gun - Assault Rifle Of note, I haven't bothered binding the minigun. 2003.11.21 ~09 "Prince of Persia: The Sands of Time" TV ad The (longer) TV commercial ad for "Prince of Persia: The Sands of Time" is simply mindblowing. I can't really describe it any other way right now. Rarely do I come across a TV ad that I would not mind simply watching over and over again for hours on end. The way the music, the graphics, the sounds, and the voiceover are put together is just amazing. I don't think this game is something to which I could get too attached. But still, the TV ad... wow. 2003.11.17 ~04 Another Pokemon movie on CN Cartoon Network seems to be a Pokemon binge. This past Friday they aired "Pokemon Movie 2000". Next Friday they air "Pokemon 3". The second(?) movie wasn't as cheesy as the first. OTOH, it illustrated a greater degree of idiocy. Super-rich collector unleashes earth-shattering forces for the sake of collecting them. "Moron" doesn't even begin to describe that motivation. Um. I forgot what I was gonna rant about. *shrug*. 2003.11.08 ~05 Pokemon movie (the first one) Cartoon Network aired the first Pokemon movie tonight. Overall, the cheese factor went off the scale. I can see how a Pokefreak can get a kick out of this movie, but the cheesiness had me laughing to tears. Oh, and a hour-plus long movie that ends with a Big-Reset-Switchosis. World teeters on the edge of destruction, brought back from said edge, and everyone's memory erased. Bah, cheesy. 2003.10.23 ~08 bittorrent 3.3 Yay, bittorrent 3.3. My greatest relief is that 3.3 does away with the "stampeding files" effect when starting to torrent, say, 8 files with btlaunchmanycurses.py. Now the files are sequentially checked, instead of all the files demanding simultaneous disk access. 2003.10.14 ~07 Final Fantasy Tactics Advance for GameBoy Advance Despite the freaky FFTA [helpline] commercial, on Saturday I nabbed a cart of FFTA, anywayy. It was on sale at Fry's anyhow, so I snagged one while reloading my supply of CD-R and CD-RW discs (I really should just get a bigger HDD...). Firstly, I've observed FFT for PS1 before. Never played it; had one of those college roomates that was "look, but don't touch" with the PS1. So I had inkling knowledge of what I was getting into with FFTA. The turn-based tactics combat I was familiar with; you can maneuver your character around the arena, and whallop enemies from the back for added damage. I was also aware of a jobs system, although I'm more familiar with the jobs system in Final Fantasy 5 (Butz, Lenna, Galuf, ...). In Final Fantasy 4 through 7, I spent a ridiculous amount of time leveling up my characters. In 4 through 7, leveling up involves running in circles until randomly stumbling into battle. Since FFTA's world map is confined to routes between city/location sites, running in circles would accomplish little but wasting time (circular paths, not really running in circles as with FF4-7). So, for the first 6 hours of play, I was taking on battle missions head-on, and often barely making it out alive. In one engagement (basically a battle, but engagements can also be won without bloodshed, e.g. negotiating) deploying 6 friendlies, I was left with 1 friendly unit on critical (very low) HP vs 1 enemy on medium HP; after a lucky missed hit from the enemy, I returned with Ice spell at point-blank range and dropped the enemy with one hit. Won that battle by the skin of my teeth. When I noticed an enemy clan trapsing on my turf (sites I should own), I wailed after them, and stumbled into an engagement, winning it (losing 4 of 6 units along the wya). After the second time I noticed an enemy clan on my turf, I finally recognized these clan wars to be the FFTA method of leveling up characters. The whole of the second day I had FFTA (a Sunday), I did nothing but trawl for enemy clans. The "Laws" system in FFTA is somewhat wonky. I distinctly remember nothing of the sort in FFT. The "Laws" are basically engagement restrictions, such as no Swords, no Poison spells, or no Arrows (sucks for archers). Violation of a Law result in a penalty depending on the Law rank (1 through 6, 6 is strictest), ranging from gil fines to instant imprisonment. The imprisonment system adds a new facet to RPG haggling. You can get a clan member (ally) out of prison by paying bail, "hostage-swapping" with another clan member, or invoking an anti-law card. Anti-law cards are a new class of items to deal with the Law system. Such cards can be invoked during engagements to nullify a Law in effect, and would probably be useful at higher levels when engagements can have up to 7 Laws in effect. For added perversion, there are also Law cards that enact added restrictions in engagements. The Abilities system is also kinda wonky in FFTA, but I think I can get used to it. Job Abilities are embedded in equipment, are useably by a compatible job, and the Abilities are useable while the item is equipped, or after a sufficient number of Abilities Point is attained to master the Ability. I didn't figure this out until about 8 hours into gameplay. In the meantime, I was going by the weapon stats for weapon selections, so my main character was slowly gaining Abilties (incompatible weapon type, but a Soldier wielding a Terra Rod can do some serious damage, especially in a No-Blades engagement), while my other characters were getting "Ability Mastered" messages out the wazoo. Job advancement are in terms of mastered Abilities of prerequisite jobs, instead of Job levels, as I am used to in FFT and FF5. When I finally figured this part out (after the Abilities-in-weapons thing), my other characters were well ahead on the magic learning curve. This left my main character leveling up through low-level jobs with low attack power (wimpy weapons), low attack rate (wimpy job), low MP, and low magic hit rate. At least MP is naturally recovered during engagements. One thing I've noticed in my gameplay is that I play a fairly defensive game, relying on overwhelming long-distance force. My characters are often laden with a wide range of magics (Black, White, Time) or long-distance attacks (archers, gunners), and movement-enhancing artifacts. I often use a variant of a divide-and-conquer strategy, moving most of my units en masse to one side of the map, then dogpiling all my mages on one poor sob, then moving on to the next one. This strategy often involves long walks along the perimeter playing keep-away. There is also the added advantage that hugging the perimeter helps shield my units' rear (backside-to-wall, nothing gets behind). The downside to such a defensive play is that engagements can last a long time. I average about 30 minutes per engagement. For some reason, I avoid using White magics (healing spells). I suppose it's because I prefer the idea of six offensive magic spells per turn dumped on an enemy's head, instead of just five with a defensive magic on the side. FFTA is very engrossing for me, almost bordering on addictive. It's sort of like Pringles: once you start, you can't stop. But when you run out, you can stay off for quite a while. Or maybe I'm just bullshitting myself... back to FFTA. 2003.10.03 ~08 "School of Rock" ads blitz While the TV ads for FFTA (helpline?) are freaky, the ads blitz for "School of Rock" is now beyond annoying. And an ads blitz it is. I can't surf thirty channels without being spammed by another ad for that frickin' movie. From what I can glean from the ads barrage, the movie seems to have a rather mediocre premise -- fake teacher hijacks classroom for his own end. So why does this movie get a spam campaign that would put MSOE viruses to shame, and yet good indie movies don't? Um, never mind. Hollywood movie and money, 'nuff said. Nevertheless, the ads for this movie is at spam level. Someone needs to make a spamassassin for TV cards. The ads' annoyances are enough to make me want to swear to never ever watch this movie, even if the copyright expires (which would presumably happen some time after Quantum Mechanics becomes a Jr. High topic) and random people tear up the movie into unrecognizable spliced clips. Which is just as well, since I'd be dead of old age before the copyright expires. 2003.09.26 ~09 Final Fantasy Tactics Advance help-/hint-line ads Since about mid-summer, I've been yearning for "Final Fantasy Tactics Advance", the port of the Squaresoft RPG(?) "Final Fantasy Tactics" for Sony Playstation to the Nintendo Gameboy Advance. When last I checked with a game store some time in August, I could've sworn they said it wasn't due until November, but here it is, released in September. It rather took me by surprise, when reviews for FFTA started popping up. I still have not gotten FFTA. Recently there have been a spat of TV ads for some FFTA help line. These ads feature, in a nutshell, freaks. Presumably representative of people manning(?) the help line, they look like freaks, sound like freaks, talk like freaks. I get the feeling these people wasted more pencils on pencil-and-paper RPG than on schoolwork/homework. These TV ads are rather disconcerting, and discourage my purchase(?) of FFTA. Not only the feeling of association with these nut jobs, but also the unease of thinking how they're reaping (exploiting?) the difficulty of FFTA. Each time I pass by a FFTA cartridge, I can't help but think of some delusional schizophrenic wearing an off-blonde wig with a telephone to his head, speaking in a tone reserved for exorcisms while extolling the virtues of Chocobos. It's a disconcerting image. And it really turns me off from FFTA. I was really looking forward to getting my Time Mage to help my Monk kick some goblin ass, too. 2003.06.19 ~10 Palm OS 5 and Linux The Palm OS 5 Simulator is the primary tool supplied by PalmSource, Inc., for debugging and testing Palm OS apps for Palm OS 5. Most Palm OS 5 devices use a variant of the ARM CPU, a little-endian CPU. Pre-OS5 devices primarily used a derivative of the Motorola 68xxx family of CPUs, which are big-endian CPUs. To retain compatibility with older apps, Palm OS 5 has a m68k sort-of-kind-of-emulator layer called PACE (Palm Application Compatibility Environment). As I understand it, PACE is more of a translation layer than emulation, but in any case, the point of PACE is so that m68k-compiled PalmOS apps can run on the ARM-based devices. In any case, the Palm OS 5 Simulator isn't an emulator in the same sense of the Palm OS Emulator (POSE). The Simulator, currently available only only for MS-Windows, uses host-native code, instead of code targeting for a particular Palm device. I'm not sure what the exact mechanics are, but I'm assuming there's some sort of Palm OS 5 library targeted for win32-x86 involved somewhere. I haven't bothered looking at, much less downloading, the Simulator because of its current bigotry. The end result is that I can't test nor debug ZBoxZ under Palm OS 5, unless I get a Windows machine, which is not likely to happen. Another option is trying to run WINE, but I munged up my WINE setup badly. Lastly, plex86 or vmware, but those involve a Microsoft tax. An expensive option is to cough up the cash for an actual Palm OS 5 device, such as a Zire 71, one of the Tungstens, or a Sony CLIE with a camera. Anyway, my primary bitch-and-whine is that I can't test for Palm OS 5 using a linux-based machine. 2003.05.18 ~06 Subtlety in TV ad for Microsoft Windows Server 2003 There's a TV ad for Windows Server 2003. The ad presents a party going on at some office company, presumably because they saved money (as hinted later). The ad focuses on a "manager type" asking a "techie type" what's going on; the latter says something about moving over to Windows Server 2003, reducing domains from hundreds to just four, this and that, etc. In response to a blank look, the "technie type" reduces the explanation to "we're saving over 2 million dollars". One thing I didn't understand about the ad is how a company buried under a Microsoft lock-in can possibly spend 2 million dollars less, much less a single buck. I take it for granted that once a company dedicates to using Microsoft products, they're stuck in an endless loop of buy-more- Microsoft-stuff (in the form of upgrades and "services", such as tech support). The claim of saving money in the ad made even less sense to me, since Microsoft, as a for-profit corporation, wouldn't want their customers to spend less on their "products" and "services". Then I received a flash of insight when I paid more attention to the term "ActiveDirectory" mentioned in the commercial. But, of course... LDAP wasn't MSIE-style-integrated into prior versions of Windows, so third-party providers of LDAP flourished. Then the ad started making sense. Microsoft wasn't promoting cutting off a stream of revenues to themselves... they're promoting customers to shunt the cash flow entirely over to Microsoft that otherwise would have gone to Microsoft's partners and competitors. That's how the office company portrayed in the ad would save $2M by going down to Windows Server 2003. They cut off the n million dollars going to Microsoft's partners and competitors, and give a portion of that cash to Microsoft (boosting MS's own revenue at the expense of others). The expenditure in the company's books would show a $2M reduction, Microsoft's books would show a cash boost of some amount, and the books of Microsoft's partners and competitors would show reduced revenues. Devilishly clever. The wording in the ad, I mean. 2003.05.09 ~11 Patents, a moment of zen US Patents System -- a non-market government instrumentation designed to promote free-market competition by forbidding free-market competition. 2003.04.03 ~01 USB solid-state storage devices Is it just me, or do those little USB solid-state storage mechanisms (those small enough to hang on a keychain) eerily hint at Star Trek-style isolinear chips? On a related random thought, these things are small enough that, if they were to be cheap enough, could be used as, say, business cards, the way shaped mini-CDs can be used to hold business-card data. Or as a means of distributing resumes. Flash the info to a solid-state device of a couple MB that's about the size of a stick of gum, distribute. Recycle. etc. 2003.03.19 ~07 BAFO BF-120 IrDA<->USB dongle So, I went to Fry's Electronics (in Manhattan Beach, the one with the Hawaii theme -- coincidentally, also the smallest of the Fry's stores) to get a new fuse to replace the one I blew in my multimeter (a cheap-o one that only measures up to 250mA; I tested the current through two full batteries in series (400mA) for a split second). This led to that, and for the next few hours I kind roamed around the store floor looking at this and that. As I started to wind down on whatever hell this phenomenom is called (I think it's the same one that induces women to wander for hours through clothing stores without buying a single article), I finally stumbled across the only IrDA-over-USB doohickey in the entire store. A BAFO BF-120 IrDA dongle. It's a IrDA dongle that connects via USB, instead of connectors on the mainboard that directly wire to IrDA controllers. I basically bought the thing on impulse, with intent to use the existing TV/VCR/cable/etc. remote controls we have at home to control my PC. Should that fail, plan B is to use the IrDA for Palm syncing. The BF-120 comes in three variants, apparently each with a different IrDA chipset, if the packaged manual is any hint. The dongle has a label on the flatter surface, towards the USB plug, that indicates the particular Windows driver to install (so I assume the three different labels indicate three different chipsets). A synthesis of information from /proc and the web revealed that (a) if the label reads "V6102F", it's a SigmaTel Ir4200 (STIr4200) chip, (b) there is no existing driver in linux for the STIr4200 chip, (c) the full technical specs for the STIr4200 (down to the physical packaging!) are available with little fuss. These docs should suffice for writing a driver. My options at this point were (A) return the doohickey and hunt for another IrDA dongle, (B) wait for someone else to write the missing drivers, (C) write the damned thing myself. I was about to go with A when our dear local Mr. chunky mentioned he has the same device. Bought at the same store. But at different times. I switched over to option C, partly as a challenge. I printed out the docs, and have been mulling over the 22 pages of it for 3 hours, at the time of this writing. If only I knew how to program Linux drivers... It's learnin' time. 2003.03.18 ~10 OES UI The last three (four?) days I worked on overhauling the ui system for Orbital Eunuchs Sniper (http://www.icculus.org/oes/). For one thing, I was annoyed at the existing menus not working. Secondly, I wanted a platform to prototype a ui for my q3 mod (the one done in Scheme). Mainly because of the Scheme slant, I used S-expressions for storage format. For quite a while, I knew of the existence of sfsexp (http://sexpr.sourceforge.net/), but didn't have much practice actually using it. To cut my teeth on sexpr, I started on something smaller, the preferences file in OES. The original preference format was binary, a memory dump of a C struct. I'm a strong believer in the unixian way of plain-text configuration files. As an added bonus, the preference file only held four settings, so the preferences could be simplified into a four-member association list. Reading would involve a simple one-level traversal of the list, and then picking the pairs out of each member of the list. This little exercise gave me a sufficiently half-clued idea of how to use the sexpr data structs. Afterwards, I took on the menus system. The initial idea was to parallel the menu system in Q3TA, involving text files that describe the initial state of the gui, then letting the system rip loose with a C core. The first goal was to have the buttons react to the mouse, focus and clicking. The first incarnation checked the mouse location every time the screen was redrawn, checking if a button was in focus or not. The ui system walked down the widgets heirarchy to propagate click events, checking each widget's clickability, mouse location, and name to react to mouse clicks. This method was really nasty, since button actions were hard-coded according to their name, embedded in the ui functions (broken encapsulation). I think I went through four rewrites of the data structures for the widgets. What I wanted in the data structure was a simplified query/modify interface to widget properties. Initially, I wanted to directly modify the sexp structs describing the widgets, in the form of alists, but I couldn't quite figure out how to modify the structs decently, either to add a key/value pair or to modify one. The data structures I finally settled on involves a singly-linked list of structs holding a key/value pair, which I found to be more easily modified than the sexp structs. A couple of support functions translates the sexp structs into the linked list. After the buttons started reacting to clicks properly (starting game, quitting, etc.), I worked on purifying the encapsulation of the ui system. Namely, to separate the OES-specific data and actions from ui.cpp. The goal was to make the ui system capable of being a drop-in component into another project. One interesting progress I notice in retrospect is my gravitation towards a signals system as used in gtk+ and SWING, away from the "cascading events" style. Initially I couldn't comprehend the signals system, and partially as a result had a general distaste for it at first. For one thing, I didn't like, and couldn't handle very well, the notion of multiple paths to a widget (one via parenting heirarchy, and one via signals, etc.). OTOH, what I found out is that using a signals system greatly expanded the capabilty of the ui system. I don't know if it's something intrinsic within the signals system or if it's a "perspective" thing, like taking a different slice of The Whole General Mishmash of widgets. As a hack, the extent of signal-handling within the ui system itself is emitting yet another signal. There is C instruction to handle signals not understood by the widgets in the ui system. So, for example, handling of the Escape key (which was added fairly late in development) to backtrack through menus was done by connecting the toplevel (menu) widget to the "esc" signal; the "esc" signal is generated by pressing the Escape key (from the ui input handler); the toplevel widget re-emits the signal "go-main" upon receiving "esc"; no widgets understand "go-main", so this signal is handed off to the C handler, which does a series a string checks to figure out what the signal is, then rearranges menus accordingly (in the case of "go-main", bringing the menu named "main" to the foreground). This signals system is still better than recursively stepping through child widgets and repeating events to all of them. For one thing, signalling doesn't need to worry that some widget that doesn't want/like/know an event won't stop the entire event-propagation loop. For another, CPU cycles aren't wasted on widgets that don't care about a particular signal. The advantages of a signals system are probably common knowledge to developers of ui systems, but I'm scribbling all this down for my own future reference. 2003.03.13 ~04 Triseism - standalone Q3VM interpreter http://www.icculus.org/triseism/ Standalone Q3VM interpreter. Most of the workings of a stack-based machine became clearer when I brushed up on Forth. And Forth didn't make much sense until after I learned Lisp. After learning lisp, the idiosyncrancies of python became understandable. Q3VM sets aside 64KB total for stack. Forth uses two stacks. If Q3VM's stack is split in two (which I'm not absolutely certain on, but makes sense), to mirror the two Forth stacks, this gives a limit of 32KB for a stack frame. This limit is enforced by q3lcc at compile time, and I've always wondered why 32KB in particular. Looks like the run-time stack is involved. Some of the emulation techniques I borrowed from my experience on PHFC, the CUSP emulator. And from hacking on q3asm, the opcodes were fairly transparent. I created and compiled many very simple programs to see the translations of C source into Q3VM asm. The Q3VM syscalls are a bit of a zinger. For one, I can't possibly implement ALL the syscalls -- this would basically lead to rewriting Q3. The other problem is that Q3 has three sets of syscalls, one each for game (server-side), cgame (client-side), and ui (client-side menus). I'm thinking of using a dlopen() system to optionally load one set of syscalls over another. Splitting off the syscalls package would also be helpful in utilizing triseism as a general-purpose sandboxed VM. The other problem I'm having is the mysterious two words allocated on the (return) stack upon entering a procedure. Local storage starts after these two words, so the two words are likely involved with the return process. I'm thinking of distilling triseism into a library. One of my motivations for finishing this was an acquaintance's desire for being able to load a .qvm in another app, as one would open a dll. In other possibilities, since the opcodes of the Q3VM are now very clear, it should be possible to compile Lisp directly to qvm bytecode, bypassing any C translations or C compilation, i.e. foo.l -> foo.qvm. Also, I'm certain gcc and the gnu toolchains to can be hacked to compile directly to .qvm. Implementing a dll system within Q3VM is doable, but would probably need changes to the .qvm format. The current .qvm format discards the symbol table, precluding any dynamic symbol resolution. Since triseism is developed independently of Q3 proper, triseism isn't bug-for-bug compatible with idsoftware's Q3VM. This means triseism may not mimick every tiny detail of Q3VM down to the fiddling of bits. Triseism may help in tracing an execution path through a Q3 mod, but without debugging symbols, there isn't a simple way to link an instruction location with its matching line of C source. 2003.02.05 ~09 snes9x console http://www.icculus.org/~phaethon/snes/console.html I started on this hack the day before shuttle Columbia disintegrated. Motivation to hack this up came from several places. Primarily, I wanted arbitrary bindings of the buttons on my gamepad (Thrustmaster FireStorm Dual Analog 3) for use in snes9x. A strong impetus came from ZSNES and its GUI. I liked the immediacy of changing key binds and fiddling with options in zsnes. In snes9x, changing options meant saving game state, quitting, futzing with command-line options, starting, and restoring state. Another source of inspiration was Brad Jorsch's control-remapping patch, which is applied to the Debianized snes9x package. I thought the configuration file for that to be rather clumsy, and it didn't bind joystick axes and buttons. The notion of a console came from Quake (1, 2, 3) and Unreal Tournament (pre-2003). I settled on mimicking Quake's console since (a) I am familiar with Quake III's console, and (b) snes9x lacks the underlying objects, widgets, and language system to mimick Unreal's console. Also Quake's console is based on a command language, simpler than Unreal's more advanced Algol-family language. I mimicked most of the functionality and commands found in Quake's console, with various extensions of commands and cvars appropriate for snes9x. The cvars that affect emulator settings are not directly tied to their associated C++ variables. Rather, there are explicit calls to synchronize the values between cvars and their variables. Somewhat inefficient, but saved massive refactoring. FlightGear has an interesting configuration system. A key binding describes how a particular "FlightGear property" is modified. For example, swapping values with another property, incrementing the property by a certain amount, or _conditionally_ setting the value of one property based on the value of another property, at key press or key release. Bindings for (analog) joysticks are described in the same syntax, but describes a formula for translating the joystick position into a property value, using a scaling factor, an offset value, and a "dead-zone" range. Anyway, FlightGear's binding of analog joysticks inspired me to figure out a way to incorporate axis-handling in the new snes9x console. I spent much time thinking over keys, input, and key states. Often, the state of a key is treated as a boolean, as either true (pressed) or false (released). I thought of an axis of a directional (digital) pad as being one key with three possible states: 0, positive, and negative (i.e. left and right do not occur at the same time on a joystick). In the case of an analog axis, there would need to be continuous values on either side of 0. At first, I considered using floating-point values, i.e. -1.0 for one end, +1.0 for the other, and fractional values to represent intermediate axis positions. Well, due to some inconsistency in the cvars mechanism at the time with float-point values, I wanted to stay away from floats. That's when I remembered joystick calibrators worked with integers, where 32767 represented maximum and -32767 minimum. So I went with integer-only values for a key state. For regular keys, the state would still be 0 or 1, but for axes, would be a value from -32767 through +32767. In Tribes 2, a key is bound to a function -- a key handler. This function is passed one parameter, a value of either 0 or 1, indicating whether the function was called because the key was released (0) or the key was pressed (1). I never dealt with joystick handling in Tribes 2, but a reasonable extension would be an axis-handler function being passed a value indicating the axis position. Quake III supplies commands linked to action primitives, in a "start" and a "stop" flavor. For example, "+attack" means start firing, and "-attack" means stop firing. If a key is bound simply to just "+attack", when the key is released, Quake III automagically runs the command "-attack" (i.e. replaces the '+' with a '-'). The '+'-'-' swapping is apparent with a simple test: "/bind SPACE +crap". Hit Space, and the Q3 console complains about not finding "+crap" nor "-crap". The complaint about "-crap" happens when Space is released. A while ago, in an attempt to extend the Q3 console capability to be more shell-like, I added an "alias" capability. This capability allowed a cvar to run as a command without need for an explicit "vstr". The basic idea was, for some alias named "foo", to prefix it with an ampersand, "&foo". Should the Q3 engine fail to understand a command (and pass it off to Q3VM code), the VM code tries to find a cvar matching the unknown command's name, but with a leading ampersand. Then, on a successful match, runs the cvar's content as a command. I took this idea over to the snes9x console. The primary goal was to have a bind named "+turbokey", defined entirely in terms of commands (instead of C++ code). This alias would then be bound to Tab, such that holding down Tab puts the emulator into "fast-forward mode" (skipping boring/useless/pointless parts of a game), and releasing Tab returns the emulator to "normal" speed. Most of the keynames were ripped from Quake III. Q3 basically goes off on its own naming system for high-bit key, so there had to be a way to map the host key to Q3's (or rather, snes9x console's). This comprises the most massive patch to files outside of the console/ directory -- just mapping host keys to s9xconsole keys. I didn't want to mimick FlightGear's axis handling completely. One problem I have with FlightGear's joystick handling is the complexity involved in trying to control the throttle properly with an auto-centering joystick (i.e. a little push to increase a little, big push to increase a lot, instead of the throttle every time the joystick auto-centers). The Tribes 2 style was more attractive, but that meant having some primitive form of conditional and flow control. That got nasty. I don't want to get into it, other than the commands for conditional and flow control are more reminiscent of assembly than any kind of HLL. I implemented a primitive form of multitasking to deal with rapid-fire (press, release, repeat, but if the console doesn't yield to the rest of the emu, the emu never gets to see the buttons) and a primitive form of multithreading to deal with infinitely-looping commands. Also, as part of rapid-fire, I had threads record the key that initiated the thread. Then the thread manager kills off all threads associated with a key whenever its state changes (e.g. killing rapid-fire loop on release). Originally I had a cvar named "axisval" that records the axis position for the AXISn "keys" (analog axes). One AXIS bind could make several comparisons to the cvar, but then the multithreading meant another AXIS bind would then change value of "axival", before the first thread manage dall its comparisions. Race condition. I resolved this by attaching the axis number to the end of the cvar name, so that each AXIS bind has its own associated cvar (instead of one cvar shared across them all). So, now, any of the three joysticks on my gamepad (one D-pad, two ministicks) can emulate the SNES Directional-Pad. 2003.01.22 ~10 Random thought: shell as "action-oriented programming" Stumbled across this thought while pondering config/rc files. Object-oriented programming, as in C++, usually has a form of: OBJECT METHOD ARGUMENT1 ARGUMENT2 (object first, a method in that object, arguments to pass to the method) e.g. foo->bar(0), bonk.oif(quux, quuux, quuuux), $fred->yabba(dabba, doo) Shell programming, when typed out, usually has a form of: COMMAND OBJECT1 OBJECT2 ... (command first, then objects to operate upon) e.g. rm -rf /, mv foo bar, touch this that private pubic lockfile Of course, shell programming can get much hairier. But if shelling can be considered "action-oriented programming", that'd be some kind of fit-the-slot counterpart to OOP. Just a random thought. 2003.01.12 ~03 WFA dead Lead coder for Q3 mod WFA called it quits. The alternate coder is throwing the mod into the freezer, never mind the back burner. The new project leader can't touch the WFA sources. It's essentially dead. I may take up coding WF for Q3 from scratch, separate from my FI mod, for speed/time reasons. For those same reasons, I may have to abandon much of what I consider "good coding style" to churn out results. 2003.01.07 ~08 X10 Firecracker Got one of those X10 Firecracker starter kits. The halogen lamp I intend to control is rated 500W, so I had to purchase a separate 500W-capable X10 module. The transceiver that comes with the kit is capable of 500W, but the lamp's socket is rather far from the 'puter. The 300W dimmable module that came with the kit is currently unused. We have no pluggable lamps under 300W. The Firecracker dongle is tiny. I expected it to be at least half the size of an average X10 module (which in itself is about the size of a typical AC/DC power adapter). The Firecracker is small enough to be mistaken for a mismanufactured serial gender-bender. The Firecracker connects on the (9-pin) serial port and is a write-only gadget. Lack of read ability is no matter, as I can get direct feedback of any X10 action by turning my head. Curently, to drive the Firecracker, I'm using Bottle Rocket. I have GNOME launchers to control the lamp, for gawk-and-click controls. 2003.01.04 ~10 mark-and-partial-sweep garbage collection This turned out to be an interesting hack to the mark-and-sweep gc. For some reason, TinyScheme partitions its heap into N segments of M cons cells. This appears inexplicable, as TinyScheme is hard-coded to use only 3 of the segments and refuses to use any more segments (short of an explicit procedure call to "new-segment"). I decided to use this inherent partitioning of the heap for a partial sweep mechanism. Partly inspired by incremental-style garbage collection (superset of "multi-threaded garbage collection"), the idea was to sweep one segment per Q3 frame, so that the time to sweep up all the garbage is spread out over a long time, interpersing regular Scheme processing. This depends on the sweeper recovering garbage faster than Scheme allocating space, which is most of the time (recovering up to M cells per frame, vs allocating perhaps a dozen cells per frame). Each module's vmMain() would need to call the partial sweeper once per frame or somehow ensure the sweeper gets called frequently per second. A problem is that in between partial sweeps, Scheme can still request additional cells. By default, TinyScheme does not initiate garbage collection until the heap is entirely exhausted. With this behavior, Scheme may wind up requesting cells when the sweeper has barely started, triggering another mark+sweep cycle. The free-at-exhausted behavior is also annoying as it tends to lead to lost symbols and bindings (no chance to establish a path from a root cell). As a workaround, I changed TinyScheme to initiate garbage collection after the freelist dips below a certain low mark, which is currently half a segment's size. This way, fresh objects get a chance to join the marked tree, and the allocator gets "padding" to keep Scheme satisifed as the sweeper starts. I also had the sweeper watch for "extremely tight memory situations". This would happen should Scheme allocate a very large chunk of memory right after a mark pass (just as partial sweeping start). Since sweeping when freelist hits zero tends to cause lost objects, I wanted a non-zero panic point. Should the freelist drop below the panic point, the sweeper goes into aggressive full-heap sweeping. Lacking a reference for this panic point, I chose a random number, 42. Empirically, on my K7/1200, with N=32 and M=32768 (total 1MiB), mark phase takes about 5ms, and a partial sweep of one segment takes 18ms, with a full-heap sweep taking a little under 600ms. Wishlist items: somehow automagically setting partial sweep to stop after a certain time threshold. One hack is to continually sample elapsed time, but the call to get the time (a Q3VM trap) takes up processing time. A better method would be to calculate the cells-per-ms rate, then using an appropriate number-of-cells to finish a partial sweep within time, but that method is more complicated. 2003.01.03 ~20 Showstopper in Scheme UI Just ran across two showstopping bugs in implementing the entire ui module in Scheme. The current garbage-collector algorithm is mark-and-sweep. Even with a heap of 1MB, every gc cycle takes a noticeable time to complete. This produces a heartbeat-like lag pattern, where the entire UI just freezes up as the heap is marked and swept. A clean solution is to use a garbage collector better suited to realtime interactive use. The other showstopper, partly related, is that due to the way TinyScheme manages memory (to wit, symbols are not garbage-collected), the Scheme subsystem eventually exhausts the heap after running the ui module for a moderate time. Once the heap exhausts, anything can happen. Usually Q3 abends. I'm thinking about falling back to my prior UI idea, which describes the menus in S-expressions and uses Scheme as a Turing-complete language for the more complex UI behaviors. This way, the most frequent actions (drawing, repositioning, etc.) can be done in C or something, and leave the less frequent actions (fancy animation, commands-wrapping) to Scheme (less frequent garbage collecting). 2003.01.03 ~17 Undocumented feature of Q3VM's trap_FS_FOpenFile() The trap never opens a filename beginning with "q3key". This is filename, not pathname, so even "gfx/not/gfx/ha/ha/foold/you/q3keylist" fails to open. For my Scheme UI system, I'm rewriting the UI from scratch. I even have a vmMain() replacement done in Scheme -- that low-level. Since I'm not sure what's happening under the hood, and without a half-decent menu, I can't get the console to open. I think it has to do with all those repeat calls to trap_Key_SetCatcher, but I'm not that desperate to track it down. In any case, since the key event handler is also in Scheme, I wanted to use symbolic names for the keysyms, instead of trying to figure out numerical keycode. In particular, I wanted to use K_F12 to quit Q3 (since console is unreachable). So I wrote up a script to list out the Q3 keysyms, assigning the appropriate keycodes to each symbol. This list of definition went into a scheme file called "q3keys.cfg". Scheme failed to find it (load "qs/q3keys.cfg"). I renamed it "q3keys.scm", and it still couldn't find it. I tried debugging the stdio, unistd, and devfs functions trying to find out what was wrong. I traced flags, file modes, file permission. Everything looked fine. Recalling that the Q3 CD key is stored in a file named "q3key", on a hunch I renamed the definitions file to just "keys.cfg". And blamo, the load procedure suddenly finds it and everything is peachy. The upshot of this undocumented feature is that a malicious mod cannot read the CD key off the filesystem and covertly transmit it. Gotta love undocumented features... 2002.12.29 ~19 Objects in TinyScheme Attempting GUI in Scheme. The easy way out is to translate the .menu syntax into S-expressions. This gets sticky when it comes to widgets performing special actions. In the TA menu system, special actions are done through "script" actions, using keywords and commands interpreted by the UI system. This means the set of actions that a menu item can perform is limited by the commands recognized by the underlying C. And even then, allows only simple sequences, no conditional nor looping constructs. I feel a replacement of the UI system is in order. I intend to use Scheme as the implementation language for a new UI system, using an object-oriented widgets set as in most modern GUI systems. I find SDL_gui to be a useful scaffolding and template, as it is immature (less code, easier to follow) and lacks the luxury of a preexisting "toolkit" library (contains code for low-level input and output handling). Researching OOP in Scheme led me to YASOS (Yet Another Scheme Object System). While looking through and reading about yasos, I learned some finer details about OOP and encapsulation, and just how badly C++ mangles the whole picture. The problem at hand, though, is that TinyScheme can't support yasos directly, lacking "define-syntax". SLIB can provide a working "define-syntax" implementation, but I'm having a bitch of a time getting SLIB to work in QuakeScheme. I could either try to get an almost-yasos system going in QuakeScheme by whacking up some of the yasos code, or try to get QuakeScheme to play nice with SLIB. A yasos-less alternative is to use a different objects system. There aren't a whole lot of those around. The author of TinyScheme has some notes on a TinyScheme-specific object system, but (a) the resulting GUI system would be implementation-specific, (b) the notes are "theoretical ramblings". In any case, having a working OOP system would help with widgets and associated inheritances. 2002.12.25 ~12 Q3A bot files The runtime files that reside in botfiles/. They munch ass. Seriously. Mr Elusive ought to be hurt in a very painful manner for using such a sadistic file syntax. 2002.12.20 ~23 Rise of the Triad GPL'd Well, crap. RotT went GPL, and my hands are already full with the Q3 toolchain, two Q3 mods, and SMPEG. 2002.12.20 ~11 bummer... q3as == Quake 3 Advanced Server mod I planned to split q3asm into two distinct tools, "q3as" for just the assembling, and "q3ld" for just the linking. Apparently the term "q3as" is already used to describe a Q3 mod oriented towards server admins, Quake 3 Advanced Server. I have no idea what it does in particular, but it came up during discussion of the other Q3 mod I'm working on (Q3Matador, http://q3matador.dragon-rider.org/), in the context of planning additional features. I don't know what I should/could rename the assembler-only tool to be. First thoughts are "qas", "asq3", and "q3vmas". Whatever it is, I plan on reusing the naming pattern for the linker tool. 2002.12.19 ~08 MSN TV ad Several weeks ago, I was watching TV, and for the first time saw an advertisement for MSN (Microsoft Network). Before I had cable TV installed two weeks ago, I didn't watch any TV. At the time, I was watching TV at someone else's house (cable TV at that). First the laughing part. While this ad was running, I was chewing on pizza (jalapeños & ham, as I recall). I reiterate this was the first time I ever saw a MSN ad on TV. As the voiceover rattles on about the benefits of MSN, they said, and I quote, "with advanced Microsoft technology". At least I wasn't sipping milk nor soda at the time. Thankfully I didn't snort the chewed-up stuff out my nose (jalapeños). But chewed-up pizza looks rather nasty. I think I went on laughing for the next two minutes. Next, the disturbing part. I didn't realize this until I pondered on it for the prior... uh... 10 minutes. The TV ad sports a male, in a brightly-colored suit, resembling a giant butterfly, covering up pictures of scantily-clad women. With the wings of the suit. Something just doesn't jibe here. And I just realized something else here... The MSN mascot goes around eliminating any attention-grabber (boomboxes, lifesize images of women, etc.). Covers up said attention-grabber. Presumably to draw attention to the brightly-colored winged suit, and person within. And while covering said attention-grabbers, thrusts chest out at a child. Repeatly steps into the line-of-sight of said child, and thrusting out chest. This MSN character turned his back on a picture of a nubile woman and thrusts his chest out at a (underage) girl. Then chases after said girl, running ahead of her, repeating the chest-thrusting actions. OK, so this MSN person goes around eliminating distractions, tries very hard to draw attention to himself (q.v. bright-colored butteryfly suit), constantly places himself in the child's line of sight, turns his back on a picture of a naked of-age adult in favor of aiming at a child, repeatedly thrusts out his chest at an underage child, AND STALKS HER! Um, hello?! What is MSN about, again? 2002.12.10 ~09 Q3VM /dev/tty Well, it's done. In the cvs repository for my Q3 mod, there is now a (dumb) terminal emulator. Currently the tty devices is capable of some sane reads and writes (i.e. open("/dev/tty", O_RDWR) acts as expected). The tty device can provide uncooked key input, but no line-buffered input yet (as expected by various command-line code). Local echo is implemented, and could be toggled if the termios functions were done. Writing to /dev/tty works as expected. Text falling off the bottom of the tty region scrolls the text as expected. Scrolling the other way not yet tested. Only a subset of command characters yield non-character effects: BS, NL, CR, LF. Other command characters produce glyphs. Backspacing past first column not tested. Reading from /dev/tty produces an octet stream of characters. Raw keycodes and key release events are not reported via /dev/tty (but instead in /dev/keyboard). Also supports ioctl(), and I made up a bunch of TIOC_* constants to fit the idiosyncrasies of Q3VM. For example, the cgame module needs to explictly blt the tty content every frame, by calling ioctl() with a request value of TIOC_DRAW (this should be renamed to TIOC_RUNFRAME or something later on...). Later I plan support for some of ECMA-035 (character sets extensions) and ECMA-048 (control characters and escape sequences). 2002.12.07 ~02 Q3VM devfs Well, another layer thrown in. This time to simulate kernel-level calls for file I/O. POSIX is hardly an optimal model to copy, but it's has a long-established tradition, and been documented to hell and back. I finally settled on having a separate /dev/keyboard, to allow for eventual reads of raw key events (press and releases). Key release events are not handled by /dev/tty; the tty device only handles byte streams, not structured data or release events. I'm wondering if I should have a separate /dev/mouse devices instead of integrating mouse events with the keyboard device. The keyboard device isn't actually _used_ yet, but it's a stepping stone towards getting /dev/tty to work as expected. BTW, doing /dev/null was very easy. Every function returns 0. :) Also, being the easiest device, it also doubled as scaffolding for the other devices. SUSv2 demands a /dev/console. It just demands the device exists, not that it does anything in particular. I'm thinking of implementing this as a replica of the currently extant chat box (the three text lines at the top of the screen that gets spammed with everything), as the sink for writes to stdout and stderr. 2002.12.01 ~05 glib removal I got glib-1.2.10 ported to Q3VM, but didn't commit the relevant source tree. I planned not to until I can figure out if there are any licensing conflicts. I finally got around to poring through the LPGL and the Q3A Game Source License (Q3AGSL) back-to-back and side-by-side. My understanding is that the two licenses conflict with each and declare the ability to copy (and other copyright activities) is revoked due to each other, that is, both of them point at each other and claim license violation. Or at least I think this file called "QIIIA Game Source License.html" applies to the mod source... The wording in the license sounds rather like some kind of model creator or map editor program, rather than the baseq3 mod source. The major sticking point in my reading is where the Q3AGSL prohibits reverse-engineering (section 2f), but the LGPL requires RE ability (section 6). I wonder if this applies to baseq3 mod source itself, since Q3AGSL section 2j prohibits preparing or developing derivative works based on "the Software", which describes just about every Q3 mod in existence. Obviously those Q3 mods aren't illegal, so either I'm reading this license wrong, or this is the wrong license. 2002.11.30 ~06 Blue Sky: Q3VM... ".qso"? I got into a conversation over the limitations of Q3VM and wishlists for it. The discussion came down to having a scripting interface for modding, much like my idea for using Scheme in my own Q3 mod. I mentioned that one of my gripes about Q3VM is the complete inability to have third-party add-ons. All that is available is the .qvm file. Nothing else can run as code text. One useful addition would be a shared-object mechanism, to load third-party code. Trustworthiness precautions mean there would need to be a tiered syscall mechanism. Or something like that. The idea is that first-party modules (i.e. from the mod team, in the distribution paks) can have willy-nilly access to all traps, while third-party modules (non-pk3; on the host filesystem) shouldn't be allowed access to all traps (such as the traps to change wall textures...). These ideas still apply to my Scheme implementation. Currently I have all client-side traps wrapped in Scheme, but all loadable programs shouldn't have that much access to traps. This pretty much follows from OS rules of thumb that userspace code shouldn't have all the access that kernelspace code does. Restricted access helps limit rogue programming and helps thwart malicious code (*cough*cheats*cough*). Perhaps I can glean something from various real CPU architectures. I recall the M68K having a supervisor bit, and the x86 having rings (rings of what, I don't remember). 2002.11.23 ~07 Blue sky: Q3VM SDL This would be one interesting hack. However, large chunks of SDL would need to be pared down. For example, the image routines would be limited to load-from-file only, no load-from-memory or somesuch. Other SDL subsystems may need to be left out completely due to Q3VM limitations, such as Joystick (Q3 intercepts joystick movement and converts them into special-case key events) and CDROM. I'm wondering how many SDL apps could be portable to Q3VM afterwards. This is a far-off blue sky, though. Much of the libc I have just returns "not implemented" errors, so while various parts of SDL should compile and link without problems, SDL won't work as expected (e.g. select() currently always fails). 2002.11.22 ~00 A limerick inspired by PunkBuster Originally I planned to have a four-line poem as a suitable .sig, but I also wanted to capture the essence of my PunkBuster experience by cutting off the last word with a PunkBusterism. I thought both A-A-B-B or A-B-A-B rhyming pattern would be unsuitable, due to my plans for omitting the final word (not enough "priming" for fill-in-the-blank). A-A-A-A would have worked best. After wanting to mention "autoaim" (aimbots), I worked through rhymes, coming up with "shame", which perfectly describes a connection under the influence of Pb. Then I made up the first line on the fly to fit the AABBA rhyme pattern. This version is slightly toned down. My intended "distribution use" version changes "incredibly" into a far more colorful phrase. It's harder to stay on the Quaking way... Had to reinstall PunkBuster again today; The ping is a crying shame, And llamas can still autoaim, oh my gawd, this is incredibly g***ERROR*** ^5client in distress - could not load pbcl.so 2002.11.20 ~08 Blue skies: vt100, ncurses, and Q3VM. Firstly, I wanted a way to place random text on a random location on the screen at random times. There is already a function in cgame for this functionality. A problem arises if I need to shift the location. If done in all-C, the module needs to be recompiled. Alternatively, I could write a QuakeScheme wrapper so the position is adjustable from Scheme... but if I wrap DrawString(), why not DrawChar()? And the cell-measuring functions? How about the whole font system? Then there's the cvars method, but then comes the question of having more than one string to draw. Have a set of cvars like "string0loc", "string1loc", "string2loc"? Or the dimensions laid out like "0:20:foo" in a cvar? I can see this method getting very very messy. I got around to thinking about cells-based positioning, like a tty with an addressable cursor. Row 3, Column 42. First model that came to my mind was vt100. One possibility presented by an addressable-cursor screen is a full-screen text editor. In real life, there already is a full-screen text editor with a Lisp back-end. Or rather, a full-screen Lisp acting as a text editor. Anyone moderately involved with text mode is likely to be familiar with the curses library, which helps utilize an addresssable cursor terminal by presenting a terminal-independent interface (an API). The curses API is fairly well-established in the area of text mode, and so is a useful basis for C-coding to a full-screen text mode in Q3. One of the free implementations of the curses interface is "ncurses", which is part of the GNU system and thus why its most familiar to me. As an aside, the Q3 UI is based on a 640x480 units coordinate system regardless of resolution (and scaled up to current screen resolution); character cells are 8x16 units. This yields a textscreen resolution of 80 cells horizontal and 30 cells vertical. If I can whip up the necessary glue code to attach ncurses to Q3VM, other potentials open up. For one, ncurses also comes with a text windowing system. In a pinch, the ncurses windowing system can fill in as a half-baked forms GUI. Porting (or rather gluing in...) ncurses also allows porting ncurses-based programs to Q3VM. Such as... err... um... tetris??... Well, here is one far-fetched possibility arising from getting in ncurses: Q3nethack. 2002.11.18 ~07 Q3VM glib In another of those mad-scientist streaks, I added enough libc headers so that glib-1.2 compiles without error. The libc headers are in CVS for my Q3 mod; glib itself isn't. I haven't tested glib, yet. The funny thing, I forgot why I wanted glib in the first place. 2002.11.13 ~11 QVMlibc In the CVS repository for my q3 mod, I added a subset of libc and SUS (POSIX). Covers ctype, strings, stdio, stdlib, errno, assert, unistd, fcntl, dirent, time. With some of the off-the-wall stuff I try, I'm thinking of renaming my mod to something like: "Nonlinear Experimental R&D-Type Stuff Modding". 2002.11.09 ~13 Compiled vs Interpreted I actually started on a long-winded entry on my thoughts about criteria for "compiled" or "interpreted" for a language, when a google trip turned up this link that is pretty much a superset of my ideas: http://www.oche.de/~akupries/ics_lang.html I had pondered over compiled vs interpreted as I mulled over the Q3VM specs and the way it makes a distinction between code space and memory space (JUMP to address 0 is vmMain(); a LOAD from address 0 does not return the bit-level representation of vmMain()). I decided the dividing line comes down to observing how the Program Counter (or Instruction Pointer, et al.) acts, whether it branches into newly created code (compiled) or stays within already pre-existing code (interpreted). Since a VM has its own (emulated/simulated) PC, this would mean bytecode would technically be compilation (from the point of view of the VM), but still interpreted by the host machine (as the host machine does not branch directly to the byte sequence). I had considered bytecode to be a middle ground between compiled and interpreted, but then I wondered if there may be other categories as well -- echoes of the zero-one-infinity principle. As the mentioned url illustrates, the whole gig is a matter of how many layers you need to tear through; "compiled" and "interpreted" are relative terms. Java is "more compiled" than Bash, Perl is "more interpreted" than C, and so on. 2002.11.08 ~10 Pb rant addendum Right about now, I feel I'd rather play on a server full of aimbotters than fucking with Pb. At least when I take out a cheater, I can righteously gloat haughtily for the rest of the game. With Pb on, you can't really be sure if a cheater slipped through or not... 2002.11.08 ~09 Punkbuster Burn@g3 The inevitable has thus happened. But a lot sooner than I expected. Punkbuster managed to fuck itself in the ass with a short one. Word in the grapevine is that the cheats/anticheats war is divided into two goliaths: OGC and Punkbuster. Apparently OGC has something to do with aimbots or other cheats or something. Punkbuster is... well, most of the quakers know by now. Seems there's a back-and-fro between these two camps, and the fun-seeking fraggers have gotten the short end of the stick yesterday. Or the day before. Something. What I observe: being randomly kicked from a server for "technical difficulties" in loading "pbag". Whatever the hell that is. The kick period ranged anywhere from before even seeing the loading screen to 50 minutes tops. The kick effect ranged from a graceful "disconnect" style (with error messages el al) to a process murder so violent that the entire computer locked up (fuct vidcard state). I've tried whatever I could to restore playability, ranging from restoring from backups to copying files from strange places to reinstalling Q3 1.32. Results are mixed. As I write this .plan entry, I cannot play on *any* Pb-enabled Q3 server. For values of any including local server (dedicated mode) on network loopback. For fuck's sake, **LOOPBACK**!!!! Rumor has it the Pb folks (evenbalance.com?) were so eager to push out an anticheat update that they missed installation or propagation validity, or somesuch. To add to the irony further, www.evenbalance.com was unreachable as of 6pm local time. So no manual updating/fixing. An acquaintance theorized (D)DoS attacks by the counter-punkbuster camp -- take down the master while Pb updates are broken and still in flux. I managed to peruse part of the evenbalance forums before it went unreachable. There was one thread where one very angry server admin was venting over Pb's b0rk3ness (to the extent that he was getting kicked off his own (presumably remote) server), calling for the ability to revert to earlier (unbroken) versions (countered as being contrary to Pb's lifestyle), or the ability to selectively choose or tweak Pb checks (countered for similar reasons -- "all or nothing"), or announcing significant changes in updates (countered as being a loudspeaker announcement to cheaters). The response from the Pb folks was basically along the lines of "the EULA you agreed to says you agree to ride along with whatever updates we push out as they're pushed out; if you don't like it, don't use it". The server admin's rebuttal was along the lines of "we shouldn't have to put up with BROKEN updates -- this stuff is supposed to work transparently". Then the rest of the thread were basically denouncing the thread starter for being hot-headed and rude, pointing out "cheats in general", history of cheats, yadda yadda, without really addressing the points raised. In fact, one responder even declared there was no point in the post. Then the usual "if you don't like it, don't use it" fluff. (I think one of the funnier exchanges in the evenbalance forums was someone establishing the correlation of punkbuster's appearance with a lack of cheaters in RTCW as being a purely cause-effect relationship.) What disturbs me is the "don't use it, then" part. There is no middle ground, no competitor, no alternative. It either is or isn't. Admins would like anticheat mechanisms, but as things stand at the moment, the choices are either Punkbuster (with all its secret agendas, benevolent or not) or absofuckinglutely nothing at all. I think that's what disturbs me the most about Punkbuster. Not any unknowable ulterior motive, not the fact that reflexive voodoo magic is bound to fuck itself, not that all anticheat mechanisms are fundamentally breakable. But rather the fact that there is no other choice, except larking out stark raving naked. An adage from a darker age of telecommunications comes to mind: "you have any choice of telephone color, as long as it's black". You have any choice of anticheat software, as long as it's Punkbuster. 2002.11.06 ~07 The so-called "Super Tuesday"; voting day Election Day. The ballot reminded me again that the US is based on a representive democracy (as most so-called democracies tend to be). Five of the seven pages regarded "whom" to vote for, and the other two were "what" to vote on. I prefer not to dawdle and languish over the ramifications of a so-called democracy that puts into office people easily... "swayed" by... "donations"... that lead to... er... "sponsored bills" that "help" the said "sponsors" campaign to put into office said people that were... "persuaded". So I'll concentrate on something that came mind as I looked at the voting mechanism doohickey, which sort of relates to security in general and a little bit on forensics. The two times I've ever voted in my life (today, and two years ago), the voting mechanism looked the same. In fact, it still looks the same from when I went in with my dad a decade ago to watch him punch his ballot. I don't know if this is an artifact of my city in particular (been here for nearly 16 years), or the State of California in general. The (paper) ballot itself has roughly the same area as that taken up by the typographic ("letter") keys on a typical PC-ish keyboard. The ballot is basically a souped up punchcard; for those familiar with Scantron forms, it's like a big version of one that has the choice poked out to form a hole instead of bubbling-in with a #2 pencil. The voting machine is all-mechanical. It's a mostly plastic thin box, just large enough to house the ballot. The machine's business face is a grid of hole masks (to guide the holepunch). Stiff paper pages with the meaning of the particular holes are bound between columns of holes (rotating on fine metal rods). Laid horizontally, the pages flip down to hide all but one column at a time. The end result is that the voter turns to a particular page, and the printed choice points with an arrow to the exposed hole representing the choice. As a neat trick against improperly inserted ballots, another layer of plastic hole mask lies just under the machine main grid of holes, spring-loaded against the ballot, such that the two holes do not line up (blocking the holepunch) unless the ballot is properly inserted deeply. An equally simple mechanism at the insertion end uses small plastic posts that the ballot end slips over to keep it anchored against the springs. Should the ballot slip out, the spring pops out the ballot and de-aligns the two layers of hole masks to prevent any punching. (ASCII art, monospace font required) punch holes contents | semi-blank page V V V more pages>> +-------------+-+-------------+-+-+ |#OFFICE FIO=>|o| |#|#| |# ERI=>|o| |#|#| <- # = zebra codes (!) |# RUMI=>|o| ========> |#|#| |# |o| GO TO |#|#| |#FOO YES=>|o| NEXT PAGE |#|#| | NO=>|o| | | | | |o| | | | | GOATSE YES=>|o| check for | | | | NO=>|o| chad | | | +-------------+-+-------------+-+-+ next column on ballot | (next page) V +-+-------------+-+-------------+-+ |#|#PROP X YES=>|o| |#| |#|#blah NO=>|o| |#| |#|#blahblah |o| ========> |#| |#|#blahblah |o| GO TO |#| | | |o| NEXT PAGE | | | | MEASURE Q |o| | | | | blah YES=>|o| | | | | blah NO=>|o| check for | | | | blahblah |o| chad | | +-+-------------+-+-------------+-+ Eh... where was I... Oh yeah. I mulled over my choices "on the spot", taking it SATs-style (mark what I dunno, mark it for return (but on another sheet paper!), go on to others, come back later). Yeah yeah, should've researched, yadda yadda. But while I did, I noticed bits of chads in the holes, of choices I didn't decide on yet. So much for secret ballots. Well, OK, so I don't know who was at it before, but it's certainly disheartening when you see a bit of chad in the "No" hole when you're thinking "maybe Yes...". Even more disheartening when the chad doesn't fly away despite all your blowing and realizing the only way you're going to get rid of it is by punching it through into the chad collector... as your choice (can't do it with ballot removed -- the holes masks don't line up). Anyway, I was thinking, despite all this effort to make the ballots "secret", something so insignifcant as a random cruft of paper sticking to an anonymous holepunch on its way out can still give away so much information. I find it intriguing how something so insignificant as a tiny tad of chad can say so much. Security is one thing, secrecy another. Security through obscurity rests on secrecy, and then some tiny bit (literally) in just the right/wrong place can blow this kind of security. Hrm. I forgot where I headed with this. 2002.10.31 ~23 Using balanced BST in TinyScheme Basically I copied the trees algorithms in q3asm over to TinyScheme, the C portion. Currently only the oblist (list of existing symbol names) is a tree, but the speed increase in my mod (layered on top of TinyScheme) is still noticeable, since TinyScheme constantly searches for existing symbol names. The environment register (E), for resolving variable names, still uses a list of frames, each frame using a list of bindings. I don't think there's much I can do about the list of frames, but the frames themselves might improve with the use of trees. I don't remember how large the root (global) frame gets; I think it's beyond a thousand. I haven't gotten around to incorporating splay trees into q3asm, since I don't have a very strong motivation to do so at the moment. When I do, I'll probably bring splay trees into TinyScheme as well. 2002.10.29 ~04 Splay tree, a more complex tree structure OK, because of this q3asm thing, I'm suddenly in a tree mood. Apparently in my textbook, three chapters after the one on R-B and A-A trees, is splay tree. This may be a(n overkill) solution for my opcodes worries. Basically the idea of a splay tree is to repeatedly split apart the tree and glue them back together in different ways such that more frequently-accessed elements rise towards the root (and thus cheaper for *future* accesses), while still maintaining the tree's order. The penalty here is that worst-case scenario is much much worse than RB/AA tree, on the hopes that average-case, for the more frequent nodes, gets better. And all that splitting/splaying also costs. The idea is to spread out the cost of the few worst-case accesses across many very-good-case accesses (this is where the term "amortize" comes in, but I'm still not sure exactly what the definition of the word is). Of course, this depends on there being *some* "frequent nodes". Apparently the cost of splay trees is horrendous for purely-random accesses. Fortunately, (functioning) assembly doesn't involve throwing together random opcodes in random sequences. The splay tree, in some ways, reminds me of Huffman coding, where the more frequent sequences use fewer bits than less-frequent sequences. Or of caches, scoring big wins for frequently accessed memory. Splay tree would dynamically re-arrange itself so that the more freqently sought node cost less to find than less frequently sought nodes. Splay tree may also be a good idea for the symbols tree, as there are likely to be some symbols accessed more frequently than others. For example, g_entities[], the list of all entities in the game world. 2002.10.29 ~01 Bring back hashtable to q3asm-turbo? Just now I bothered looking at the numbers related to q3asm-turbo's data structures. For my mod, the hashtable q3asm-turbo had these numbers: Symbol hash: 17819 nodes, longest chain = 45, mean non-empty = 9.320 Opcode hash: 95 nodes, longest chain = 3, mean non-empty = 1.484 The Bal.Bin.Tree implementation has these numbers: Symbol tree: 17819 nodes, tree height = 19 Opcode tree: 95 nodes, tree height = 10 Export tree: 26515 nodes, tree height = 21 In the optimal case the symbol tree would have a height of 15 (log2 of 17819), and the opcode tree would have height of 7. The height of the tree represents worst case time for searching. In the hashtable implementation, the longest chain indicates worst-case time for search, and the mean average roughly corresponds to mean (average) search time. Within each chain in the hashtable, though, sorting is done by linear-time insertion sort, and thus the major portion of cost. The thing is that the opcode hash has a longest chain of 3. This is next to squat (almost constant) for sorting and searching. Meanwhile, the opcode tree has a height of 10, worst case searching is visiting 10 nodes. In the tree, only 15 opcodes would be reachable in 3 hops, while any opcode in the hashtable can be reached, guaranteed, within 3 hops. The question here is if I should resurrect the hashtable specifically for the opcodes. Trees have major wins in the large-amount-of-data department (due to reduced insertion costs), but hashing seems to win in small-sets-of-data. 2002.10.29 ~00 q3asm "static" and balanced binary tree done http://www.icculus.org/~phaethon/q3a/q3asm-turbo/q3asm-turbo.html http://www.linux.ucla.edu/~phaethon/q3a/q3asm-turbo/q3asm-turbo.html I did it. Two birds with... uh... two stones. Two separate forked updates. The first is just a straight port of the old q3asm to the 1.32 SDK, so that patch(1) stays quiet. The second has some major mojo. Firstly, I finally carried out my threat of moving the data structures from hashtables to (balanced) binary trees. The speed improvement over hashtables isn't very dramatic, but still noteworthy. Empirical testing suggests a time decrease of 10% to 30% compared to hashtables. I'm too lazy to set up millisecond-resolution timing, but it feels faster to me. I actually cracked open my CS textbook and read through the trees chapter for the nth time. I finally half-grok what's going on with the rotations, but I'd be ****ed if I have to implement a R-B tree from scratch on a blank screen without any references. An added benefit of putting in trees is extra flexibility in additional data... data... err... yeah, additional data. For example, a mapping of private symbol names to public symbol names. Such as that implied by the "static" keyword in C. As I had priorly brainstormed, all symbols in a file are mangled based on filename (actually, file index number, but close enough) to mimic private namespaces. The "export" assembler directive, which takes as the sole parameter the name of the local symbol to be made global, creates a mapping such that the specified global name resolves to the file's particular private symbol (name). The "import" directive acts similarly, creating a mapping such that the local private symbol name resolves to the global name, then recursively re-resolves to the "actual" private symbol in the other file('s namespace). These mappings are sorted and searched in a balanced binary tree. Good thing, too, since there are upwards of 20K such entries. Basically, it was a matter of mimicking private namespaces and shifting names between those (fake) namespaces. 2002.10.28 ~09 Thoughts on Blender win32 build, and q3asm "static" keyword + Blender win32 Blender is a cross-platform app, so consistency dictates the build process should remain cross-platform. The problem is that the primary compiler used in win32 is Microsoft Visual... um... Studio? C++? Whatever. (Whether this can be considered "the system's C compiler" is a topic of another rant). The point stands that MSVC isn't very make(1)-unfriendly, is very non-standard. The problem is that automake as-is does not work well with MSVC as the C(++) compiler. One solution is to attempt to conjure up the necessary MSVC files based on the automake files. This method seems doable -- the tree structure of the source is patterned enough to establish a build path even without the automake files. The problem with this attempt is, again, non-standardism. I can't grok the formats of the MSVC files (the ones packaged with the Blender source tree). Or maybe I don't want to... but they seem just plain weird. Primarily on issues such as whether those header lines are critical, the sensitivity on whitespaces (valid chars and amounts), and wtf are the comment delimiters. Oh yeah, and those crazy-ass backslash for path separator. Wonder if there's a grammar describing these .dsp (.dsw?) files. + q3asm I have many reasons for wanting to split q3asm into two distinct programs, q3as and q3ld. One is to assist the migration of q3vm compilation into GCC later on (WAAAAAAY later on). Another is to allow use of library (.a) files in Q3VM linking -- this helps cut down on reaching across directories, as is currently done in cgame/ for obtaining bg_* (both games) source files. Related is testing my libc reimplementation, to avoid repeated recompilation and to test standalone worthiness (i.e. not intimately linked to my mod). An offshoot to that is properly handling the C keyword "static" (libc has stuff that really should be private). I already started on a hack for "static" support, using the source filename as a "tag" to symbol names, to make symbols unique to a particular source file. This establishes private namespaces per file. The sticky part with this method is trying to get globals to be globals. At some point the filename-"tag" portion needs to be stripped (simple), and somehow resolve to the unique still-tagged symbol (a little hairy), while ensuring no conflicts (some more hair). The key to the breakthrough lies in the assembler directives "import" and "export". The hard part is trying to come up with the proper data structures to express this method of scoping. I think I need to work out some more of this on paper. I really want to shift q3asm's symbol table to a tree, for many reasons. For one, trees would boost the speed some more (although the need is arguable, as some people are getting reported time-elapsed of 0 seconds). Second, the data structure and methods for trees are much neater than those for a chain-and-bucket hash table. And finally, trees are just cool. For speed reasons, the tree would need to be weight-balanced somehow. I would like to just link to a tree library of some kind, but that would be an extra burden on whomever wants to use the tree'd q3asm. So my options are either to rip tree code and stuff 'em into q3asm, or dig through my CS books again looking at the tree implementations. I understand the basic concept of R-B tree, that the markings help keep the balance... but I just get lost in all those rotations. :( 2002.10.27 ~06 improved RNG in Q3VM, Q3 1.32 + Towards a better (Pseudo-)Random Number Generator. http://www.icculus.org/~phaethon/q3a/nbrng/nbrng.html My quest for a better RNG started in Quake 3 Urban Terror (q3ut) v2.5, fueled by countless numbers of "Bullshit Incidents", aka "being 2.5'd". I'm not in a position to improve q3ut myself (read: damn elitist "dev group"), but the repeated 2.5'ing fired up my drive. The stock random number generator in Q3A is a laughably deterministic cyclic PRNG. Just multiplying the seed by 69069, storing the result back into the seed, and then using the new seed value as the random number. (Note: mods compiled to native code use the host OS's (P)RNG) A google search for free RNG source turned up "noiz". The original noiz acts like an ad-hoc system-wide RNG, using an entropy pool file in /etc (or elsewhere) and explicit programs to take the pool, stirs the pool with stdin, and writes back the altered pool; basically a shellified+disked variant of an entropy collector. My terminology is probably rather shoddily used and incorrectly applied, since I just started to look into RNG. I never realized the breadth of research on just figuring out how to *induce* randomness. Anyway, I took noiz and modified it to be function+cvar based. The function to actually collect entropy needs to be strategically placed throughout the mod to correctly scoop up entropy, but otherwise the noiz-based RNG is far more nondeterministic than the stock PRNG. + Quake 3 Software Development Kit v1.32. ftp://ftp.idsoftware.com/idstuff/quake3/source/linuxq3a-sdk-1.32.x86.run So, the new SDK to reflect the new Q3A mod (baseq3) source was released a few days ago. Apparently most of the baseq3 changes involve PunkBuster-related options, such as UI elements to turn it on/off. At last id released their patched lcc, which compiles C to Q3VM assembly (which is actually a variant on the lcc bytecode machine description). As far as I can tell, the 1.32 q3asm doesn't have any speedups over the prior (1.27?) version, although someone took the time to clean up the code to keep gcc quiet. + PunkBuster So now Q3 1.32 has PunkBuster. I have no idea what the basic principles are behind it, but apparently it's supposed to reduce cheating somehow. Since it (PB) deposits .so files on my (client) side, I presume these checks are done client-side. One lesson I recall from the Q1 source release is that anything run on client-side is totally untrustable, as there is really no limit to what the client-side can "say". So I seriously doubt PB can catch "all" or even "most" cheats, if it relies on this client-side .so file to check for client-side... um... stuff. Aside from that, I'm starting to notice strange lags in Q3. Now everything feels like a 100+ ms lag, instead of the usual inherent 50ms lag. It almost feels like CPU/client-side lag, but the framerate still pegs the meter at high double digits. Everything, from baseq3 to ufreeze to q3ut2 to wfa, from extremely low ping to extremely high ping. Either the netcode in Q3 1.32 has hit the shitter, or PunkBuster is stuffing Q3's face into the shitter with extra net comm. Neither one bodes well. Still, it would be extremely stupid if PunkBuster maintains some kind of "out-of-bounds" channel _during_ gameplay, since even so much as a rogue SYN packet can exponentially compound the lag on a 56K connection (a large segment of Q3 players, iirc) and completely ruin the experience (of either side of 0wn@ge). But I find it harder to believe Id would deliberately cripple the netcode in 1.32 sufficiently to make the difference noticeable on a broadband connection. Which is it? Which way would Occam's Razor cut? 2002.10.19 ~05 Blender web plugin problems The last compilation stretch is the Blender GamePlayer web plugin. The problem is that the plugin was initially developed using the API in Mozilla 1.0 (or earlier?). Debian unstable has the bins and dev files for moz 1.1. Problems at compile time. My options at this point are hacking on the plugin to use the 1.1 API (XPCOM in particular), fall back to moz 1.0 (via cvs), or abandon the compiling plugin altogether and concentrating on the preliminary ODE patch (physics engine) for Blender trunk. Oh, fwiw, the original collision-detection library in Blender, SOLID, had to be removed from the Open version due to licensing constraints. Yay proprietary license. 2002.10.18 ~01 Blender Open-Source Blender Liberated The Blender source code is distributed under a dual GPL/not-so-GPL license. Reminds me a bit of Mozilla. Freed 13 October 2002. Blender Autoconfiscating http://www.linux.ucla.edu/~phaethon/blender/blender-autoconf.html The initial build environment was heavily broken/undocumented. It didn't "out-of-the-box", so on Sunday night (localtime) I started rearranging directories and files, and autoconfiscating the tree. Started late 13 October 2002. Hacking at it since. First I got a modelling-only Blender. Then GameBlender eventually fell into the autostream. Now it's mostly cleanup and tweaks. Hoping for a pub CVS repository on www.blender.org. Blender Publisher semi-freeware The v2.25 that was previously off-limits to non-bondaged users was released in limited "freeware" style, um... yesterday, I think. RE'ing and decompilation are still forbidden, but at least the "common rabble" can take a stab at 2.25 without trying to figure out the compile path. 2002.10.03 ~06 Ogg Vorbis 1.0 in Q3, cgame outline So I took the plunge and snarfed Ogg Vorbis v1.0 (no shmamsy-pamsy rc suffix), then untarred it to my working directory, then made the necessary make-q3asm-happy patches. Vorbis decoding promptly b0rk3d. Oh well. I'll keep it that way for the time being; no plans for serious cgame modding any time soon. In other non-news, http://www.icculus.org/~phaethon/q3mc/outline2.html The cgame portion of an execution trace in outline form. 2002.10.03 ~03 Compiling Scheme to Q3VM bytecode Right now, compiling Scheme directly to a Q3VM file is possible. The opcodes for Q3VM are all laid out, the peculiarities of Q3VM are in the q3lcc patch, the memory structure is not complex. A suitable halfway hack is to compile for a SECD machine, then translate the SECD operations into Q3VM opcodes. The SECD layer could be done away with entirely, but that's an entire research project in of itself ("Optimized Scheme Compiler for Quake 3 Virtual Machine"). Programs for compiling Scheme into SECD byteocde are already available, and written in... Scheme. Well, C compilers are written in C, so that's not so entirely weird :) I'm wondering if it may be more worthwhile to try to hack one of the existing Common Lisp compilers to target Q3VM, instead of trying to compile Scheme via SECD. 2002.09.27 ~07 Another universe SIGSEGV 00:43 < Chunky_Ks> vogon: turn the computer off and leave the house 00:43 < Chunky_Ks> talk to a girl 00:43 < Chunky_Ks> I'm going to bed 00:43 -!- Chunky_Ks [chunky@gamehenge.icculus.org] has quit ["Leaving"] 00:43 < vogon> chu: I try, but the Universe always segfaults. Maybe it really did raise signal 11. That timing is too eerie. 2002.09.24 ~08 Welcome to the City of Angels :) (timestamps PDT) 00:56 and this is the most socially backward an uncivilsed place I've ever been 00:56 huh? California? 00:58 LA, specifically 00:58 yep. That's us. 00:58 :) 2002.09.17 ~19 Q3 mod commentary http://www.linux.ucla.edu/~phaethon/q3mc/outline1.html A few weeks ago, I decided to write out a "execution trace" description of a Q3 mod, using baseq3 (the default Q3A game) as the example. Next I plan on describing the "unchangeable" structs in q_shared.h, then going on describing the gentity_t and gclient_t structs, then maybe bg_* structs, maybe pmove, perhaps some cgame structs. Other potential forks in efforts include commenting on functions themselves or doing an outline, of this style, for cgame and/or ui. 2002.09.16 ~05 Road trip to Mexico Family trip to Mexico (Baja California) over Labor Day weekend. Note for future: if planning a trip for Labor Day weekend to anywhere, make reservations at least a week in advance. More is better. Even then, the hotels in Mexico aren't that great. First hint of a bad night: the beddings reek of the insect repellent in which it's been doused. Just about the only thing in favor of a road trip passing through Tijuana, Rosarito, and Ensenada is cheap food. Dual-currency economy (peso & dollar) is kinda nice too... saves a trip to the currency exchange. 2002.08.26 ~06 Amber(?) Alert System on MSN There seems to be a recent spate of child kidnappings. Or at least a recent surge in high-profile kidnappings reported by the news radio station I listen to on commutes. One such case involved a girl named Amber, resulting in a child-abduction system dubbed Amber (or is it AMBER?). The basic idea is to that when an abducted child is feared to be in great danger *and* there is some publicly identifiable property/attribute of the abductor and abductee, law enforcement gets the word out to the public (via TV stations, radio stations, freeway signs(!), electronic marquees, etc.). Basically applying the Open Source/Free Software principle of having many many eyes identify and solve problems. I saw the system in effect one morning commute, on a freeway sign (dot-matrix LEDs, usually used to indicate serious traffic jams). While hearing it on the car radio. The vehicle description (some kind of white SUV, iirc), license number, and last known location at the time of kidnapping that morning were the identifying marks. The kidnapped children (two, I think) were recovered later the same day, before dusk (somewhere in the high deserts?). Anyway, cool idea. Currently, I think the alert system is merely county-wide in Los Angeles. Maybe it's extended state-wide, I'm not sure. There is momentum to propel the system nation-wide. One company is drawing up plans take the alert system to the net. Some kind of net. Just MSN, and I think in conjunction with Microsoft. Alerts going out to MSN subscribers only. Or something. Instant message and SMS messages. This is from where my concerns stem. Now, given Microsoft's recent and not-so-recent track record on security and virus propagation (IIS, MSOE, MSIE, etc.), in the first year of this MSN presence I expect no less than two "very serious" security breaches, almost-double-digit instances of "practical jokes" or "vengeance" alerts (say some disgruntled black hats getting back at their neighbors), and a handful of false alerts not attributable to oversensitive law enforcement agencies. This isn't a prediction. Just my own sadistic pessimistic expectations. I really do hope such a system won't mess up nor be abused, but I don't hold any high expectations wherever Microsoft sticks in its hands. 2002.08.11 ~04 Intermedial charged weaponry Finally came up with a hack to get charged weaponry to work. It isn't as clean as I would like, but it works for now. Large pieces of the source tree suffered manglings as I worked towards charged weaponry. Some data structures had to be rearranged, and I don't see as much potential flexibility as I would like to see. In any case, charged railgun works. I should get around to packaging this up now into another release. 2002.07.17 ~05 Charged railgun Q2WF sniper rifle was a charge weapon, in that the weapon "charges up" while the fire button is held, then releases its load upon release. The damage delivered is proportional to the time spent "charging up". I'm trying to find a clean way to integrate a means to allow such a charge time to influence the effects of a weapon and its projectiles. Thus far, there doesn't seem to be any particularly clean way. Large parts of the infrastructure may need to be replaced to accomodate charging in a clean manner. The current problem is that, for both ballistic and hitscan projectiles, the projectile has, within a single function, two distinct stages, an initialization of properties, then an actual instantiation of the projectile based on those properites. I initially attempted to squeeze a "modify properties here" bit of code between the two stages, but I can't see a way of accessing the appropriate re-modding code cleanly. Ideas are currently to use a global (tres ugly), modifying all relevant firing code to take a callback parameter (some overhaul), split the initialization and instantiation into two distinct functions that have a guaranteed sequence such that remodding code can just "pop up" normally in between (lots of work, especially ensuring sequence). Ponderances. 2002.07.09 ~06 NaN Blender blue sky http://www.blender3d.com/ On July 5th, Ton Roosendaal (head dude of some kind of Blender... or of NaN... or something) announced having reached an agreement with NaN shareholders to open up the sources to Blender. The majority stakeholder apparently is a VC firm called NetVenture. From what little tidbits and snippets I gathered since NaN tanked back in March, this VC firms seems the type to be bass-ackwards enough to "not get" the GPL. I *seriously* doubt Blender will be licensed under GPL. Well, that's the first of the blue sky: Blender under GPL. - File format Apparently the native file format used by Blender is a real mess. Hearsay has it that the file is "a glorified memory dump". Regardless, I'd like to steer away from binary format. Other folks pitching plans for Blender's future are rooting for XML. Personally, I'd rather use S-Expressions. S-expression is simpler than XML, it's less verbose, it already has a "natural form" for lists and aggregates, and it looks prettier than XML. Oh, and it's a small step to throwing in a full Lisp system :) I should probably draw up a proof-of-concept s-expr export in the current incarnations of Blender. - Python & Armatures Armature bones are currently inaccessible via Python (Blender's extensible language). This means automated/procedural animation of armatures is impossible, and must be all hand-animated. I feel this needs to be resolved first. - Blender210 module, model import There's a minor bug in Blender210.Mesh.addFace() which bit me during my development of a Blender MD3 import script. The method has six arguments: four vertices (index number into list of vertices defined earlier with addVertex()), boolean for smooth shading, and index number into the list of materials. Whether a quad or a tri is created is determined by the fourth argument. If it's 0, the method forms a triangle, otherwise a quad. The problem is that I often needed to make quads where the fourth argument is vertex 0. This leads to an erroneous creation of a triangle when I really wanted a quad. Although I could reverse the order of vertices, that would change the face normal to an incorrect value. The workaround in my import script creates a meaningless "throwaway" vertex 0 before the actual vertices, sets up the polys, then deletes vertex 0 afterwards. This bug needs to be worked out. I came up with three potential solutions: * Use "-1" to mean no vertex. This is ugly. * Use separate methods for quads and tris. This gets messy. * Based quad-vs-tri on number of arguments. 5 for tri, 6 for quad. This is potentially confusing. - Completing the menus The popup (SPC) menu could really use having all possible Blender actions thrown into it, possibly also allowing reconfiguring of hotkeys GIMP-style. - Intersect sucks The closest thing that Blender has to a boolean operation is its "Intersect". The results are often ugly and splintered, especially when both objects are complex. I have no idea if I'm up to snuff to improve this, but it's a wishlist item nonetheless. - Ogg Vorbis I throw Ogg Vorbis at everything. - Blender Game Engine Neat-o feature, but sort of distracts from Blender's modelling/animation roots. On top of that, activating UV-texturing starts doing weird things to shaded mode. This isn't reversible until Blender is restarted. Even without this annoyance, I'd prefer the game stuff to be clearly separated from Blender, either plugin-ish or moved into a separate project. The current Blender python modules already split the gaming stuff from the modelling stuff, anyway. 2002.07.04 ~09 Q3VM bit vectors A few days ago I implemented a form of generic (compressed) bit vector. It uses an array of int, and packs 31 bits per int (for reasons of overflow and sign). Bits are accessed by bitshift, in sizes from 1 to 31 bits (values passed around via int). The initial purpose for the bit vector was for my mod implementation of multiple-pierce hitscan (viz. railgun). The original (unmodded) railgun uses a three-element array of ints, to hold the entity number for each object pierced (up to three). My rationale was that such limit is arbitrary, and decided to expand it as much as possible. The most obvious extension is to expand this array to 1024 elements of int (maximum number of entities possible). That leads to 4*1024 = 4KB memory use, and most of it unused since there aren't many weapons that will be infinitely piercing. Just to keep track of a yes/no state. This led to wishing for an array of bits. Thus the implementation. At 31 bits to the word, and 1024 bits, this resulted in 34 bytes to record entities pierced. Major win. A general bit vector of arbitrary length can also lay the foundation for bignums, integers of arbitrary size. 2002.06.27 ~10 bg_lib.c vsnprintf() http://www.linux.ucla.edu/~phaethon/q3a/vsnprintf/vsnprintf.html Probably one of the more subtle omissions in the Q3A game/mod source is snprintf() (and vsnprintf()). This had been on my mind for many months, since I always wondered about buffer-overrun situtations, but I never paid it much heed, relying on "big enough" buffers and va() (with 32KB buffer) to avoid buffer overruns. The lack of snprintf() in Q3VM surfaced again while chatting away on IRC. This time around, I actually felt competent enough to pull off an implementation of vsnprintf(), and did it for the heck of it. Well, actually, I had nothing else to do at the time, but having sprintf() is very handy, especially in Q3VM's limited memory. Basically vsprintf() and three of its support routines were modified to take an extra parameter (the `size' parameter) and add a couple more state variables. A macro was thrown in for simplification, but it makes the code look a little uglier. That was about it. 2002.06.23 ~08 FI CVS branch merging Yay. My first shot at CVS branch merging. Branch "qs-tinyscheme" merged into trunk. Now the version QuakeScheme built on top of TinySCHEME is in the trunk. This should have actually happened a couple months ago, but I forgot about it when the web CVS access stopped working for FI and I didn't get to browse the CVS repository (and its ensuing branches) GUIly. 2002.06.23 ~07 FI decoys and count limits A lot of credit goes to Inferna| on irc://irc.enterthegame.com/#br for giving me a push in the right direction. Limiting the number of simultaneous instances of a projectile per player is now implemented using an array of reference counts. The actual limit value is stored with the projectiles definition in the weapons config file. This limits some of the insane configurations I've been dreaming up, but for the most part such restrictions are sensible for what amounts to a WF clone. The decoy has been solidified. Now I can stand on my own decoy and shoot it with just about whatever. Gauntlet is acting buggy, though. Currently the number of deployed decoys isn't limited. In most MOCK cases, having more than one decoy doesn't make a whole lot of sense. Still, I'd like to mull over whether the coding design for decoys is "good" or not. 2002.06.23 ~00 Puter problems My K7/1200 has been acting up lately. It may or may not be related to the onset of summer. In the K7/1200 (anticleia) are... were... three HDDs and an internal IDE ZIP100 drive. Of the HDDs, they are labeled 4GB, 2GB, and 400MB. The 400 MB bit the dust, and now I'm down 400MB in swap space to 160MB (80 per remaining drive). OpenGL use has started to destabilize anticleia. This might be related to using GATOS drivers, but the summer heat certainly isn't helping. A long time ago, the PS/2 controller in anticleia fried. Dunno how. Plug a keyboard (or even not) into the PS/2 port, and the keyboard buffer fills with complete garbage. At least Linux doesn't accept the rubbish -- initial handshaking with PS/2 keyb fails, so the port gets ignored. Perhaps related to this, APM sleep mode fails. Well, actually, waking up fails. Nothing can get anticleia out of APM sleep mode, even pressing the power switch (which is supposed to trigger the ACPI sleep signal or whatever). The fileserver/router, a K6-2/350 (penelope), has suffered from a series of reboots lately. Most were related to using the CD-RW drive (jamming up or whatever and taking down the kernel and CPU with it). I'm thinking of switching around the ZIP100 and the CD-RW drive next time penelope reboots. All in all, this has wreaked general havoc on my development efforts. I normally have about 30 local shell sessions going (20 on penelope, 10 on anticleia), all doing different things. A reboot means I have to take time to go around and re-establish sessions. Sort of makes me wish for a persistant-object/state OS. 2002.06.12 ~17 X-Wing nostalgia It's been many many many years since I played Star Wars: X-Wing, the space combat simulator. Never played it again ever since that hard drive crashed (a whopping 345MB...). Recently, however, there appears to be a surge of re-release/re-package at Fry's Electronics. A large number of old-ish games repacked into a simple shrink-wrapped jewel case (instead of a massive box large enough to hold a couple trans-Atlantic oil tankers). Among the LucasArts games in said small packages were X-Wing, TIE Fighter, X-Wing Alliance, Dark Forces (1), Rebel Assault II (where's 1?), and X-Wing vs TIE Fighter. What I distinctly remember is the original X-Wing running under MS-DOS. This X-Wing CD required Microsoft Windows and DirectX something or other. This suggested (a) someone, somewhere, is doing an authorized maintanence of this stuff, and likely to do so well past the expiration of MS-Windos XP, (b) trying to get this to work under WINE will probably turn out to be a fscking PITA. Similar thing with TIE Fighter: I remember it originally ran under DOS only, and the CD cover stated MS-dows as a requirement. I decided to get X-Wing vs TIE Fighter, to get the basic feel of both the Rebel and Imperial snubfighters in one package (I only got as far as the TIE Fighter demo version before the hard drive went farming). It also stated network play (at 8 max... oh well). WINE 20020610. Installation went mostly well -- at least all the files made it to disk. Startup was a problem; XvT (and apparently the other space combat games) use a launcher app. The launcher kept wanting to install DirectX no matter what. There was another executable, z_xvt__.exe, which looked promising (weighing in at 1.7MB, over xwingtie.exe's 200K, I figured this was the meat of the game). Intro played fine... sort of. After six seconds, the WINE debugger popped up. More strings(1)'ing. Found "skipintro" option. No more debug window, but now the "Create Pilot" dialog appears. No keyboard input recognized. Dammit. Visit LucasArts support. Visiting X-Wing downloads to get topace5.plt pilot file. Plop in and hope for best. XvT gets to main menu ("Data Pad"), crashes. Try brute force, "echo foo > foo.plt". Starts fine, pilot data repopulated, but name ends with a funny glyph. Probably the newline. Try again, "echo -n foo > foo.plt". Start again, pilot data repopulated with initial data, name looks fine. Keyboard still ignored. Try an actual combat. Briefing works. Start mission. Says "Prepare for mission launch". Crash. Presumably related to 3D gfx. Error messages mention some WINE function with the string "MESA" in it. It maybe not even be related to 3D per se, since the line after mentions a function about DirectSound and setting Cooperative Level. WINE dies with error 254. Probably I'll just wait for WINE to mature. Either that, or try to whip up an SDL based engine, which would be an overwhelming task to do from scratch. Pondering... 2002.06.09 ~17 Q3LCC-ZINX Wow. I didn't expect zinx to solve it that quickly. With patches by zinx, I actually manage to get .qvm files with the same md5sums as the id-provided q3lcc. Way to go, zinx! Now to update the page... 2002.06.09 ~14 Q3LCC-PH v1 http://www.icculus.org/~phaethon/q3a/q3lcc-ph/q3lcc-ph.html My next major hack is showing progress. Since the sources to q3lcc (modifed lcc for Q3 mods), I started my endeavor to modify the stock lcc to see if I could make it Q3VM-compatible. A few weeks ago I had modified lcc sufficiently to accomodate the widths of data types. However, that wasn't enough -- Q3 consistently crashed on the resulting qvm files. Some groveling through the assembly files (*.asm) showed an opcode/directive not found in stock lcc: "pop". Comments in q3asm indicate this is an opcode to discard the return value of function calls. One pattern was that all CALLV (call to function of void type) were followed by a "pop". I took this to mean that even void functions returned a value (despite the meaning of "void"). What I also noticed where the some CALLI (call to function of unsigned integer type) were followed by "pop", but most weren't. Some pattern checking showed that the return values of CALLI were discarded if the return value wasn't used for another operation immediately (such as for assignement, comparison, or arithmetic). This pattern also held for the other CALL* variants. Groveling through lcc-4.1/src/bytecode.c led to a pretty evil hack tha brute-forcefully checks if the return value of a CALL* is used. CALLV did not need to be special-cased, as the return value of CALLV is never used. I don't think qvm worked yet at this point. When I got this far, I sort of back-burnered further modding. A few hours ago, zinx on irc.openprojects.net piped up regarding sources to q3lcc. Apparently my patches to q3asm have been making the rounds, as I've been called upon by name regarding lcc. Apparently zinx was determined to patch stock lcc to be qvm-compatible, and so I started sharing what changes I had so far. To figure out what I had to change, I had to read through the lcc sources again. Freshened up on the lcc source again, I decided I might as well continue with my own quest. The big stickler was CNSTF4, opcode for loading a floating-point constant. The canonical q3lcc outputs an actual CNSTF4 opcode, but my patched lcc turns this into "ADDRGP4 floataddress; INDIRF4", i.e. loading the float value from the data segment via indirection rather than placing the float value inline. In my search, I found where float is parsed, in lex.c. What I thought was happening was that when lcc reads in a literal floating- point constant, it would type it as a double, then attempt to spit out code for loading a 64b double indirectly, but that the data-width mods changed the INDIRF8 to INDIRF4. Though I eliminated setting type as double (to float-only) in lex.c, CNSTF4 was still coming out as "ADDRGP4; INDIRF4". I decided to try compiling qvm with the changes anyway, and surprisingly, Q3 didn't crash. I even went to the extent of eliminate any traces of the original linuxq3a-sdk I had. Still no crash. "It compiles, ship it". I'll bang on it some more later. In the meantime, zinx is busy tracking down the CNSTF4 thingy. 2002.06.04 ~15 FI decoys Weapons Factory has a feature called "decoys". These are solid objects that are visually similar to the owner, and little else -- no health, no armor, no weapons, no controls. The idea is basically to momentarily deceive enemies, usually to get them to waste a shot or expose their position(s). Perusing the source code, I extracted decoyness from CopyToBodyQue(), which replicates the player's body as a corpse that lies around. The player entity is always within 0 to 63, and other game entities are 64 to 1023. Since the player and their past-life corpse can coexist, CopyToBodyQue copies all properties of the player (0-63) into a game entity (64-1024) so that two separate (identical) bodies can coexist, but the player entity is always under control by client (client 2 always controls player 2, etc.). Basically I duplicated CopyToBodyQue() and changed some of the copied properties so that the replica is standing (or at least not lying down). The problem is that I can't seem to get the model to be solid. Splash damage can destroy the decoy, but direct damages (bullets, rail, gauntlet) pass right through it (including players!). One hint is that client-prediction wants to clip at the decoy, but the server says to go ahead and pass through. I'm thinking I should attack bg_pmove.c, but I'll still poke around anyway. 2002.06.01 ~16 'dows woes Local gamehenger Chunky Kibbles ranted about Windows XP. Reminded me of my wrastling with it's incestuous parent, W98. So here's the gig. I play Tribes 2 under our favorite penguin's choice of OS. For one reason and another, the T2 builtin VoIP are (a) incompatible between T2.Linux and T2.Windows, (b) just plain sucks in general. The T2 tribe/clan I'm in uses an out-of-game VoIP called "Roger Wilco", by Resounding Technology(?), now a wholly-owned subsidiary of GameSpy Industry (GSI), another company I have some serious beef against. To put a long story short, RW is available only for Windows. Well, there's the "server" end of RW (to relay packets) available for Linux, but that's about it. No actual codec'ing under the penguin. Cue WINE. It failed miserably. Cue my hand-me-down laptop computer from my sister. This laptop suffered a very dead screen when someone accidently stepped on its closed form while unattended, cracking the LCD screen. No one fessed up. In the time since, she has (a) gotten a desktop worthy of... Counter... counter-something FPS, (b) stopped being a nomad requiring a portable. This machine I have dubbed Polyphemos, after the cyclops who's (single) eye was poked out by Odysseus in Oddyssey -- the screen does sort of look like someone took a pole straight at it, albeit way off to the left side. It's a Pentium II-based Celeron/400, with a meaty 64MB RAM, and 4GB HDD, imbued with the curse known as Windows 98SE, and a Phoenix BIOS that is hopelessly glued to the hip of FAT FS for Save-To-Disk. It has since been sprinkled with the holy water known as Debian GNU/Linux, but it still suffers from split personality, primarily because of the Save-To-Disk. On the darker side of its personality, there was a mass of cruft collected over two years of use by my sister. I wanted to reclaim much of the space so that (a) lots of 'dows crap will be rid, (b) I can set up a Q3 server. This, as far as I can recall, is the first time I voluntarily elected to boot into Windows since 1997 (all other boots since being involutary, forced, or otherwise accidental). I decided to start on diskspace recovery. Calling upon skills lost and buried since 1997, I managed to get to "Add/Remove Programs" and started picking on anything starting with "Microsoft". Click remove. "Are you sure you want to remove" type dialog box. Yes. "Windows now requires a reboot for the uninstallation to be complete" type dialog box. No, I have more cruft to remove. Go on selecting a few more, with the same cycle of Yes and No. Can't think of anything else, so close the control panel thingy and reboot. The programs didn't disappear. They stayed there, in the dialog box and all the menus, mocking at my vain attempts at removing them. The sadistic humor dawned on me. The only way I was going to remove all this cruft was by individually relecting them for removal... and rebooting after each and every selection. After rebooting probably more times in two hours than everyone on lkml does during an entire x.{odd-number}.y development cycle, combined, I came to the issue of lookOut Express. For security reasons, I wanted this gone gone gone. But, lo and behold, it failed to list itself in the Add/Remove doohickey. I could probably attack the binary directly, but, knowing the predecessor Windows 95, that would leave all sorts of cruft behind, perhaps even more cruft than before deletion. So, at three in the morning local time, I visited the only place where I knew others dabbled in the dark side of the force, #linpeople. The instructions I received weren't hope-inspiring, but it was something: grab MSIE6 to install IE6 and OE6 so they appear in the Add/Remove, then remove. I should note at this point that networking has not yet worked under Windows. Under my sister's usage, it interfaced to a USB-to-Ethernet dongle (borrowed from a friend, and returned since). Under Linux, the machine uses a Linksys PCM100 PCMCIA card (which works great). Apparently Windows doesn't know how to use this. I started the download of the 30MB zip file at a *cough*whopping 22KB/s (of 150 cap) to my main desktop. In the interim, I fiddled with other stuff. After a significant portion of this zip file came through, I realized how Windows could be made to recognize and use the Ethernet card. This was shortly after, out of desperation, I reopened the box the Ethernet card came in. Sitting in there was a floppy disk. In some ways, I probably spent too much time in GNU land. I had LONG forgotten that in Windows, device drivers are packed with the hardware, rather than the operating system. Plop in floppy, and hope for the best. It crashed once upon attempting to install the driver. I should probably specify that the installer crashed, not Windows as a whole. That happened a short while later. Try again, says driver got installed... and needs reboot. Reboot. OK, so it continues with whatever the hell Windows does for driver installation. Then came more sadistic jokes. BEFORE the shell even started, IT REBOOTED AGAIN. No prompt! No shell! Poof, reboot! WTF?! Navigate GRUB menu for the nth time... Install Mozilla 1.0rc3. Reboot again... Eventually the IE6 zip finishes. Now to get it get from desktop to this laptop. Network Neighborhood? Claims I didn't enter a password for networking. Try a different tact -- pull over HTTP (using Mozilla and Apache). That worked. But there's nothing that understands ZIP. I have no idea why my sister never bothered with that WinZip thingy. Visit cygwin.com. More installations. Least I get bash now. And reboot wasn't required. Nice change of pace for once. Unpack ZIP, run. Dunno why I have to agree to a license agreement when I want to wind up removing OE. IE6 and OE6 install. The GRUB menu is starting to get annoyingly familiar and frequent. Post-reboot rest-of-installation of IE6 and OE6. Really, seeing GRUB again so quickly can gnaw on your bones. Then I proceed to select IE6 *and* OE6 for removal. *sigh* Maybe I should patch GRUB for animation or something. Removing IE6 and OE6 only managed to restore the previous OE and IE, MSIE5 and MSOE5. These don't appear for removal. So I look for OE's base directory, looking for uninst-something.exe. There isn't any. On a mad (both senses of the word) impulse, I exported the registry via regedit and sicced grep upon it for anything mentioning "outlook" and "uninst". This actually turned up something useful, the command line to remove MSOE5. The invocation was such: "SETUP50.EXE /APP:OE /UNINSTALL /PROMPT". Query if I want to remove. Of course yes. And of course, we meet our dear friend GRUB yet again. OE was the last thing that needed to be purged. IE is of course an inseparable and integrated (... humor me) component of the operating system, so I leave it be. Defrag time. I forgot what I did during the wait. Maybe I ranted on IRC, maybe I tried stupid rocket-jumping tricks in Quake 3, maybe I read Slashdot comments back-to-back, maybe I measured glacier movements, maybe I fell asleep. Eventually the defragmenting finished. Then it was time to install Roger Wilco. Never knew a sunrise could feel so strange. Installing RW went fairly straightforward, as Windows programs go. At least GRUB could remain sleeping. Some minor wiring to set it up as satisfactorily as possible. Microphone to laptop's soundcard, laptop's soundout to desktop's line in, old PS/2 mouse plugged into laptop and used as the "transmit" button (with my foot). Then I find out I won't be able to actually test this setup since the next tribe practice is in two weeks time, as next week is filled completely with matches. Sigh. TODO: rant about RW with emphasis on porting TODO: rant about GSI 2002.05.27 ~00 PiNGer.JPEG http://palmboxer.sourceforge.net/ What is now known as ZBoxZ was known as Palmboxer, prior to a sawfishian (re)naming... incident. ZBoxZ is a GPL'd file manager application, with several satellite applications (plugins, if you will). Among them is PiNGer, an image viewer, to view files packaged in "boxes" (some sort of PDB encapsulation of files), which supposed displays GIF (87 and 89) and PNG images. So far only PNG works (as an aside, the GIF portion was based on gif2png, but a source check against gif2png 2.4.2 shows the GIF code in PiNGer to be inconsistent). I spent the last couple of days banging on PiNGer for JPEG support. One breakthrough discovery (for me, at least) is an alternative PalmOS library mechanism called "GLib" (no relation to GTK+'s glib). The original library mechanism, SysLib, requires all library functions to take a library refnum as their first argument. Eyemodule (a Handspring Visor camera thingy, http://www.eyemodule.com) already did a port of IJG's JPEG library ("libjpeg") to PalmOS using the SysLib method, requiring a mass of wrapper code to expect the refnum argument. Unfortunately, Eyemodule's JPEG port only covers the compression half (i.e. from Eyemodule image data to JPEG-in-PDB). GLib, on the other hand, doesn't require this refnum passing doohickey. I suspect this is based on using one of the spare registers on the M68K. In any case, porting existing *nix libraries is more straightforward, since the necessary state munging is left to the compiler instead of the developer. There are still other brick walls, like the 32K code segment limit. Which libjpeg slams into at 130KB. Cue a prc-tools hack, the multiple resources mechanism. The basic idea is to divvy up the code into a bunch of <32K segments, then glue them together with jump tables. The developer still has to mark how the code will be split, but the glue stuff is done automagically by the tools. This method comes with a cost: reaching across the boundaries is time-consuming. What is not clear to me, though, is whether using both GLib and multiple resources is canon. I've already marked libjpeg for the various sections, and already set it up for GLib-style shared-library compilation, but linking this to PiNGer and using a jpeg function causes catastrophe. Then I tried regular static library (.a) linkage without multi-res. That broke 32K easily. Then I split up PiNGer and relinked. Near as I can tell, it falls over when it dereferences a function pointer to a function in another segment. Nonetheless, my meddling in PalmOS programming is enlightening me on matters of Q3 modding. In particular, toolchains, library, C extensions, limited environment, assembly. 2002.05.23 ~11 Shazbot Wow. Hit the end of that search quickly. Bad news: http://zerowing.idsoftware.com/archives/gtkrad-macos/2001-November/000096.html Worse news: http://www.timedoctor.org/gimps/byzakk/bugging.jpg Heartening news: http://zerowing.idsoftware.com/archives/gtkrad-macos/2001-November/000104.html Conclusion: time to start groveling through (stock) LCC source. :( 2002.05.23 ~10 Where be them damn LCC patches Google searches stumbled across J. Carmack's .plan entry for 26 Aug 1999, mentioning "[the] modified LCC and q3asm will be available both in source form and precompiled,...". I found the q3asm source, but I can't find the damn patches to LCC. The biggest difference I can spot (between "canon" LCC and Q3's LCC) is the usage of a special "pop" instruction added to the Q3VM to no-oply consume the previous value (as with a void function (which actually returns a value on the stack anyway) or an integer return value not assigned to a variable). I'd rather not grovel through the LCC source tree to try patching it up by hand into q3lcc. 2002.05.17 ~11 Project FI zlib For the hell of it, I threw in zlib to the compile pipeline. Only two modifications were needed to compile cleanly: (1) getting rid of "short" (16-bit integer), which QVM bytecodes doesn't like for endian reasons, and (2) defining fdopen(), which zlib manages to use some place. Actually, fdopen just returns NULL (signifying error (to wit, "not implemented yet", but errno isn't set properly (there's no EDAMNPROGRAMMERWASTOOLAZY))). This is only sufficient to get an error-less compile. Actual (de)compres has not been done. I'm not sure how the semantics would change, especially since "short" was simply jacked up to a full "int" (32-bit), and there are all sorts of short-based offsets and (de)referencing throughout zlib. OTOH, Ogg Vorbis used arrays of shorts, and promoting those didn't break it horribly. The fdopen() whacking disturbs me, though. There's only one use of fopen in zlib, and that's just to (re)generate the compile-time file trees.h. All other functions related to I/O points back to fdopen(). Trying to implement fdopen() in QVM is quite non-trivial. It basically goes something like this: EOF is determined by recording the file length and checking current file position against that. File length is obtained at open time as the return value of trap_FS_FOpenFile. This trap will only accept a file name (to specify a particular file). File name is not recorded elsewhere by the trap, i.e. there is no native means of obtaining the file name give the file handle/descriptor. In effect, given just a file descriptor, EOF-ness cannot be determined, as the length is not available. The return value of trap_FS_Read() will return the final character of the file upon EOF; in this regard, a repeat character is indistringuishable from EOF state. There are a few attacks at this problem I can think of. One is writing wrappers around the traps (the trap_*() are already wrappers around a generalized syscall trampoline), to keep track of the fd-filename association. Another is to just traverse the array of stream objects, searching for any member that has a record (bad pun) of the given file descriptor in hand, then resurrecting or copying the object. Another is to cannibalize parts of PalmZlib that may help with regards to I/O (fdopen in particular) in a crippled environment. Or maybe a combination. Yes, perhaps a combination... 2002.05.16 ~06 QVM-bytecode libraries I was pondering the separation of the libc files into a separate directory. This would mean altering the compilation scripts (bash scripts) to deliberately reach into the libc directory, compile each file to assembly, then explicitly link the resulting files. Then I wondered how I could cut down such tediousness (i.e. editing a couple files to list every single file affected). One method that sprung to mind was using ar(1), creating .a files for each distinct library packages, e.g. libvorbis.a, libc.a, libz.a, etc. These .a files contain distinct .o files, each derived from an associated .c file (for the most part). The .a file can also contain a symbol table, an association of symbols to locations within the .a and .o files. So for each library package, an associated .a file is created. Then if some symbol "funcfoo" was needed, the linker (q3ld?) can look through some existing .a file (e.g. "libmystuff.a"), find "funcfoo" is defined in "foo_bie.o", extract "foo_bie.o", and link it into the resulting qvm, taking into account adjusted offsets. The end result is a simplification in adding new external sources. I would no longer need to edit the compile scripts to list every .c file to look at, every .asm file to link. Instead, I would need only to compile each "library package" separately into .a files, then leave the tasks of searching and resolving to the linker. To do the adjusted offsets (of symbols) would mean needing some kind of structured format for the .o files to keep track of "normal" offsets. Using an already existing format, such as a.out or COFF or ELF, would allow using standard ar(1) and ranlib(1) to create the .a files (and its symbol table). Doing so would also save me the trouble of trying to come up with an appropriate format then re-extending it repeatedly in the future :) This could mean utilizing GNU BFD in some form. At this point, I realized something chilling. The .a files are self-contained; they don't "depend" upon outside files for its content. In other words, it would be very much "drop-in". Binary drop-in. Libraries could be distributed without source. 2002.05.14 ~01 Nightmare flashback So I was just driving along and out of the blue came a flashback of a nightmare I had several years ago, when I was in middle school (jr. high). Well, more like a recall, but "flashback" sounds more dramatic =) The details are fuzzy, but the major points were basically these: a world (or city, rather, as my "world view" at the time was rather small) where there is a central "operating antenna", resembling a tower radio antenna, by which automobiles are able to run. All automobiles in existence had to check through the antenna in order to run at all; those that didn't failed to start. So far things are already deviating pretty wildly from reality. The scary part is when the antenna failed. It just lost power suddenly; looked like a major power outage (blackout) to me. In any case, the result was that all cars stopped immediately (engines just choked to death) and could not be (re)started. I was stranded. Mind you, most of my life was spent in and around Los Angeles, California, driven around by my dad to one extracirricular activity to another. This is a city where "mass transit infrastructure" is a Bill-Clintonism ("it depends on your definition of 'mass transit'..."). So being stranded in some remote place with means of transportation seemed plausible at the time. So, anyway, thus far, this "central automobile antenna" died and all cars were rendered useless on the spot until at such time power was restored (and I don't remember that happening...). And so I was stranded in some remote pocket of the world (or rather, L.A.). Far away from home. This is rather terrifying for a 12-year-old raised in a "traditional" nuclear family. Sounds crazy so far. And rather irrelevant. But as I pondered through this nightmare, I found a parallel to the modern world. Not cars (yet), but rather software. Think about it. The fascist licensing models used by a disturbingly increasing number of software [of any kind] where authorization to run, much less even to start (or even install), must be cleared through a centralized inet server. Should the connection be severed or denied, for any reason, the software dies, perhaps taking (live) data with it. This would be different kind of stranding, but just as terrifying as in my nightmare. In some ways, more terrifying. Denied the means to support myself (or be supported at all) by an external force beyond my control. Should the central server undergo a sudden failure in existence, no amount of money thrown anywhere will help resurrect such bondage software. And without source, no amount of time spent will help either. And at the rate current US legislation is headed, no amount of technical genius would help either (as it would be outlawed). I frequently reflect back on my views of Free software over the years since I was first introduced to GNU software and stumbled upon the *nix universe. At first, I found libre software to be "cool", as the philosophy of GNU and other free software oufits happened to overlap much of my thoughts and philosphy that I had developed independently of the *nix community, interestingly enough (e.g. the value of source, the value of sharing, the crazed notion of claiming loss of money never headed your way in the first place). Then I found it "convenient", as Linux easily stepped around the 2GB BIOS fiasco (PC hard drives) of the late 90s, and Debian GNU/Linux magically fixed itself from a libc5->libc6 bung-up (I still have no idea how it did that; I swear I f*cked up the upgrade!). Then it became "practical", as libre software let me do what I want to do, rather than be limited by the [original] author's notion of what ought to be done (cases in point: Window Maker customization, sawmill/sawfish customization, three simult XFree86 sessions, massive cheats hacking into snes9x (Super Nintendo emulator) like rapid-fire and joystick macros). In some ways now, I see libre software as "critical". When I was 12, the notion of automobiles umbilically tied to the functioning of a single operations antenna terrified me. Nowadays, the notion that software being similarly tied to a centralized inet server is fairly terrifying. The notion that the mere existence of my data, and/or my ability to use my own personal data, being intimately linked to the market performance of some company, is contrarian to the notion of personal liberty, never mind conflict of interest. If I'm driving a Ford F-150, I really don't want my ability to start and drive the truck to be intimately linked to whether Ford Motor Co. will decide to continue the line or not, or whether they might declare bankruptcy today/tomorrow/next week. In today's world, I (among many) would consider silly the idea that a car would suddenly fail to work any more simply because the associated car company said so. I'm not certain if contemporary proprietary software has reached this far, but, to me, this seems a very likely scenario given current trends of "subscription" (more like "rental") software. Libre software certainly is among the solution to ensuring that the free market stays free, without any one company's dictate controlling the activities of any other company beyond the force of "The Market"/"The Invisible Hand". 2002.05.07 ~17 "static" support in q3asm Ogg Vorbis reference library makes a few uses of the static keyword for some functions. Staticness is recognized by q3lcc, and it shows in its assembly output; static functions do not have their symbols flagged for exporting. The linker, q3asm, blithely ignores staticness, along the lines of: else if (!strcmp(token, "export")) { } else ... In effect, all functions are exported; static functions aren't static. Although I already patched Ogg Vorbis to be static-less, WIBNI q3asm properly understood the [not] exporting function symbols. 2002.05.07 ~04 Q3 libc My reimplementation of various additional Standard C functions for Q3VM is growing large enough to be its own project. I'm thinking of moving the files into a directory of its own, in both the CVS and (home) web trees. The game/ directory is starting to fill up with too many bg_* files. 2002.05.06 ~08 Spider-Man the Movie Yesterday I watched the Spider-Man movie. Overall, I was very impressed and satisfied. I think sticking to the original comics (story-wise) really helped with the quality; this particular movie displayed a level of cause/effect, consequences, and reflection deeper than the usually Hollywood cruft. I am very *UN*familiar with the whole Spider-Man story. My exposure to Spidey have been primarily limited to offhanded remarks, a handful of cartoon episodes, and hours of watching "Marvel vs. Capcom" (1 and 2). Still, I was quite aware the original Spidey was created a few decades ago, definitely before 1985. In light of this knowledge, the "era-syncing" in the movie really impressed me: cellular phones, car models (no years shown :), ubiquity of computers (somehow everyone could afford LCD flat panels...), and the newspapers listing of Help Wanted for computer jobs when Uncle Ben browsed though it (Comp. Analyst, Comp. Salesperson, S/W Engineer, etc.). The opening scenes in the movie (opening credits) were quite engrossing, despite the fact it was minutes upon minutes of miles upon miles of CGI spider webs. Later through the credits, though, are flashes and scenes of characters, buildings, and swinging flight paths between buildings. A look at things to come, sort of. I do recall [original] Spider-Man resulting from the bite of a radioactive spider. The movie slighty modifies the spider to being a genetically- engineered spider (broken free from its cage), inducing a DNA alteration in Peter (but overnight transformation is still pushing it, puberty or no puberty...). I find this more plausible than $random_radioactive_object, but I think the significant theme in this part of the story is $freak_spider. Sort of reminds me of the way the ancient Greek mythos were passed by word of mouth from generation to generation, with the details being updated with whatever was contemporary at the time of telling -- radiactive then, genetically-engineered now. I certainly think the field trip scene vastly differs from the original comics -- 40-ft scanning electron microscopes certainly weren't available in '85 (at least one dedicated to arachnology). Although what arachnologists need with a such a huge SEM is beyond me (direct DNA observation is about the best I can think of). Still, the lab scene gave interesting foreshadowings to Spider-Man's ability: insane jumping (hunting spiders), obscene web strength (never mind the organo-vs-mechano webbing flamefests), and short-term premonition ("Spider sense"). The gen-en'ing going around in the movie certainly made me think this fantasy world would've somehow gotten all these abilities wrapped up in one specimen. Oh yeah, and the lab was decked out with LCD flatpanels and plasma screens. Peter's first day of Spider P0W@HZ was enjoyable to watch. My particular favorite is all the eye-candy slow-motion right before Peter dodges a locker-denting punch. Also, the explanation for Spidey's wall-crawling ability cleared up one of my biggest questions, even if it isn't the original's: retractable bristles/quills (they reminded me of barbed bee stingers, actually) on the hands that cling (in)to surfaces. After the movie, I did some very raw mental calculation and concluded that each "quill" would be sustaining roughly 0.5 to 1.5 lbs (220 to 680 g) each if used as the sole means of support. Not too unrealistic, IMO. The stretch of experimentation was also fun to watch and ponder. I suppose the process of discovery and experimentation is something that piques the interests of introverts everywhere. This paragraph may have been unnecessary. Then there's the webshooter. I was very certain (original) Spider-Man had to construct mechanical webshooters; something about fooling around with formulas and one time really f*cking things up with his webs as a result. The movie has "organic webshooter"; "built-in" webshooters as a direct result of the spider bite. The rest of the movie flowed pretty well with the organoshooters, but organo raises a few [other] questions for me. Such as: that's a helluva lot of web -- eat hearty dude; normal spiders have a web sac that contains liquid that turns solid upon hitting air -- does his arm have enough room for both sac and muscles?; how does Spidey reel back into the rafters -- sucking the web back into his arms? And so on. Costume. Peter goes to a ["pro"-]wrestling match to nab an 'easy' $3K with his new superpowers. He goes with a dorky-looking outfit: pants, silk- screened sweater(?), balaclava. This despite Peter having finished his concept drawing of the outfit commonly associated with Spider-Man. Then his uncle gets killed. This is the part of the story that had me notice the depth of cause/effect and consequences was deeper than most of the other movies out of Hollywood I've watched. Later on, out of the friggin' blue, Peter somehow obtains the "real" Spidey costume... with raised embossed lines and whitish plastic eye ports. This is just screaming "I am f*cking expensive!". Yet this kid just starting college and working his way through obtains this costume without anyone noticing. And it's tough material: it takes a point-blank shrapnel grenade to even tear off half the face mask. Seriously, the Spider-Man outfit literally pops out of the fscking blue. One day he doesn't have it, the next day he's swinging around among highrises with the trademark Spidey suit going crime-busting. Green Goblin. Some reviewer said the GG (costume) was a bit cartoonish. I agree somewhat. Much of the facial form is (understandably) exaggerated, but little of the face inside is viewable, nor shows through (at least Spidey's mask deforms as his jaws move). This would explain why the movie had a few times the Goblin's mask's eyes open to show the person's eyes underneath. And the movie's Goblin mask is (thankfully) much less scarier than most clown faces. And in another one of those Great Unanswered Questions... where the swutting heck does that costume come from? I've never seen it exist anywhere but when Osborne gets all pissed and suddenly appears in that costume/armor. At the end of the movie, I expected a Darth Vaderish laying down of the mask next to the dead body. But the GG costume just ups and disappears. Like the way it appeared. Really irritated me for some reason. I expected at some time during the movie to see the entire vacated armor in a closet or something. Green Goblin's glider/flyer/whatever. Enjoyable back story to it (result of human performance enhancement widgetry research [hovercraft airfoil], which conveniently was done within the confines of Osborne's/GG's company Oscorp, and thereby provided a convenient mechanism by which GG obtains a means of transportation), except... good grief... I don't think even Star Trek had devices so gaudily packed with widgets and whizbangs. The Sadistic Choice -- love or duty with death(s) on the line. Seems every superhero faces one. Is this some kind of running gimmick among all comics or something? I know Batman faced one, I'm pretty sure Superman faced a couple, and heaven knows how many the members of X-Men faced. When GG was giving the speech on "The Sadistic Choice", I was wondering if he was talking about the entire superhero genre in general. Actually, I think he was, but it sounded more like he was preaching to some vague audience than to Spider-Man in particular. The scene was borderline cliche for me. The final showdown. About when the tides turn, I'm reminded of a quote from some place -- when you have your enemy/ies down (but not out), don't ever give them time to build up a second wind (especially by gloating or excessive taunting). In any case, Green Goblin's final strike was about as predictable as Wile E. Coyote's attempts as soon as I saw the glider levelling with Spidey's back. Let's see... I face Spider-Man square on... I try to sneak up my massively huge glider right behind him to try to impale him full speed... all three entities are colinear... gee, I maybe I'll be in the line of fire. Looks to me that Osborne never used a gun (rifle in particular) seriously, otherwise the concept of "overpenetration" would've dawned on him before calling for his glider. Or maybe he was going for kamikaze: "I'll take you out even if it takes me out as well". On the whole, an enjoyable movie, especially since I don't know enough to be nit-picky, but knew enough to have a clue where the next few minutes were likely to be headed. In the meantime, I'm pretty certain the first dozen hits for Spider-Man on Google are inundated, so I'm avoiding hitting up any Spidey-related info for a week or two. This movie just screams sequel. I just hope the title won't wind up corny. 2002.05.01 ~09 Ogg Vorbis in QVM Nailed the problem. It was a faulty ldexp() [re]implementation. Decoding sounds MUCH better now. Now for the commit... 2002.04.27 ~04 Mod development using Scheme, prospect not good My goal was Scheme in QVM mode. Unfortunately, the layers of interpretations causes Scheme to be extremely slow, even in the JIT(?)-compiled. I wrote a set of accessor routines in Scheme to modify the values of various C structs involved with gameplay. On my K7/1200 (hardware which I consider to be excessivly powerful for just a mere dedicatd Q3 server), in compiled QVM mode (vm_game 2), just *loading* this file takes 30 seconds. In interpreted QVM mode (vm_game 1), this explodes to 180. In native SO (vm_game 0), it's a relatively speedy but still slow 3 seconds ('Hitch Warning' is 0.5s). And this is just loading this particular set of procedures, not even getting to the other support functions and then actually *running* any Scheme code. Trying an entire mod in just extension form is out of the question. I feel the optimal tool would be a Lisp compiler targeted to QVM bytecode, but I doubt that exists, and doubt it'll exist until Q3A goes GPL, and even then, I doubt any Lisp maintainers would really want to bother targetting QVM. Another alternative is a Lisp->C compiler (like CLiCC), which then uses the existing toolchain to compile the generated C file to QVM. This approach may be a better one than tacking Scheme onto the mod as an extensible language. At least the speed-critical/impaired functions (like, say, struct accessors) can be made speedier. I'll need to look into this approach. Still, QuakeScheme in its current form is still useful for "build-up" stuff, implementing new features -- prototyping. The set of routines established so far is useful in poking and prodding the structs, to see values were inserted properly, or to see what values were inserted, or to force the proper values. Although the Scheme code is slow, prototyping in Scheme precludes the need for a C compiling. And despite a complete recompile taking less than six seconds, not having to quit/restart Q3A means I don't have to rebuild session states (players, bots, entities, etc.) for testing/debugging. Once the Scheme form is stabilized, the routines can then be rewritten in plain C for speed. CLiCC may help make that last part automatic, though... hrm. 2002.04.21 ~03 Documenting MD3 and MD4 http://www.icculus.org/~phaethon/q3a/formats/formats.html Partly I was bored, partly the forums at quake3world.com had me realize documentation on MD3 and MD4 formats is pretty sparse. My documentation on MD3 format were based on the files from the Q3AToolsSource package, and my personal experience wrestling with the format for my Blender MD3 import module. I have no personal experience rangling with MD4. My words on MD4 are mostly shots in the dark, based on patterns from MD3 and Blender. Still, it's best to get familiar with MD4 at some level, even if I am spewing hogwash as I look over the header files. 2002.04.15 ~00 TinySCHEME Poking around with Google, I came across TinySCHEME. It's a really tiny Scheme implementation without all the setjmp/longjmp doohickeys I've had problems with in other Scheme implementations. TinySCHEME is derived from MiniSCHEME, (heavily) modified to work as the extension language to a mini web server frontend. TinySCHEME compiles into QVM bytecode with some minor modifications and a few extra libc function reimplementations. I may wind up using this as the primary Scheme core. In other news, I finally got around to slicing down the size of my .plan, now that I have attained "hugest fscking plan file": phaethon@gamehenge$ ls -s * | sort -n | tail -5 8 theoddone33 12 vogon 16 chunky 24 yoda 36 phaethon 2002.04.13 ~10 Depressed over tail-recursion I'm still depressed that my Scheme implementation isn't properly tail-recursive, and that I still haven't figured out how to make it T-R. It's been a real showstopper. 2002.04.03 ~07 "The CUSP emulator corpse stirs back to life.--More--" http://www.linux.ucla.edu/~phaethon/cuspemu/ Turns out that UCLA Computer Science Department (which is one of the few universities that places CompSci under "Engineering") is *still* using the crufty PITA POS known as CUSP for its assembly/machine-language course. I'm not too fond of having had CUSP shoved down my throat, instead of a real CPU. A short background on CUSP (Carleton's Utterly Simple Processor): * Developed at the University of Carleton (Ottawa, Canada) in late 80s for their assembly language course (they have since moved on to Real CPUs(TM)). * Fictitious CPU, exists only in emulation. * The only "official" emulator is binary-only (sourceless) MS-DOS EXE last updated 1992. * Copyright encumberance causes... "special parties" for the UCLA CS-33 students. A short dump of CUSP specs: * 12-bit address bus, 24-bit data bus * 4096 (i.e. 2**12) memory words (24 bits per word) * 4096 I/O ports (8 bits per port), separate address space * memory addressable 24-bit or 8-bit (but not 12) * 1 24-bit general-purpose register * 4 12-bit special-purpose registers * 4 CPU condition flags * 10 instruction addressing modes * 1 instruction occupies only a single whole word * Five devices: - Keyboard, input - CRT, output (monospace text, 14 rows, 38 columns) - tape, input/output permanent storage (emulated as a file) - printer (emulated as a file) - timer (in emulated system ticks, not host time) PHFC (expands to many thing: Officially "Phaethon's Hack For CUSP", but my personal favorite expansion is "PHFC Handles F***ing CUSP") is my (incomplete) GPL'd implementation of the CUSP emulator. For varying reasons, I got dismissed (kicked out) from the CompSci program at UCLA, so I have no chance of taking CS-33 again. So I don't have need of completing the emulator. PHFC is, as far as I recall, the first time I started a large-ish programming project, using compilation in parts, autoconf/automake, function pointers, and (meaningful) data encapsulation. As I said, I'm not too fond of CUSP. This fact is reflected in my choice of filenames and variable names. A few choice selections: * cataplex.l (asm source lexical analysis) * cramps.y (asm source grammar) * spasm.c (assmebler, linker) * phfc_bitch_and_die() (error messaging) Just recently, though, a student taking CS-33 this quarter sent me e-mail querying about PHFC, along the lines of actively helping development. I'd really prefer handing off the project to someone else, since I'm not in the mood to hack PHFC to completion (for whatever "complete" means). But not many people would be both willing and able to take on the project. On another note, turns out I had my old e-mail address on my PHFC pages, which is no longer valid (much less its domain). I'm surprised he found my current e-mail address at all. Well, OK, granted, it's the canonical pattern of ${~username}@${domain} reflected in the URL, but this person had determination to contact me [above mindless clicking]. 2002.03.27 ~06 IRC snippet This is gonna be a a classic for me. Victim's name obscured out of (little remaining) respect. 21:55 < XXXXXX#blenderchat> anyone interesting in descussing modern philosophy? 21:55 < XXXXXX#blenderchat> anyone interested...that is 21:56 < phaethon#blenderchat> 42 21:57 < XXXXXX#blenderchat> 42? what the hell does that mean 2002.03.26 ~18 ZBoxZ dev access http://sourceforge.net/project/memberlist.php?group_id=7522 Woohoo! In other news, I hacked on ZBoxZ proper some more. I converted the app's preferences data structure from an array of chars to a struct. Inspired by LispMe, I also added a "left-handed scrollbar" option that moves the scrollbar over to the left side, for the left-handed folks. This way, left-handed use doesn't cover half the screen face with the hand and stylus. No, I'm not left-handed. 2002.03.26 ~01 PalmZLib, PiNGer An interesting little experience combining my two favorite Palm apps. In order to properly hack on PiNGer, I hit the PNG docs on www.libpng.org. The format is surprisingly simple, flexible, and powerful. I'm surprised no one created it earlier... everyone probably figured GIF was "good enough" until The Great GIF Ymezth started. Anyway, so I started hacking on PiNGer. Well, "hack" is probably an exaggeration at this point... I just merely shuffled variables around and introduced a boatload of data encapsulation. This will certainly help in maintaining and extending PiNGer in the future. Of particular note is how PiNGer accesses various system structs directly (i.e. not using accessor functions), a deprecated method starting with PalmOS SDK 4.0. I ran frequent compile, upload, run cycles to check effects equivalence. Lots of crashes. Last time I remember having crashes this frequent was... um... using my TNT2 with nVidia drivers 0.9xx-something-something. LispMe's DatabaseManager functions (dm-*) came in handy for tracing PiNGer's progress. PiNGer uses a "scratchpad" database as a buffer holding the decoded image. After a reboot, I could use LispMe to dig through the corpse of the scratchpad. I preferred this over dragging the PDB to the desktop then dissecting it there. I think it was because I could start whalloping on the db with Scheme code =) The GIF decoder seems broken. For one, PiNGer can't decode any of the remaining GIFs I happen to have. Two, PiNGer's GIF decoder advertises having used pieces of gif2png (gifread.c in particular), but after tracing the two sources, this doesn't seem true any more (maybe gif2png updated?). Still, not like this is a big loss. I'd just as soon rip out the GIF code. Creating an updated PalmZLib from zlib-1.1.4 was very straightforward. Tom Zerucha's 1.1.3 patch for zlib->palmzlib fit snugly with zlib-1.1.4 (read: no serious rejects by patch(1)). I found a free-speech JPEG compression-only library for PalmOS. It is just a Palm-ified port of the JPEG reference library (libjpeg6b), but the _de_compression routines were left unported. As it were, the library was created/ported to accomodate a camera module for Handspring Visor. For the curious, www.eyemodule.com[/developer/index.asp]. I also started hacking the ZBoxZ core. My greatest achievement there as of this moment is getting the file's list to update on a scroll event without causing screen flicker (which was caused by erasing the whole screen then redrawing every little component). An HTMLized version of the Palm OS Reference manual would be of immense help to me; I find something profoundly disturbing in "flipping through pages" of a manual on a screen. I should also add my PalmOS work to my .project, and finally get around to snipping my .plan to something smaller than a monolithic 26K text stream. 2002.03.24 ~23 PalmOS stuff. - ZBoxZ (palmboxer.sourceforge.net) - I found this while googling for "GPL graphics viewer". Based around in-PDA (de)compression (zlib (with the buffer-overrun bug!) now on PalmOS!) and the Palm serial port, ZBoxZ encompasses a set of useful doohickeys. Among these doohickeys: PNG/GIF viewer, compressed archival (like tar.gz), compressed executables and runtime decompression (like a compressed filesystem), YModem over the serial port (almost-substitute for HotSync), MIDI player, Fax xmit/recv (!), and a simple web server (!!). Emacs comes to mind. I plan to spend quite some time hacking on PiNGer, the image viewer component. If nothing more than to get it to compile from source at all. Oh, yeah, and ZLib[.prc] could use the latest zlib patches. - LispMe (www.lispme.de) - A new version, 3.1, got released a month ago, just after I gave up the project for dead. It now has enough hooks to create Palm resource databases ("Rsrc") within itself. To actually make a resource compiler is nontrivial... after converting 8% of pilrc.h to suitable Lisp form, ennui got the better of me and I gave up. There should be an automated way of extracting the info from pilrc.h. Or maybe I can just type it up from scratch based on the Palm OS docs. It's not like the Rsrc format is a moving target. 2002.03.19 ~13 Oops... not tail-recursive... Turns out my Scheme interpreter isn't truly tail-recursive. I'll be banging my head against the wall a bit to straighten out this mess. 2002.03.15 ~07 More on Blender and MD3. First of all, NaN (the company behind the the 3D modelling software Blender) is going kaput. No word as to the fate of the software, although I do recall a promise of Blender going open-source in the event of company's death. In the meantime, www.elysiun.com appears to be the interim web site for Blender users. Second, I figured out a half-assed way to import MD3 animation, after looking at various (other) Blender python tutorials. Link the script with the object using FrameChanged. That way, whenver the frame number in Blender changes, the python script will be re-run, which can then manually(?) move all the vertices in the mesh according to frame number. There really ought to be a way to just plug and chug the coords into an IPO curve. It's a lot tougher to figure out with www.blender.nl (and its accompanying python docs) demolished. 2002.03.11 ~12 Significance of data structures After tampering with Scheme, Python, and object-oriented programming paradigms, I've taken a different view of the data arrangements in my mod. I've separated out "templated" information from "instantiated" data, otherwise known in C++ parlance as "classes" and "objects". The data type gentity_t describes the base properties of all objects (entities) in the game. Player-specific data go with gclient_t, to reduce space waste. There are 1024 entities, of which the first 64 are the clients (players, bots). I extended gentity_t and gclient_t with unions of instantiation-specific structs. Since an entity can only be of one "type" at a time, a union is quite suitable -- only one of the extended structs makes sense at any time. The CVS repository of FI has been updated with this revised view of data. 2002.03.07 ~14 Q3 Extensibility Ok, just got an interesting brainstorm courtesy of our local Chunky Kibbles. One reason why I'm trying to tough it out with QVM is because of its cross- platform nature. That is, compile-once run-on-a-lot. The limiting nature of QVM makes it somewhat safer than the [unrestricted] native code form of Quake 2, to paraphrase one of jcarmack's .plan entries (somwhere...). 2002.03.06 ~09 Q3TA menu docs update http://linux.ucla.edu/~phaethon/q3tamenu/q3tamenu.html This is something that I've been working on for... whoa... over a year. It started when WFA cannibalized Quake 3: Team Arena's new menu/HUD code. Originally, I set out to customize my HUD in Weapons Factory Arena. I banged up this file to sort out what was available and how I could combine the pieces for desired effects (analysis to assist synthesis). As I became more disinterested in WFA, the scope of the docs expanded to general documentation. Currently, its target audience consists of HUD customizers and the poor sod stuck typing up all the .menu files for a mod, but not those of the programming persuasion. I expect to gradually include the coders in due time. The significant update recently, though, is the section on uiScript. Much of the initial substance is contributed by dementor (dementor@c:::::.n::). While trying to figure out uiScript by groveling through the Q3 game source tree, more of the menu puzzle fell into place for me. It's uiScript that initiates complex actions within the mod from the menu UI (e.g. adding the currently selected server to your list of favorite servers unless the list is already full). I consider this something of a kludge. Although the Q3TA menu system is heavily data-driven, Turing-complete code can only be expressed in the pre-compiled QVM files ("mod code"). Code cannot be created or extended at runtime. I consider this a Bad Thing, as it puts limits on what can be accomplished in the menus and HUD by those without access to the mod source (mostly those who would be called "end users"). One thing I like about Tribes 2 is its extensible language. It is powerful and flexible enough to allow different modules to sit on top of each other simultaneously, the player mixing and matching on whim. Unreal Tournament also achieves similar effects, however, almost all Tribes 2 code extensions come with source, providing _me_ with an unprecedented amount of tweakage -- instead of working around a misfeature or starting over from scratch, I can hack on the component directly. This sort of extensibility is something I'd like to have for Quake 3. 2002.03.03 ~07 http://www.icculus.org/news/news.php?id=335 D'oh. 2002.03.01 ~17 md3import bug-squashing Got rid of the most annoying md3import bug, the "some polygons missing" bug. List of vertices in Blender is zero-based, so that the first real vertex is index 0. The method addFace() is used to connect the vertices (referenced by index number) to create a polygon. A vertex index of zero is treated as "no vertex", instead of vertex 0. See zero-based vertex list. Workaround was to create an initial throw-away vertex, which goes into the vertex list as #0. Then all the vertices in the actual model are then shifted by one, with the end result that none of the model vertices will be indexed zero. After all triangles are established, the initial throwaway vertex is removed, and the rightful order is then restored. I also put in FileSelector widget (point-and-click md3 import), and got MD3 tags to convert to Empty objects. 2002.03.01 ~14 MD3 import into Blender http://www.linux.ucla.edu/~phaethon/q3a/md3import/md3import.html Importing works. The objects do look a little strange (a couple polys missing and such), but otherwise I would call the venture a success. No textures imported, the tags don't import properly, no exporting, animation is NOT accomodated, yadda yadda. At least (most of) the mesh is there. The step towards exporting to MD3 shouldn't be that big; all the bit-banging stuff just needs to be straightened out. On impulse, I started on a joint mini-project to create a rendition of The Restaurant At The End Of the Universe, and I'm a little eager to start swapping around prototype models without having to learn QERadiant. This means I'll probably be getting around to an exporting of some kind soon. 2002.03.01 ~10 Analyzed MD3 I think I've finally figured out what all the bytes in a MD3 mean. The output of my initial python program parallels the output of q3data (which I've finally got to compile mere hours ago). Shouldn't be too long to get Blender to import MD3 directly, even if the objects come out a little strange. 2002.02.23 ~12 Q3TA Customizable Popup Menu http://www.linux.ucla.edu/~phaethon/q3vchat/q3vchat.html This is a hack I had envisioned since maybe September or October of 2001. I couldn't establish a solid goal for the final form until I played a lot of Tribes 2, and thus took much inspiration from the Tribes 2 vchat menus. I actually scribbled most of the solidification/finalizing notes while waiting for my car to be repaired. =) This hack was inspired by my WFA peri HUD; the basic idea of the popup menu is to throw all the parts of the popup menu onto the screen, but render most of them invisible most of the time, selectively setting certain pieces visible. This creates the illusion of several menus appearing at different times in the same spot on screen. Unfortunately, implementing the idea in this exact manner exceeded the memory capacity of the menu system. Fortunately, though, I found a workaround. Instead of creating all possible pieces of menus, I instead use a single set of Editfields arranged in a column. Since the HUD cannot obtain mouse focus, the Editfields are safely read-only (to an extent). The Editfields can also be set to display the contents of a cvar. The Editfields are given a patterned cvar name. A description of the menu layout is provided in a plaintext file. Using this file, a perl script automagically generates the ridiculous number of cfgs to help create the desired effect. The collection of cfgs work together to set the values of each of the Editfield-associated cvars and the bindings of keys at appropriate times and depths of the menu. The resulting effect is a popup menu that is traversed by keystroke sequences, much like the vchat ('v') menu in Tribes 2. 2002.02.20 ~11 Ogg Vorbis/Q3VM decoding successfully. I am HAPPY!!!! My Q3 mod, Project FI, successfully decoded a short vorbis file into 16-bit PCM. The test vorbis is a 12-second thunder sound effect from some Q3 map, I forget which. The resulting PCM is rather poorly decoded; I'm guessing this is because of my horrid log()/exp() implementation, perhaps in combination with Q3VM's 32-bit-only floating point. The Ogg Vorbis codebase is based on the source release of the reference library version 1.0rc3 from Xiphophorus (read: copied and hacked). In total, not much functional hacking to the vorbis source itself was required (had tons of printf()s for debugging, though), but I had to spend considerable time on supporting code, math functions especially. I assumed that the Vorbis code is correct, and that my own stuff needed fixing. By-products of this effort: * A saner and somewhat more robust, if more space-consuming, malloc() system. * Expansion of the math library. * Cleaning up of the expanded math library. Now to get all this stuff into CVS... 2002.02.20 ~03 Icculus's Razor More fitting for a cookies/fortunes file, but oh well: "If it takes more than two minutes on Google to find an ISO, your distro is no longer qualified to be called 'modern'." -- Icculus 2002.02.18 ~12 FLAC While perusing the Ogg Vorbis mailing list archives, I came across FLAC, Free Lossless Audio Codec (for context, the discussion started with a suggestion of a lossless mode to Ogg Vorbis, then a possible merge with FLAC). I may look into FLAC, instead, as its decoding can be done with integer-only arithmetic (read: faster in QVM than Vorbis). 2002.02.17 ~02 just after reading chunky's .plan echo 'set nocompatible' > ~/.vimrc Ha. 2002.02.17 ~01 Ogg Vorbis integrated? Trying a complete decoding of a test ogg to a test.raw finishes without crashing (ov_read()). But the numbers come out all wrong. I think it might be because the Q3VM 32-bit floating point values don't have enough precision to decode properly, but I'm not so sure. 2002.02.17 ~12 Ogg Vorbis integration progressing Good news: TestVorbis1() doesn't crash. Bad news: It doesn't exit, either. 2002.02.15 ~08 V-Day There's something missing from Valentine's Day. Christmas : Scrooge :: St. Valentine's Day : ??? 2002.02.15 ~07 UDF UDFFS makes a lot more sense for file storage on CD-RW discs, than using ISO9660, ext2, or some other filesystem designed for extensive rewrite/deletes. Although UDF support in GNU/Linux has a rather high suckage quotient, using UDF sure beats out ISO9660 (mkisofs(1) and whatnot). Using ext2fs on a Write-Few-Read-Many just doesn't feel right. 2002.02.12 ~06 NOOOOOOOOOOOOOOO!!!!! phaethon@gamehenge:~$ uptime 1:10am up 4:33, 11 users, load average: 0.00, 0.14, 0.25 ^^^^^^^^ NOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOOO!!!!!!!!!!!!!!!!!!!!!!!!!!!!! 2002.02.11 ~08 shells shells shells Why, yes, I do need 18 simultaneous shells open. Why do you ask? 2002.02.10 ~06 AOL 7.0 Hrm. Got an AOL CD ("All-new! AOL 7.0"/"Try it now for 1000 Hours Free (for 45 days)!") by snail mail. It's addressed to "Current Resident", so apparently this came as a result of some kind of carpet-bombing campaigns, and not because I'm still on AOL-TW's "list of people to send a CD". Intriguingly, the provided "password" is "KNOW-THANKS". Phoenetically, that's exactly how I feel about AOL, minus a few choice colorful words sprinkled before, after, and in the middle of the phrase, along with explicit suggestions of what they can do with this CD. In any case, now I have another layer of protection (if rather busily colored) between my hot drinks and my desk, and the provided DVD-style cover (after removing all labelings) is well-suited to housing my more precious CD-R discs (i.e. Debian CD, backup of ~) I probably wouldn't be as annoyed at these AOL mailings if the text didn't talk down to me like I'm a dull-witted, Windows-using, bandwagon-hopping luser. 2002.02.04 ~10 ogg vorbis The OggVorbis reference library is rather hefty. Gonna take a bit of hacking to get this to work in QVM. So far, it reports my test ogg as 16-bit 22KHz. That looks about right. Currently, my mod is dying horribly somewhere in the Vorbis codebook initialization. 2002.02.04 ~09 minor research I should start collecting stats on how long it takes people to finally adjust to writing the new year's number. There also needs to be a unit of measurement to measure the level of embarrassment experienced by a person realizing that they've been using the wrong year for over a month. 2002.01.31 ~23 more CD-RW discs OK, postpone that MD3-in-Blender trick. The Q3 MDL format is a bit trippy. Importing from MD3 maybe easier than exporting to. That, and I gotta relearn python. Got a 20-pack of CD-RW from Costco. For once I may actually be able to do a true backup of my system. 2002.01.30 ~10 blender, python, .md3 For my next trick, importing and exporting Q3 MD3 (model files) to and from NaN's Blender Creator (http://www.blender.nl/). 2002.01.30 ~07 not hacking gcc Please quit asking me to hack gcc to compile directly to QVM. Please. 2002.01.29 ~08 -o loop I dunno just exactly what causes this problem, but it's reliably reproducable: generate a romfs image burn directly to CD-R/CD-RW mount -t romfs /dev/scd0 /mnt mount segfaults, kernel oopses <- the problem (drive remains inaccessible until kernel is killed (read: reboot)) Then (after a reboot), doing the same mount command causes segfault and kernel oopses. Reboot again, then throw in a "-o loop": mount -o loop -t romfs /dev/scd0 /mnt And everything's all hunky-dory. No segfault, no kernel oops, and I can read stuff directly off /mnt. This is on a K6/2-350 with 192MB RAM, linux 2.4.17. My laptop has a DVD/CD-ROM drive, where doing the "-o"-less form on the same disc doesn't cause an oops. Celeron/400 32MB RAM, linux 2.4.17. As near as I can tell, it's romfs barfing. Might be a combination of something in romfs with one of the modules involved in driving an IDE/ATAPI CD-RW drive. Since I've figured a workaround in the meantime, I don't feel like hunting down the root cause. If this crops up in 2.4.18, I'll probably go a-hunting. 2002.01.28 ~22 CD-R spindle Bought a spindle of 50 CD-R blanks. These CD-Rs look shinier than CD-RWs. It's burning time. Rewriting at max speed wedges all other apps on my system. Probably doesn't help that the bulkier swap drive is on the same IDE cable as the burner. Trying to mount romfs from CD in CD-RW drive causes kernel to oops. Hrm. Doesn't happen on CD-ROM drive. 2002.01.28 ~09 Growing wiser in the matters of CD-based storable media After much more reading, I now know the (physical) difference between CD-RW blanks and CD-R blanks, and why CD-RWs are, therefore, more expensive. The phase-change nature of CD-RW does a number on my "intuitions", but, hey, if it works... I recall the first generation of CD-RW being rumored to be good for only 3 to 5 rewrites. The CD-WRITING HOWTO implies that current effective number of reuses are either widely varying or indefinite (or both...). I should get a spindle of CD-R. It's cheaper and faster, and arguably more permanent and more readable by (other drives). I'm also running out of coasters. A mug of hot cocoa leaves a nasty mark on even fake wood, and AOL took me off their "People To Annoy With Free Trial CDs" list or something. Maybe it's because of that "@linux.ucla.edu" e-mail address of mine... 2002.01.27 ~08 first burn go boom Ran my first real CD-RW writing session. It looked like it finished properly, but upon trying to mount the newly written disc, kernel oopsed. IDE driver. Very bad. Reboot :( 2002.01.27 ~00 playing with CD-RW Being new to CD-RW (or any non-ROM optical storage), I read up on and played around with 'cdrecord' and 'mkisofs'. Decided to give dummy-writing a go to see how long it would take. # dd if=/dev/zero bs=1M count=650 | cdrecord dev=0,0,0 -dummy - After it did the normal 10-sec countdown warning and started, I C-C'd it after 6 minutes since it defaulted to 4x speed and I calculated it would take over a half-hour to "write". The WRITE LED stayed busy. I pushed EJECT. WRITE LED stayed busy. I waited. WRITE LED stayed busy. Played a round of Quake 3. WRITE LED stayed busy. Played a few rounds of Tribes 2. WRITE LED stayed busy. By now, the WRITE LED stayed busy for three hours (more than enough time to write even in half-speed). As an IDE/ATAPI CD-RW, I figured all I need to do is tell the hardware to give it a kick to the interface. A reset. But I didn't want to reboot. Check hdparm(8), canonical tool for doing untowards thing with the IDE system. Lo and behold, drive reset: # hdparm -w /dev/hdc WRITE LED went non-busy. CD ejected. CD-RW responded to bus queries, et al. Happiness. Then I tested with a 10MB chunk of zeroes and speed=10 (16x10x32 drive). 12 seconds. Then 65MB. 51 seconds. Multiply. 8.5 minutes. Should test if it'd buffer underrun next. (20 minutes later) Yep. 8.5 minutes, and no buffer underrun. 2002.01.26 ~19 Hardware additions to home system(s). Purchased yesterday: LG CD-RW (16x10x32), US$79 K-Byte (generic brand?) 512MB PC133 SDRAM, US$58 TDK 5-pack CD-RW data[1] blanks (rated for 10x), US$8 Before Penelope - mini-tower, K6-2/350, 64MB RAM, 6GB+10GB+42GB HDD, Matsushita CD-ROM (4x) Anticleia - mini-tower, K7/1200, 256MB RAM, 2GB+1GB HDD, IDE ZIP100 After Penelope - mini-tower, K6-2/350, 192MB RAM, 6GB+10GB+42GB HDD, LG CD-RW (16x10x32) Anticleia - mini-tower, K7/1200, 512MB RAM, 2GB+1GB HDD, IDE ZIP100, Matsushita CD-ROM (4x) Penny's mainboard (VIA MVP3 chipset) can only handle 128 max per DIMM, thus 192MB and not the expected 320MB. [1] damn the RIAA 2002.01.25 09UTC FI alpha release 00000 My Scheme interpreter stopped puking in QVM mode. I'm ecstatic enough to just throw together a mod release based on what I have now. Of all things, one (but frequently visited) switch()'s case fallthrough in the Scheme interpreter was causing Q3VM to corrupt its opstack. I thought this problem (fallthrough-causing-corruption) was fixed a while ago, but now I'm making a mental note to avoid any switch() fallthroughs in future mod code. For future reference, CVS tag "fi_00000". 2002.01.24 ~23 .plan Makefile Fellow gamehengers tell me there's some sort of automatic .plan-update notifier doohickey running that announces when a gamehenger's .plan is updated. My .plan is decomposed into individual file per entry that gets mashed together with a Makefile. This provides me with the following flexibilities: * Create .plan from pieces (duh). * Selective choose n most recent pieces for the actual .plan. This helps cut down on byzantine .plan sizes. * Change the order of entries at whim (newest first or oldest first). * Work on entries remotely then upload to gamehenge without having to lug around a complete copy of my .plan. * Meditate on the meaning of using .plan as an online diary. As for the auto-notifier, I hope it didn't flip out on my first dozen test runs of my Makefile. 2002.01.24 ~22 q3asm-turbo3 (later that day) OK, got it to work the way I wanted it. The problem hinged on the combination of lcc's output of values and the way atoi() functioned. Floating-point values are expressed in the .asm files as positive decimal value forms of little-endian IEEE-whatever-thingy floating-point format interpreted as an integer. This meant the decimal value could range anywhere from 0 to (2^32 - 1). However, there were explicit byte vales of "-1" in various places as well (which made me keep atoi() for a while). Signed values are capped at 0x7FFFFFFF in atoi() (as it should), but the float-point values were frequently surpassing that limit. So almost all the floating-poing values were coming out as 0x7FFFFFFF, since they were expressed as Very Large Decimal Values. (I have problems expressing my technical thoughts...) The end result was that a whole lot of math functions came out insane. The workaround was to create a new function that converts to something larger than 32 bits (long long on gnu-x86 is signed 64 bits), then smash it down to 32 bits in a "proper" manner. This might prove unportable, but like relnev^WPeople's Linux-Centric Modifications To the Quake 2 Game Source, I'm more concerned about making this work correctly on linux-x86 right now. Thus ThingThatConvertsDecimalToSigned32SoThatAtoiDoesntCapAt7FFFFFFF(). At last, nice speedy 2-second linking that comes out correcty. 2002.01.24 ~18 q3asm breakage q3asm unpatched apparently comes out horribly broken under linux-x86. As far as I can tell (AFAICT), it has something to do with bit-shifting and sign-extensions. With the help of a hex dumper, all 32-bit values over 0x7FFFFFF in the proper qvm output comes out as 0x7FFFFFFF in any q3asm I try to compile from source. Maybe there's some Secret Spidey Switch in GCC that needs to be activated? In the meantime, I'll just grovel through the q3asm source and see if I can make it work right without special GCC switches. 2002.01.23 ~00 q3asm-turbo http://www.icculus.org/~phaethon/q3/q3asm-turbo/q3asm-turbo.html In the course of trying to debug my Scheme interpreter (which fails horribly in QVM bytecode form), I got very annoyed at the tremendous wait time for a complete compile cycle to finish, with q3asm taking up more than 60 seconds. This long of a wait for each tiny tweak. So I set out to speed up q3asm. I hacked q3asm to support a chain-and-bucket hash table, where symbol values were to be stored during the symbol table construction pass (pass 0). By just using this hash table for lookups alone, linking (q3asm life time) shrunk down to 28 seconds. After spotting a singly-linked list insertion sort in pass 0, I diked that out, and linking time dropped to 3 seconds. I nearly did very aggravating(?) things to my pants. After groveling through the source, I concluded that sorting the symbols list (by value) never did anything worthwhile in q3asm, anyway. Then I sought to optimize the foonting turlingdrome out of q3asm. With the assistance of GNU profiler, I hand-optimized various heavyily-called functions. Or at least I think I optimized them. q3asm-turbo2a regularly reports 1 second elapsed compiling the game/ module of my mod. But my Scheme interpreter is equally broken in unmodified, turbo1, and turbo2a, so I don't know if the modified q3asm actually works correctly. But it's swutting fast :) 2002.01.22 ~00 FI demo floating So out of both altruism and ego, I provided a demo of an older version of FI to someone on IRC. Already someone else is nabbing it, viewing it, and commenting about it. So I made a new demo based the current CVS version, and linked both demos in my web site. 2002.01.21 ~00 ln .plan .diary ? Seems everyone else is using their .plan as a kind of online journal. I think I'll give that a shot as well. [section="life"]Life:[/section] No Life found. [section="project"]Project:[/section] 1. Project FI, Quake 3 mod (http://www.icculus.org/fi/) a. provide an extensible environment for a Q3 mod. The intended notion is that of "mutators" in Unreal Tournament. b. FI:WFC, a more faithful reproduction of Q2WF for Q3 than WFA. 2. QuakeScheme * Extensible language for Project FI. * Builds on TinySCHEME (http://tinyscheme.sourceforge.net/) * Deal with the idiosyncrasies of Q3VM not handled by most other Scheme impls. 3. Q3VM libc * Implementation of Standard C Library for Q3VM bytecode. * Implementation of a subset of Single Unix Specification v2 (SUS v2). * Help import third-party library into Q3VM. 4. QuakeScheme GUI/widget set a. Need to research advanced OO and GUI of Scheme derivatives and Common Lisp. b. Replication/extension of boxy widgets in Q3TA (Q3 PR 1.27+). c. Pie menus -- just to annoy theoddone33. 5. Q3 compilation toolchain [X] q3lcc sources (official version out with Q3A SDK 1.32) [X] q3asm - get static to work, dammit. [ ] q3as - assemble-only (.asm to .o). [ ] q3ld - link-only (.o/.a to .qvm). 6. ZBoxZ (PalmOS) rewrite um.... hrm... 7. misc PalmOS stuff a. PiNGer (gfx viewer) * generalize interface to a "any-gfx" viewer (libpnm?)