Wednesday, January 17, 2018

Parsing 6502 Assembly

The tokens that make up the line being processed need to be converted into machine language. There are essentially 5 valid lines that can be in an assembly language file which are blank lines, labelled lines, labelled statements, directives, and statements.  Blank lines can simply be ignored. Labelled lines simply add the current address being processed to the list of links (more on that later). Labelled statement lines simply act like the label, then remove the label and act like a statement. Directives are assembler commands which are processed separately and will be covered in a later article. Finally, statements are what the assembler turns into machine language.

Assembly language has a very simple structure for the statements making it much easier than parsing a higher-level language. The format for a 6502 assembly language statement is: mnemonic [value]. The value is either a number that the command will act on immediately or is an address and the mode in which the address is going to be used in. If you know the number or addresses being used then this is simply the process of taking the base mnemonic and then looking at how the address was specified to determine the address mode to use. The following table demonstrates this.

MNEMONIC
EOL
IMPLIED
MNEMONIC
A
EOL
ACCUMULATOR
MNEMONIC
NUMBER
EOL
ABSOLUTE or RELATIVE or ZERO_PAGE
MNEMONIC
NUMBER
,X
EOL
ABSOLUTE_X or ZERO_PAGE_X
MNEMONIC
NUMBER
,Y
EOL
ABSOLUTE_Y or ZERO_PAGE_Y
MNEMONIC
#
NUMBER
EOL
IMMEDIATE
MNEMONIC
(
NUMBER
)
EOL
INDIRECT
MNEMONIC
(
NUMBER
)
,Y
EOL
INDIRECT_Y
MNEMONIC
(
NUMBER
,X
)
EOL
INDIRECT_X

As you can see, the different combinations of tokens form different address modes so simply finding which sequence of tokens is used but you will notice that there are three cases where different address modes use the same syntax. The distinction between absolute addressing (with or without X and Y) and zero page addressing is simply the address used. If the address will fit into a byte then the more compact zero page instructions can be used.

Determining if relative mode should be used is a bit trickier as you need to look up the mnemonic and determine if it has a relative address mode in which case you use that mode. We know this is correct as relative address modes are only used for branching instructions which only support the relative address mode.

We now have enough information that we can parse the statement and generate some machine language, which we will cover next week. 

Wednesday, January 10, 2018

Tokenizing

I finally got around to putting up my source on GitHub. The code is in a very rough state as it is more prototyping than production and it is a bit ahead of what I am posting but anybody who is interested in it can find it at github.com/BillySpelchan/VM2600 . My original plans were to self-host it on 2600Dragons, but that just seemed like too much work. Once I get to the point of getting the emulator running in JavaScript I may post it to 2600Dragons but that may be a few months or so.

As explained last week, tokens are broken down into a number of types which are stored in the AssemberTokenTypes enumeration. Tokens are effectively just a simple data structure so I take advantage of Kotlin’s data class support to define the class which is all that is needed.

data class AssemblerToken(val type:AssemblerTokenTypes, val contents:String, val num:Int)

The contents holds the actual string that forms this token while the value is the numeric representation of the token if appropriate or 0 otherwise. In the case of label declarations, the contents does not include the postpending colon.

The tokenize function is quite long but is simple. Essentially it simply loops through each character in the string that is about to be processed basing what to do based on the character encountered. Spaces, tabs, and semicolons as well as everything after them get converted into whitespace. Commas are matched with an x or a y. Brackets form the indirect start and indirect end tokens. The hash becomes an immediate token. The period becomes a directive token. The percent indicates the start of a binary number so the ones and zeros after it are converted into the appropriate base 2 number. Likewise, the dollar sign signifies hexadecimal numbers so the hex characters after it are taken and used to form a base 16 number. Numbers get converted into a decimal number. I could have taken the route of making an octal number if the first number starts with a 0 but don’t really use octal so never bothered.

Strings of letters form labels with a colon indicating the label is a link label. If not a link label, the text is checked against the list of mnemonics and if it matches becomes a mnemonic token.

