Jump to content
IGNORED

Using the score for a game title or inventory strip


SeaGtGruff

Recommended Posts

This is something I'd been wanting to do, so I did it. :) The demo program I wrote may be a bit hard to follow, so I've included a lot of comments to try to explain it.

 

I've modified three include files: 2600basic.h, std_kernel.asm, and std_overscan.asm.

 

Note that I've modified the 0.99c2 patch versions (the ones I posted for Superchip bankswitching), so don't apply this patch to anything except 0.99c2!

 

If anyone wants the modifications for another version, just let me know which version you're using, and I'll post the modifications for that version as well.

 

Basically, you add the following statement anywhere in your program to tell bB that you want to use the "userscore" option:

 

  dim userscore = y

It doesn't matter what you dim userscore to, the important thing is that you dim it to something so bB will compile your program with the userscore modifications.

 

What this does is let you define up to 256 different 8x8 sprite objects that you can display in place of the usual score display. (You can actually define more than one set of 256 objects if you want, such as 512 objects in two sets of 256 objects, as long as you manage everything appropriately in your program, but I'd rather not get into that right now, since it's probably going to be difficult enough for anyone to use 256 objects!)

 

For example, you can define six sprite objects that spell out the name of your game, as long as you can fit it into a 48-pixel-wide image. In my demo, I do this to spell "Reventure!" in the score.

 

You can also define various "inventory" objects that can be selectively displayed in the score. For example, if you define 16 inventory objects, you can display any of them as a "score digit"-- i.e., up to six selected objects. In my demo, I do this to display a key, a dagger, and a sword. Of course, you'll also want to define a "blank" object for any empty inventory slots.

 

If you want, you can define each object twice-- once with "normal" graphics, and then a second time with "inverse" graphics-- so that you can display each object as either a "highlighted" ("selected") or "unhighlighted" ("deselected") inventory item, as long as you manage the logic for moving the inventory "cursor" and displaying the correct version of each object (i.e., normal or inverse). In my demo, I do this to move a cursor left and right in the inventory strip. Be warned, though-- the logic for moving the cursor is pretty strange, due to the way bB handles the scorepointers.

 

Finally, you can switch between the normal bB score display and your custom userscore display, without losing the values for either one! For example, you can display a game title in the score on your startup screen, then switch over to the normal numeric score display once the game begins. Or you can display the normal score display in your game, then temporarily switch to some kind of text message or other userscore display, and then switch back to the numeric score, without losing the value of the numeric score. Performing math operations on the numeric score doesn't affect the userscore display, so you can increment or decrement the numeric score whether or not you're actually displaying the numeric score, then switch to the numeric score whenever desired to display the new score value. In my demo, I set the score to 123456, then let you switch between the title and the numeric score, or between the inventory strip and the numeric score, using the joystick (press up to see the title or inventory strip, and press down to see the numeric score). The demo starts up with the title, and you press the fire button to go to the inventory strip. If you want to go back to the title after you've switched to the inventory strip, you'll need to press reset.

 

This modification is achieved by using two of bB's "available" variables-- aux2 and aux3. These are redefined to be userscore_page and userscore_flag, respectively.

 

The userscore_page variable is used to point bB to the page where the score's sprite graphics are located. Normally, bB sets the hi-byte of the score pointers to the page where the default score graphics are located. But if you specify the userscore option (with "dim userscore = y"), you can use userscore_page to point bB to the page where you've defined your custom sprite graphics. If you happen to know what the page number is, then you can say "userscore_page = xxx", where "xxx" is the decimal or hex value of the page number. However, since the page number of your userscore graphics could change as you add code to your program, it's actually easier to do the following:

 

  rem * set userscore_page
  asm
  LDA #>my_userscore_graphics
  STA userscore_page
end

In this example, "my_userscore_graphics" is simply the name of the label you're using to mark the beginning of the userscore graphics data area. Yes, this example uses inline assembly (and there's a lot of other inline assembly code snippets in my demo), but you shouldn't let that intimidate you.

 

