Wednesday, August 31, 2011

So that is what Ultima 1 looks like…



Hello all,
Well, call me stupid, but I didn't realize that I was following the wrong version of Ultima 1! I recently received an email from Bob R. who gave me some enlightening information regarding the original Ultima. "Thanks Bob!" Ultima was not called Ultima 1 at the time because Richard didn't know there was going to be a version II or III, etc...
So Bob gave me some great documents covering the game and how to see the files on the original disk images. One really cool doc was from a magazine called CORE, which showed how to create printed maps of each of the [4] Ultima world maps.  WOW! This was truly an eye opener! I didn't realize I was biasing my version on the updated Ultima version created later.  The original version was completely coded in Applesoft BASIC and had a number of issues related to game play, which Bob pointed out, such as:

·  If you died, you were often resurrected in the middle of the ocean. You couldn't move, and you'd have to starve to death or be killed by a serpent and hope to be resurrected in better circumstances.


·  There were no Up and Down keys on the ][+. Up was "Return" and Down was "/"


·  Hit ESC after any disk changes (if you select 2 drive mode at the beginning this shouldn't be necessary)


·  Movement was SLOW, especially with the dungeons redrawing themselves line by line after every step. (FYI if you're using AppleWin it has to be set to ][+ emulation mode for the dungeons to work)

I can relate to these issues because now that I have the original disk images I have played through some of the game and seen these bugs first hand.
I also found out some interesting points regarding the world map. The world map was made up of [4] binary data files that were 64x64 tiles. In my version I create [2] binary map files that are approximately 180x82 tiles. The reason my maps are much larger is because I have two map sections plus the ocean tiles that are surrounding them.  I made it so if you move around the world map 1 you had at least 11 ocean tiles surrounding that entire map section. If you moved off the 2nd map you would cause the second world map binary file to load and movement would continue on to the second world map area. I'm not sure if I want to change this to having four separate maps. I guess it all depends on memory size and if the files fit on the disk when complete. I was once told that as long as the game plays and looks like the original than it doesn't really matter how I program the internal parts.  I have to agree on this because since I’m programming the game in assembly it is going to be different from the original from the start! 

I also need to make some major changes to the tile shapes.  The shapes I created are from the updated version and they look totally different than the original shapes.  This isn’t too big of an issue because all I have to do is draw the new ones on graph paper and update the data values.
Also, I will be posting a detailed tutorial of the entire world map movement program written in assembly very soon.  I need to clean up the variables used in the program and put more remarks in the code so it will be easier for reader to comprehend.  I will try to break down each subroutine so as to explain how the program reads the data for the tiles, creates the shapes, created the maps, places the character on the map, and how it allows you to move around the world.  This to me will be very critical for programmers because once you have this code you can literally make your own world map with your own shapes and then move around it.  I plan on making a ZOMBIE game after this one that uses a different world map and city block and towns that a player can enter to find objects and fight zombies.  The game would be similar to Ultima but with a zombie theme.  It is in the works but I need to complete the Ultima game first.
Talk to you soon,

Joe



Tuesday, August 23, 2011

New look to Ultima 1 Revisited...



Hello all,

Well I've been working on some new improvements to my Ulitma 1 Revisited program and I've added a border to the game screen as you can see here. The problem; and yes it was a big one, was I had to make major changes to the code due to the change in tile layout. Since I was initially using 20tiles x 10 tiles for the gaming screen section of the world map, the new look changed the layout to 19tiles x 9tiles! This caused some shifting of starting values and an extra Binary file for the border. I also need to condense the code for the banner to make it so I can fit it in with the initial program code.



Right now my program is too big to include the banner code. :0(



The other issue that cropped up, which I didn’t think about, was the color change due to the shift in the tile starting locations! Since I had to shift the starting location of the upper left corner by [1] byte to the right and down [1] byte to compensate for the banner, this caused a color shift in certain tiles. This affected the ocean, trees, and plains tiles.  These tiles use a set bit set to high to get the blue color.  When I ran the program for the first time all the ocean tiles came out orange due to the color shift! All the trees and plains came out purple due to their color shift! This was a major pain in the butt!



So I had to go back to these shapes and recalculate the byte setting to compensate for this shift!  This meant I had to redraw each of these shapes and redo the values that make up the byte count.



I also had to change some byte values within the main program that was used to draw the shapes on the screen.  Luckily I have good remarks in my code or it would have been a lot of searching.



I like the new look and if gives if a more game feel.  Let me know what you think!



Enjoy,



Joe

Wednesday, August 17, 2011

Ultima 1 Edvard Munch style.....


Hello everyone,

I was messing around with some of the images I created from Ultima 1 and produced this interesting take on Ultima 1 art similar to the painting Scream by Edvard Munch!

Edvard Munch eat your heart out.

Let me know what you think!!!

Enjoy,

Joe

Monday, August 15, 2011

Tutorial covering CALL, POKE, and PEEK statements...

Hello all,

Well, yesterday I was doing some testing with CALLs, POKES, and PEEKs and realized I had a less than desired understanding of these concepts and how they are used within assembly and Basic programs.  I know there is a lot of information floating around out there that covers these topics but I haven’t seen anything that gives a direct sample and explanation to how these work in an adventure game.  So I thought I would give some examples of how they work and how they are being used within my Ultima 1 revisited program!

Here we go:

A CALL statement by definition is as follows:  A CALL statement executes a machine language subroutine from a BASIC program.  Control transfers to the subroutine.  When is finishes, execution goes to the statement following the CALL.

Ok, great but what does that mean?!  Here is how I will try to explain what this means and show you how I’m using it in my program.  Within the game I have a subroutine in my assembly program that checks when the player character moves on the map and if there is a collision with different types of map tiles such as mountains, oceans, or normal movement tiles.  In the beginning part of the game I use a BASIC program to check the key strokes while on the world map of the game.  So, while I’m using the  I, J, K, and M key to move around the map, if I hit an “I” to move up I use a CALL statement within an IF-THEN statement to execute the subroutine in the assembly program.   

In essence, it passes control from the BASIC program to the assembly program and then back again.
We all remember that GET A$ in BASIC is used to track when a single keystroke is pressed and that key can be checked within an If – Then statement.

Example:  10 IF A$=”I” THEN CALL 26534

“You have to convert HEX to DECIMAL for the call statement in Basic”

The way the CALL statement works is as follows; everything in assembly is written to a specific memory location. So, I have a subroutine in assembly called MOVEUP and it starts at memory location $67A6. 

You will discover this memory address after you compile the assembly program and it gives you a listing of all the subroutine headers and there HEX location!” 

Remember that memory locations $6000 to $BFFF are free for program statements.  

Now, the CALL statement is executed when you hit the “I” key and it executes the MOVEUP subroutine at memory location “in decimal” 26534, which equals in HEX $67A6”!  Within the MOVEUP subroutine I do different things like check against tiles I shouldn’t be able to move through and against tiles I can move through.  If the tile is a collision tile such as a mountain I have a statement that writes “YOU CAN’T MOVE THROUGH MOUNTAINS!” and then it returns back to the line immediately after the original CALL statement in the BASIC program. 

If the tile is a plains or tree tile, the character is free to move and the screen must be updated with new tiles.  Since the movement is clear I use a JSR command in assembly, which is a “Jump to a Subroutine” command and update the tile and shape information for the next 200 tiles that will show on the screen.  These new tiles are drawn to the screen and once complete the subroutine returns back to the line immediately after the original CALL statement awaiting the next keystroke press.

This is how the CALL statement works with assembly from BASIC; it goes to the memory location and executes the subroutine then when it completes its task in the subroutine, it returns back to the BASIC program.   This is the link between assembly and BASIC so both programs can communicate with each other. 

The assembly program does not necessarily have to have a name header like I’m using such as the MOVEUP header but without some kind of name reference it is much harder to find the exact location of the memory address where the start of that routine is located.

I hope this tutorial was informative and gave a little better insight into how the CALL statement is used within a BASIC program to communication with your assembly program.

Joe

LAST BUT NOT LEAST.... Ultima 1 revisited program clarifications...

HI Beth,

A few things...

1.  I tested the POKE and it worked like a charm!  My initial program had the row and column values set in the main assembly program, which didn't allow for modification.  So, my test was to set the ROW and COLUMN as set variables which were equal to $1E and $1F.  I then entered in my Basic program two lines that read:

10 POKE 30,10
15 POKE 31,11

I did these lines before the BLOAD of my main assembly program and it worked!

The main character shows up on the map in the location set by the poke statements!   I tested this with different values and the character started in different locations on the map.   I love it when things work like they are suppose to.  So now I think I can use a 2 dimension array in basic with X,Y to track the main characters movement and when the player wants to save the game I can PEEK these values and BSAVE them, right???   Also, I know that the first Page of memory is 256 byte locations, do you think I should use these bytes for all of my variables or is there a better location from memory to use??  So now that I know how to use the POKE statement in my basic program I was thinking that I could use these locations for the variable such as player character map location, hit points, gold, experience, food, monster and transportation locations, etc...  right???  Then I was also thinking I could save all these values with a BSAVE when the player wants to quit and save his place in the game.  Is this the correct way of doing this?

Joe, yes, that’s exactly how you pass information back and forth, as well as loading and saving the data. However, be VERY careful with using the “first page of memory”. That is referred to as “zero-page” memory and it’s a very valuable and constrained resource. Here’s a link to how it’s being used by the system:


You don’t want to use any locations that might be in use by something else, as those may change your values or you may corrupt what it is that they do. You should reserve your use of zero-page memory for critical timing routines where you optimize using fast instructions that rely on zero-page indirect addressing, for example. For all of your program variables, find a higher location in memory and use PEEK and POKE on those addresses. (This gets back to figuring out a memory map so you can know exactly where in memory you’ve allocated all your variables, your data, your programs, etc.)


2.  Concerning the towns and castles:  Since there are probably 8 to 10 castles and 30 to 40 towns, which all seem to look slightly different.  I was thinking I SHOULD do them in assembly to save space as you mentioned but I still have the issue of the number of shapes that will be created for all these places and how do I use data compression?  The world map was easier because I only had about 12 or so main tiles on the map, less than 15 total, but the town and castle have way more.  I won’t be able to use the data compression even if I create a separate assembly program for each separate town or castle because some of the towns look like they have more than 20 shapes that make up the tiles for the town!  So that bring me to the main question:  Should I just do them in assembly and use normal data strings which use a byte for each shape #, like I did in the beginning.  This way I could create one assembly program that would generate the images for all of the towns and castles  OR should I do them in BASIC, which would use a single file that had all the shapes necessary for all the castles and town and create a ransom assess files that would have a text file that used three values for each shape, such that it would have the X,Y, and shape # for each shape in each town/castle.    Which do you think would take up more space; the BASIC program of the Assembly program????  I know that space is a critical issue and I would hate to start spending a bunch of time of one path then realize I should have done it the other way just to save a bunch a memory!!!  

Well, I think you’re fine with doing it in Basic, but I don’t see why you need three bytes for each shape. Why not just store the data in data strings like you store uncompressed maps, so each byte is the tile # and the X,Y is implied by the location of the tile # in the array? You just lay out 20 x 10 tiles for 200 bytes, for example. You could still randomly access the file every 200 bytes or so to pick off the specific town/castle you wanted, or you could have a bunch of different little data files. Regardless of whether you use basic or assembly you should keep the X & Y out of the data, imho. Save that space at least! I don’t think you need to bother with compression, since you could load in the town/castle instead of an outside map when you switch between modes, for example.

3.  I think I got where you are coming from concerning monsters and transportation tiles and the memory they use but let me reiterate just to make sure.  Since I plan on using individual memory locations for the locations of transportation tiles and monster tiles, similar to how I did the ROW and COLUMN deal.  Did you mean I should set aside a number of these locations just for a set amount of these items locations on the map?  Meaning, if I use the first page of memory and set aside 10 or 15 for each transportation tiles, which would mean two byes needed for each tile, which is basically for the X and Y location values, correct?  This way I could create arrays for each new monster or transportation tiles and save their location in each byte with their X and Y values.  Then I would able to check these values on each character move and if they fall into the map screen parameters, I could use them to draw their location on the map.   Is this what you meant or am I way off???

Well, again, don’t use the first page of memory. Find another block somewhere for this type of data. I would argue you still need 3 bytes for each, one byte for the type of transportation (e.g. 1 = cart, 2 = horse, 3 = ship, etc.) and an X, Y for that as well. Otherwise yes, what you say sounds correct!

4.  Concerning front and back buffers:  I understand now what you mean about using these two pages of graphics and will start testing them.  I know now that I have to add Page 2 "$4000 and up" graphics memory locations right after my Page 1 graphics locations used for indirect indexing.   After that I will have to create another addition to my program to incorporate these two page swaps.  The question I have is:  You say to draw on screen two that is not seen by the user but how do I draw on the screen when I don't know which direction the player wants to go?  My understanding was I would start with the initial map view on Page 2, while Page 1 is blank!  Then show Page 2 and when the player makes a move I would draw on Page 1 then switch them.  Is this incorrect?  If so, I'm not sure how to implement the page flipping for the game.  I see there being a delay between page flips due to the amount of time it takes to get the new information concerning the direction move.  I also see how the 90% could make a huge difference with speed due to the page flip delay!!!  I need to figure out how to get the 90% shift working because I already notice that the redraw is not fast enough!!!  I will do more testing on the 90% map shift because I have to get this working in the program and then utilize page flipping at its most!

It’s easy for me to say, but don’t overthink this too much. It’s actually pretty simple.

1.       Get user input for direction they want to move
2.       Copy the 90% of the front buffer to the new location in the back buffer – shifted by user input
3.       Draw the remaining 10% of the back buffer required
4.       Flip the pages
5.       Goto 1

Since you aren’t trying for constant animation, you don’t have to keep things running. You can always wait for use input. If you were animating (say you wanted to have the water tiles always moving so it looked like all the waves were in motion) you wouldn’t wait for the user input at step 1, you’d just check to see if there was any.

To break this down further:

Step 2:
You can literally copy screen-memory lines from the front-buffer to the back buffer. You just need to copy them from the current location to the shifted location. So instead of copying from $2000 to $4000 directly, you might copy from $2000 down a full tile to $4080 or whatever it is in the event the user decided to move up.

Step 4:
Flipping the pages is very fast. All that happens here is you switch which hi-res screen the user is seeing. As I recall, this is done like so (where K can be 0 or 1):

POKE49236+K,0                               //set hi-res graphics page (K)

And to keep things consistent, you might want to follow it with this:

POKE230,32+(32*(K=0))                 //set hi-res plotting page (for basic, 32 = page 1, 64 = page 2)

And of course this clears the current plotting screen to black (if you need to do so)

CALL-3086                                       //clear current hi-res screen to black


5.  I had an idea that I wanted to get your opinion on:  I was thinking of using a main location array in the BASIC program that would have the main character map location tracked at all times.  This array would basically have the X,Y coordinates of the characters location on the world map.  My thinking was I could use this array values for a number of issues:

 A.  I could have all the town, castle and signpost X,Y locations on the world map saved in a data file and check after the player hits the ENTER key, which is the key used to enter these locations.  Once the enter key is hit I could check against the players X,Y position and if it matches an X,Y value within the database I would know exactly which town, castle, or signpost for that matter, which the player was trying to enter!!!  Then all I have to do is a simple CALL statement to the portion of the assembly program that draws that town or castle of updates the quest when the signpost is visited.  What do you think?? 

B.  Also this would work out great for when I want to board a transportation tile because when the player hit the "B" key for board I could check this value against the values save for all the purchased transportation tiles on the map!!  What do you think?

C.  Also, also... "hehe"   I what be able to use this X, Y value for the monsters to track too.  I know in the game that if you move on the map while a monster is near it will move after you.  So I thought that I could use this X,Y value to help the monster's track the player’s location and attack this location accordingly.  Again, what do you think?

All of the above sounds good! I worry a bit when you say “data file”. As long as you mean a data block in memory, cool. You don’t want to be loading an actual disk file every time the player hits ENTER, though! I’m assuming you meant in-memory locations.

Also, as a bit of an aside, check out this article:


I realize you’re not really concerned with how to do smooth animation on the Apple ][ (at least not yet), but this goes into that, which is a whole topic in and of itself. What I thought you might find immediately interesting was to check out how this program interfaces with its assembly bits. It involves a fairly integrated Basic and Assembly program which both read/write data used by the other, with calls from the Basic program to the Assembly program(s). Sound familiar? Check out how they made it work and maybe it will help further inform your own efforts!



I know these are a lot of questions but what better way then to go to the source!!!

Thanks again,

Joe

MORE, MORE CONT.... program changes and updates...

Hi Beth,

You are right, there is a space part to the game where you travel in a space ship and have to doc to a space station. Then you enter hyperspace with one of two or three types of ships to get to the wizard. This doesn't look too complicated but I will leave that for last.
I was able to create one of the towns in assembly just to see if I could do it but I don’t think it will be practical. I have a question regarding the towns and castles: Q. On map one, "There are 4 total maps in the game!" there are 8 towns and 2 castles and they all look different! If I keep this numbering throughout that would make 24 towns and 8 castles! I think they are all different but I'm not sure because I have been able to take a look at each one. The problem I see with using assembly is if I use the same data compression method as in the world map I will have a problem with needing more shapes then 15! I think because of this issue it does seem to be more practical to make the towns and castles in basic using a character generator and maybe text files. What do you think?
Would basic be more data on the disk then assembly?
This make sense when you talk about page flipping because then I would be using the low res graphics screen and the HGR2 screen would be available to me for page flipping. I still am a little vague on this page flipping process.   So to understand what you are saying: 
1. Show user front-buffer graphics screen -  “I awesome this is the main world map screen?”
2. Draw all terrain on back-buffer graphics screen – “What is back buffer graphics?”
3. Draw transportation at locations on back-buffer – “again, What is back buffer?”
4. Draw monsters at locations on back-buffer
5. Draw player in center tile of back-buffer
6. Switch user to be looking at back-buffer. Back-buffer is now front-buffer. Front is now back.
7. Goto 2.
Is the back buffer page 1 and front buffer page 2 graphics screens?
Also, if I am going to pass data back and forth from basic to assembly using POKE and PEEKs, Does this mean for example:  Let’s say I’m using X and Y for grid coordinates on the map and I need to have the character start at x=60, y= 35.  I get the impression that I would use the first page of memory like $1E and $1F for values stored in the game.  So if I set the following variables in my code would this be correct:
Row                 equ      $1E
Column            equ      $1F
Then in basic I could POKE the value 60 into $1E and 35 into $1F before I do the CALL statement and the main character would be all ready to start at a new location on the map correct?
This seems logical.
Thanks
Joe

+++++++++++++++++++++++++++++++++++++++++++++++++++

Hi Joe,

I think you have a lot more flexibility in how you handle the towns/castles. You’ve sketched out one idea, using the character generator and text files. I think that’s totally reasonable. You could load each one individually as needed.

The data itself won’t be any bigger. However, Basic is a big fat pig. It takes up space just to load the text that makes up the Basic. It takes up memory and CPU overhead to run the Basic interpreter. So from that perspective, you will take up more space on the disc and in memory using Basic. Hopefully that won’t be a problem! I don’t think it should be, it just comes down to how you structure things and that’s on you.

As to terminology, “front-buffer” and “back-buffer” are video pages 1 and 2. However, whichever one the user is currently seeing is always the front buffer. The other one (the one you always draw on) is the back buffer. So front and back alternate between pages 1 and 2. I’ll lay it out explicitly:

Game Frame 0 Render cycle: 
Front buffer – Visible to user – Screen 1 - black screen
Back buffer  - Not visible to user – Screen 2 – drawing Game Frame 0

Game Frame 1 Render cycle:
*flip frames*
Front buffer – visible to user – Screen 2 – has Game Frame 0 on it
Back buffer – not visible to user – Screen 1 – drawing Game Frame 1

Game Frame 2 Render cycle:
*flip frames*
Front buffer – Visible to user – Screen 1 – has game Frame 1 on it
Back Buffer – not visible to user – Screen 2 – drawing Game Frame 2

Etc.

As far as the Peek/Poke thing goes, you’re absolutely right. I’m not sure what address you want to use for your values (that’s up to you), but you have the right idea for communicating between the two.

-          Beth

MORE CONT.... program changes and updates...

Hi Beth,

I guess I'm confused...   I thought that I would use the Page2 graphics screen for the towns and castles!?   The reason I thought this was because if you went to page 2 for a town, when you left the town you could go right back to page 1 and nothing would have changed and you wouldn't have to draw or shift anything to get the same location on the map that the character was on before he went to the town or castle.  Is this wrong? 

This brings me to the issue of the towns and castles... I'm having a hard time trying to figure out how I should do the towns/castles.  Do I program these in assembly also and make either individual Bsaves for each town/castle or one big file for all the towns and one big file for all the castles?    OR, should I do the towns/castles in Basic using generated character sets that have the town/castle graphics, which would replace the lower case character set.  "These characters aren't used in the game and could be redrawn for town and castle graphics. 

Any idea what the best way to go regarding the towns/castles? 

I think I understand your information below regarding the monsters and transportation devices but I will need to test it out and will I still be able to do this if I plan on using page 2 graphics screen for towns and castles?

Which part of the game do you think uses actual basic coding?  I don't think he programmed the entire game of Ulima 1 in assembly since he didn't know how to program in assembly till Ultima 2 or 3.  His friend Ken Arnold was an assembly programmer who did the tile map part of the game but I think the map and the dungeons are the only part that was programmed in assembly.  Not sure though!

The hard part of this for me is I'm trying reverse engineering the game and figuring out which parts of the game are in assembly or basic and I have no idea which would have worked the best.  I know speed is the biggest consideration but menus, town, and castle movement doesn't have speed issues.  I'm feeling as if I'm getting lost in the minutia......

What do you think?

Thanks

Joe

+++++++++++++++++++++++++++++++++++++++++++++++++++

Joe,

Hey there! No worries. Like you noted earlier, there are a lot of ways to accomplish any given programming task. As long as it works at the end of the day, it’s all good.

However, I think there’s no reason to have one page for exterior and one for interior. You could easily manage the transition out of a town by simply doing the global-redraw thing on the back-buffer and then showing that and resuming a normal page-flipping scenario. Personally, if I were implementing, I’d have the page-flipping thing using both video pages for outside to keep everything simple and then I’d use one of the two pages for the town. When it was time to leave town, I’d just launch the “outdoor app” and go back to page-flipping.

If you aren’t page flipping you’re going to have to make your code significantly non-optimal, in that you have to do the monster/transport array lookup for every tile you draw. That will blow the whole reason you did all that assembly work in the first place, imho. Alternatively, you can always draw the monsters/transport afterwards but you’ll end up with a nasty refresh flicker.

As to how to implement the town/castle, they’re pretty easy to do in Basic and with the generated character sets, you might as well go there! As you note, there’s no speed issue there. You’ll just have to figure out the best way to transition your drawing algorithm and your data storage between the two modes. In a way, it’s like two totally different games. You might even try to handle it that way – run the towns/castles in one program (basic) and then launch an “outdoor” program with your assembly when you go outside, and vice-versa. Keep the problem separated until you know what bits you need to optimize and constantly keep in memory (e.g. player statistics).

I’m sure he did the town/castle in basic. I’d also bet he did the dungeons in basic as well. There’s really at least three programs here – outside (assembly), dungeon and town/castle. Also, was there a shooter/spaceflight thing in Ultima 1 or am I remembering wrong? I know Ultima 2 went into space, but for some reason I’ve got this screen memory of manipulating a little spaceship around in Ultima 1 and going “pew pew pew”. Maybe I’m crossing old games. Anyway, if present, that would make 4 programs…

-          Beth