When I was planning my tokenizer, I created the following diagram which explains it. This was probably not necessary as the logic is very straight forward, but this may help make the process easier to understand.



The tokens are stored in an array list of assembler tokens, with whitespace tokens not being added to the list unless the function is told to include it by passing false to the ignoreWhiteSpace parameter. Testing is simply verifying that passed strings produce the appropriate list of tokens.


Next we need to take the tokens and convert them into 6502 assembly which will start being covered next week.

Wednesday, January 3, 2018

Assembling the Tokens

Assemblers are easier to write than a complier would be as the structure of the code is a lot simpler. There are still a lot of similarities between a compiler and an assembler that some of the common techniques used to write a compiler are also useful for writing an assembler. With a compiler you first tokenized the source code (Lexical Analysis), parse the tokens into something meaningful (syntax and semantic analysis), generate some intermediate code which then finally generate the machine code. With the assembler, I am taking a similar approach. I am tokenizing the source code, parsing it into intermediate machine language, then generating the final machine language.

Java does have some tokenizer classes that will do part of what I want done but while it is possible to use Java classes in Kotlin I am not sure how well those will work if I try to compile my Kotlin code to JavaScript, which is something I do want to do eventually. For this reason, and my NIH syndrome kicking in, I opted to write my own tokenizer for the assembler. I created a simple enumeration to hold the different types of tokens that my assembler will use, though suspect that I will be adding some new ones later.

enum class AssemblerTokenTypes {
    DIRECTIVE, ERROR, IMMEDIATE,
    INDEX_X, INDEX_Y,
    INDIRECT_START, INDIRECT_END
    LABEL_DECLARATION, LABEL_LINK,
    NUMBER, OPCODE, WHITESPACE }

A DIRECTIVE is a command for the assembler. There are a number of different ways that these can be handled but I am going to start my directives with a dot. I have not worked out all the directives that I plan on supporting but at a minimum I will need .ORG, .BANK, .BYTE and .DATA with .INCLUDE and .CONST being nice to have. More on these when I actually get to the directives portion of my assembler.

ERROR is an indication of a tokenization error which kind of breaks the assembling of the file. Invalid characters used would be the likely culprit.