The userscore_flag variable is used to switch the userscore display on or off, so you can switch back and forth between the userscore display or the numeric score display. If you want to turn on the userscore display, just say "userscore_flag = 1" (or any other non-zero value between 1 and 255). Likewise, if you want to turn off the userscore display and show bB's normal numeric score, just say "userscore_flag = 0". When userscore_flag is set to 0, bB uses the page number for the default score graphics digits, and updates the score pointers during overscan based on the current value of the score. But when userscore_flag is set to any value between 1 and 255, bB uses the page number that's in the userscore_page variable, and bypasses the overscan routine where the score pointers get updated (so your userscore display won't get destroyed). If you've previously set userscore_flag to 1 to display the userscore graphics, you can change it to 0 and the numeric score will be restored automatically. However, if you change userscore_flag from 0 to 1, you'll need to reload the values of your userscore sprites (or "item numbers") back into the scorepointers before you call drawscreen again, because bB can't load them back automatically for you.

 

Note that since all of the score graphics data must reside on the same page, your userscore sprite data must fit within 256 bytes, and must not cross a page boundary. If you're defining only a few items (e.g., six sprite shapes for a title display"), you might not have to worry about that if your userscore graphics just happen to fit within a page without extending into another page. But to make sure you don't have a problem with page boundaries, the best thing to do is to include an "align 256" statement just before the beginning of your userscore graphics data, as follows:

 

  asm
  align 256
my_userscore_graphics
; insert up to 256 bytes for your userscore graphics data here, 8 bytes per object
  BYTE %00111100
  BYTE %01100110
  BYTE %11011011
  BYTE %11111111
  BYTE %11010111
  BYTE %11010111
  BYTE %01111110
  BYTE %00111100
; etc.
end

Note that the "align 256" statement must be coded as an inline assembly command. Also, it's best to define the userscore graphics data with inline assembly, rather than with bB's data command, since bB's data command has to insert code for telling bB to skip over the data. However, if you're going to define less than 256 bytes of data for your userscore graphics, then it's okay to use bB's data statement, as follows:

 

  asm
  align 256
end
  rem * insert up to 256 bytes for your userscore graphics data here, 8 bytes per object
  data my_userscore_graphics
  %00111100
  %01100110
  %11011011
  %11111111
  %11010111
  %11010111
  %01111110
  %00111100
end

Since your userscore graphics must fit on one page (or in one block of 256 bytes), that means you can define up to 32 sprite shapes on each page, and can select from only 32 sprite shapes at a time. Thus, even though you can have up to 256 sprites or objects (because each "userscore digit" or item number can be a value from 0 to 255), you can't choose from all 256 items at once. Instead, you can define up to 8 pages of userscore graphics shapes, and display any of the 32 shapes on a page at once. For example, you can have one page of 32 items for your game title and brief text messages (e.g., "Game Over" or "You Won!"), and another page of 32 items for inventory objects, etc. When you want to display objects from a particular page, you must set the userscore_page variable to the desired page number.

 

I've incorporated the modifications so that your bB programs will compile as normal if you don't use the userscore option, with one small exception-- I tweaked the positioning of the score display so that it lines up in the center of the screen, which adds a few more bytes to the std_kernel.asm code. Normally, bB's score display is positioned a little bit to the right of center, which has always bothered me a little bit, although it isn't very noticeable unless you've drawn a playfield, in which case you can see that the score is a little off-center. If you use this 0.99c3 patch, the score will now be centered.

 

If anyone has questions about using this modification in a program, just post them and I'll try to help as much as possible. Aside from using the score to display a game title or an inventory strip, another idea might be to display up to six "lives remaining" icons. However, you can't display the numeric score and the "lives remaining" at the same time.

 

MR

 

post-7456-1158541149_thumb.jpg

 

post-7456-1158541169_thumb.jpg

 

post-7456-1158541188_thumb.jpg

 

post-7456-1158541209_thumb.jpg

test_inventory.bas

test_inventory.bas.bin

userscore_patch_0.99c3.zip

Edited by SeaGtGruff
  • Like 1
Link to comment
Share on other sites

This is fantastic. I've been torn between title/demo graphics and health bar OR score, now I don't have to worry about it. Plus when I picked the former, I had only 10 characters to work with. I was just trying to work this out last night and figuring a compromise would be the extra character trick posted for a2600l. So glad to not have to worry about it anymore, and have all the extra characters on top of it.

 

Thank you x 1000

Link to comment
Share on other sites

This is fantastic. I've been torn between title/demo graphics and health bar OR score, now I don't have to worry about it. Plus when I picked the former, I had only 10 characters to work with. I was just trying to work this out last night and figuring a compromise would be the extra character trick posted for a2600l. So glad to not have to worry about it anymore, and have all the extra characters on top of it.

 

Thank you x 1000

I'm glad you like it, even though my demo wasn't much to look at. And to be honest, I'm not really too keen on using the score for a game title, because it's so small (short) and so low on the screen. I'm actually thinking of writing a new kernel specifically designed for game title screens, with a much bigger title in the center of the screen, including additional lines for things like the copyright message, or "press fire to begin," or the game difficulty level picker. The userscore stuff could still be used for things like inventory strips, or "lives remaining" icons, etc.

 

MR

Link to comment
Share on other sites

I still tend to use the playfield for the actual title, but I use the score as a marqee to scroll things like "2006 MAUS GAMES", so it's great to add to the title screen for me.

 

The in-game applications are huge though, especially since it can easily hold an entire alphabet, an inventory, a command list, a health bar, and the score on top of that.

 

It would be gross to program and to use, but it could even be used for graphic adventures with actual type-in text, ie selecting an eye icon for look, then up-downing each letter in a word, to create 'look at door' for example. Six letters limit that somewhat, but still, it's possible now. EDIT - actually the decent way to do this would be with icons such as look and a cursor, that shows the word for each item in the score bar as the cursor moves over it, then marquees resulting text. If you can find a way to build in text scroll so you can create data lists and scroll the symbols/letters corresponding to each number in the data list, at a certain speed, this would be really effective.

 

PS - Thanks for centering the score, that always kinda bugged me.

Edited by MausBoy
Link to comment
Share on other sites

  • 9 months later...
  • 1 year later...
I'm actually thinking of writing a new kernel specifically designed for game title screens, with a much bigger title in the center of the screen, including additional lines for things like the copyright message, or "press fire to begin," or the game difficulty level picker. The userscore stuff could still be used for things like inventory strips, or "lives remaining" icons, etc.

Do you think you could find the time to do what you mentioned here? Our bB games would look more polished. No more horizontal titles or blocky playfield titles. It would be great to have those additional lines for copyright message, options menu, and so on.

Link to comment
Share on other sites

That sounds awesome too. I would love a title screen kernel.

 

I'm actually thinking of writing a new kernel specifically designed for game title screens, with a much bigger title in the center of the screen, including additional lines for things like the copyright message, or "press fire to begin," or the game difficulty level picker. The userscore stuff could still be used for things like inventory strips, or "lives remaining" icons, etc.

Do you think you could find the time to do what you mentioned here? Our bB games would look more polished. No more horizontal titles or blocky playfield titles. It would be great to have those additional lines for copyright message, options menu, and so on.

Link to comment
Share on other sites

  • 2 weeks later...
This is freakin sweet. This is just what I wanted if it were for 1.0.

 

I had an idea to keep score, but when a new level started it would say LEVEL 1 or LEVEL 2, etc in the score area. Now this is possible.

Okay, I just reviewed what I'd done before, and it was simple to add this modification to bB v1.0. I've made a few changes in this new version.

 

Following is a description of how to make the new modifications yourself, in case anyone ever wants to put them in other versions of bB.

 

std_kernel.asm

 

This file contains the code for bB's standard "canned" kernel. There are or have been several versions of this file, including versions modified by other people for special enhancements. I like to rename the various versions of this file to something unique, to keep them separate and distinct. The std_kernel.asm file I modified for this version is dated 12/28/2007, so I've renamed the modified file as std_kernel_20071228_userscore.asm. After you download the new modified file, you can rename it back to just std_kernel.asm if you wish. (If you *don't* rename it, then you'll need to make your own includesfile that uses the new file name.)

 

However, if you're currently using some other version of this file, and want to modify it for this new userscore enhancement, just open it up in an editor and find the following line:

 

  lda #>scoretable

Replace that line of code with the following five lines of code:

 

  ifnconst userscore_page
lda #>scoretable
 else
lda userscore_page
 endif

(In my original modification, the first line was slightly different; but this new version is more flexible.)

 

std_overscan.asm

 

This file contains the code for bB's standard "overscan" routine. The version that I modified was dated 04/19/2007, so I've renamed the new file to std_overscan_20070419_userscore.asm. You can rename it back to std_overscan.asmif you want-- but again, if you *don't* rename it, then you'll need a custom includesfile.

 

If you want to modify some other version of this file, open it up in an editor and find the following line:

 

;set score pointers

Directly below that line, add the following four lines of code:

 

  ifconst userscore_flag
lda userscore_flag
bne vblk
 endif

(Again, the first line was slightly different in my original modification; but this new version is more flexible.)

 

That's all there is to making the modifications! The rest is a matter of putting the modifications to use in your bB programs.

 

In my original post, I said you need to add a line that says

 

   dim userscore = y

This is no longer true! This new version doesn't use the "userscore" keyword-- instead, it uses just the "userscore_page" and "userscore_flag" variables. In my original modification, these two variables were defined in a customized 2600basic.h file-- but now you have to define them yourself. The reason for this is threefold-- (1) the newer versions of 2600basic.h already define the aux3 for other purposes, and I didn't want to interfere with them; (2) now you can decide which variables you want to redefine as "userscore_page" and "userscore_flag"; and (3) now you can define one or the other, or both. In other words, now this modification has been split into two separate enhancements, and you can either use one or the other by itself, or you can use both of them together.

 

The "userscore_page" enhancement lets you point the score display to a different set of score characters, but it doesn't prevent bB from setting the score pointers. For example, you could make the digits of the score change to a different appearance. I still need to work up an example of this, but you would activate this feature by adding this line:

 

   dim userscore_page = a
  rem * or whatever variable you want to use for this

The "userscore_flag" enhancement lets you flip between the standard score display and some other display. What it does is prevent bB from setting the score pointers itself, so you can set them to whatever you want, and then when you're done displaying your custom display, you can switch back to the standard score display. Again, I need to work up an example, but you would activate this feature by adding this line:

 

   dim userscore_flag = b
  rem * or whatever variable you want to use for this

Of course, you can also activate both features at once:

 

   dim userscore_page = a
  dim userscore_flag = b
  rem * or whatever variables you want to use for this

Then you could use the methods I demonstrated in my original post.

 

Michael

 

Edit: I guess it helps if I actually attach the files. :roll:

userscore_bB_v1.zip

Edited by SeaGtGruff
Link to comment
Share on other sites

  • 4 weeks later...
  • 3 weeks later...
I haven't been able to get this to work with 1.0 at all, any chance of a demo? I got the original sample to compile, but it only shows "123456" as the score.

You'll need to modify the original example slightly to make it compatible with the new includes. Basically, you just need to replace the following line:

 

   dim userscore = y

with these two lines:

 

   dim userscore_page = x
  dim userscore_flag = y

However, when I ran the program I realized that the modified std_kernel.asm file has two timing problems. One problem is my fault, but the other problem existed in the original std_kernel.asm file.

 

To fix the problem that's my fault, open the modified std_kernel.asm file (that was changed according to the instructions I posted on 11/14/2008) and search for this line:

 

 sta temp5,x

Cut that line and paste it immediately after both the "ifnconst" and "else" lines that are just below, then take the ",x" off of the second one (the one you just pasted inside the "else"). If you like, you can also indent the two lines you just pasted, so they line up better. When you're done, that section of code should look as follows:

 

 lda scorepointers+5
; ldy temp5
; sty scorepointers+5
ifnconst userscore_page
sta temp5,x
lda #>scoretable
else
sta temp5
lda userscore_page
endif
sta scorepointers+1
sta scorepointers+3
sta scorepointers+5,x
sta temp2,x
sta temp4,x
sta temp6,x

Unfortunately, the other problem-- the one that was already there in the original std_kernel.asm file (dated 12/28/2007)-- isn't so easy to fix. Basically, the last digit gets updated 1 color clock too late. This doesn't show up with the standard score characters, because the first column of pixels in each character is always blank. I'll need to reverse-engineer the 6-sprite score code from that kernel to figure out the best way to fix the timing problem without messing anything else up.

 

Michael

Link to comment
Share on other sites

  • 6 months later...

Okay so this seems to work fine in the standard kernel and with bB 1.0, but I am having trouble adding an inventory strip to my game project using the multisprite kernel. :x

 

I have examined the comparable areas of the code in both the multisprite_kernel.asm and the std_kernel.asm that has the modified code with the userscore variables added, but now my eyes are going buggy and I don't what I need to add or change as it appears the score routine is handled differently with the two kernels.

 

As I understand it I have them included in my bBasic code, but I need not add userscore_flag or userscore_page to the 2600basic.h like in earlier examples, because the aux variables are being used by other features now, so I haven't modified that includes file, and the multisprite kernel does not make use of the standard kernal.asm though I went ahead and modified it with the inventory in mind for other projects ( and the original files saved in a separate folder )..

 

So, anyway.. Has anybody had success with adding this userscore routines to the multisprite kernel? I would really like to keep the multisprite features for this particular game I am working on. Any help or suggestions are appreciated!

 

-Weston :cool:

Link to comment
Share on other sites

  • 10 months later...

Okay so this seems to work fine in the standard kernel and with bB 1.0, but I am having trouble adding an inventory strip to my game project using the multisprite kernel. :x

 

I have examined the comparable areas of the code in both the multisprite_kernel.asm and the std_kernel.asm that has the modified code with the userscore variables added, but now my eyes are going buggy and I don't what I need to add or change as it appears the score routine is handled differently with the two kernels.

 

As I understand it I have them included in my bBasic code, but I need not add userscore_flag or userscore_page to the 2600basic.h like in earlier examples, because the aux variables are being used by other features now, so I haven't modified that includes file, and the multisprite kernel does not make use of the standard kernal.asm though I went ahead and modified it with the inventory in mind for other projects ( and the original files saved in a separate folder )..

 

So, anyway.. Has anybody had success with adding this userscore routines to the multisprite kernel? I would really like to keep the multisprite features for this particular game I am working on. Any help or suggestions are appreciated!

 

-Weston :cool:

Here's a multisprite kernel hack that supports the userscore option, but-- like the one for the standard kernel in version 1.0-- it suffers from a timing issue in the score routine.

 

Michael

multisprite_kernel.zip

Link to comment
Share on other sites

  • 9 months later...

Thanks, Michael, for your multisprite mod. :)

 

