After much mulling over it, I have decided that BASeBlock 2.0 will be “shareware” sort-of. This version will add a numbectr of new blocks, loads of bugfixes, and even fix the high-scores to work properly, which should have been simple but was dastardly to remedy.
What I mean isn’t that it will actually be shareware but rather that the program will be free but some parts of it will require “registration” to unlock. In BASeBlock’s case I’ve decided that the entire application will be free, along with almost everything that comes with the game, including the editor.
The difference is that the editor will be “crippled”- you can create and edit LevelSets and test them with the main game, but you cannot save them to a file unless the game is registered.
DWM
The “protections” will be relatively simple, and almost surely a breeze to crack. I plan to document some of it, in fact. I might utilize the otherwise dead-code that is part of the new licensing component to release encrypted .reg files that are specific for each user’s key and will only decrypt properly with the right key(making it difficult to work around by simply inserting a few jumps or skipping code or something)
The original plan for BASeBlock was to make the entire thing free; but it represents a lot of work- Graphics, some of the music, sound effects, etc. and I haven’t gotten anything monetary out of it yet. It’s not a particularly good breakout clone but it has it’s merits. loads better than my previous attempt, Poing, which is embarassing in comparison. It’s certainly no Ricochet Lost worlds (A fine game and one I highly recommend if you have any interest in the “block and ball” type genre), but then again, I’m only one person, right?
Basically, I’ll add code for simple protection to try to prevent casual piracy (well, really casual piracy) but anything more than that and I risk screwing up when the game is in fact legitimately obtained; which is something I absolutely will not tolerate.
I don’t know how helpful this will be, but it sort of surprised me.
Basically, my brother has managed to go through three PS3 consoles. Each time, being the hardware expert he is – the type that would, when my 486 wasn’t booting up, open it up and make sure every connection was plugged into something – decided he could fix it himself. I think the issue was it wasn’t reading discs or something. Of course my advice was to send the bloody thing to Sony, but hey it was his warranty to void. What ended up happening of course was he ripped the entire thing apart, had absolutely no idea what he was doing and he ended up having to buy a new one since that one was no longer applicable for service. Anyway, I stumbled on the picked apart carcass of his old PS3- and I remembered that they have hard drives. So I opened up the HD access panel, took out the HD, and to my surprise I found it was just a 2.5″ SATA drive. To confirm this I plopped it into my laptop and installed Mint 12 on it. It’s mine now, heh. I’m not sure where his other picked part carcasses are, though. It’s a shame this laptop only allows for the installation of one Hard Drive, too.
Anyway, I didn’t know that they were so interchangable with PC parts in this manner, so maybe others might not be aware of it either. And I know quite a few people with dead consoles (PS3/XBox 360, etc) that they have basically shelved and forgotten about so if somebody needs an emergency Hard Drive this could be a useful nugget of info.
On a related Note, Mint 12 is extremely impressive… Although it primarily Reminded me just how heavily I customized the Mint 10 installation I was used to using on my laptop. The changes were mostly UI and I couldn’t figure out how to get my beloved Emerald working with a few quick googles so I swapped the drives back over. Now I could have messed about with Mint 12 by simply using the Live CD, but the Live CD is always somewhat slow and hardly really shows the OS at it’s true potential. And of course you can’t really add anything or make many changes to it, since it’s booting from a Read-Only medium.
Regarding Console Systems, though; is it just me, or are they basically just re-purposed PCs? The Xbox and Xbox360 are quite literally PC hardware specially built for handling gaming tasks, with specific software and also firmware “locks” to try to keep nosey people from finding out it’s really just a PC. This isn’t so bad, but it’s sort of stupid- I mean, really, the original XBox is essentially a Pentium 3 PC; The controller ports are just freakazoid USB connectors that they purposely changed just so they won’t be USB connections,and possibly to make them stay in better, USB ZIF slots aren’t what I would call the greatest for controllers. On the other hand, why change the entire pinout configuration- why couldn’t they have simply added some sort of additional mechanical connection that made them stay in better? And all the fancy crap about locking the Hard Drives from being changed by the user, and so forth is sort of silly. It doesn’t make a whole lot of sense to artificially limit what the device is capable of simply because you charge less for it than an equivalently configured PC.
And with all the add-ons for Console machines, such as keyboards, support for USB controllers, Hard Drives, Ethernet; the only real difference between consoles and PCs is that consoles always have the exact same hardware (things like GPU and CPU) that software developers can expect, whereas PCs have widely varying hardware; also, the Consoles are purposely locked down for reasons I can only guess.
This is all well and good, but as I noted, my Brother has gone through at least 3 Playstation 3 consoles. He wasn’t throwing them around the room or anything, I doubt he was abusive to them at all. And yet- they stopped working in one way or another. The failures of Xbox machines is no less of a problem. Meanwhile, my Super Nintendo is 20 years old and still works perfectly fine. A commonly cited “excuse” is that the machines are more complicated. Well, these people need to take a good hard look at the schematics for the various SNES ASIC chips and perhaps re-evaluate their definition of complicated. The only change is that newer consoles have more mechanical parts and they generate more heat and are squashed into as small a form-factor as possible. It has nothing to do with them being “more complicated” and everything to do with them being built out cheaper components than a PC (to justify the lower price point) and makes all hardware issues “non-user servicable”, unlike, say, a PC. This was a acceptable policy for things like the SNES or the Sega Genesis or earlier consoles of that nature; most of the issues that those consoles have are the result of loose connections that typically require Soldering knowledge to fix properly. But now, that sort of policy is sort of silly, since a lot of the problems with modern consoles are relatively simply in comparison, and many enthusiasts who know what the issue is could fix it themselves, if the machines themselves weren’t put together in a way that dissuades attempts to dissassemble- things like special screws (Torx); again, warranted when the device innards were generally something that wasn’t user-servicable to the typical enthusiast, but now it’s just a artificial barrier to make the machines seem less user-servicable than they are. And, more to the point, the fact is that they simply fail more often now, and it seems like it would be in the company’s best interest to make them more user-servicable since that would mean fewer warranty repairs. (Obviously they can keep their old “take it apart and void the Warranty” thing.
Not generally speaking, but for any game with a large fanbase. Really, it actually kind of holds true for anything that has a large fanbase. People will always find things the complain about. The thing is, a forum for a game is more likely to become filled with people who want to bitch and complain rather than post any genuine critique.
One of the only game forums, and probably the last, given my experiences over the 6 or so months I have been a member (and from my understanding the situation is really quite the same on any game forum) that I am a member of is the Minecraftforums. I think I’m a member of the zsnes forum as well as eduke, but those don’t count as those are mature communities built up around well established older games- they don’t typically appeal to the average gamer these days. Minecraft is the only “new” game that captured my attention enough that I decided that I would join the official forums built up around it.
Now, with every update since than, people complain. Over. And Over. And Over. Mojang adds beds to the game- a useful feature for changing your spawn point in what is effectively an infinite world- people complain that it “ruins game balance”, which is a tad weird given it’s just a sandbox game, but oh well. I’m sure people complained about the addition of sandstone in that same version, come to think of it.
The only feature I don’t really like in minecraft is the wolves; I tend to avoid them. Especially since whenever I use them they annoy the piss out of me and I end up killing them. The last time I tamed some they pushed me unto a ravine I was peering into that was floored by lava. I didn’t have to kill them that time since they piled into the ravine behind me. The reason I don’t complain about it that I really cannot think of anything that Mojang doesn’t already know. They already know the AI sucks. The only thing I can really say, and the only complains you can really find on the forum, amount to “the AI sucks” They already know that. repeating it isn’t going to get it fixed any faster, it just shows how impatient you are. Same with most new features.
Anyway, as usual there are hate threads for 1.0.0, “this should be released” “OMG how can it go from 1.8.1 to 1.0.0!” etc.
One of my responses, in this thread, pretty much summed up my thoughts on the constant complaints:
I swear to god the minecraft fanbase can be the biggest whiny bunch of entitled assholes. They add a feature, people bitch about game balance. They add a bug by accident, people accuse them of being lazy fucks. They remove that bug in the next version, people bitch that they had built mechanisms around that bug. People ask for more interesting mobs with unique abilities. They add more interesting mobs with unique abilities, and people complain that those mobs are destroying their work using that new unique ability. So they nerf that ability, and people complain that the mob is stupid now. People complain that the ores don’t have enough purposes, and then suggest that they add more. People complain about biomes being too small, so they make them bigger, and people complain that the biomes are too big and the landforms aren’t as “epic” (as if that is even quantifiable). People complain that they are spending too much time on new features and not enough time fixing bugs. They code freeze and release a few fixes, and people start bitching that they aren’t releasing enough content. Make up your fucking mind. All the while, they complain that Mojang isn’t listening the the “community” by which they actually mean Mojang isn’t listening to their personal half-baked ideas.
It’s no fucking wonder the Dev steam stays away from these forums. Any actual useful information is drowned out by the noise from people with a phd in being pretentious douchebags.
End of story right? at least three people agreed. Almost all of that is easily verifiable; All those complaints can be seen to exist in the archives and older posts. And there is no doubt that there are so many trite complaint threads that it would be impossible for anybody to sift through them to find the ones that are in fact reasonable critiques with usable suggestions/information on how to fix it. And the attitude of many of those posting such idiotic threads makes it clear they are in fact pretentious.
Imagine my surprise when I wasn’t just warned for that post, but suspended. The “warning” writes:
You made several insulting remarks towards other users. This is not acceptable.
My response essentially inquired as to where these insulting remarks were. I don’t see any. Use of swear words and foul language are there, but they aren’t used directly against anybody. The only thing remotely insulting might be the very last bit about “Any actual useful information is drowned out by the noise from people with a phd in being pretentious douchebags.” And really, nobody can argue that, either. But that is still only one instance. Unless “insult” has suddenly become a way to say “you pointed out facts that occured in the past and used them to form a coherent argument” I fail to see where this comes from.
Hilariously, all my warnings have come from people that only more recently became moderators. Not that that is really relevant, but at the same time it sort of makes sense. I know because I’ve been a moderator on a few and with that “title” you have a tendency to pay more attention to “rule-breaking”. After all, it is ones job. At the same time there is such a thing as taking it to seriously. it’s a game forum, and when somebody happens to use easily cited examples to make a point, I don’t see how that is an “insult” and I certainly didn’t insult other members directly. Unless somebody feels they are a pretentious douchebag, there is no reason for anybody to feel insulted by any of that.
Oh well. At least it fueled me to write a post.
Today, when somebody says “Video Games” people think of Disc-based formats, steam, or another distribution service; they might also think about violence and other ‘inappropriate’ material. Anyway, There used to be a time where Gaming was far less mainstream, and in many ways considered to be something of a toy use for technology. Generally, the way they were designed was to be as simplistic as possible; the entire thing was very simple to connect to a television, and switching games was as easy as removing the game and inserting another. Most early game consoles were cartridge based systems. Home Computers also experimented with the idea of Game cartridges, but eventually the lower price of things such as Floppy disks and cassette tapes for those systems made the cartridges obsolete.
For consoles, which are in many ways simply a special-purpose home computer, the cartridge based format was around for ages. There is something of a special charm, to them; they aren’t just software, and they aren’t just hardware. In many ways they were a very flexible method, particularly in those days. Many games on various systems that used the cartridge based format employed special chips to add new effects that you wouldn’t otherwise see. Without the ability to essentially change the available hardware, the games wouldn’t be able to do this. Another advantage, is that cartridge-based games are a powerful demotivator for piracy; the games, as well as the hardware has to be fully understood before one could properly attempt to make a “copy” of a game; and the fact that the game used hardware as well as software meant that a copy would often be equally expensive to produce as merely buying the game itself; not to mention that you would need an original copy to work with and examine anyway, making it a bit of a moot point. While you could, in those days, turn the actual ROM code in a game into data on a PC, the PCs and home computers of those days weren’t even close to being powerful enough to run the emulation software many old game aficionados take for granted, and those programs didn’t exist until such time as the hardware abilities of a general purpose PC were high enough to make their goals workable.
Of course cartridge-based formats have significant drawbacks, such as higher cost, more expensive to produce, the fact that, particularly with later titles, making the eye-dazzling effects that were expected of newer titles in the later days of a console required the use of expensive chips which had to exist in every cartridge, and also made things somewhat redundant, as multiple games used to the exact same chip.
I only have a Super Nintendo console and cartridges (or “Game Paks” as the official literature states), so let’s take a look at some popular and rather common games, and their innards.
Who can forget this classic SNES title? Super Mario World was the pack-in game sold with the majority of all SNES consoles. It was, in many ways, the “Super Mario Brothers” for the Super Nintendo. Additionally, it was rather innovative, except perhaps in story. Naturally, the story is the same “Save the princess” stuff; but the game itself is far more dynamic than, say, Super Mario Brothers 3; defeating levels would often change the surrounding terrain (in purely aesthetic ways) and defeating a level would clear a path to the next one. The most interesting new feature was the introduction of entire areas that were secret and required you to find keys and their respective keyholes to access.
I personally feel it makes more “sense” than it’s predecessor (SMB3), if sense is something you can really apply to a game franchise that generally lends itself to cartoony characters, art styles, and mechanics. In any case, it tries to return to a more simple set of game mechanics. Super Mario Brothers 3 had several power ups: The Super Leaf, which turned you into a flying racoon, The ubiquitous Fire flower, A frog suit, a tanooki(mischievous bear being the best description) suit, and a Hammer Brother Suit. Naturally these all had their own unique abilities; additionally the game added an item system, whereby you could acquire powerups and use them on the map screen before entering a level. In that manner, Super Mario World simplified many of the more complex mechanics in it’s predecessor; for powerups you had the Super Mushroom, Fire flower, and Cape feather (flying with a cape making far more sense than being able to wiggle a raccoon tail and fly). The only item system was a single item box that you could deploy within any level, and could hold one item. It also automatically fell down when mario was damaged. Additional changes involved turning directly from a powered up Mario (Fire Mario or Cape Mario) into small mario; then you could try to get the powerup that fell as a result of the hit. Additionally, the game was in many ways longer (to complete in it’s entirety) than Super Mario Brothers 3, and the game featured three battery-backed save files.
So, what made all this possible? Surely all this excitement and awesomeness means that that game pack is cram-packed with electronics to make it happen? Well look at Fig 2. and be disappointed if that was your expectation. It’s just a small board with four chips, and the battery to keep SRAM information alive. Note that to dissassemble these cartridges, there are a number of methods. I personally just use a Torx screwdriver set I purchased off ebay quite some time ago.
In any case, the larger cartridge sort of hides the relative simplicity of it’s innards. Another interesting point that could be made is that in the context of a SNES system, the game pak is sort of a “add-on” card; that is, it fits in a slot on the system board, and is interacted with. In the case of the SNES, (and NES and N64) these cartridges are necessary for proper operation; otherwise you are merely greeted with a blank screen. A good analogy might to consider the game paks as something of a “system BIOS” for the game, in that they are necessary for there to be any actual executable code within the system, and they are based on ROM chips.
The primary reason for removing these “cards” from their cases would be for either investigative purposes (such as this posting) or for replacing or testing the battery. The battery is a basic CR2032 battery, the same one used in PCs for keeping track of clock and CMOS information, and much for the same purpose. They usually last a good number of years, but if your game is suddenly unable to save games or you find save corruption or issues, checking the battery is a good first step. One thing that many enthusiasts do with battery-backed save games is actually replace the battery holder with their own, that allows them to slip a battery in and out with ease. Most carts actually solder the battery on, and sometimes glue it. They weren’t designed to be user-servicable by any means (thus the special screws to open the system unit as well as game cases).
Super Mario Kart for the SNES is the first in a long line of Mario Kart games that employ the Mario Kart characters as the cast of a Go-kart race, and use a variety of cartoony obstacles and items based on the franchise, such as banana peels, koopa shells, Invincibility stars, Coins, and so forth, as well as featuring settings from the franchise for the tracks. This game is still extremely popular to this day, and competition for best times is still fierce. It became a “Million seller” and my first owned copy of the game was emblazoned with the “Player’s choice” logo. This copy that I purchased off ebay long after selling the original games and console are what some might call a “first run” of the game; I am unsure if there are software or hardware differences (such as bugfixes) between this and the Player’s Choice version. Nothing sticks out at me after playing the game, so I am willing to say that is not the case.
Something you may notice about this cartridge is that it seems to be designed differently from the Super Mario World cartridge. What makes this even more interesting is that it seems almost random what design a game will use. There are Super Mario World cartridges that use this “line” type design, and there are Super Mario Kart cartridges that use the smoother gradient design as seen on the Super Mario World cartridge above. I’m not really sure when, or why there is a difference. I initially suspected that maybe it was a cost issue; the cart for my previous Super Mario Kart was the recessed version, and it was newer than this one, so I suspected maybe it was a result of it using less plastic. But my Super Mario World cartridge uses the recessed variant. Also, I’ve seen all sorts of games that happen to use both designs, and I cannot find a consistent explanation, other than there maybe existing different factories that produced these that happened to use different moulds. Anyway, moving on to this games innards.
Taking apart this cartridge, (results of which are shown in Fig. 4) it is clear that the game uses a larger circuit board than Super Mario World. Of interesting note is that this game also uses a special chip, known as the “DSP-1″ for advanced processing. It can be seen to the right, in the middle. This is used for the Mode 7 “split screen” that is used in the game both for single player and multiplayer. Mode 7 itself is a feature supported by the console, but the game requires a bit more horsepower to get it to work with the split screen model, thus the DSP-1 chip. The game also has Battery-backed memory for saving best times in Time Trials mode as well as what Cup’s/difficulties you have made the podium on and your place. The same sorts of information apply with regards to batteries as mentioned before. The board seems to have some sort of oscillator (not sure what that white thing is, to the right and down of the battery), which would make sense, the game does time you in hundredths of a second, so it might need that for more accurate timing. I presume I am wrong about this assumption though.
Following in the footsteps of the wildly successful “Legend of Zelda” game released for the Nintendo Entertainment system, and abandoning many of the gameplay changes that were introduced in and shunned by many players in The second Installment for the NES, “Zelda II: Adventure of Link” This game returns to the “overhead” perspective used in the first game, and much like Super Mario World compares to it’s franchise counterparts on the NES, this game expands on the gameplay, graphics, items, and story of the original. Story is something that is pretty interesting, the original game basically through you into a world you were unfamiliar and had you figure out what you had to do. There is still a lot of that in this game, but now it is far easier to find and get hints about where secrets lie and where to go next. This is an improvement over the first game, because I can’t stand just wandering around a dangerous world hoping I stumble upon whatever it is I am supposed to be doing. The game features things such as upgrading your sword (first at a smithy, then by way of a fat faerie (don’t ask)); and upgrading your items either by purchasing the upgrade or using a number of other methods to get those upgrades for free. Dungeons, much like the first game, feature unique items that are often critical to progress further in the game world. The game is the first in the series to introduce the now franchise-ubiquitous “piece of heart”; basically, the game has hidden Heart pieces throughout the world; finding them will restore your HP, and for every four you increase your maximum life energy. In the previous game on the NES, you could find whole hearts in a few places, but the game didn’t have the heart piece system. Using a system whereby the hearts are found in pieces means the game has more discoverables, as well. And the much larger world basically requires that the world have plenty of discoverables and collectables to properly populate it with secrets.
The innards of the game can be seen in Fig 6. Because it doesn’t really use much functionality beyond what is provided by the console, it has no need of special chips. It pretty much looks exactly the same as the Super Mario World “Board”. An interesting note as to this cartridge in particular. I picked it up off of ebay, and when I first played it I pretty much went through the entire game in one sitting. However, when I returned to finish it off, I found the save missing. Upon opening it up, I found that the battery still held a good charge, but was completely disconnected from the proper circuit (the metal “holder” that was supposed to press down on the top of the battery was in fact nearly a half centimetre away. upon remedying this situation, the game has saved fine every since. I just found it to be rather peculiar. One might note, again, the use of the different exterior design for this game as well. I swear they just did that to mess with people. Bunch of sick weirdos. I did notice that the notched versions seems to “look the same”; that is, the inner, depressed notch seems to be analogous to the more shapely form of the other cartridges appearance (in my case, Super Mario World being one)
Arguably one of the best games available for the Super Nintendo system, Super Metroid, like Super Mario World and A Link to the past, essentially “extends” both the lore as well as the world and general mechanics of it’s franchise. In this case, it is the third game of the franchise; the first being ‘Metroid’ for the NES, and “Metroid II: Return of Samus” in which Samus, the main character, um… returns, I guess. I have no idea since I’ve not played that title.
As you can see pictures in Fig 7, Nintendo is still playing their mind games with regard to the cartridge design. The game itself also has a Battery backed save feature, so we can expect a battery when we rip it open and see if it’s insides are still fresh. I believe this game was also re-released as a “Million seller” title, but I can’t be assed to google that at the moment.
The Innards of the game are pretty much the same as all the other games. a few chips and a battery. Very little to get too excited about. The game, being a launch title for the system, (or very close to one, anyway) doesn’t utilize any special chips as even first-party developers were still learning how to best take advantage of the relatively powerful capabilities of the SNES system itself.
This game is something of a personal favourite of mine and has been for a number of years. It’s colourful presentation mixed with a bit of dark humour fridge logic (What happens to the monkeys when Yoshi swallows them?) is pretty epic. Of course it’s various advanced effects in the form of image scaling, rotation, lushly animated and coloured backgrounds and foregrounds, and so forth add to that experience. The title is sort of silly. Most people just call it Yoshi’s Island; the actual title is too long for casual conversation. And sort of redundant, and even silly. How is it Super Mario World 2: when you specifically control Yoshi for the duration of the game. Seems like a bit of spotlight hogging on Mario’s part to me. his primary roles in this game seem to consist of sitting on Yoshi’s back lethargically, and crying inside a bubble.
The insides of this game prove to be the most interesting so far, however. Yoshi’s islands various high-quality image effects are made possible by the SFX2 chip that is built into the cartridge (the square one in the middle-right). The cartridge also features two additional “tabs” which connect to slots in the console that weren’t usually used. Why? for moar power, obviously. The game also features the battery-backed save feature which of course means it has a battery. The SFX2 was one of the latest add-on chips used with the SNES, and as in fact the second version of the SFX chip, which was used with Starfox. In that regard it could be used for 3-D effects. Yoshi’s Island does indeed use a few of these 3-D effects for some platforms and objects, and it does so rather well. Capcom created a similar chip, the Cx4 chip, which has a more limited feature set and works exclusively with wireframes. This was used in Megaman X2 and Megaman X3 for various boss fights and whatnot.
Here is another Wonderful game. The best way to explain Super Mario RPG would be that it is the gameplay mechanics of Final Fantasy mixed with a Story, characters, and graphical style that fits into the Super Mario Universe (which incidentally is probably the name of the Mario game to be released on the next console, after all we’ve go Super Mario Land, Super Mario World, Super Mario Galaxy, it’s the next logical step) Anyway this game is the result of a joint effort between Squaresoft and Nintendo. The result is unique and has appeal to fans of both companies games.
The Innards of the game are revealing; note that this game also uses the extra tabs in the cartridge slot. Some might guess “ah, so it has the SFX/SFX2 chip” Well, no. Many games with extra chips utilized the full cart connection. In this case, he game actually has the SA-1 chip, which can be best considered an “overdrive” chip, that speeds pretty much everything up. That isn’t a precise definition but that is the jist of it. We see once again the Battery, indicating a Save feature. And- that’s pretty much it. the SA-1 chip, a few ROM chips, and that’s it.
What did we learn? well, possibly not a lot, possibly a lot, I don’t know. In any case, the Cartridge based format is fairly interesting, because it arose both as a result of market conditions as well as to curb the cost of installing things like disk drives and the like into various consoles; additionally, before that many games were “solid state”; for example, the Magnavox oddysey, which was basically two player-controlled squares that could be moved around the screen. You had to use your imagination to make it into a game. The entire machine was hard-wired.
later machines were “programmable”, example being for example the Atari machine, which used what it called a “game cassette”; you had the system, and you chose a game by simply plonking your appropriate game cassette in it. This technology prevailed for many years. Nintendo in particular held fast to cartridges longer than many other companies.
For a time, cartridges were really the only route to go; any other form generally meant magnetic media which meant mechanical drives in each system, which were prone to failure. This also presented the problem of making the games something that could be copied, which was rather rampant at the time and was something the game creators would have liked to avoid. Later, when Optical media was coming to the fore, it was a matter of trade-offs; the price for the optical media was far less than manufacturing cartridges, and it had a lot more storage space (whereas with a cartridge you would need to buy more ROM chips to hold more data). The Sony Playstation was the first console to really storm the market with it’s Optical drive; in those days CD-ROM drives were becoming something of an enigma and were the “cool and techno” type thing, so the Sony Playstation really reflected the pinnacle of entertainment systems at that time. Additionally, it featured a 32-bit processor, which was faster than either the SNES or the Genesis/Megadrive.
Sega responded by introducing first the Sega CD attachment for it’s Genesis/megadrive, than by releasing the Sega Saturn. These were both comparative flops. Nintendo made the surprising move of sticking with the cartridge based format for it’s new console, the “Ultra 64″ which would be known as the Nintendo 64. This meant that the two systems (the playstation and the N64) had distinct disadvantages and advantages; the N64 had literally zero load time, but at the same time most of it’s textures were washed out; on the other hand, the Playstation lacked any sort of processing of it’s textures, but the N64′s extra processing power (in the form of the Graphics chip) was able to filter the otherwise low resolution textures, so you didn’t have low resolution textures all pixellated and stretched on a large object. If you pay attention, you’ll notice also that a lot of N64 games have the main character with very few textures; Mario in Mario 64 for example is predominantly solid-coloured and has no texture at all, merely vertex colours that are goraud shaded by the console. The playstation of course had it’s load time, but it also meant that games could be loaded on several discs; at the same time, because most code had to be loaded into the playstation’s memory before executing, this often meant less memory for the game itself, depending on how much it loaded. Nintendo finally accepted the Optical drive with the gamecube, but it made the disc spin the opposite way (to prevent piracy, or something I guess).
Every system since has used Optical disks; moving from CD-ROMs in the playstation, to Blu-Ray DVDs in the case of the PS3… (I think). And now consoles even have hard drives! They are really almost the exact same as a specially designed PC.
Everybody knows war is hell. That hardly needs any introduction.
However, not many people are aware of a certain intergalactic struggle that earth recently recovered from. This war was against an alien race known as the… well, actually, nobody really asked their names. They were all “hey, earth, we’re on your turf killin your doods” and we were all “hey” and stuff. Anyway we didn’t really know what they were called.
So at any rate, Earth deployed an elite squad- well, actually, they deployed a single ship, code-named Zanac.
Now one wonders- “why just one ship?”
well, back in those days they had a “sprite limit” see, nobody could see more then about 8 (maybe it was 11, I forget) moving objects on at once. Zanac was a experimental machine that allowed the pilot to perceive more then 8 objects at once using a method known as image compositing. The Zanac ship pilot explains:
“It was a philosophical question, back in those days- nobody was even sure if the human mind or visual cortex could handle more then 8 objects in their view at once without instantly exploding, or at least without frame lag. This was rather troublesome for mormons, since they had lots of wives and kids and generally had very oversized families, it made getting family photos rather difficult, with the photographer having the wear an anti-sprite-limit suit and all. So anyway, in the war against these new alien oppressors, we deployed the ship, code-named “Zanac” that included a sprite-capacitor that absorbed sprite information and fed it to the user in smaller, more managable chunks. The first few test runs were pretty promising, excepting of course the pilots heads exploding and making quite a mess out of the ships upholstery. But we didn’t have time quite to finish the tech, we needed to fight the aliens. I do recall my cousin bob making a note in his logbook at the time, about how well his beans were growing in his garden, and I think I said something to the effect of “It’s cold outside” or something, to which he remarke…
Me:You were talking about the Zanac war, and why you only deployed a single ship at a time.
Pilot:Oh yes, I do apologize- so anyways, they sent me on this mission to infiltrate the Alien federation and destroy it- or something. The actual mission was sort of vague, in fact I believe it may have been a yorkshire pudding recipe jotted down on a napkin. In any case, I had no idea what I was in for, in fact at the time I did believe there was going to be a fleet of ships. However, I wasn’t aware of the newest feature they had installed on the ships. See, although the ships’ sprite capacitors could absorb sprites and allow the viewer to see them in more managable chunks, there was a sort of force feedback with any nearby disturbances in the sprite continuum, so there could only feasibly be a single ship in operation at once. When I first heard the news of this, I was rather heartbroken- I couldn’t drink milk for a good week after that.
So they sent me on my mission, Which was pretty crazy right from the start.
Me:How do you mean?
Pilot:Well, when I started this weird triangely thing swooped towards me, so I figured I’d shoot it, it being an alien vessel and all.
Me: And?
Pilot: Well it turned into a giant fucking smiley face! I mean, what the hell was going on? I mean, it was the 70′s but a giant smiley face? people, come on!
Me: Actually, we have to satellite footage of this smiley face- refer to “Exhibit Q”.
Pilot: So, there I am, in this state of the art machine, fighting a god damned giant smiley weird face. So I decide- well, I may as well shoot it right- I shoot it. And nothing happens!
Me: And this was hardly weak weaponry, I take it?
Pilot: it was state of the art- well, truly speaking it still needed me to find weird blue boxes and grab yellow spheres from inside them for whatever reaso…
Me: wait, what? How does that make sense? you grab yellow spheres from blue boxes, supposedly owned by the aliens, to power up your weapons? Why not just attach a god damned nuclear warhead and just kill them all at once.
Pilot: Ahh, the sprite limit is why. See, if you tried to use a nuclear device in those days, you’d end up spawning too many explosion sprites and cause lag fallout that wouldn’t really do that much damage.
Me: Ok, so you shot the smiley face-
Pilot: I had to shoot it several times- and you know what happened? the damn thing turned orange/red. Like it was teasing me, saying “yep, you hit me, but I’m invincible”
Me: and what weapon were you using for this?
Pilot: for that I was using the blue circlely thing attachment, the silly string main weapon was pretty useless, it went right through them. So then I decided that I was done for, and set a kamikaze course into the smiley face, intent on wiping that god damned smirk off their face- and you know what happened? moment I touched him, he dissapeared!
Me: you’re saying he? How do you know?
Pilot: I was pointed straight up between his legs, He was like a bloody smurf… well, until he turned red, then he was a red smurf. Anyway, so there I am- dumbfounded. Already sure I had seen the strangest thing ever- but then I saw the aliens secret weapon coming right towards me- two concentric circles! It was awful, the pure horror of it all is indescribable.
Me: I can imagine.
Pilot: So there I was, ducking and dodging… shooting my silly string… and then I see an odd glass thing coming up on the horizon- so I naturally try to shoot over top of it at an enemy. And the damned shot hits the glass thing even though it was about a million feet above it in the air. Quite odd. So I continued shooting, and eventually this strange transparent number appeared. So, I of course grabbed it.
me: Wait, why the of course?
Pilot: Well, I’m not sure, it just looked inviting. I mean, can you think of a single time where a number in a square looks dangerous to you? I sure can’t. I can think of times that twigs looked rather menacing from the distance due to the way the light and shadow plays with them, and how our perceptions cause us to recognize patterns and objects that aren’t necessarily there.
Me: ok, well, carry on
Pilot: So there I am, I grab this number thing- and nothing happens.
Me: Were you expecting something to happen?
Pilot: Well, yeah, I guess so.
Me: OK, carry on
Pilot: so, anyway, I keep fighting, and I go to use my blue swirly thing attachment, and it is all purple and fuzzy and downright weird looking.
Me: oh, so something did happen.
Pilot: Yes, most importantly, it cut through everything like a sharp knife through goat entrails.
Me: Sounds useful.
Pilot: Hell yeah it was useful, in a world with giant blue circular smurfs, you need all the help you can get.
Unless you’ve been living in a cave for the past year, or are a hermetic monk seeking spiritual enlightenment, you no doubt have had least heard about Minecraft; I’ve referred to it in a few of my previous posts. What exactly is it?
Well, It’s a game. That much should be clear. But the question should really be “what makes it worth mention”? Well, That’s a loaded question, since naturally opinions differ. Some people think it’s the best thing since sliced bread; others think it’s nothing more then a child’s plaything, like lego. I fall neatly between these two.
The basic idea is that there is:
Anything you can think of doing, you usually can do. The nice thing is that it appeals to several different game players, who would normally seek different genres; you have the ability to explore and adventure through caves and find dungeons, and fight several types of enemies. Seeking treasures and materials; or adventure above-ground to find scenic locations or certain rare above-ground material deposits. Another “segment” is that if you can think of it, you can build it (as long as your idea fits within the game engine). For example, if you want to build a brick house, you can. But you will need to adventure and look for clay deposits, and then fire that clay into bricks, and then fashion the bricks into Brick “Blocks” which you can build with. It tries to balance the various things. Of course, that last bit is a taste of the concept of “crafting” which adds the “craft” to “minecraft”.
Basically, you can arrange various materials in a grid, and then that can create a new item that has a new use; For example, you can create axes, which make it easier to chop wood; shovels, which make digging dirt,sand, clay, and gravel easier; pickaxes, which are a necessary staple for underground exploration, swords to help inflict damage, armor, and various other tools and implements. Some people say that it’s the “procedurally generated world” that makes it worthwhile; I have to correct them, however, since although the world is “procedurally generated” that is no different then random maps on age of empires or Command & conquer; that is, the maps are generated procedurally. The appropriate term might be dynamically generated worlds- as you enter new areas, the game will randomly generate those new areas It’s not really so much “random” as it is “random with cues” that is, it doesn’t just randomly place blocks in a complete noise distribution, it randomly generates terrain and caves to look “natural”. This makes the replay value infinite; since even on the same file you could practically indefinitely go in a single direction and never run out of areas to explore. This brings about what I feel is sort of a bad point, though; while everything is generated randomly, the game has a habit of making things look pretty similar; in many ways, once you’ve seen one minecraft desert, you’ve pretty well seen them all. Of course occasionally the generator tosses in some unique landmarks or strange landforms, such as perhaps a dungeon lying right underneath sand so that the sand creates a small “dip” with exposed cobblestone, or perhaps grass covered mountains of trees in the center of a vast desert, etc.
This doesn’t so much detract from the game as much as it makes it easier to get lost. Thankfully, it usually throws enough unique landforms in that you can recognize them; “ahh, I remember, my main base was north of that mountain with the giant cave near the top”. The caves can sometimes be immense; having to light up every crevice to prevent monsters from spawning can get repetitive and boring, as you constantly find that the paths branch out in a handful of directions, and you find yourself getting lost near the bedrock with no torches, or something (which is more a result of being unprepared and reckless then of a particular problem with the game).
In a followup post I will discuss several “clone” games that are attempting to siphon off of Minecraft’s success, and even bring the game to new platforms.
And now for something completely different. By which I mean, A post smaller shorter then 1000 words I would have never expected this to occur; in fact by posting this I am throwing away a lot of work on other post drafts that I have yet to actually publish because I think they are “too short”. Although, come to think of it, I’m equally likely to insert a nonsense story at the end of this in order to add some fiber.
In any case, recently I’ve been rather heavily adding youtube videos. Almost all of them are gameplay; many of them are minecraft; some are doom; etc. They (almost) all share one thing in common – commentary.
Now, Although I haven’t actually gotten any messages (being that I have very few subscribers and so forth) on this, but I have seen people provide advice for making “let’s play’s” with advice something like “never talk about stuff unrelated to the video” obviously, I cannot apply this to my since that pretty damn well defines what one of my videos is. Only in one of my videos will I ramble about fighting cazadors in fallout 3, and somehow not clue in at the time that Cazadors are in New Vegas and not Fallout 3. Another suggestion I read about is that the sound of the keyboard/mouse/controller shouldn’t be heard. I don’t think it really matters, to be frank. In fact one could say it adds an extra dimension to the affair. Of course if you have a nice heavy keytronic keyboard (the mechanical switch type… drools ) then those will be pretty loud and if you are typing anything you will almost certainly find that nobody can hear a damn thing you say.
Also: I’m well aware that my attempts at humourous lyrics to go with the otherwise wordless music in the games has a tendency to fail. These things aren’t planned; if I could plan the lyrics they would be a lot more smooth; it’s the “on-the-fly” nature of it that makes it entertaining, dammit. Same goes for my youtube videos demonstrating progress on any of my programming projects.
When it comes to Older games; and even just games in particular, The developers obviously have to make some compromises; a game is never 100% realistic, even the most open sandbox game restricts your actions; Fallout 3, for example, while a vast world with numerous ways to complete the game and perform actions, still provides only a finite number of ways to go through the game; additionally, you can never “leave” the capital wasteland thanks to.. well, for no good reason. It just won’t let you leave thanks to invisible walls.
NES games, in particular, really use this. Take- Super Mario Brothers.
Right at the start, there is a goomba. If it happens to shuffle slowly into you, you die. Realistically speaking, being touched by a mushroom is not something that is usually fatal, even a anthropomorphized one that can magically move by changing the size of it’s feet.
it’s a permissible break from reality, given the limitations of the system, and in the name of fun. Extending this logic back into reality has some pretty interesting results, what with people exploding at the slightest touch, meaning that reproduction of our species is made both very impossible and all attempts to do so rather messy.
But wait! They wouldn’t explode, they would look to their right, hold up their arms and legs, and jump up several times higher then is physically possible and fall through the floor. Additionally, we will find that grabbing seemingly innocuous objects will grant us super powers; the leaves of any deciduous tree will allow you to become a mutant freak raccoon hybrid, while grabbing flowers will allow you to shoot fireballs.
Then you have the various games, such as contra, that represent bullets as slow moving projectiles. Allowing you to literally see the enemy shoot, the bullet come towards you, and effortlessly jump over it. It’s like the entire game is played in bullet time or something. Which naturally makes the game a lot easier, which isn’t saying much, as anybody whose played this game can attest. They may have made the bullet mechanic less frustrating, but they compensate by literally filling the screen with these bullets, especially the later levels.
Additionally, most games often represent lasers as projectiles that have an observable speed- see Goldeneye 007 for the N64 for one example- super metroid provides another, with the Plasma beam (which to my understanding is a laser).
a laser, by definition, travels at the speed of light, not something you can really “observe” in transit. On the other hand, the results from this particular difference are a lot more fun to observe; seeing a laser coming at you and blowing up your head, even though you died in the game would be a lot more “fun” then simply having your head explode for what seems to be no reason.
On the flipside, you often have games that perform what is known as “hitscan” testing. That is- the bullet is never actually “in-flight” when you shoot, it instantly hits the target. This is an acceptable compromise, since a game like Doom was both made many years ago (when computers weren’t as powerful) and the aim of the game is to kill evil stuff, not to learn about firearm ballistics. Some newer games try to avert this by actually having the bullets trajectory’s estimated and accounted for. This makes for more realistic gameplay, which can be just as fun.
Mario is an example of many of another interesting issue. for example, it’s easy to create a perpetual motion machine; simply find a koopa or buzzy beetle between two pipes, stomp them, and kick their shell. The shell effortlessly glides along the ground as if it was made of a completely frictionless material (despite mario’s clear ability to grip and move along it) additionally the shell will rebound off the pipes or blocks to either side in a perfect elastic collision and it preserves 100% of it’s horizontal momentum. Further, having two shells do this and collide causes them both to “die” (flip upside down and fall off the screen, just like how objects are destroyed in real life, right?) whereas one would expect they might bounce off one another. Actually, the reason for this I suspect is that a shell in movement essentially kills any enemy whose hitbox it collides with; in this case, both shells kill each other. (since there is no special case whereby a shell hitting another shell causing any specific behaviour). This is changed in Super Mario World, since making two movable enemies (such as upside down goombas, koopa shells, buzzy beetles, etc) collide will cause them to die but it also gives you a different amount of points; whereas on the first SMB two shells colliding would give you the sum of the number of points each shell is worth (depending how many enemies they have collides with so far) colliding two objects in smw would always give you 1000 points. additionally, you could just walk into a second shell or enemy while holding another and destroy both, while simply dropping the shell on said enemy’s head will kill them but preserve the shell. Really it’s a lot of rather complicated rules that make sense to people that play it but when you consider it it not only is entirely unrealistic (justified, it being a game designed for fun) it is also inconsistent even with it’s own rules (a ‘la the “drop or kick the shell to kill an enemy but preserve the shell, or keep holding it to destroy both)).
RPGs are of course not exempt from this, clearly because people don’t advance through levels nor actually acquire experience points; nor do they magically learn new skills out of nowhere when they acquire enough tech points or reach certain levels. Earthbound has this, when you reach certain levels, you instantly learn new PSI skills. “Ness realized the power of PSI Rockin’ A” for example. However, when you consider it, it doesn’t make any sense, realistically, whatsoever. “Wow, it’s a good think I killed that boss. Hey, I just realized I can kill shit with my mind, cool.”. You’d expect there to be some training involved. And then later in the game, Poo, a hilariously named character from the Far East area called “Dalaam” is whisked away by somebody who actually does teach him PSI skills. So it would seem that when you have PSI abilities, you can just walk around and kill things, using whatever you want and you suddenly learn new ones. Hell, you could even get Jeff to just kill stuff with bottle rockets while everybody else watches.



Ness: OMG! A blue swirl enveloped me, and now you guys have suddenly appeared next to me to fight a oak tree!
Jeff: Don’t Worry! I’ll launch a Big Bottle Rocket at it! *shoots bottle rocket*
Ness: OMG! the Oak tree exploded into flames
Jeff: ACK! I have taken mortal damage!
Paula: AHH! I also have suffered damage that will lead to my death
Poo: the flames missed me.
Ness: Whew, the battle is over, everybody OK?
Jeff: yes, thankfully despite having 86%A of my body covered in third degree burns during the battle in what would realistically cause me instant death, because the HP counter had not rolled over to zero by the end, I survived just fine with only a few scratches.
Paula: I’m a GHOST!
Ness: OMG! Watching you kill that Oak tree with a bottle rocket has caused me to learn a new psychic move, despite the fact that PSI healing Omega is clearly unrelated in any way to bottle rockets.
Poo: I can mysteriously speak english, despite being from a country on the other side of the world.
Paula: HELLO! I’m a ghost here! Not good!
Ness: here, Paula’s Ghost, have a cup of noodles
Paula: Ahh, much better, I have become corporeal again. That was odd. These are damn fine noodles.
Ness: OK, gais, let’s go to a hotel
*they all stay in a hotel*
Jeff: dudes, despite the fact that I didn’t get any sleep, my HP is fully restored!
Ness: cool. why’d you not sleep
Jeff: DUH! I was fixing this Broken Spray can, and when I fixed it, it became the DEFENSE SPRAY!
Ness: That took you all night? It’s a spray can. Why are you carrying around broken stuff anyway?
Paula: Hey guys I think if we battle a few more random enemies I might learn how to freeze enemies using PSI Freeze Omega!
Ness: Wow, cool, and then we can go and defeat the big bad enemy who has no true form and is a lampshade of all “ultimate evil” type enemies in all games.
Poo: OMG I LOST MY SHOES.
Ness: dude, you never had shoes.
Poo: Oh.
This of course happens in nearly all RPGs…. and let’s not forget Final Fantasy’s thing where they always make the bosses like fifty times the size of your characters. (And of course the whole “I will walk forward and slash the air… TAKE THAT! numbers have appeared in front of you!” thing).
Additionally, when you kill enemies (in older games) oftentimes they don’t leave a body behind. In Chrono Trigger and final fantasy, for example, they just sort of dissipate. If that was something that occured in real life funeral homes would go out of business. Thankfully, in the game, they still leave plenty of lootz.
Several Shows on Television suffer this to a hilarious degree. CSI is a prime example, as well as NCIS. Whenever an episode has any sort of involvement of computer hacking or anything remotely similar, you may as well change the channel. It’s basically a stream of made up crap that means nothing at all. Let’s not forget the classic case whereby none of the computer interfaces are even vaguely familar half the time; you’d expect them to use; I don’t know, an OS that exists; however they all use some weird special OS whereby all fonts are at least 72-point and every single piece of text types itself out when you go to show it; showing that, despite the computers being super fast, they haven’t mastered the basic art of text display. Or more likely they made it look fancy for no good reason. Also, when they are comparing fingerprints, rather then the program, I don’t know, just saying a % of the database it’s gone through, it instead displays every single entry as it goes through the database. Apparently none of the people responsible for this realized how stupid and pointless and slow that was.
Another magic feature is the “enhance” option, which appears to be a part of anything that can handle images. Merely displaying an image in Paint, for example, and saying “enhance that” and pointing at a vague location of the screen tells the computer to enhance a 5 by 5 pixel area that represents a suspect/victims face, and then it magically extrapolates, using those 5 pixels, exactly what that person looks like in high definition. Of course this is entirely impossible with even the BEST software because it’s basically constructing data out of nowhere. It’s like having a picture of yourself from that only includes your face and telling the computer to give you body and then having it actually create what you looked like that day. The data is gone, or it never existed. no amount of “enhancement” is going to bring it back. Sure, you can apply various filters to highlight trends or patterns in the data that does exist, and so forth; but “enhancing” the image and causing missing data to be “interpolated” out of thin air is nonsense.
Star Trek, naturally, is no exception to this sort of thing; characters can perform about 20 different things on one console, while only tapping a few random buttons. And of course, the interface makes no sense at all; it’s a few colourful rectangles, only some of which have a random number over top of it, and yet everybody seems to know what each one does, even [i] aliens who have never encountered it before [/i] . If these aliens can do it, why can’t us viewers make sense of it?
And now I have totally forgotten what I was talking about. Oh well.
No, Not the kissing disease, Infectious mononucleosis, the open-source .NET CLR interpreter and class library.
.NET; I might have ranted about this before, if not on my blog, elsewhere. most of my arguments were against it, being a VB6 using ignorant buffoon. In any case, I’ve found C# to be an awesome language. One of the obvious downsides is that for the most part programs written in C# using Windows forms cannot be run on other systems.
The concept of Mono is to change that; remember, C# isn’t a Microsoft standard, it’s an ECMA specification, and Microsoft holds no copyright over it or anything like that. Mono is a relatively huge undertaking; the creation of something on the scale of a Virtual machine as well as a class library is gargantuan, and of course there is very little hope for 100% success.
On the whole, Mono performs it’s primary goals admirably; there is a GTK# framework that can be used to develop windowed applications… of course then the installation on a windows PC would require the install of the Mono GTK# framework, but I digress. In any case, applications can be developed and the C# code interpreter (for on the fly syntax highlighting) as well as the compiler are top-notch and seem to work well.
My only beefs can of course be in the class library. Of course, re-implementing the class library provided by MS on non-windows systems is not something that can be done in a single afternoon; this stuff takes time. My attempts to create a Mono-compatible project have been stifled, however, by seemingly innocuous issues. AlLlow me to explain.
As many reader may be aware, I have been working on a “upgrade” of sorts to my now ancient “Poing” game, which can be found on my downloads page; the original game was written in Visual Basic 6, and, in it’s earlier incantations didn’t have a single Class; it was all based on User-Defined Types (structures for those privvy to C parlance) and functions; (short explanation: it was made before I understood classes). Later, after I had learned about classes, I refactored everything into classes. This is all rather redundant; in any case, I have since created a new project in C#, in an attempt to learn about GDI+ as well as what appeared to be a different (in some ways) painting model. As one can see by the youtube videos I have posted on it, development has gone well.
The idea occured to me, after Tux2 (of http://www.jrtechsupport.com/) managed to create a Mono-workable, if soundless, version of my earlier C# game, BCDodger that worked in Linux. Sound was unavailable as a result of my choice of sound library, the IRRKLANG library, while truly usable in Linux, doesn’t have a wrapper that works in Linux (or something, I don’t know… it uses DSound or something, I forget). In any case, I have since added the ability for various sound engines to be used, and have added working implementations for Open-Source and Linux-available Sound systems, such as NBass (as well as a broken fmod implementation, let’s ignore that though).
Much obliged, I had decided to try to get it working via Mono as well; this was facilitated by my recent reformatting of my laptop to run a dual boot Windows 7 and Mint 10 system. Installing MonoDevelop and all that, etc.
So, I of course open the project in Monodevelop, quite ready for errors relating to porting.
The version I am using is MonoDevelop (and I assume also Mono) version 2.4, for those following along.
My first hurdle was getting my Appdata files for the program in the right location; on windows systems they are placed in the application data folder; so too they would need to be on a Linux system. Thankfully, a quick C# program run on the Linux machine cured this issue:
using System;
namespace specialfolders
{
class MainClass
{
public static void Main(String [] args)
{
foreach(Environment.SpecialFolder sfolder in
Enum.GetValues(typeof(Environment.SpecialFolder)))
Console.WriteLine(sfolder.ToString() + "=" +
Environment.GetFolderPath(sfolder));
}
}
}
Which gave me, on a Windows system:
Desktop=C:\Users\BC_Programming\Desktop Programs=C:\Users\BC_Programming\AppData\Roaming\Microsoft\Windows\Start Menu\Programs Personal=C:\Users\BC_Programming\Documents Personal=C:\Users\BC_Programming\Documents Favorites=C:\Users\BC_Programming\Favorites Startup=C:\Users\BC_Programming\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\Startup Recent=C:\Users\BC_Programming\AppData\Roaming\Microsoft\Windows\Recent SendTo=C:\Users\BC_Programming\AppData\Roaming\Microsoft\Windows\SendTo StartMenu=C:\Users\BC_Programming\AppData\Roaming\Microsoft\Windows\Start Menu MyMusic=C:\Users\BC_Programming\Music DesktopDirectory=C:\Users\BC_Programming\Desktop MyComputer= Templates=C:\Users\BC_Programming\AppData\Roaming\Microsoft\Windows\Templates ApplicationData=C:\Users\BC_Programming\AppData\Roaming LocalApplicationData=C:\Users\BC_Programming\AppData\Local InternetCache=C:\Users\BC_Programming\AppData\Local\Microsoft\Windows\Temporary Internet Files Cookies=C:\Users\BC_Programming\AppData\Roaming\Microsoft\Windows\Cookies History=C:\Users\BC_Programming\AppData\Local\Microsoft\Windows\History CommonApplicationData=C:\ProgramData System=C:\Windows\system32 ProgramFiles=C:\Program Files MyPictures=C:\Users\BC_Programming\Pictures CommonProgramFiles=C:\Program Files\Common Files
Nothing particularly out of the ordinary there. So, running the program on a Linux machine:
Programs= Personal=/home/bc_programming Personal=/home/bc_programming Favorites= Startup= Recent= SendTo= StartMenu= MyMusic=/home/bc_programming/Music DesktopDirectory=/home/bc_programming/Desktop MyComputer= Templates= ApplicationData=/home/bc_programming/.config LocalApplicationData=/home/bc_programming/.local/share InternetCache= Cookies= History= CommonApplicationData=/usr/share System= ProgramFiles= MyPictures=/home/bc_programming/Pictures CommonProgramFiles=
which gave me what I needed: the appdata folder “BASeBlocks” needed to be copied to /home/bc_programming/.config.
Doing so was easy enough; the file manager on Mint 10 (dolphin) is different from windows explorer but hardly paradigm-breaking.
That copied, I simply threw the source folder as it was on the Visual Studio 2008 projects folder into the MonoDevelop projects folder (well, not really, it was /home/bc_programming/projects/ which I suppose means that any program that uses a projects folder will use it, oh well.)
psyched as I was I ripped into it with MonoDevelop, ready for anything! well, nearly anything.
My first error occured on line 107 of “Block.cs”:
mPowerupChanceSum = Powerupchance.Sum();
Java programmers may be thinking “ew uppercase characters” to them I say be quiet you. Anyways, the problem here was that there was no “Sum()” Extension method defined. Which I found odd. Oh well, though, I simply created my own:
#if MONO
public static class monoextensions
{
public static float Sum(this float [] floats)
{
float accumulator=0;
foreach(float loopfloat in floats)
accumulator+=loopfloat;
return accumulator;
}
}
#endif
this solved the immediate issue of the “Sum()” extension method. (For more info on C# extension methods, see here )
My next hurdle was on line 540 of cBall.cs:
if (wholeref.Blocks.Count((q)=>q.MustDestroy()) == 0)
The error was something to the effect of not being able to pass a delegate or method group to a lambda expression.
oddly enough, the fix was the change the “q” to an x… and after it successfully built I was able to comment out the “new” line (with the x rather then a q) and uncomment the original. very odd.
In either case, now I was confronted with what I knew to be the biggest issue; the fact that I had to now discover how to set it up so that I was able to use the same nBASS library, but so that the nBASS library was “silently” made to use the BASS.so linux library, rather then bass.dll which wouldn’t load either way.
The first step in this process was in finding bass.so. Hoping for the best, I pulled up good ol’ synaptic package manager.
No luck there
so, I went into the depths of the internet….
the BASS for Linux (note the lack of the n prefix; it’s the core BASS library that the nBASS dll is wrapping) can be found here
this topic; or, the original post, to be precise, gives the download location for the Linux source files for BASS 2.4, which can be found at http://www.un4seen.com/stuff/bass24-linux.zip
So, I downloaded the zip file, extracted it to a folder, and am about to attempt to compile it. (there is a libbass.so that I could probably try, but I think I’ll compile it myself instead).
Before I continue, however, I would like to mention something that has most impressed me about Mint 10; the multiple desktops. Now, this is hardly a new feature; programs can be downloaded that do this on windows, and windows itself has built in API support for multiple desktops; however, what impresses me most is that when you activate a window on another screen, it switches to it; what I mean is, for example, in this instance my FF download window was on another desktop (no idea why) and when I went to open the downloads window via Tools->Downloads, it did the fancy compiz box animation (as I have selected in preferences) and switched to it. very cool. But enough if my gushing over the unexpected presense of sanity in the UI design of a Linux desktop environment! back to my attempts to get BaseBlock working on Linux.
my attempts to make the bass project, however, failed:
bc_programming@Satellite ~/Projects/bass $ sudo make make -C 3dtest make [1] : Entering directory `/home/bc_programming/Projects/bass/3dtest' cc -Os -I/home/bc_programming/Projects/bass -L/home/bc_programming/Projects/bass -lbass -Wl,-rpath,/home/bc_programming/Projects/bass `pkg-config gtk+-2.0 --cflags --libs` `pkg-config libglade-2.0 --cflags --libs` -export-dynamic -D'GLADE_PATH="/home/bc_programming/Projects/bass/3dtest/"' 3dtest.c -o 3dtest Package libglade-2.0 was not found in the pkg-config search path. Perhaps you should add the directory containing `libglade-2.0.pc' to the PKG_CONFIG_PATH environment variable No package 'libglade-2.0' found 3dtest.c:7: fatal error: glade/glade.h: No such file or directory compilation terminated. make [1] : *** [3dtest] Error 1 make [1] : Leaving directory `/home/bc_programming/Projects/bass/3dtest' make: *** [3dtest] Error 2 bc_programming@Satellite ~/Projects/bass $
Oh the humanity! now I had to learn about this package nonsense. I first suspected perhaps, as evidence by the fact that it wasn’t found, said package wasn’t installed; so I did a quick sudo apt-get install libglade-2.0 … it reported it was installed already.
after a bit of effort, and installing a few dev packages, I gave up. I was able to resolve the missing dependencies but then it complained about a missing .h file (which was indeed missing and clearly should have been present) so I gave up on that, and am at the time currently trying to simply use the .so file included. An additionally problem that arises here is the obvious fact that I am using a x64 Linux system, working with C# code written on a x64 windows system but targeted towards a x86 system, problem being that to my understanding Linux is not as lenient when it comes to architecture differences; but I suppose I’ll figure that out for myself if it’s the case.
In any case, I am now attempting to get the nBASS library to wrapp around libbass.so rather then bass.dll; from my research if the imports are the same I should have no problem creating a dllmap entry in the appropriate config file. From the documentation it would seem that discovering where that config file goes is left as an exercise for the reader.
Actions:
pasted libbass.so in the “Debug” folder (alongside the dll).
Copied the BASeBlock.config file from the project root to the debug folder; renamed to Bass.Net.config.
opened preceding file in gedit; it now looks like this:
< ?xml version="1.0" encoding="utf-8" ?>
And now, I attempt to run BASeBlock… recall that it now compiles on Linux, so it’s just a matter of making it work. I could, in a worst case scenario, construct a “nullsound” driver that simply stubs out the sound playing interfaces. But that seems like a bit of a cop-out. IN any case, attempts to run it resulted in the same error; clearly either the documentation I was reading was incorrect or I was not interpreting it properly.
I did a few more googles and came upon this page, which, despite being about something completely different addressed the same problem; that is, translating the dllimport(whatever.dll) into imports of functions from Linux .so libraries. namely, it told me where the Mono parameter file was- /etc/mono/config. I quickly opened the feller using gedit:
I tossed in the line:
and crossed my fingers…
It still didn’t work. I guessed maybe mono only loaded that stuff up when it was started? So I restarted monodevelop.
excellent! a little progress. Now I was still getting the error, but it was complaining about libbass.so missing. At least we’re getting somewhere.
It still should have found the file; however, I decided that instead of just throwing it in the app directory (because god knows where Mono is truly looking for it; even putting ./libbass.so in the dllmap failed, so Mono clearly thinks something else is the “current” directory. Instead, I decided to simply cp it somewhere globally accessible;
It still didn’t work.
Anyway, I messed around with the config file and the dllmap attribute and no matter what I put it it refused to find the file; clearly I’m missing something obvious (maybe capitalization? a missing slash? who knows). In either case I decided to defer that work to later on; I’m sure there was more to be fixed afterwards.
So, I created the aforementioned “Null Sound” driver; it worked fine. compiled alright. Encountered a bunch of issues during startup relating to my use of the \ as a path separator, whereas Linux uses /, fixed this with a simple Replace to change all slashes to the slashes of the OS (Environment.PathSeparatorChar).
It still refuses to start; Some gdi plus error. I have no idea how to workaround this, since it seems to be related to the windows forms, and has nothing to do with my own code, but rather with some configuration option. I recall Tux2 working around a similar error in BCDodger but I wasn’t paying very close attention and forget what the fix was, or even if he mentioned it. Either way, at least now BASeBlock compiles on a linux system, and most of the code-related oversights have been resolved.
EDIT:
I’ve managed to solve both issues; not at once of course.
First, the loading issue was fixed; pretty troublesome. In my attempts to resolve the problem I created a number of projects that used the same Image.FromFile() method to load pictures, and they worked fine.
Clearly, the problem then was not in what was not visible; the difference between the two. I realized that the difference was pretty clear: in my test projects, I was loading the images from within the form’s Load event; in BASeBlock, they were being loaded in a static constructor. So I decided to try to load the images elsewhere; I converted the static constructor to a static function, and called that function in the form load; there were a few other changes that I needed to make, mostly in the form of initializers attempting to use values that wouldn’t have been initialized.
The game started and ran fine with the NullSound driver.
Now, to fix the Sound; I opted to try to get nBASS working.
the solution was actually quite simple; merely a dllmap for bass.dll to libbass.so, and placing the x64 libbass.so in usr/lib was enough, and sound worked fine.
Unfortunately, it’s still slow as hell but at least I think that’s Mono’s fault.
I was looking over some of my old project folders, and I found a 54-page (well, 54K text file) development log (devlog.txt) for my VB6 version of BASeParser.
despite what many people would logically assume, it doesn’t appear to contain quite as much development logging as it does general griping about my situation. It’s damn nearly a journal. (you’ll note my quite conscious decision NOT to use the term “diary”. Awful lot of references to Motocross madness, and I seem to like the spell it MotoCross. Oh well.
Because I haven’t posted in a while, I thought it would make an interesting blog post. I’ve gone through and tried to “markup” as much as possible (italicize, code boxes, etc). Everything else exists in the text file (including the “edits” that might appear to be made as I create this).
BASeParser Development Log, Started 30/Dec/2006 13:25
—————————————————–
*I’d like to take this opportunity to mention that this development log seems to double as a upgrade log for my computer.
oh well…
Also, it is a DEVELOPMENT log, not a Changelog. I’ll peruse this text later on and make a changelog.
PREFACE:
This is NOT my first Expression Parser/Evaluator. My first one, also named “BASeParser” was actually almost as good as
this one (albiet it took about a year to get that way). However, after a series of computer mishaps, I no longer have it’s
code. In fact, I lost the code to all 4 of my large projects during this time. I will explain this, because, looking back,
It is funny. Annoying, but funny. Ok, not funny. Freaky, maybe.
Anyway, I usually kept ALL my Visual Basic files on a small USB thumb drive. Now, I know the importance of back-ups, so I
backed up the important stuff off of this key once a week. One day, I decided to open up one of my programs, BCFile. I was
greeted, from VB, with a nice “path not found: I:\vbproj\vb\BCFile\BCfile.vbg”. I immediately thought that, as usual, the
key had for some reason assigned itself the drive letter “G” or “H” as it sometimes does. However, it appeared as I: in
windows explorer. I immediately became concerned. Looking in I:\vbproj\vb\, and- I found no BCFile directory! I knew what
to do, so, as quick as I could, I copied all the data from the key to a NEW backup folder, on my third hard drive,
E: [DAMNDISK] (the reason for the name involves another long-winded explanation about data-loss as well as a CD-RW drive
getting fried.). OK, so I had all the data I could grab. or did I? I ran Chkdsk /f (NOT scandisk) on the drive. It found
23 megs of lost clusters. I converted them to files, moved the files to E:\CHK, and re-formatted the usbkey. I then
assessed the damage I had received. A major blow. what happened was, for some reason, the FAT on the drive thought a
crapload of files where only occupying one cluster (4K) of space. thus the lost space. Now I just needed to examine all
the files on the backup. My prize program, BASeEdit XP, was completely ruined, with it’s main Class gone and the resource
file truncated, it seemed obvious that re-writing this over would be easier then fixing this one (although I did put a lot
of work into it). another, BASeMetry, suffered fairly heavy damage, with a class representing Polygons was truncated.
BCFile, well, I assume the files were there, but the directory was munged up, so I couldn’t access them.
With all this extensive damage to a random assortment of files on the disk, I got smart- I used the windows find utility
to search for all files that were EXACTLY 4K (4096 bytes) in size. The list was very long. I was very sad. Then began a
excruciatingly long process that I would not wish on my worst enemy…
So, had I lost the files? I had no file-recovery tools to speak of. But I did have the chk files. All the data that was
truncated from ALL the files was inside those CHK files. But every single CHK file was only one cluster, 4K, in size. So I used the COPY command to append all the CHK files into a big file, which I named, “BIGCHK”.(as if the name I chose is relevant here) I then opened this file in editpad. And so began a night-long struggle to recover data.
My first step in each case was to drag one of the 4K files from the search into the editpad window. Then, I would look for
something within that file that would be unique. Using that, I would search the BIGCHK file for that string. When it was
found, I would grab all the data that belonged to the file and paste it back into the truncated one, save it, close it,
and repeat. It worked better then it should have, I got several of my modules and classes back.
This was a monotonous task, but I was determined. If I was to lose my projects, I wasn’t going down without a fight. I
actually managed to recover two projects completely- BASeParser, my expression parser (Not the one for which I wrote this
devlog, as you will see) and BCFile, my File Access component. BCFile, was completely recovered, except for one of the
Type libraries it used was truncated. Until I got that type library, I could not use it.
So I managed to recover from that bout OK- all I had left that was usable from BASeEdit XP was it’s Logo (how very
helpful),as well as a few classes from it. I kept all these old, mostly corrupted files on my E:, third hard disk, becuase
I figured since it had NTFS and was freshly formatted, it should be far more reliable then my D: drive, which consistently
freezes randomly (Actually, I fixed that since then –Bad sectors–). I decided I would work only from my desktop
computer, as the USB key kept failing, and I kept having to pick up the pieces.
So I was working with E: as my code drive. Everything evened out- I accepted the loss of my code. I then decided to see if
I could fix the usbkey- it seemed to believe it had bad sectors. I decided to repartition it. I right-clicked the I: drive
in disk manager, as one would expect to do. I got the basic warning, “all data blah blah deleted blah”. The moment I had
clicked OK, I realized what would happen next. It dismounted Drive I:, as it would for any other drive- however,
dismounting the key made it disconnect as a drive. I watched the drive dissapear from the Disk management window,the
selection move up to my E: drive, and disk management began deleting it’s partition. I will not repeat the expletive I
uttered at this point. I tried to recover the data by somehow re-constructing the partition information alone. I of
course, failed miserably to do so. I re-create the partition, formatted it, and once again, found myself assessing damage.
All my code was gone, with no hope of recovery, at least, not without an expensive software package.
#1 30/Dec/2006 13:25
——————–
As a result of either a bug in the disk management program or a misclick by me, my entire E: drive got wiped out.
This means that I have only the code that was in my D:\vbproj directory. As a result, two of my prize libraries,
BASeParser and BCFile, have been lost forever.
***EDIT, 30/Dec/2009 05:35 – theeeeeey’re BACK! BASeParser and BCFile, in FULL Force. of course it’s been 3 years to the
day since I originally wrote this section,(BASeParser is still under semi-active development, but the groundwork was laid down in 9 hours as I state here)
… I did take a “sabbatical” from programming for a while there, too, in those three years.***
On the bright side, I immediately set to work writing a new BASeParser
library. After 9 hours of straight coding (with a short break for food) I have done it. I made a complete replacement for
BASeParser. This version however, is purely my code (The old one was based on a Parser by Konrad Rudolph- that is, I took
his code and made it good (ha- just kidding.)) although I based the algorithms on those found in the previous version. In
addition, I have abstracted both operator and function recognization and execution into a separate interface. This cleans
the BASeParser code up considerably, whereas in the old version the Operation and Function Resolution where both in the
Parse Stack, which made it difficult to implement custom operator and function resolution. Not to mention the ExecFunct routine
was completely irrelevant as far as the Stack itself was concerned.
In short, I think I should be proud of myself. I re-wrote an application that originally took almost a year to build. of
course, I didn’t work on it every day, but still, this much code in so short of a time, and it works. (Well, as far as I
know).
In fact, I’m surprised I set right back to writing it, since I lost EVERYTHING. BASeEdit XP …
***EDIT, 30/Dec/2009 05:35
BASeEdit XP has a project skeleton and basic menu structure created (and I <THINK> the whole IDocument interface stuff, too)
but it’s far from a usable application, still.
***
…was already a write-off, but
at least I could have salvaged code from the parts that were left. Now I no longer have that luxury. So when I finally to
start that (that will be AFTER I re-create BCFile.dll), I’ll need to rewrite a lot. Thankfully, I still have the awesome
VBAccelerator Components that I downloaded, as well as a module, modCmdBarXML…
***EDIT, 30/Dec/2009 05:35
The stated module is now a Class module and is FAR better then the module was.
***
…that populates VBAccelerator CommandBars
From XML files/Strings, using the MS XML parser. I also lost my CommandLine Parser, but I should be able to toss that out
in no time. ***EDIT: I did during a few spare moments on my laptop
*** I can’t seem to escape string parsing, and I have become extremely proficient with the string handling of
Visual Basic (not that I wasn’t before).
#2 31/Dec/2006 3:28 PM
OK, so the BASeParser ENGINE is pretty well completed. All that I need to do now is decide on one thing- do I
implement all the different core operators/functions in a single internal implementation of the IEvalEvents Interface, or
separate them into different modules, like PPCoreArray,PPCoreOpFunc, PPCoreEnviron, etc for (Array,Operator, and
Environment variable evaluation respectively). Now, I think that segregating it will make the files themselves harder to
manage, but tracking down bugs will be a lot easier. Besides, I get to see if this “plugin” architecture works the way I
designed.
Oh, I found a pretty old version of the original BASeParser on my Thinkpad laptop, from a time I tried to document it.
It is almost a year old, which is sort of satisfying (if it was newer I would suddenly have TWO really good evaluators).
the good thing is I can borrow the code therin that implements the CallByName function. I totally forgot how to do that.
(Read, I’m to lazy to do it AGAIN!). (EDIT:(2/Jun/2007 5:00) Actually, I didn’t want to include too many references)
3/Jan/2007 1:00 AM
Working on the BPCoreOpFunc’s class. Fixed bugs relating to multi-argument functions (namely, the parsearguments function
would return arguments after the first with the comma included). Fixed that. Now I have a new dilemma- Unary operator
support. Obviously I’m going to need to delve back into the operator parsing and execution code. I also changed all
the function return values into ByRef values from subs, so as to allow for Objects to be returned (otherwise, I’d need to
make two calls, one on an IsObject, and another to actually retrieve it)- the isobject would be used to determine if Set is necessary.
UPDATE: during the same day I THINK I got unary operators working. Don’t be too surprised if you see a new bug arise. I
don’t really want to call the way I implemented it a hack. What happens is, during the resolution of an operator, it
decides that the operator is unary if either it is the first item in the expression or the previous item was a operator.
This takes care of functions and brackets, which implement their interior as sub-parser objects, and operators working,
such as 5*-1, and 4+-5 and such. I am sure I missed something. I just thought I might have problems with an expression
like -(5) and such, but, it turns out, I don’t. What the Unary operator does is NOT move itself around on the stack, like
the other operators. Since the unary operators precedence is essentially the same as the value with which it is paired, it
stays put, so you get a stack like this, before the BuildStack_InFix Procedure runs through:
(this is for “5+-70″)
(IT_VALUE,5) (IT_OPERATOR,+) (IT_OPUNARY,-) (IT_VALUE,70)
the BuildStack_Infix rearranges the operators according to their precedence. Their precedence is derived via calls
from the plugins. Higher precedence plugins will always have their operators listed first, and they will be called first,
as well. In this case, the only operator is the +, which, upon encountering, the Stack fixer pushes onto a temporary,
operator stack. after looping through the remaining elements, it pushes all the values from the operator stack back onto
the parse stack, ending up with:
(IT_VALUE,5) (IT_OPUNARY,-) (IT_VALUE,70) (IT_OPERATOR,+)
This may look impossible to collapse (evaluate), because the unary operator has no idea about what it is supposed to act
on (since when the loop iteration is at the unary op it still has not reached the IT_VALUE for which it is paired)
however, due to a clever scheme, the IT_OPUNARY does not handle it right away- instead, it sets a module level variable,
which is a event sinker for the ParseStack, as well as another variable that holds the current parse item (which is the
unary operator’s CFormItem). Then, when something happens which Pushes something onto the stack (say, a function is
evaluated, a variable is pushed, a value is pushed, whatever- the DataStack raises this event, we catch it, and already
know the context of execution- and simply call the EvalListeners Unary evaluation, and return that in the ByRef DataStack
Event parameter. (Of course, being able to change the code in the DataStack enabled this event to appear. (I can change it
because it’s mine).
-after getting the basic “-” operator to work, I discovered that it wouldn’t work with the Unary NOT operator. The fix?
well, I traced the bug into the ParseValue function. the string it returned was NOT4 (my expression was NOT 4). I
concluded that for some reason the MakeParsable Function was not re-adding spaces to the NOT operator. Turns out the
entire problem was within my BCoreOpFunc class. the Constant that had all the operators ended with NOT, but there was no
space at the end, so the class was returning that it didn’t recognize the operator (it searches for ” ” & Operator & ” “),
or, ” NOT ” which it can’t find. fixed it by adding a single space to the end of the constant. lo and behold, Not 5 is -4!
Wednesday January 03, 2007
Work for today on BASeParser- implement more functions. This Parser seems much better then my previous one- the previous
one included all sorts of hacks, because I was working with what was not originally my own code. Not to mention the Sinks
for operator and function implementation where completely messy hacks. They worked great, but that didn’t change the fact
that the engine was not originally designed for it. It was like putting a Jet engine in a Volvo (No pun to the Jet
Database engine intended). I designed this one from the ground up to NOT have a single implementation detail inside the
parser- it simply knew how to parse the syntax of an expression. It would then pass on how
to execute the Stack it thus created to external classes. Of course, core stuff, like +,- and a bunch of VB functions, are
implemented internally in a Implementor that is automagically added to the CParser class upon create().
BUG FIX:
found a bug in ParseArguments. A REALLY stupid one. seems that it only looked for the VERY next “,” – so if a argument to
a function contained another function call with multiple arguments- it wouldn’t work right. I fixed it by moving a If
block that for some reason tested for an impossible condition (it was checking if Char=”(” right AFTER the case that
confirms it ISN’T a “)”. Now it seems that Array values can contain even MORE arrays.
BUG FIX:
found ANOTHER stupid bug. this time, inside RemoveExtraneousSpaces. it is supposed to add stuff to a buffer- but at one
point instead of appending I simply replaced what was there.(I smart) It also added one too many to the value being used to
pass through the string.
BUG FIX:
not really a bug fix- just a feature not working as intended. the Unary operators, upon being executed, where setting a
module level variable and a event sink. However, if two unary operators were encountered in a row, only the most recent one
would be present when the next value was pushed on the stack (thus triggering the event). I fixed this by adding each
unary operator to a module level stack. when the event occurs, the stack is emptied, with each operator on it being
executed on the value being pushed. It worked on a expression like “not -sizeof “”TEST”", which returned 3, or (NOT -4)
good.
BUG FIX:
Geez! A lot of bugs are surfacing. This one had to do with MakeParsable and RemoveExtraneousSpaces, in Cparser.cls. the
functions were not properly handling strings and ended up placing spaces within the string literals themselves. This
occured when I first tested the GetFileDateTime function, which had problems getting the path of a file named “C: \
Autoexec.bat” (not surprisingly) I fixed it by adding the very pervasive inquote variable.(If you looked through my code,
you’d know what I mean)
NEW IDEA:- implementation in progress.
add new exposed interface- IOpFuncInfo. this can be requested via a call to the getinfoobject method of the IEvalEvents
interface.
**(EDIT:30/Jun/2007 20:59)**
**That IOpFuncInfo interface is really old now.
)
6/Jan/2007 23:56
UPDATE: finished the previously mentioned idea a few days ago. Now I have a fully functional parser. All that is left to
do now is touch it up.
***EDIT, 30/Dec/2009 05:35
“All I have to do is ….” I keep saying this!
***
I think the sample app will be a re-write of my old standby, Grapher. Grapher used my REALLY old
BASeParser, which didn’t support either arrays or strings. It hacked in it’s own support for lists, which was REALLY
kludgy. It ran alright, but it suffered from really bad design. Even I had trouble navigating the dialogs.
FINALLY- I removed those god forsaken GoSub references. I had no idea they were slowing my code down as much as they were!
I initially tested a really long expression, 5+5+5+…. etc for about 600 5′s, and it took almost 3 seconds to execute.
Now, it occurs in less then one one hundredth of a second.
9/Jan/2007 22:18
Just when I think I packed too many features into BASeParser, I think of another one to add! (Good thing I don’t need to
re-version it after release, given the Plugin stuff)- for example, I was reading HardCore Visual Basic, and read his
reference to Pascal’s In operator and his creation of an analogous function in VB, which lacks such a operator. Now
BASeParser has an IN operator.
10/Jan/2007 2:49
I’ve decided to implement some more direct debugging techniques. It’ll be annoying, but I’ll add a MODULE_NAME const to
every module, PROCEDURE_NAME const to every procedure, and a global var CurrModule and CurrProc, that have the current
module and procedure names. to further enhance such an effort, I will manually keep track of the Stack. Of course,
multiple exits in my procedures will make this less then easy. Here goes…
10/Jan/2007 8:08
I just thought of a better way to implement implicit multiplication. I decided before that I couldn’t do it without
severely screwing up my current Object method/property access- for example, my idea was to simply insert a new IT_OPERATOR
multiplication operand when I encounter a IT_OPENBRACKET immediately after another. (well, it wouldn’t be (( since the
parser creates child parsers for those- so it would be like this:
(2+3)(7-2)
would have a * inserted…
(2+3)*(7-2)
I began implementing this while thinking about how it would regress- then I realized- what if the previous subexpression
ended up evaluating as a Object? Since you cannot multiply objects (unless it is a class Called CRabbit
) they must want
this next set of parentheses to denote a parameter list to the default method of that object.
After giving up on that idea, I eventually realized that I could implement it.
The trick is to give the client the ability to choose between “Default Object Methods” and “Implicit Multiplication”.
11/Jan/2007 3:27
I was going to go to sleep about two-three hours ago. I finished a OK Console App in FreeBasic that uses my library, and
found a bug in my library. a VERY shameful bug. the IN operator was being parsed out of the SIN function, so a innocent
expression:
Sin(8+2)
Would become:
S in (8 + 2)
**EDIT:30/Jun/2007 21:02- notice the single apostrophe right below? I wonder why I put that there?**
**Anyway- if a bug like this Sin() bug arose today, I would be really pissed. Mostly because I hate when the same problems resurface. I want to SQUISH the bugs, not let them multiply. Geez.**
‘which- well, is NOT what they wanted, I imagine. I surmounted this obstacle with a new interface function,
GetHandledFunctionString, which I parse and compare. If I find a function during the iterations (a function name followed
by a “(“, I plop it on the buffer (along with a “(“) and zero out the char value).
11/Jan/2007 19:19
I just realized what regression testing is for, after this two hour debug session.
quite some time ago, I added the ability to define operators that are any string.
I added the IN operator some time ago. What I forgot to test was what happens when I use the SIN function,
the function that removes and adds spaces didn’t skip function names. So I added that- when it encounters
a function name(by checking the functions defined in a new method for the interface, (getHandledFunctionString))
it will skip it. this is important, because if it is allowed to iterate through the consituent characters, it might find a
string within the function name that is also a operator (IE, the SIN function has IN, the STORE has OR, and other stuff)
That was the bug I fixed yesterday. What I forgot to include yesterday was a similiar mechanism for variables. I did it-
but it will only work if that variable has been added already- IE: IEvalEvents implementors need to
add the appropriate variables (regardless of value) to the parsers array of variables.
You know those debugging days that simply don’t go your way? Well, today was one of them for me.
of course, I did find & fix a bunch of problems. I use the word “fix” pretty warily here, because I often end up causing
all sorts of problems on the other side of my program when I kludge out some other bug.
12/Jan/2007 16:50
My next task will be a pretty neat one, I think- it will require another IEvalEvents implementor- FunctionHandler. This
will be responsible for managing the custom Cfunction objects that will exposed via the CParser class. These functions are
simple one-line expressions, with the Alphabet being used to denote the parameters. The basic idea here is actually for my
own benefit- the first program I intend to write that uses the Parser is a Graphing application. It will of course allow
you to name functions and graph them, and as such one function should be allowed to reference any other function.
13/Jan/2007 17:00
Wow. I just squashed another bug in the parser. It was somewhat odd, to be honest, and confused me a heck of a lot.
I forget the exact function location of the bug (regardless of the fact I just fixed it) but it was in one of the many
Select Case Statements that determine the type of a CFormItem. the IT_FUNCTION types were not being placed onto strBuffer
(oh wait- it was ParseValue). Also, I found that my recent change to ParseArguments didn’t allow for single,one character
arguments due to a incorrect Len test of “If Len(arguments(0)) <=1″ where that 1 should be a zero, to test for empty
parentheses, which are a required part of the syntax. I tested it with a varied expression just to be sure:
{1,2,3,4,5}@MEAN()*Sin(2)
This was the expression I initially found the problem with, and so was a perfect candidate to see it I fixed it. (No, I
didn’t find the error via a incorrect single value- This should have returned a single value, but (this is very strange)
it returned an array- (2,2.5,3,3.5,4,4.5) from 2 incrementing 1/2 each time. This left me bewildered, it couldn’t have
been more wrong. I might have understood if it returned the Sine of the values 1,2,3,4,5 in an array, which would have
indicated a problem with the Object Access @ operator calling Mean to reduce the array into a single value- but no, it was
a completely different value that made absolutely no sense whatsoever. I only wanted to fix the problem- perhaps I should
have looked into the cause of that mysterious Array return? Oh well. It seems to work fine now- rest assured, the next log
entry will quite possibly contain ANOTHER major bug, I’m going to do some more testing right now, and I feel quite
confident that I am not confident in the program just yet.
13/Jan/2007 17:25
Surprise. No less then ten seconds later, I found a terrible, fatal, horrible, awful, crappy problem. I want object access
operators to work- the way it DID work was it would set a flag, and then the method/function after the @ would be found as
either a function or variable. I changed a bunch of code to support other things, so now it only supports methods that
also happened to be intrinsic functions. I fixed this.
15/Jan/2007 0:56
I have made a decision as to BASeParser- No third party controls as long as I can help it. (This doesn’t count the common
controls or other components that CAME with Visual Basic- just the VBAccelerator CommandBar, which I wanted to use for pop-
up menus. (Say, a POPMENU() function or something) But, I think that if I DO add that it would be best added as a separate
as all BPXP knows is the syntax of an expression, how literals and values are separated by operators and used in functions. All of these operators and functions are contained in external “plugins”. For convenience, the Core Function and operator implementations are included in Internal plugins that are automatically loaded when the Parser Object is initialized. In addition to this supreme form of extensibility, BPXP supports what I could only think to call “Core Plugins” These Core plugins are called upon during the very Core Parsing routines, and deal with the same data structures I do within the innermost guts of the library. The purpose? To provide the ability to create new token TYPES. For example currently this is how the Core list support (using the squiggle brackets) {} is implemented.
1/Jul/2007 19:15
Sigh. The last few days I haven’t really even been able to OPEN BASeParser’s project. Not because Visual Basic is busted or anything, but because my video card was (is?) having problems. It all started when I installed MotoCross madness. Then all of a sudden all of my DirectX based games were having problems. AOE2 gets a garbled screen every 30 to 40 seconds. Sure, I can fix it with a Alt-Tab, but that is far from quick to do. Another instance with Need for Speed:High Stakes with Windows apparently detecting and recovering from a device failure, sticking me into 16 colours. Great. So I tried a few things:
Uninstalled MotoCross madness (Duh)
(no effect)
Reinstalled Video Drivers from the CD that came with it.
interesting thing is I can’t use the actual XP drivers for the card, because if I do that it get’s stuck in an infinite loop when drawing the windows desktop after about 30 to 45 minutes of working perfect. Don’t know why. Quite annoying. So (I did this when I first installed the video card too, and it worked for the last year…), was copy the Windows 2000 version of the file ati2dvag.dll over the XP version that was installed on my hard drive (of course, in safe mode).
This just made it worse. Doom Legacy (a kickass OpenGL port of Doom) worked for a while and then froze. surprise- Device failure. Hmmm. I tried various convolutions of XP and 2000 drivers (even using all Windows 2000 versions). Then I had a idea. The cause of the problem was Motocross madness (OK, I had to think back, I couldn’t remember the first instance of the problem, but I remembered it was motocross madness). But that was back in the bad old days of DirectX, when half of the worlds problems were caused by having a corrupt installation (since a crapload of programs would assume that the version they use is the newest one available). The solution was to reinstall 9.0c from my Command And Conquer DVD (thank goodness it was there!) Not sure if it works. Also not sure why I put this completely unrelated information in the develop ment log for BaseParser.
7/Jul/2007 18:01
Fixed an IPF yesterday. THe solution involved adding a err.clear to the end of a procedure. The problem was that even though no error occured err was not zero, and so the calling proc got confused and ended up using TLI to invoke the member improperly. Thus causing an IPF.
31/Jul/2007 19:30
I haven’t really managed to get a lot of coding done in the last month. The main reason is computer hardware problems. I’ve been trying to decipher the problems for a long time, and it’s getting annoying to say the least.
Although I did learn that my motherboard is high-end for it’s age. The problem? Well, first, I suddenly couldn’t play DVD’s for more than, say 20 Minutes. I attributed this to my Video card- since I installed MotoCross madness I had been having all sorts of problems with DirectX. All My OpenGL games worked fine though. Well, Mostly. Then, suddenly, Every once in a while, my third Hard drive would make some, well, Scary noises, then Drive E: would vanish without being prepared for removal, same with the DVD drive. For some reason, I attributed this entirely to the hard drive, Even though it is likely the IDE controller.
My solution? Well, I’ve found that the problems seem to occur only when I access both devices on the second channel simultaneously, so I have two possible solutions:
1: get an PCI-IDE controller card, plug the drive and DVD into it, and disable the secondary IDE controller on the motherboard. See if that fixes the problem, if not, the drive and DVD drive simply don’t like each other.
2: Buy another Hard drive, the exact same one- a WD Caviar SE (80GB). Remove the other one, and install the Data Lifeguard tools to D:. Then, to a Partition copy from my crappy C: drive (2GB- Woop!). This will become my primary Boot drive. This will solve another problem I have, since my current WD Caviar has been subverted from 80GB to 36.2GB due to limitations on my BIOS. I’d update it, but with my luck the upgrade would freeze halfway, there would be a power failure, brownout, or something to cause my BIOS to be corrupt. In addition, I’d also solve my extremely low disk space problem on C:, which, as I write this, has around 80 megabytes free.
Current New
C: 2GB C: 80GB
D: 8GB D: 40GB
E:36.2GB E: 40GB (D and E: partitions of old E:, with drive overlay program installed)
F: DVD F: DVD
G: CD-RW G: CD-RW
This won’t be a simple upgrade, and the possibility of losing a crapload of data is just so great I almost HAVE to back up my Work files, since whenever I act on something like this, I always lose all my VB code (a copious amount, BTW)
I’ll update this devlog as appropriate with an entry when I do this, as well as after. First I back up all my stuff.
What worries me is the Drive Overlay program I need to use to access the drives as 80GB. I need one to be accessed with the DTD, but the other natively (IE, with 36GB) so I can copy the contents of the other one to the 80GB. The question is, will the DDO (from WD’s Data Lifeguard tools) let me do this? In fact, will the DDO even WORK?
Err… wtf is all that doing in THIS file?
20/Aug/2007 17:52
Added Oops- read “Adding” ability to address functions and specifying the plugin name. For example, BPCoreOpFunc.Sin() should be valid.
22/Aug/2007 2:24
Ha! It seems to work now. I stress seems. The problem I was having before was not that RipFormula couldn’t parse it properly, but that MakeParsable was ironically making it so RipFormula() COULDN’T parse it. too funny. Anyway, it seems to work now. Not sure about any regressional effects.
23/Aug/2007 2:29
Ah! I finally thought of a feature worth implementing- Events fired from the Plugins, and handled via set BASeParser “Event Expressions”. For example, a keyboard watcher Plugin could install events named “KeyPush” and “KeyRelease”. subsequently a Core routine, InstallEventHandler() could install an event handler for an event.
most of the new code will deal with the new data structures involved. For example, a CEvent and CEvents Class and collection, as well as code therein. In addition to, of course, the code that runs the CEvent’s CFunction.
ROADBLOCK: realized I already HAVE this ability- the appropriate code can be installed as a CFunction object into FunctionHandler, and called THAT way.
26/Aug/2007 20:58
Darn. Now I have nothing to add. Looks like I might actually have to try to get existing code to work for once. darn
.
4/Sep/2007 1:10
Sigh. Another entry that has very little to do with BASeParser, and much to do with my Video card/Driver. Haven’t been able to play DVD’s reliably for a while now, and DirectX started having the same problem. Now my OpenGL games are displaying corrupted video after a while. Sigh. I know! I’ll get a new Video Card. probably won’t help though…
-realized a quirk with the manipulation of Arrays. The parser converts the List delimiter tokens, { and }, into a call to the Array Function. I purposely don’t qualify this with BPCoreOpFunc. Why? Well, now if for some retarded reason you want to override the Default operation (which is to make an array out of the elements) you can. Why you would want to do this I don’t know, but the ability is there.
10/Sep/2007 8:58
ANOTHER redundant entry. replaced my RADEON 7000 64MB AGP (which replaced my ATI Rage Pro Turbo AGP2x 8MB) with a new Radeon 9250. Cool. In a interesting quirk, I have JUST realized that the drivers on it’s CD might have entries for my All-in-Wonder 9000 AGP. which is good, because this 9250 is a PCI card, and, well, I just can’t stand to leave my AGP slot empty. (not to mention the freeing of a PCI slot that I don’t have to insert a TV tuner into, since I eould have one built right into the card
17/Sep/2007 23:08
reverted InvokeDynamic code to it’s previous form- code was err-ing in situations where it shouldn’t. Will work
on this problem tomorrow, right now I am just too darn sleepy.
18/Sep/2007 9:11
I’m BACK! and refreshed. Not only did I sleep for a full- um- 5 hours… (not sure WHY I couldn’t sleep any further). anyway, I Was browsing through my extensive library of code (not all mine), and discovered FileSystemLib, a library from KillerVB that used to be slightly worse then my Library (Mine could also do pop-up menus for files, although it lacked in about a million other departments. Anyway, I browsed through the code for useful tidbits, and came upon some code dealing with SafeArray’s. long story short, I can now retrieve the dimensions of a Variant into a SafeArray. retrieving them and setting them is all I need to discover.
I also fixed a few syntactic errors in the different projects in the group that were preventing a Shift+F5.
2/Oct/2007 5:27
new stuff on the way:
Ability to load plugins dynamically via a Function (InstallPlugin and LoadPlugin functions- both as CParser Methods for clients as well as part of the Core Operators/Functions.
a big one: Macros. Some may think, yeah- a macro is just a variable. But, I must disagree. a Macro will NOT even be visible within the resulting Parse Stack. Rather, the Core Plugin (yes, a core plugin will be used to implement Macros) will simply use the ParseLocation Function override. If it finds a macro definition, it will insert the macro’s expression into that location (replacing, of course, the existing reference to the macro) and return False to indicate it didn’t do anything, and move the current parse location back one character (so the Parser re-examines the location that had the macro) The Parser will then re-parse the macro. exemplary. Of course, this means there needs to be a way to define macros. Damn.
10/Oct/2007 5:15
wow, I actually thought of an idea! ByRef parameters. Currently the Parser simply discards the changed array from it’s call to the handlers.
UPDATE: Cool, another single-day feature addition. Now I simply need a way for functions to specify that a parameter is ByVal…. oddly enough, too, ByVal is FASTER then ByRef- weird? no- because I’m forced to manually copy the new values back into the original variable. Oh, and assignment doesn’t work for array elements yet. I lied just now. Well, not when I wrote it. It works now. One problem though- I used the assignment operator := and it didn’t work! I had to use store.
11/Oct/2007 18:36
Managed to trace the assignment operator problem to some kind of priority problem. For example, this expression doesn’t work:
X:=4/2*Sin(y)
However, simply adding parentheses fixes this:
X:=(4/2*Sin(y))
that’s weird- because I’ve set the assignment operator to the lowest priority!
11/Oct/2007 20:28
I swear, this one feature has been on the list of TODO:\\ since the start, and only once have I even come close: DLL function calls. I mean, it can’t be difficult- After all, Every single DLL declaration in VB is invoked this way (IE, an error is raised when you Call a non-existent function, not when you compile) and The Virtual machine DLL exposes DLLFunctionCall. I just don’t know the parameters. this is so very annoying. Anyway, Now that I have By Reference parameters, I need a way to prevent the logic from running. The solution? the FunctionInformation! Simply define a new field for Parameters- “PARAMTYPE” or something.
16/Oct/2007 4:54
mostly cleaned up a bit of the code. Noticed some conditional compilation in ModImprove (which contains my improvements on VB functions) that really wasn’t necessary, since I could move the functions used within the block into the ModImprove module (none of them depended on BASeParser functionality). These two functions were Flatten and Assign. I have moved them. yet to see any regressional bad behaviour.
finally fixed up the code. IT_STATEMENT was so simple and yet I gave up so easily before- It is now implemented in Ripformula, with each statement simply being stored in a fashion similiar to IT_SUBEXPRESSION. in fact, in all fairness, I could probably make RipFormula change the Itemtype to IT_SUBEXPRESSION instead of IT_STATEMENT and it would still work. In any case, IT_STATEMENT’s are always executed in order, but only when they appear on the same level of the expression. the last expression’s result is used as the return value. (NOTE: perhaps it should return an Array consisting of the return value of each IT_STATEMENT? I don’t know….
18/Oct/2007 20:21
Sigh. Everything is in order, except for the issue of DLL calls, but in general that isn’t exactly high on the priority list. sure, if I develop a dll or find a way to do it, of course I’ll add it. In the meantime, I’ll stick to more attainable feature sets.
Had an interesting debug session- I tried to give it garble, but it still parsed it- I had an expression consisting of some random stuff, and it parsed out VARIABLE names and operators! makes sense too!
23/Oct/2007 4:04
Thank god for small favours- I finally got the internet, but not exactly through the proper channels. It was as easy as purchasing a wireless network adapter. Seems at this point none of my neighbours know what a “password” is. On the up side for them, I don’t exactly plan on hogging it or sabotaging it at all, right now I just want to activate the programs I bought that won’t work until I do so, and use MSN to tell the story to my cousins, whom I haven’t had contact with in over a year. THANK GOD. although the card wasn’t cheap- almost 70 bucks. compare that to the meagre 14 dollars I paid for the network card in my other computer (so I can play network games with this one- or, could, until I removed my standard NIC.)
28/Oct/2007 20:44
ANYWAYS: thanks to Internet access, I managed to find a somewhat incomplete class module for calling Functions Dynamically.
needs some work though, and I would have preferred if it included the ASM code. Right now, I simply chucked a new function, DLLFunction() that will add a API function. One up-side is that the functions parameters don’t need to be defined (I know, it IS weird…) Although it will only work with API functions that return long’s. I haven’t found a API function that doesn’t, however. (the API uses the return code for success state, it appears.
So, For example, the following BPS (BASeParser Script) will return the activeWindow’s hWnd:
DLLFUNCTION(“user32.dll”,”GetActiveWindow”);GetActiveWindow();
I lied. That didn’t work. Just returned zero. Although GetActiveWindow() did work as a expression afterward.
-BUGFIX: discovered the cause of the above. turns out it was a simple “Type Mismatch” in the IsFormItemConstant Function when the passed parameters are empty (Lbound/UBound on a Empty Variant). Added Error Handling to return False. Fixed.
31/Oct/2007 8:04
I think I’ll make this my first milestone release. Step one: find an Installer Maker program.
15/Nov/2007 17:34
Did some Internet Searches for Evaluators, to see what the competition has. And the answer is, “Not Much”. I did find several libraries, most notably USPExpress from UBISoft. The disadvantage, of course, is that is costs $149. BASeParser XP (At least how I plan for the foreseeable future) is Free. Or it will be, once I start F-ing distributing it. This is always the hard part. I think I’ll use good old “Advanced Installer”, because I found it to be quite versatile when I tried it before.
25/Nov/2007 20:10
A fairly large bugfix has been implemented. Turns out I only, err, kind of Half Supported implied multiplication. Revised the code during Ripping of the formula to detect when certain items (IT_FUNCTION,IT_VALUE,etc…) occur immediately after each other.
Speaking of which, I’m pondering a new addition in the area of formula ripping, for handling the occurence of multiple operators between expressions. For example, 5+*2
the question is- what does it get turned into? (5+2)*2? probably best to abandon such an effort for fear of promoting ambiguity.
I’m also someone curious as to the actual speed of the parser- sometimes it just seems slow. I’m trying to excuse it for many reasons:
1. My computer is 350Mhz
2. There is way to much debugging code- with file logging and so forth (probably the main reason)
3. so much must occur within the parse and execution for all the different scenarios (IE: Object access)
27/Nov/2007 13:45
Discovered a few simple optimizations I can easily make. The problem is with a few of the Case Statements in RipFormula.
For example, some will go as such:
Case Function()=Value
TempVal=Function()
See the Problem! Function() (that isn’t the name, but rather ParseValue,GetOperator, Etc…) is being called TWICE. what makes it worse is that these functions are some of the more expensive low-level parsing functions to execute. the question is how do I optimize it? Simple. use a new Store() function that stores a value in a ByRef Variable And returns that value. That way, the only time the function is called is as an argument to that function, and not once for the test and again to use the result. I guess this is a bit of an idosynchrisy of the Select Case Block, but nonetheless…
Also, Discovered a bug in the parsing of a value. for example, some thing like 2t should not be interpreted as a variable name. Since the Variables.Add method will scream bloody murder. Not sure why this is occuring. I believe it may be a result of my support of Hexadecimal being so haphhazard.
28/Nov/2007 1:11
Gave some older features some regression testing. Strings still work and Objects still work. The test expression? Right here:
CREATEOBJECT(“Scripting.FileSystemObject”)@GetFile(“C:\AutoExec.bat”)@SIZE()
which returned zero. Silly me, I thought there was an error, and then I was debugging and got to the point where BASeParser uses TLI to call the function and realized that everything was A-OK. the file was just, well, empty. This is XP, after all.
2/Dec/2007 20:12
Unexpected delays deploying BASeParser onto my test machine. First the sample app crashes with a Object defined or Application defined error, next I go to test the DLL as it exists on my W2k Machine. And find that it hangs on the call to Create(). having a hunch this may have something to do with the registry, I go back to my dev machine and do a debug run after deleting the keys. Lo and behold, it goes to the error handler because an Array wasn’t initialized. And what do I find there? A Debug.Assert. And a Resume Statement!
2/Dec/2007 20:36
TODO:\\ Fix-up InvokeDynamic Function to prevent intermittent IPF.
4/Dec/2007 2:53
InvokeDynamic Bug discovered and fixed. Turns out that the error was actually NOT intermittent, but rather occured whenever the parameter list to a object member was empty. For example with the Scripting.File object’s Size(). I had already re-written InvokeDynamic before I discovered this though. However, the new function implementation is much cleaner, requiring only a single loop. Oh, and it doesn’t IPF (
).
18/Dec/2007 8:16
tweaked up the parsing of the Subscript operator ([) to recognize an empty argument list and set the Value property of
that cFormitem to a uninitialized array. As such, it is now a simple task within a plugin to determine wether a empty subscript was passed and act appropriately- for example, now the expression:
"I like words, even looooooong ones." [] [5]
will return “looooooong”, since the core operator/functions handling of strings with array access will split a string into a array of words with empty parentheses. note that the above expression differs from this one:
“I like words, even looooooong ones.” [5]
which returns the fifth character in the string, or “k”. I’ve even successfully done this:
“Words are great and good too” [] [3] [2,2]
which returns “re” or the string 2 chars long starting at position 2 of the third word.
all in all this parser is really becoming quite powerful, I’m still a bit wary of instability issues that may arise.
6/Jan/2008 18:52
I STILL have yet to actually publish BASeParser on the web. Actually, right now, my access to the net seems to be cut-off at the router. This happens usually when there is a power spike or outage, and I did notice my lights flicker earlier in the day, so I’ll just hang tight for a while, just like last time.
In any case, I haven’t completely stopped development work on BASeParser, although I seem to be in one of my non-programming phases. It happens with me every few months. I seem to stop programming, preferring, well, almost anything else. For example, I have started playing the Megaman series again on my old DOS/Win 3.11 laptop.
I did, however, manage to get my plugin, CScriptFunctions, working properly. I actually pretty much re-wrote the implementation. Originally it would load ALL scripts into the same Script Control object. I have changed this. Now a Key exists in the registry for each Script control to be created,(with a name that ideally describes the files therein). The key contains a “language” value, which is used on the Language property of the ScriptControl created for the section. the “Scripts” section contains values for each Script file that should be loaded.
The actual implementation of the feature within the BASeParser Plugin was easy. The tricky part was the creation of the UI widget that implements the ISettingsPage interface required by the BASeParsert Library’s Configuration Page. (I did manage to fix a bug within the settings page involving the use of height instead of Scaleheight. Took almost three hours to trace the problem of why I couldn’t see the tabs for the plugins.). Why was it so hard? Well, I really don’t like programming the GUI part. Of anything. It seems I always overlook a lot of stuff. for example tab order. speaking of which…. there. Never mind I fixed the tab order, well, at least on the userControl…
Improvements to be made:
As is, the Script Function Plugin is fairly versatile, but, ideally, it would support more functionality. For example, what if the desire is to have several files in different sections with a function of the same name? As it stands now, no error would occur, but the Plugin will only use the first ScriptControl it finds in the collection of script controls for any call to the function. specifically, adoption of the dot notation, as in, SectionName.FunctionName would be useful, and probably quite easy to implement directly in the script control (which is good, I don’t want the parser’s core routines associating with such vermin
.
16/Jan/2008 17:08
New modification to the CDataFunc external library plugin. this is a plugin that is used to load functions from a database when the plugin loads. The original design loaded all the functions at once into the CParser objects Functions collection. I decided that that would not do.
6/Feb/2008 4:43
Due to the fact that I released it on the net, I have incremented the version number of the current development project of baseparser. Why this requires mention I don’t know.
In Any case, I’ve been scouring the net for Expression evaluation related stuff.(mainly downloads to other VB made parsers, or even VB.NET. Personally, I have VB.NET installed, but, I don’t think it’ll become usable until I upgrade to a new computer. I’ve been stowing away money in my bank account for quite some time, living on tea and sandwiches from work. And I have just realized that this saving is due almost entirely to the weather! But, back to the whole purpose of this devlog. It’s SUPPOSED to be about BASeParser XP, not a frikkin’ personal journal.
TODO list:
- Either fix or remove the substring parsing. right now it’s enclosed in some conditional compilation, as I have yet to get it working.
Probably a good idea to create some more GUI components, for example, one for defining functions would be useful in the Graphing control I created.
3/26/2008 3:07AM
Note to self: when making backups, ensure to label them as such. I had a complete duplicate of my code tree (D:\VBPROJ”) placed on my E:\ drive as E:\VBPROJ, and
when I went to copy the files to my new computer, I copied from the E:\ drive. (I thought I was working on E:…). Then when I got the project working and started fixing stuff that came up,
I got a strange sense of Deja-vu- I had fixed the problems ALREADY!. Took me a few days to figure it out. Main giveaway was the BPCoreOpFunc.cls file size being over 10k larger with the one on the old D: drive.
and that is how I revived it!
04/02/2008 1:44AM
well, I have a week off starting today, so as better get some coding done, I suppose. Anyway, I thought of a novel plugin to write: a plugin that
allows Scripts to be plugins! This would be fairly simple- just delegate all the calls to the loaded Script Plugins.
05/17/2008 8:13 AM
I’ve finished (untested as of yet, however) the Script Plugin architecture. Now the major hurdle is the SettingsPage Implementor that will be loaded into the Configuration dialog.
For now I’m going to simply release (in the loosest sense of the word) just the Core library itself, without all the extra fluff I’ve added. The first distro will just be a ZIP file with the requisite files, leaving actual installation to the end user (hows that for respect?) I generally falter when it comes to setup, despite the fact that it really is easy with Visual Studio 2005.
Before I do that though, I’m going to make sure the setup program can properly install it without the dreaded “ActiveX component can’t create object” error occuring.
05/20/2008 3:52 PM
New feature in the works: a new interface method, BeforeFunctionCall, that will be called on all IEvalEvents implementors, allowing interception of function calls or redirection of the Interface method to another implementor.
Finally completed implementing the CSet Class’ interface methods for Evaluation. I programmed in all sorts of convolutions to recognize a “SetOf {<set values>}”. Then, I realized something- JUST MAKE IT A BLOODY UNARY OPERATOR! It took over 2 hours to code the ICorePlugin Interface methods, and yet in the last ten minutes I extended the functionality and wrote it from scratch with just the IEvalEvents Operators….
If I’m ever going to release this library I’m going to need one tome of a doc!
05/26/2008 8:13 PM
Now that BASeParser is essentially complete, I need to program in some security features. Although I highly doubt that anybody would target BASeParser for the creation of malware (IE, a implementor that doesn’t do anything Parser-wise, but sits in the background and monitors stuff). Not sure how to go about it though…
05/27/2008 6:04 PM
very useful feature to implement- a more generalized method of changing the settings of plugins from code. As it stands now, a client would need to know the registry keys, INI files, or whatever else is used to change any of those settings. This would be fine, except that plugins could change their behaviours based on these settings (makes sense) and perhaps cause incompatibilities with the way the client wants the expressions to be parsed. Instead, it should stand to reason that there be a generalized way for client code to automatically change the settings of a plugin, without necessarily requiring in-depth knowledge of where it is stored.
06/05/2008
new feature that will make use of some of the advanced COM classes I have- the sinking of events from any source with a CFunction object.
12/10/2008
Alright; there is NO way i’s been 6 months since I updated this devlog… alright so checking the last modified time confirms that it has. Huh. Anyway- I’ve been making quite
a few changes to several parts of BASeParser, and neglected to document them.
The first change came as a result of my inability to create a small console application that used it’s facilities for simple on the spot parsing; after some testing,
I managed to get the program to run flawlessly, but only when I had BASeParserXP running (the DLL) in the IDE. Odd!
A few hours of code sleuthing later (involving my very forward thinking use of OutputDebugString() in my CDebug class, as well as DebugView) and the placement of some
CDebug.Post methods; the problem was very vexing; when running in the IDE, the Create() method properly executed and added all necessary plugins. However, when I compiled the library, no amount of coazing was able to get it to
load even the basic BPCoreOpFunc plugin. with the CDebug.Post methods littered about, and some error printing in those portions that shouldn’t fail, I managed to trace the problem
to a exact line in IEvalEventSinks; namely, this one:
ParserSettings.VerifyPlugin GetObjectProgID(ObjAdd)
the strange part was, placing a debug print in VerifyPlugin or GetObjectProgID, they never appeared. The error was occuring trying to call GetObjectProgID; the error was
“Object doesn’t support this property or method”. It’s as if the getobjectprogID routine didn’t accept Object parameters; which it did, in fact it only supported object parameters.
Another mystery was why everything was howdy-doodee in the IDE; my first thought was of course optimization options; no dice.
I never solved the mystery, but I decided that the VerifyPlugin call was a bit overzealous; obviously an error will be raised if I was to try to add a object that didn’t support IEvalEvents so I was a bit premature to presuppose otherwise at that point.
the fix was to comment out the code. I have a feeling something along these lines will crop up again, though. But with my enhanced debugging output it will be even easier to trace the problem into the problematic parts of the code.
12/11/2008
Fixed Multiple statement parsing; now it could even be used as a programming language… a slow one, but a language nonetheless.
Right now performancec is sub-par, I hope that is caused mostly by the rampant CDebug.post method calls; each one writes to the log file and stores quite a bit of data about the call.
with any luck execution without the debugging facilities enabled will be far faster.
01/19/2009
Made a few tweaks and improvements, and added some better error handling for non-existent Object methods (I had a If reversed).
Started BCScript Script program interpreter- works well. Command line prog.
02/03/2009
Another couple tweaks here and there- added some implementation to the BPCoreOpFunc function Cases- INSTALLPLUGIN,UNINSTALLPLUGIN,LOADPLUGIN, etc.
I’ve decided (At last) that this WILL be the first release version, just as soon as I find a place to post it.
02/05/2009
ALRIGHT… finally created what I believe to be a working installer program for it- installs and uninstalls fine. Only installs BASeParser and the BCScript Scripting engine; will probably add some simple little program to demonstrate BASeParser itself, though.
thought of a change to make while I was reading about javabeans somewhere- automatic use and detection of methods with names such as “setX” and “getX”- for cases where that object doesn’t have a “X” property for reading/writing. (Obviously, this will be in the InvokeDynamic routine)
02/11/2009
New feature- “importing” of constants from external typelibs. This will likely require a new object type, CEnumeration, which will implement IOperable and possibly hook Variable accesses.
** Feature implemented, Minor Version number incremented.
the functionality is quite basic, however…
02/12/2009
FINALLY got some dynamic DLL calls working. All API’s I’ve tried (MessageBox,GetTickCount, and a few others) worked flawlessly.
uses a COM component I found online, but I’ll reverse engineer that and create my own.
04/20/2009
Many changes over the last while thanks to bug reports and some testing by myself.
the STORE() function wasn’t working for expressions like STORE(X,Msgbox(…))- Msgbox was being invoked twice.
Traced the source of the issue to the HandleFunction() routine in CParser, which Evaluates each argument to test for IOperable Objects. I’ve commented out that portion, so for now Objects (such as ccomplex) no longer have their own function handling.
Not sure how to workaround this issue- I might need to place it in BPCoreOpFunc…
Also, discovered a “minor” issue with Variables- for example:
XSIN:=12
would fail to work, since it finds SIN as a function name. Only way(that I can think of now) would be to change the Plugin Interface to allow for Operators to have unparsed operands…
06/03/2009
haven’t been working on BASeParser or BCScript for the last month or so. Was occupied with my other BASeMetry Library. But, coming back to this I had decided to add my “backticks” idea for redirection. It worked as long as I didn’t enclose it in brackets or a function call!
the problem turned out to be my clone routine. The parser simply wasn’t copying a reference to the core plugins collection, so my CPlugBackticks core plugin wasn’t being loaded within any Sub-parsers.

Categories
Tag Cloud
Blog RSS
Comments RSS
Last 50 Posts
Back
Back
Void « Default
Life
Earth
Wind
Water
Fire
Light 