Some of the 6502 instructions have an immediate mode that lets the programmer specify a constant value to use in the next byte. This is indicated by prefacing the constant with the hash (#) symbol. The tokenizer simply indicates that an immediate mode value is going to be next by having an IMMEDIATE token.

The 6502 supports offsets of an address using “,X” or “,Y” so the tokens indicate such an index is being used. These indexes are used for zero page indexing, indirect indexing, as well as your normal indexing which is officially called absolute indexing. The particular type of indexing address mode that will be used will be determined by the parser which will be covered later.

Indirect addressing modes prefix the address with an open bracket and postfix the address with a closed bracket. To indicate this the INDIRECT_START, and INDIRECT_END tokens are used.

It is certainly possible to write an assembler that does not track the addresses of locations for you but requires you to know all the addresses that you are using but one of the reasons that assemblers were invented was to remove this busywork. This means that we need to have some type of support for labels in our assembler. Most 6502 assemblers will indicate the location within the code by having a label that is followed by a colon at the beginning of the line. This  is indicated by the  LABEL_DECLARATION token with LABEL_LINK tokens being used for links within the code.
As assembly language revolves around numbers, we obviously need a NUMBER token. This is a special token for processing as I am supporting binary, decimal, and hexadecimal formats for numbers. My Machine Architecture teacher will probably be upset that I am not including support for octal numbers but I never use that format in code so didn’t see the point in adding that. I am using the pretty standard 6502 convention of representing hex numbers by prefixing them with a $ and by prefixing binary numbers with a % symbol. Supporting binary is not vital but very handy to have, especially for a machine like the 2600 where you are doing a lot of bit manipulation.

While I probably should have used the term MNEMONIC instead of OPCODE for the enumeration, I often call the mnemonic an op code even though technically the op code is the actual numeric value that the assembler ultimately converts the mnemonic into. Should I change this in my code, probably. Will I?

Finally, WHITESPACE is the spaces, tabs, and comments. In most assemblers comments are designated with a ; so that works fine for me. Most the time the whitespace characters will be ignored so I could arguably not have a token for whitespace and simply ignore it.

Now that we have the tokens out of the way, we need to write the tokenizer.

Wednesday, December 27, 2017

Making of Santa’s Search

I am posting this early today as I am going to The Last Jedi tonight so will be busy. I have decided that for next year I will not be interrupting my emulator project for game material unless it is for a game jam that I am participating in. Material relating to resurrecting Blazing Games games and the revised version of my Flash Game Development book will be on my resurrected Blazing Games development blog which I will be starting this Saturday. Now onto Santa’s Search.

When I originally create Santa’s Search, Flash did not have any 3D support at all. Worse yet, it didn’t have direct bitmap support so manually building an image was not possible. My Coffee Quest series was already using ray casting. The CQ ray caster had only partial perspective correction but after taking graphic programming courses I realize that the solution I found was simply wrong and that the better approach would simply do a world transform to make every ray act as if it were the center ray. But that is way off topic. The point I was trying to make is that at the time I couldn’t do ray casting so I went with a more primitive algorithm known as the painter’s algorithm.

The idea here is that you paint the things furthest from the player first then overpaint the items with things that are closer to the player. The downside to this approach is that you are potentially overdrawing the same pixel multiple times. As this is not a real-time game, this is not a huge concern so the painter’s algorithm works fine.


As you can see by the sprite atlas above, the game has three different blocks that it uses to draw the maze. A left-side block, a center block, and a right-side block. These are chosen based on the position of the block relative to the player’s viewpoint. Had I been a bit more ambitious with saving image atlas space, I could have had all three blocks combined into a single distorted block and have the sprite take just the appropriate chunk of the combined image. The deer and sled images are the same no matter which position the player is looking at them.

The original game was controlled using the keyboard. As mentioned in previous posts, I want the game to be able to be playable on touch devices. As the only controls are turning and moving, adding simple arrow buttons was the obvious choice. I was originally going to go with transparent arrows that turned solid when clicked on, but felt that the outlined arrows simply looked better so went with those.

The hard part of porting this game was assembling the sprite sheet as Flash CS 6 did extremely poor so I had to adjust the sheet manually then figure out the coordinates myself. The code was very quick to port and to my shock worked nearly flawlessly once all the “this” statements were added. Half a day’s worth of work and I have a playable game. Not too bad for porting. Let us hope that my future Flash to HTML5 ports go as smoothly as this one did.

See you next year!

Wednesday, December 20, 2017

Making Evil Gnome’s Revenge

Before I get to my game overview a brief update on my 2600 project. The assembler is functional now and while I do want to add more directives to it, will start on implementing the 6502 emulation adding new directives to the assembler as needed. I have a number of articles on my 2600 assembler ready and will be posting them next year. Now back to the evil gnome.

Evil Gnome’s Revenge was my 2012 game jam entry for Ludum Dare #25 which had the theme “You are the Villain.” At the time I really didn’t want to go down any of the dark paths that I had thought of and having had created both Santa’s Search and Santa’s Snowball years earlier I thought this would be a light-hearted way of making the player the villain without having them do anything outrageous. I can’t say that the herding concept was original as there are a number of games that have a similar mechanism with Munch’s Oddysee probably being the biggest influence.

The development time on this port was pretty abysmal as I made the cardinal mistake of working on it while watching TV. While I know that the human brain is not designed for multitasking, the lackluster performance I had while coding this clearly emphasizes how poor we humans are. The strange thing is that I normally have podcasts or other background noise playing so I had expected to have my normal development speed. When coding, however, I tend to tune out what I am listening to while the TV tended to take most of my attention as I got caught up with my shows before losing the contents of my PVR. The big lesson being that you shouldn’t let your recorded backlog build up that much. Coding is best done without distractions could also be considered a lesson if I didn’t already know that.

The first surprise was that the game was created using the Starling library. This is a molehill library that takes advantage of the 3D capabilities that later versions of the Flash player added.  When I saw the starling imports I thought that perhaps I should consider StageGL, the WebGL based renderer that is in testing now but will eventually replace the stage.js library.  The map for the game, which is procedurally generated, is 64x64 with each tile being a movie clip that goes to the appropriate frame to display the tile at that location. Once set, however, the tiles do not change. Having 4096 sprites on the screen is probably not very good for performance, but by creating a 2048x2048 pixel cache then there is only one background image that the renderer is tracking giving the game 60 fps performance on decent machines. It is easy to cache sprites, as the following code shows.

// for speed reasons, cache the tilemap
this.tileMap.cache(0,0, 64*32, 64*32);

One of the substantial changes that I am making to all the games that I am porting is to make sure that the games work with touch interfaces. Touch input meant rewriting how the player moves as the original game used cursor or WASD for movement. The obvious solution was to simply have the player click to where they wanted to move to and head in that direction. The obstacles in the map, however, made this a bit tricky. A path-finding algorithm could have been used but I didn’t feel like writing one so I opted for a simple slide along the object system. This simply checks to see if the player is stuck and if so tries moving on just one of the axis. While this method still lets the player get stuck, most of the time the player will move around the obstacle.

if (this.canEnterTile(targX, targY, mover) == false) {
if (this.canEnterTile(targX, mover.worldY, mover) == false) {
if (this.canEnterTile(mover.worldX, targY, mover) == false) {
// we are stuck!
} else {
mover.worldY = targY;
}
} else {
mover.worldX = targX;
}
} else {
mover.worldX = targX;
mover.worldY = targY;
}

This is where things got strange. The game seemed to work fine with the change until the mouse was moved at which point the game stalled for a few seconds. Out of curiosity, I removed all the tiles from the tilemap image replacing It with a 2048x2048 shape. This solved the delay problem meaning that the problem was with how create.js handles clicking. All the tiles are being checked with a pixel accurate test to see if the tile is affected by the mouse event. The solution was to not have the game screen process the mouse event but grab the mouse events at the higher stage level then manually determine which tile was clicked on. When you are dealing with thousands of objects, different techniques must be used.

var clickX = e.stageX
var clickY = e.stageY;
this.gnome.targetX = (clickX - this.tileMap.x) / 32;
this.gnome.targetY = (clickY - this.tileMap.y) / 32;

With the major issues out of the way, this was not a difficult game to port. This only leaves the final game in the series which will be covered next week and then we can get back to my 2600 emulator.

Wednesday, December 13, 2017

Making Santa’s Snowball part 3 – tweens and gameplay

I was able to finish and post the second game in this years Santa’s trilogy and got the final game in the trilogy running. Tonight I will be cleaning up the game in ready for release next Friday. With my Christmas obligation finished I will be able to get back to the emulator, though next week will be a making of Evil Gnome’s Revenge post and the Wednesday after that will be a post about the making of Santa’s Search.

One of the important things I wanted to do while creating this project was work with tween.js as tweening is very important for animation and can be useful for all sorts of other things. The term tween comes from animation as a shorthand word for in-between. The lead animator would draw the key frames of an animation then other animators would draw all the frames in-between the two keyframes. Computers are now taking care of the in-between frames, which is why tools like Animate are still popular even though the Flash player is fading away.

Tween.js is not tied strictly to animation but can be used on any class to change the value of a variable over time. The associative array nature of JavaScript is what allows for this, but similar functionality can be done in C by using a pointer to the variable being changed. For Santa’s Snowball, tweening is only used for animation but it is not restricted to that. One thing that I could have done had I thought of it at the time was have the change of score be done at the moment of snowball impact instead of when the snowball was thrown by setting up a tween.

Tweening is an important part of the game as I use it for handling the turning of the billboards as well as for the snowballs. My billboard works by having a blank billboard shape (a white rectangle), a Santa image, and an evil Gnome image. This allows for three states of the billboard namely empty, Santa, or Evil Gnome. The show board function lets you indicate the type of board to show and hides Santa and/or the Evil Gnome based on the provided board type. The billboard, Santa, and the evil gnome are all then tweened into going from a shrunken width to their proper size. Hiding is simply shrinking the three of them which takes advantage of the fact that the unused images are already hidden. Here is the code for that.

/* shows the billboard appearing animation using the indicated type */
this.showBillboard = function(type) {
this.santa.visible = type == 1;
this.gnome.visible = type == 2;
cjs.Tween.get(this.shape).to({scaleX:.1}, 0).to({scaleX:1}, 500);
cjs.Tween.get(this.santa).to({scaleX:.1}, 0).to({scaleX:1}, 500);
cjs.Tween.get(this.gnome).to({scaleX:.1}, 0).to({scaleX:1}, 500);
}

/* shows the billboard disappearing animation */
this.hideBillboard = function() {
cjs.Tween.get(this.shape).to({scaleX:1}, 0).to({scaleX:.01}, 500);
cjs.Tween.get(this.santa).to({scaleX:1}, 0).to({scaleX:.01}, 500);
cjs.Tween.get(this.gnome).to({scaleX:1}, 0).to({scaleX:.01}, 500);
}

Testing this code did turn up a strange issue. When I had more than one billboard, all of them would show the same image. This was due to the fact that I am overriding the Easel.js’s Container class but forgot to call the initialize method. The poor way that classes are handled is not one of the better features of JavaScript but at least future versions do improve this. That being said, web assembly is probably the direction that I will be going in the future.

While tween.js does support motion paths, it does require a plugin be installed. By plugin, I mean within the create.js code not with the browser. This would not have been difficult to do, but since I would also have to come up with the curves to use I decided I would have a bit of fun and write a simple path generator for snowballs. I break the snowball path into three parts, with the line to the target being used as the base path. A third of the length is added to the point a third of the way through the line as well as 2/3 the way through to form a rudimentary curve. Each third of the line takes a slightly different amount of time to traverse so the snowball will move faster nearer to the player and slower further away. In addition to the path, the size of the snowball is also being tweened.  The code for handling the throwing of a snowball is below.

// create a path the hard way as didn't want to bother with motion paths
var endx = this.billboards[indx].x;
var endy = this.billboards[indx].y;
var dx = endx - 320;
var dy = endy - 440;
var linelen = Math.sqrt(dx * dx + dy * dy);
var thirdlen = linelen / 3;
var mid1x = 320 + dx / 3;
var mid1y = 440 + dy / 3 - thirdlen;
var mid2x = 320 + dx / 3 * 2;
var mid2y = 440 + dy / 3 * 2 - thirdlen;
this.snowball.visible = true;
cjs.Tween.get(this.snowball).to({x: 320, y:440, scaleX:1, scaleY:1}, 0).to
({x: mid1x, y:mid1y, scaleX:.25, scaleY:.25},200).to
({x: mid2x, y:mid2y, scaleX:.1, scaleY:.1},300).to
({x: endx, y:endy, scaleX:.02, scaleY:.02},400).call(this.playSplatSound).to({visible:false},1);
// animation ends with a splat so set up the 8 splat animations as well.
for (var cntrSplat = 0; cntrSplat < 8; ++cntrSplat) {
cjs.Tween.get(this.splats[cntrSplat]).wait(899).to
({x:endx, y:endy, scaleX:.02, scaleY:.02, visible:true},1).to
({x:endx+this.splatOffsetX[cntrSplat], y:endy+this.splatOffsetY[cntrSplat],scaleX:.005, scaleY:.005},300).to
({visible:false},1);
}
this.doneBillboardTime = Date.now() + 900;

I suppose I could have used a similar technique to generate the curve, but this approach works well. I am liking the Create.js library finding it not that much more difficult to use than Animate making it a better choice for developing games in JavaScript. As web assembly starts to take off, however, it is likely that my future will be either using Kotlin or C++ and compiling them to web assembly. Still, I have many flash games to port with most of them being easier to port using Create.js than porting to another language but there will be a few that may be worth the effort to re-write.

Wednesday, December 6, 2017

Making Santa’s Snowball part 2 - Multiple Scenes

Not much progress was made as I am upgrading my PVR so the weekend and last few evenings were spent getting caught up with my tv shows as I will lose everything on the PVR when the swap is done. I suppose this is a mixed blessing as I have been overdoing things lately so having a forced break was probably good but that means that the port of Evil Gnome’s Revenge may be delayed. I was hoping to post the game this weekend, and still may be able to, but working while watching TV is not very productive.  Still, either this weekend or next weekend will be the second game in my Santa trilogy where you play the bad guy and need to chase Santa’s reindeer out of their corral.

Last week we looked at the preloading of the assets. With all the assets ready to be used, we still have the problem of dealing with multiple scenes. Animate CC 2017 does not handle multiple scenes at all so my solution when creating multi-scene projects in Animate was to simply put each scene in its own MovieClip and then have the main timeline have keyframes with each of the difference scene movies in it. When you think about it, if you have total control over the stage then having a MovieClip that contains all the scenes is not necessary as you can simply have a single scene MovieClip on the stage at a time. This has the additional benefit that you don’t have to worry about removing event listeners as when a MovieClip is not on the stage it will not be getting the events. The following is my switching code:

spelchan.SantaSnowball.switchScene = function(newScene, e) {
var stage = spelchan.SantaSnowball.stage;
stage.removeChildAt(0);
switch(newScene) {
case spelchan.SantaSnowball.TITLE_SCENE:
stage.addChild(spelchan.SantaSnowball.titleScene);
break;

case spelchan.SantaSnowball.PLAY_GAME_SCENE:
stage.addChild(spelchan.SantaSnowball.playScene);
break;

case spelchan.SantaSnowball.ABOUT_SCENE:
stage.addChild(spelchan.SantaSnowball.aboutScene);
break;

case spelchan.SantaSnowball.INSTRUCTIONS_SCENE:
stage.addChild(spelchan.SantaSnowball.instructionsScene);
break;
case spelchan.SantaSnowball.WIN_SCENE:
stage.addChild(spelchan.SantaSnowball.winScene);
break;

case spelchan.SantaSnowball.LOSE_SCENE:
stage.addChild(spelchan.SantaSnowball.loseScene);
break;

case spelchan.SantaSnowball.BIG_LOSE_SCENE:
stage.addChild(spelchan.SantaSnowball.bigLoseScene);
break;

}
}

In hindsight, this is not the best way of doing this. I have come up with two better ways of doing this. The first way is to have an array of scenes and create each scene using the numerical constant as an index into this array. A simple verification that the index is valid then remove the old scene and add the new scene to the stage. Much easier code. I use numerical constants for efficiency but when you consider that this function is not being called that often and the constants are fairly large chunks of text that are transmitted it may be more practical just to use string names for the various scenes. As JavaScript uses associative arrays for variables, you could simply tie the scenes to actual variables within the class for your game. This is the approach I will be taking for the second game in this trilogy.

As can be discerned from the code, there are seven scenes that make up this game. Five of these scenes just consist of images and text with a button leading back to the title screen. The title screen has a slight bit of animation, plays a musical clip, then has three buttons for navigating to other scenes. The title screen actually is a good demonstration of one of the problems with my scene switching system. The movie clips do not restart when they are switched to. This could be forced by the switcher by simply calling a gotoAndPlay method but this would require that all the scenes have a gotoAndPlay method, which is not that big of an issue but something that needs to be considered.


An example of when you may have a scene that is not a movie clip is my Billboard class. This is created as a container that holds three objects. The class does do some animation but instead of making this animation frame based, it is controlled by separate function calls which take advantage of tweens to perform the animation. This allows for the billboards to remain open for a different amount of time based on the level of the game. I even take advantage of their flexibility by having the act of throwing a snowball adjust the closing timing of the billboard.

More on that next week where we finish off the game and take a look at the tween.js class in more detail.