Okay, my new hurdle I have attached below. You can see in the pic that the inventory strip is working ( the yellow bar on bottom ) with the multisprite kernel, except that the numbers from the score pointers don't show up! It is just a solid yellow, as if it can't find the number definitions...

 

I have included the basic file and bin file if you or others can take a look. Note that I am using the modified multisprite kernel you provided when I compiled it and just added elements needed in a multisprite kernel game with your test program to get things going. The screen is populated with all the sprites, missles, and ball. I used some from the game I am working on.

 

It runs fine, just like your standard kernel version. Joystick up/down, Joystick left/right to change/highlight the items, press fire or reset to change to "Reventure!", but the code is not remembering where the batariBasic score graphics are located, or something.

 

Any help is appreciated, as I would like my game to be able to switch back and forth from score to inventory strip, etc. Thanks. :)

 

Weston 8)

post-2955-129838079333_thumb.png

test_inventory_multi.bas

test_inventory_multi.bas.bin

Link to comment
Share on other sites

The only thing I can think of is that it's something to do with the address of the scoretable. When I load the bin file into DIS6502, it looks like the scoretable starts at $FF6C. Can you post a zip with the std_kernel.asm and std_overscan.asm include files that you're compiling with?

 

Michael

 

Edit: Nevermind, that was a dumb request for me to make, since you aren't using the standard kernel. Are you using the hacked multisprite kernel that I'd posted?

