-
Content Count
13,060 -
Joined
-
Last visited
-
Days Won
21
Content Type
Profiles
Member Map
Forums
Blogs
Gallery
Calendar
Store
Everything posted by DZ-Jay
-
What is that ...? Is that ... That's not one of those ... "sports" things, is it? Eek!
-
Don't make me stop this car and ... Oh screw it! :roll: :roll: :roll: :roll: :roll:
-
Well, I wouldn't go as far as saying that it is indicative of a healthy community. There are many small communities too small and just as healthy (and indeed, many started out that way) -- the one does not prescribe the other. That said, your point is well taken. Still, in order to maintain the health of the community, the collective should not accept certain corrosive behaviour as "normal" or as a matter of course. It should always be unmasked and abhorred, and perpetrators should be ostracized. Notice that this is different from the vindictive mob-rule or vigilante justice that some other communities extol as necessary. -dZ.
-
-
Ooooh!!! Well played, sir! LOL!
-
Yeah! :thumbsup! Oh, wait, I mean :roll: :roll: I am busy with other projects right now, but maybe someone else can use it.
-
HA HA HA HA HA HA. :roll: :roll: :roll: :mad: oops wrong key! :roll: :roll:
-
Here, let me boost your ego some more: :roll: :roll: :roll: :roll:
-
:roll: :roll: :roll: :roll:
-
Damn! I'm gonna be late!! I promised myself I wouldn't leave my shopping to the last minute this year ... :O
-
Interesting. I think it was not so much fear that the PlayCable hardware investment would not pay for itself within a year (obviously it could as you point out). I think it's more that the investment was not seen as necessary when not incurring the cost lead to immediate profits from the growing number of regular CableTV subscribers, which was exploding at the time -- especially for smaller operations like the one in the article which only offered 12 channels at the time. As I suggested before, when looked at individually, each factor does not seem too daunting -- but all of them at once may not have been too attractive at a time when many were still suggesting that video games were a fad (in spite of growing evidence to the contrary). Keep in mind that when the video game market crashed initially, many articles and books were written describing how it was a fad all along and everybody sane knew it was bound to happen. I bet you that all those cable operators who decline the investment thought smugly of themselves as great prescient visionaries for going with MTV and other CableTV properties rather than investing in that "fad" of video games. -dZ.
-
Get Papi ! A first Try with the Intellivision ! :)
DZ-Jay replied to Vetea's topic in Intellivision / Aquarius
I've never played Papi Commando nor any of the others, but I have seen them before in other platforms. I'm very glad that you joined our community and hope you stay for a while programming for the Intellivision. A Papi Commando game for the Intellivision would be great -- especially if it takes advantage of the strengths of the Intellivision rather than just being a direct port. -dZ. -
I'm pointing out the apologetic waffling that tempers your "continuously stating that this is NOT normal behaviour" comments. Almost every one of your paragraphs is a "it's bad, but ... not too bad"; "there is no problem; but if there was it's not a big deal"; "nobody is supporting this; but some may" ... All your comments decrying the behaviour are always followed by some sort of "but ..." Look, the problem I have with comments like yours is that they appear on Every. Single. Thread. where corrosive behaviour is pointed out as a means of toning down or excusing the act. Not just from you. Secret releases to a special cadre of a few -- "It's only what? 2 games? Oh, but that was probably due to some licensing thing" Prices keep getting too high and exploit the speculators and completists in the community -- "Nah, it's normal supply and demand; the market will correct itself" New home-brews are released with copyright notices on the boxes from Activision, Atari, and Mattel; it erodes the meaning of copyright and suggests an invitation to piracy -- "But, but, it makes it look more authentic!" People are now selling empty boxes of games that never existed in order to tap into that OCD collector mentality -- "We're only providing what people want. Besides, it's not like we're making money ... well only a little." Someone stole someone else's code and publishes it as their own and gets ostracized -- "Well, he already apologized, and it was only this once ..." Someone now selling that stolen game -- "It's only a single occasion, nobody will support it, and it won't stop the originally from selling well ..." etc., etc., etc. It serves to splinter the community more and more and erodes trust and fosters acrimony among a few. It's not healthy. -dZ. P.S. Never heard the "captain eyeroll" epithet before. Sounds neat.
-
Thanks for the ad hominem attack, classy. What I got from your message was waffling so hard, that IHOP is planning to add your post to their menu. You forgot these gems as well: All the talk of crashes and community support for stuff like this is way overblown. I don't like secret game releases or code theft either but it's hardly indicative of the scene as a whole or the greater community in general. TRANSLATION: There isn't really a problem. Releasing games in private to avoid copyright issues will only affect completionists and only in the short term. ... So unless you have to have everything, this really isn't a big deal. TRANSLATION: And even if there was a problem, it's only to a small sub-set and it'll fizzle out by itself. The community is NOT supporting code theft. I think one can read this thread and see the very negative response Gyruss has had. Yes some of the games are selling on eBay right now, so what? That won't stop Deep Zone from coming out TRANSLATION: Let them do what they want since nobody will support it; but even if they support it, Deep Zone will still sell. etc. All that, to me, ignores the main point we've made in the past: that accepting this behaviour as "normal" corrodes the community. It also betrays a rather big gap in its reasoning: That "the community" is more than just Rev, Elektronite, artrag, or you and me -- this community is composed of speculators, hard-core and casual collectors, game publishers, retro-gamers, and home-brewers. It's varied and diffused across many categories, each with their own motivations. To say "I don't see a problem with any of this because it doesn't impact me directly nor my buddies," is to miss the forest for the trees: it normalizes behaviour that is corrosive to a community which already contains elements that benefit or are impacted from such behaviour. -dZ.
-
TL;DR: you see no problem with any of this stuff, buyer beware.
-
Well, I'm not convinced that this was not happening already; it's just that these goofballs did it out in the open. Remember, there have been a couple of releases that were kept "private" and distributed via PM. That's not to say that those were dealing in stolen games, not the ones I am aware of. Just that there is an undercurrent of private trades and deals happening out of view already, so the "box" was already opened. -dZ.
-
GET PAPI ! Collision TILE/SPRITE in 8 directions problem.
DZ-Jay replied to Vetea's topic in Intellivision Programming
Vetea, I'm sure you are aware of it, but just in case, the jzIntv emulator comes with a very powerful interactive debugger. If you are using the IntyBASIC SDK, invoking the debugger is as simple as using the tool "INTYDBUG" to execute the game, and it will take care of initializing the debugger with a symbol table and source-to-listing mapping between IntyBASIC and Assembly. If you are not using the SDK, you can add the "-d" option to the command line to invoke the debugger, but you'll have to read jzIntv debugger documentation for information on how to set the symbol table and other features. Or just ask. -dZ. -
Get Papi ! A first Try with the Intellivision ! :)
DZ-Jay replied to Vetea's topic in Intellivision / Aquarius
Vetea, I'm sure you are aware of it, but just in case, the jzIntv emulator comes with a very powerful interactive debugger. If you are using the IntyBASIC SDK, invoking the debugger is as simple as using the tool "INTYDBUG" to execute the game, and it will take care of initializing the debugger with a symbol table and source-to-listing mapping between IntyBASIC and Assembly. If you are not using the SDK, you can add the "-d" option to the command line to invoke the debugger, but you'll have to read jzIntv debugger documentation for information on how to set the symbol table and other features. Or just ask. -dZ. -
Unfortunately, programming the Intellivoice is not a simple matter. There are two ways you can do it: Using a set of speech allophones and building phrases (like you are doing) Translating speech samples into an internal formal. The first one will most likely yield a monotone phrase because the allophones are pre-programmed and calibrated with a specific sound pattern. Therefore, putting them together in a phrase will sound robotic. The allophones used by IntyBASIC were taken from the original chip manufacturer's library, which they have generously shared with our community for research and personal use. The second one is more versatile, which is what they used in the old Mattel games, but it is absolutely non-trivial. The few people who have figured out how to do it have not publicly released their work or tools for whatever reasons. I believe it has to do with a complicated algorithm called a Linear Predictive Coding. If you're up to it, everything you need to figure it out is in the technical documentation available on the orator chip that the Intellivoice uses. I warn you, though, it is highly technical, exceedingly arcane, and very "engineer-y". Elektronite seems to have a means to do it because at least two of their games use voice samples. You may want to contact them. Just be aware that nothing seems to be available to the community for just playing around. As for your second question, the PA1 .. PA5 allophones are pauses of speech. Each one is progressively longer. They are used interspersed with the other allophones to form words, phrases, and sentences. For instance, think of the word "Connection." If you say it out loud, it is not really one single sound, it is more like "Connek ... shunn". Although very brief and seemingly trivial, that pause in the middle is very significant in making the word sound intelligible. So you may want to add PA1 in there. If you play the two versions right after each other, with and without the pause, you will notice that the one with the pause sounds more natural. Obviously, you would use a longer pause between words, and an even longer one at the end of a sentence. Once you start playing around with this, you'll realize that human speech is not so straightforward as we all assume intuitively; the patterns are harder to discern than we initially imagine, and even the sounds we use in words are not the same we assume when we put them in writing. Our brains and ears conspire in mysterious ways to make it all seem smooth and simple, but it's far from it. -dZ.
-
Neat! That's an interesting article. I particularly liked the optimism in the following passage: Doh! It's too bad how it actually turned out. -dZ.
-
My little kitty (who's actually quite an old lady of 18 years), is sick and wouldn't eat. She underwent a minor surgical procedure resulting in Cyber-Kitty: a brand new bionic version, enhanced with an alternative liquid-fuel injection system
-
oh i hope this works out for you this was one of the last things we did for our boy before his kidneys completely shut down, he was diabetic.
-
-
- Show next comments 156 more
-
-
We will continue with the technical discussion on the Auto-Pilot soon, but first I want to talk about something I've come to regard as The Great Auto-Pilot Hack. It's the one change made to the Auto-Pilot framework which enabled some of its most creative uses. I liken it to having started out with a nice and sleek sports car, souping it up with some parts stolen from NASA, and eventually ending up with a space shuttle. Only that it wasn't a real space shuttle -- that's just a cool looking fiber-glass shell built feebly around the Apollo Lunar Lander. Yep, that lunar lander. It's weird, it's ugly, and it looks to be constructed out of tin-foil, unholy amounts of duct tape, and bailing wire. Yet, it fulfilled its requirements honorably: namely, it got to the moon and didn't kill anybody. So, good enough for government work, I guess. That's how I feel about this particular feature. It was a fantastically great addition: It unleashed the phenomenal potential of the Auto-Pilot system as an engine for animated cut-scenes; it enabled the expressivity and cinematic story-telling power of Christmas Carol's introduction sequences; and it let my imagination and creativity soar to places it just couldn't before. However, it was still a hack. A hack grafted on with duct tape and bubble gum, and it was ugly as sin. Before I tell you what this great big hack was, I will describe the problem which originally prompted it. A Big Problem From the very first article, I've emphasized the point that the Auto-Pilot is not a cut-scene sequencer or general game scripting engine; that it was purely and simply a sprite object scripting system. This may sound like a subtle distinction, but it is important. As Charles Dickens states in "A Christmas Carol" when pointing out emphatically that Jacob Marley was, in fact, very much dead, "This must be distinctly understood, or nothing wonderful can come of the story I am going to relate." So, per-object scripting engine, not per-scene. Got it? Alright, on we go. The Problem As development of my very own "Christmas Carol" game (thank you, Mr. Dickens, for the inspiration) wound down to conclusion, I was left with the task of creating the final cut-scenes for each of the game eight stages. I had created already one or two simple cut-scenes, mostly as a proof-of-concept. These were very simple indeed: only one sprite entering the scene at a time, then leaving; then another one comes in, and leaves; the end. Here's a sample of the very first sequence. The following "screenplay" is taken straight from my design document notes, and served as my guide to the Auto-Pilot script: STAGE #1: Haunted Hollow Elf walks across, Ghost walks and looks around. - [Standard background] - Elf enters, stage left - Elf walks across stage, normal speed - Elf exits, stage right - [Short pause] - Ghost enters, stage left - Ghost walks across stage, normal speed - Ghost stops at center of stage - Ghost looks around, twice - Ghost walks across stage, faster speed - Ghost exits, stage right - End of sequence. The newer cut-scenes I had in mind, however, were much more elaborate; having been conceived during my brief moments of down-time, thinking them up with my wife during our strolls in the park or the woods, they were intended as narrative devices: a series of short vignettes which serve to advance an overarching story. By way of example, consider the following "screenplay" taken also from my design notes: STAGE #6: Freezer Burn Elf is introduced to Bad Toy. - [Draw a bunch of presents on left edge of stage] - [Draw sign that says "Carol" on top of presents] - Elf enters, stage right - Elf walks across stage, normal speed - Elf stops in front of presents - [Short pause] - [a little head pops up from a box] - [Short pause] - Bad Toy comes out of a box - Bad Toy walks over to Elf - Elf stares at Bad Toy, Bad Toy stares back - [Short pause] - [Bad Toy beeps] - [Bad Toy extends arm to Elf] - Bad Toy "zaps" Elf - [Elf is animated as a glowing skeleton for a frame or two] - Elf is startled - Elf runs away, very fast speed - Bad Toy chases Elf, fast speed - Elf exits, stage right - Bad Toy exits, stage right - End of sequence. Notice the difference? Well, apart from the fact that it has a bunch more things going on, the main difference is that there is an actual interaction among the characters -- and even with the environment. That posed a serious problem: If the Auto-Pilot scripts were truly autonomous machines (which they were), controlling the motion of a single object (which they did), and they are invoked and managed independently for each individual object (which they are) ... How on earth can we coordinate the intricate actions that they share together on a single complex scene? Thinking about it right now, I find it very strange; the Auto-Pilot engine was almost done in by what is a very obvious lack of scope and ambition in its design. I may be a procrastinator of super-human caliber that never gets anything done, but nobody has ever accused me of thinking small, of lacking grandiose vision and ambition. Oh well. The (Incomplete) Solution For the very first sequence above, the most simple one, I solved this problem by using P-Machinery's timers from within the game program. Essentially, at the start of the sequence, I set two timers: one timer for when the elf enters the scene to trigger it's Auto-Pilot script; the other delayed just enough to trigger right after the elf leaves the scene and invoke the ghost's Auto-Pilot script. If I got the timing right, both timers will fire their events at the appropriate time, and the result would look just like if the ghost is following the elf. Finally, since the ghost was the last one to leave the scene, I set its last script statement to be the Stop command with an argument that points to a "clean-up" routine which actually ends the sequence. All together, it looks like this: https://vimeo.com/301451665 As you may imagine, this type of work-around would just not do for the more complex sequences, in which there are many more interactions between the characters at a much granular level. A better solution was needed. Enter The Great Big Auto-Pilot Hack. The Great Big Hack Well, the obvious solution was to re-imagine the Auto-Pilot framework as a general "scene scripting engine" and, of course, re-write the Auto-Pilot engine itself to address and support the environment as a whole, of which a sprite object is merely one single aspect. So I sat down one Saturday afternoon, revised all my design documents and worked furiously throughout the night so that by Sunday, I had a brand new, all-encompassing, general-purpose cut-scene scripting engine which supported complex interactions among sprites and the environment, and all! Ha! Ha! No. I thought that task would be so daunting and complex that I didn't even consider it seriously, to my everlasting regret. Instead what I came up with was quite an elegant hack. The engine still centered around individual sprite objects, and it still operated on them implicitly, but the hack allowed the individual objects to interact with each other and their environment. All that raw power (for indeed it was quite raw and ran at a very primitive low-level) was afforded by a single new command added to the Auto-Pilot repertoire: Exec -- the ability to execute external sub-routines directly from a script statement. In the actual technical implementation, the new command acted as a "call-back" or "event handler," in that the script would execute as normal, one statement at a time, until it encountered an Exec command. At that point it would call the given sub-routine, which would then do its job and dutifully return to the command executor to continue with the Auto-Pilot script. All of a sudden, it was like you had a means to create custom command executors for absolutely anything you needed! The elf reached the middle of the screen and needs to trigger the release of the bad toy? Easy! Just Exec to a special routine which will freeze the elf in wait and invoke the robot's Auto-Pilot script. The bad toy finished its initialization and walked over to the elf, which should now cause it to react? No problem! Just Exec to another routine which will re-engage the elf's Auto-Pilot script, et voilà! Special-purpose custom commands for any occasion and sundry! A Hack By Any Other Name... So if it was such a huge leap forward in functionality and such a mind-boggling enabler of creative expression, why do I talk about it as just a hack, suggesting a measure of shame and regret? Well, because it is a hack, plain and simple. It didn't solve the problem, it just bypassed it -- and instead passed on the complexity of the solution to the programmer (me) rather than encapsulating it in the engine, where it should be. Scripting the sequences stopped being merely a set of discrete statements, and instead became actual low-level Assembly Language programming of each individual action, reaction, and coordination of objects. It's like trying to fix the heavy congestion of a small country road by giving every motorist a pick, a shovel, and a ton of asphalt, and telling them that now they can build their own lanes; when perhaps the better and more holistic -- and dare I say, correct -- solution should have been to tear it down and build a 5-lane highway instead! Sure, the motorists can get to their destination, maybe even faster than before; but now they all have to figure out -- on their own -- how to build a road. Worse, they have to peer inside the bureaucracy of rural county government to get a permit, coordinate among each other so that they don't end up destroying other people's lanes, and figure out how and were is best to make their roads. The county planning commission should have done all that and the motorists should have just arrived one day to find a pristine highway with wide and open lanes for them to drive through. And if you think that my analogy about local government bureaucracy is confusing because you don't really understand (nor care) about their responsibilities and organization, then ... THAT'S PRECISELY MY POINT. You shouldn't have to. Creativity Unleashed So there you have it, The Great Big Hack in all its naked and brilliant glory. In the end, I am immensely proud of what I accomplished, and quite satisfied with how I got there. I just still believe it was a missed opportunity and, although it did spark my creativity greatly, it was at the cost of considerable incidental effort. I can't help but think how much more I could have done had the Auto-Pilot framework been a bit more accommodating in its interface, and encapsulating in its abstractions. To end, I will leave you with the final implementation of the animation sequence described in the second "screenplay" above. I wish to call your attention to the smooth and seemingly natural interaction between the characters, and their reactions to each other's actions. That -- and many other sequences even more complex that this one -- is the direct result, for better or worse, of the Exec command. The legacy, if you will, of The Great Big Hack. https://vimeo.com/301452441 We shall dig deeper into the technical details of each command executor, including the one for the Exec command, in future articles of this series. -dZ.
-
In our first part of this series on the P-Machinery Auto-Pilot, we reviewed the general circumstances that prompted its creation, how and why it was created, and an overall idea of the infrastructure that supports it. Central to that infrastructure was the concept of a Sprite Object Record, the data structure representing a game sprite, which is the very thing on which the Auto-Pilot operates. Now it's time to talk about the technical design of the Auto-Pilot itself and go a little deeper into its inner workings. Technical Overview As mentioned before, the Auto-Pilot itself is very simple. Its brilliance comes from the versatility and flexibility this simple design affords the game program. At its core, there are three main components to the Auto-Pilot: Script - An Auto-Pilot script is an ordered list of statements that operate on a particular sprite object. Each individual statement represents a command that alters the behaviour or state of the sprite, or changes any of its internal attributes. Dispatcher - As the name suggests, the Auto-Pilot dispatcher's job is to dispatch commands as necessary. On every invocation, it fetches the statement corresponding to the current step of the object's script, decodes it using a look-up table, and calls the appropriate command with any arguments given. Command Executor - Each command supported by the Auto-Pilot has a corresponding executor function, which is the actual sub-routine that performs the work to fulfill the command. Below is a simple flow diagram depicting the architecture of this system, and the general way in which the various components interact. A full description of each component follows. +===============+ | | | | | P-MACHINERY |<------------------------------------------------------------------, | | | | | | +===============+ | | | | 1. Call Auto-Pilot +==============+ | | Dispatcher | AUTO-PILOT | | | | SCRIPT | 3. Decode & execute | | +==============+ step command | v ,----->| Step 1 |------------------, | +===============+ | +--------------+ | | | | | | Step 2 | | | | | | +--------------+ v | | AUTO-PILOT |-------------' | Step 3 | +===============+ | | DISPATCHER | 2. Dispatch +--------------+ | COMMAND | | | | current step | Step 4 | | EXECUTOR | | | | +--------------+ +===============+ | +===============+ | Step 5 | | | ^ +--------------+ | | | 6. Return to : . . . : / \ | | dispatcher . . / \ | | +--------------+ / \ No | 4. Return | | Step n | ( Done? )------' to game | +--------------+ \ / | \ / | \ / | | Yes | +==================+ | | | SPRITE | | `--------------------------| OBJECT RECORD |<---------------' +==================+ 5. Increase step counter As you can see in the diagram, the P-Machinery framework (actually, any part of the game program) invokes the Auto-Pilot dispatcher (1), typically in a loop. The dispatcher dispatches the current step in the script (2) by decoding the statement and calling the appropriate command executor (3). When the executor completes one cycle of its work, if the target state of the command has not been fulfilled (e.g., the sprite has not reached the given destination, or a set timer has not yet expired, etc.), control is returned to the game program (4) and the statement will be continued on the next invocation. If the parameters of the command have been fully satisfied, the object's step counter is increment (5), and control is passed to the dispatcher (6), which will then dutifully do the same thing again for the next statement; and so on. The Auto-Pilot Script An Auto-Pilot script is a list of operational statements, each comprised of a command and its parameters. There are no requirements pertaining to which commands can be called, or in which sequence -- every command supported by the Auto-Pilot is available for any statement. The only actual functional requirement of a script is that the very last statement must be a Stop command. This tells the framework that the script is fulfilled and that the Auto-Pilot is no longer needed. Technically, it clears the AutoPilot flag in the Sprite Object Record, disabling the Auto-Pilot. Script statements are stored as program data and contain no executable code. All work is performed indirectly by the command executor invoked for each statement. Script Statement The anatomy of a script statement is as follows: DECLE <command-code>, <parameter-1>, <parameter-2> The <command-code> is a symbolic constant representing the command. These constants are conveniently defined by the Auto-Pilot library as an enumerated list of values, and serve essentially as an index into the command-executor dispatch table. Command codes will be described in full later on. As shown above, each statement is afforded up to two parameters. These are passed along by reference to the command executor, which is then responsible for using them as necessary. Design Limitations At the very beginning of design, I thought it made great sense to define scripts in a purely deterministic way, structurally, so that the execution of commands could be simplified by not having to figure out how many arguments were available. Also, by making all statements the same size (three data words), individual steps within the script could be singled out and referenced externally, merely by giving a step number and computing their offset from the top. However, in practice, none of that special functionality was ever needed nor desired. In fact, the actual implementation of the command executors was such that each one could in theory consume as few or as many parameters as it needed. Moreover, it turned out that different commands had different parameter requirements, but that even these were rather constants. For instance, setting the screen position required always X and Y parameters; while setting the speed required only ever a single velocity parameter. This made the two-argument requirement simultaneously an onerous restriction to some potential commands, and a wasteful consumption of resources for others. Yet, this restriction on statement structure was built-into the Auto-Pilot engine and as much as it bugged me sometimes, I never took the time to go back and change it -- even when faced with the stark reality of dwindling ROM space. The fact that I am complaining about it right now should serve to illustrate how much I regret not rectifying this. The Auto-Pilot Dispatcher The Auto-Pilot dispatcher is a simple dispatcher module whose sole purpose is to get the next statement from the script, decode its command code, and jump to its corresponding command executor. It performs no context-switching, except to save the return address of the caller so that the ensuing executor can return accordingly when done. The dispatcher uses a simple look-up table with pointers to each available command executor. The decoded command code then serves as an index into this table. The full command table is shown below: ; ------------------------------------------------------------- ; Dispatch table for the Auto-Pilot commands ; ------------------------------------------------------------- DECLE CMD_DELAY ; Command: AP_CMD.Delay DECLE CMD_STOP ; Command: AP_CMD.Stop DECLE CMD_STOP_DIS ; Command: AP_CMD.StopDisable DECLE CMD_EXEC ; Command: AP_CMD.Exec DECLE CMD_EXEC_DELAY ; Command: AP_CMD.ExecDelay DECLE CMD_EXEC_WAIT ; Command: AP_CMD.ExecWait DECLE CMD_GOSUB ; Command: AP_CMD.Gosub DECLE CMD_SUBRET ; Command: AP_CMD.Return DECLE CND_MOVE_TILE ; Command: AP_CMD.MoveToTile DECLE CMD_MOVE_X ; Command: AP_CMD.MoveToX DECLE CMD_MOVE_Y ; Command: AP_CMD.MoveToY DECLE CMD_MOVE_XY ; Command: AP_CMD.MoveToXY DECLE CMD_MOVE_TARGET ; Command: AP_CMD.MoveToTarget DECLE CMD_MOVE_PIX ; Command: AP_CMD.MovePix DECLE CMD_SET_POS ; Command: AP_CMD.SetPos DECLE CMD_SET_POS_X ; Command: AP_CMD.SetPosX DECLE CMD_SET_POS_Y ; Command: AP_CMD.SetPosY DECLE CMD_SET_POS_OFS ; Command: AP_CMD.SetPosOffset DECLE CMD_SET_TARGET ; Command: AP_CMD.SetTarget DECLE CMD_SET_SPEED ; Command: AP_CMD.SetSpeed DECLE CMD_SET_DIR ; Command: AP_CMD.SetDir DECLE CMD_SET_DIR_X ; Command: AP_CMD.SetDirX DECLE CMD_SET_DIR_Y ; Command: AP_CMD.SetDirY DECLE CMD_SET_DIR_WAIT ; Command: AP_CMD.SetDirWait DECLE CMD_SET_VISIB ; Command: AP_CMD.SetVisib DECLE CMD_SET_STATE ; Command: AP_CMD.SetState DECLE CMD_SET_FLAG ; Command: AP_CMD.SetFlag DECLE CMD_CLEAR_FLAG ; Command: AP_CMD.ClearFlag DECLE CMD_FLIP_FLAG ; Command: AP_CMD.FlipFlag Invocation Interface The dispatcher is invoked by the game program via a subroutine call, with a pointer to the Sprite Object Record as its only argument. The interface to the subroutine is described in the source code as follows: ;; ======================================================================== ;;;; AP_DISPATCH: ;;;; Procedure to execute the next command in an auto-pilot script sequence. ;;;; ;;;; There are two entry points to this procedure: ;;;; AP_DISPATCH Receives the data record and a return address ;;;; as input parameters. ;;;; ;;;; AP_DISPATCH.Next Same as AP_DISPATCH, but no return address is ;;;; expected. This entry point is intended for ;;;; command handlers to chain their execution by ;;;; recursively calling the dispatcher. The return ;;;; address is expected on the top of the stack. ;;;; ;;;; INPUT for AP_DISPATCH ;;;; R3 Pointer to Object Record. ;;;; R5 Pointer to return address. ;;;; ;;;; INPUT for AP_DISPATCH.Next ;;;; R3 Pointer to Object Record. ;;;; SP Pointer to return address. 1 DECLE ;;;; ;;;; OUTPUT ;;;; R3 Pointer to Object Record. ;;;; R4 Trashed. ;;;; R5 Pointer to param1 of current step. ;;;; ======================================================================== ;; Basic Algorithm Rather than posting the source code, I shall describe the functional algorithm instead: Save the return address in the stack (only applicable when called externally by the game program). Using the given Sprite Object Record, check the AutoPilot flag. If the AutoPilot flag is set then Get the pointer to the active script. Note that this address actually points to the current statement, and is incremented after every successful statement execution. If we have a non-zero pointer then Fetch the first data element of the statement. This is the command code. Use the command code as an index into the look-up table and retrieve a pointer to the command executor. Jump directly to the command executor routine, passing along the current statement pointer and the return address in the stack. [*]Else it means that the Auto-Pilot was disengaged (asynchronously) after it was queued for execution. So, we skip it. [*]Else it means the Auto-Pilot is not engaged, so skip it. [*]Return to caller. In pseudo-code, it looks like this: // Alternative entry point is// ap_dispatcher.next(obj)procedure ap_dispatch(obj) { // Only process if the Auto-Pilot is active if (obj.Flags(AutoPilot) == True) { curr_statement = obj.ScriptSeq // Only execute if we have a valid statement if (curr_statement != null) { // Fetch and decode command from statement cmd_code = curr_statement[0] cmd_exec = DISPATCH_TBL[cmd_code] // Invoke command executor call cmd_exec(obj, curr_statement) } } } The fact that there are two entry points, one which stores the return address and one which expects a return address on the stack, allows the Auto-Pilot engine to execute multiple statements in sequence, and only return to the game program when done or when a command needs to wait before continuing. This simple yet elegant design affords a simple multi-tasking mechanism in which statements are executed sequentially, and yet able to yield to the rest of the game program (or Auto-Pilot scripts for other objects) when execution of a statement requires longer than a single game cycle to complete. The Statement Command Executor As mentioned before, each supported command has a corresponding command executor, a sub-routine which implements the command functionality. In this way, each executor contains code specific to its function. That said, they all follow the same basic structure and general algorithm: Fetch the parameters needed by the function from the current statement (passed on by reference by the dispatcher). Do the necessary work needed to fulfill the command. If the command has fulfilled its purposed completely then Increment the step counter by advancing the current statement pointer in the Sprite Object Record to the next statement. Jump back to the dispatcher using the alternative entry point. [*]Else return to the caller by retrieving the return address from the stack. We can express that in pseudo-code as follows: procedure cmd_exec(obj, curr_statement) { // Fetch one or two parameters, // as needed by the command. param1 = curr_statement[1] param2 = curr_statement[2] // ... // Perform the command work here // ... if (cmd_done == True) { obj.ScriptSeq++ call ap_dispatcher.next(obj) } else { return }} As you may imagine, very simple commands such as SetSpeed, SetVisib, FlipFlag, etc. -- which are very quick to execute and require almost no time at all -- can all be executed in series within the same game cycle. Thus, each one jumps back directly to the dispatcher when done, without further processing. This allows you to set multiple flags or update multiple aspects of the sprite's state in a single go, even though they are all described as discrete script statements. A script composed only of such state-management statements, can then be executed all at once, although it may not be very interesting at all. The most interesting part of the Auto-Pilot is how it handles longer running commands such as those that require a sprite to move from one place to another at a specific speed, or delay the execution of the next statement by a specific length of time. We will dig into the gory details of all command executors in the next installment of this series. -dZ.
-
Get Papi ! A first Try with the Intellivision ! :)
DZ-Jay replied to Vetea's topic in Intellivision / Aquarius
What do you mean? Is there something we can help you with? -dZ.