Edited by SeaGtGruff
Link to comment
Share on other sites

Hey Michael, no worries.. :)

 

Yeah, I am using the modified multisprite_kernel.asm that you posted. I put it in my "includes" folder in place of the original.

 

When I look at the generated asm file of my game, I see the "userscore_flag" and "userscore_page" lines inside the multisprite kernel code (not just in the bB.asm section), so I know it found it when it compiled. Nothing jumps out at me that is wrong or missing in the asm listing..

 

Any other ideas? :)

 

-Weston

Edited by Gateway
Link to comment
Share on other sites

In multisprite_kernel.asm I changed this...

 

ifnconst userscore_flag
       jsr setscorepointers
endif

 

...to this...

 

ifnconst userscore_flag
       jsr setscorepointers
else
       lda userscore_flag
       bne skipsetscorepointers
       jsr setscorepointers
skipsetscorepointers
endif

 

...and your basic then worked as expected. So the score pointers are being stepped on somewhere.

  • Like 1
Link to comment
Share on other sites

Thanks to Michael for looking over the problem, and thank you RevEng for your modification. I changed my multisprite kernel to include your code and the score works now as expected. Switching between inventory, the title, and numbers for the score works fine now (the score display timing glitch notwithstanding) :)

 

Now I am looking to expand beyond 4K for my adventure game. Do you guys have recommendations about the best place to put "bank 2", etc, within the code? I understand all of the graphics get put in the last bank, but the main game loop should be in bank 1?

 

I will keep experimenting. So far, the program just crashes when I set romsize 8K and add bank 2 near the end of all the code..

Link to comment
Share on other sites

The only requirement should be placing the graphics data into the last bank, as you noted.

 

I switched over your example code to 8k, and it worked for me. I did need to throw a "includesfile multisprite_bankswitch.inc" at the top of the basic to get it to compile, but after that it ran ok.

 

Are you getting a normal sized binary file?

Link to comment
Share on other sites

Yeah the binary is 8k.I noticed that I didn't have the "multisprite_bankswitch.inc" in my code, that you mentioned, so I put that at the top and the program runs fine now, except..

 

I had added Michael's routines for a vertical scrolling playfield and had that working with 4K, but now it is having issues when bumped up to 8. My guess is the subroutines need to have "thisbank" or "otherbank" added to the return statements or something.. I took out the scrolling routines, but the score, etc is gone from the bottom of the screen. I will keep working on it..

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...