Jump to content

[7800basic] Graze


Recommended Posts

Note: Gameplay has changed a bit compared to what's explained below. I'll try to rewrite this to make sense later! For now keep in mind that the timer is increased a bit while you graze enemies. If it drops to 0 it's game over instantly!


Object of the game is to try to tag the enemies flying and bouncing around the screen without getting hit directly. scoring will certainly change between now and then along with bonuses awarded between waves.




Currently you gain points by grazing against enemies (Trying to touch the edges of the enemy without letting the enemy touch the center pixel of the player), or outright destroying them if your graze power is high enough. If you can manage a long enough graze you'll get more points than just destroying the enemy! Different enemies give different points for destroying them. Additionally you gain bonus points at the end of each wave based on the number of enemies you successfully touched without destroying, as well as a survival bonus for not dying during the wave that's relative to how much grazing you've managed to do!


The waves included are mostly for testing. Enemies have different colors each wave, although they will all share the same palette due to the screen mode. Once the end of the wave data in the rom has been reached, it will begin looping.



Gears - simple bouncing enemies. Some wiggle in their path to make it harder to avoid/graze. (100pts)

Heli-pod - A propeller based cannon. They can fire a variety of bullets. Their propeller can not be grazed so be careful when trying to graze the enemy! (500pts)

Lancer - A simple two pronged spear enemy that flies, quickly, in a straight line. If it hits you, it'll take you with it and try to pin you to the wall for a time! Try to dash to make it release you!


Bullet Types:

Small bullet - simple energy shot that will despawn after hitting a player.

Large bullet - A stronger punch compared to the small one. In effect it pulls a double-hit. If the player dies from the first hit, then the bullet will continue on as a small bullet.

Paralyser - Grazing this bullet drains your Graze Charge instead of fills it. Quickly! If you're hit, it will slow the player for a couple of seconds.

BossBullet - A rather large bullet that will crawl along the walls and occasionally attempt to jump across the screen at the player. Named because usually it will be bosses using them! (For now the helipod uses them but in the final game it won't.)


Power Ups:

Points (P) - simply awards a larger bonus for destroying the enemy. 1000 instead of the usual 100-200.

Graze Bonus (G) - increases the points/enemy awarded at the end of the round for grazed enemies by 9pts. Reset at death. Minimum 9pts, maximum 99.

Speed Bonus (S) - Increases player speed slightly. Reset at death. After 4 bonuses, you'll reach maximum speed.

Regeneration ® - Causes the graze power to charge automatically for about 10 seconds. It'll stop automatically on death however!


Right now G/S/R increases the points-to-destroy bonus of the gear from 100 to 200. When you've saturated the bonus of the powerup, the bonus will increase to 500pts since you won't get an increase in graze or speed bonus. In the case of Regen, you'll get the 500 bonus as well as reset the timer on the Regeneration to max.




joystick moves the player.

Fire Button 1 (or was it 2...): Dash!

Fire Button 2 (or was it 1...): Slow speed!


Console switches

Reset - reboots the game.

Select - returns to the title/menu screen.

Right Difficulty: Enables/Disables Life Stealing in 2 player games. (If one player runs out of lives, they can take a reserve from the surviving player so long as they have more than 1.)

Pause - should work with the default 7800basic behavior.


Two-Player Modes: (Old versions only)

Standard - the default mode. Basically no benefit or penalty is presented. It's pretty much like it is in 1-player.

Co-op - Players share graze charge to help stay alive longer. It won't a player's charge go below 40, but above that it will attempt to share out the charge power between players.

Versus - Players compete each round for points. Whoever has the higher bonus point score at the end of a round takes a spare life from the losing player, assuming they have one to spare.


At present I can't test on real hardware so if anyone finds anything that seems weird let me know.


Binaries for 2016-06-09 are the last ones with 2-player modes available. Leaving them here.









Edited by Mord
  • Like 9
Link to comment
Share on other sites

Nice work. Interesting concept.


I uploaded the bin to my DevOS 7800. It seems to work well.


On my NTSC CRT I lost part of the top of the screen. Also, the player sprite seems tiny on my little 13" TV.


Here are photos of my screen with your game and same screen with PMC.




Link to comment
Share on other sites

Plays good on the real deal, Mord. Great job!




Presuming the game is set to the 224 resolution height standard of 7800 games such as Tank Command, Water Ski, and also utilized by the NES, SMS, Sega Genesis, SNES, etc., anything alphanumeric may be best placed not at the top-most corner portions of the screen.


It avoids cutting information for those who have a slightly larger wrap/less viewable corner areas under their CRT. SIO's screen, for instance, appears to have top corners losing, gradually, ~6 scanlines compared to the center.


The player's sprite colors and details become blurred and unrecognizable due to its tiny footprint - on CRTs at least. Love the font being used for information and the enemies look cool flying across the screen.

  • Like 1
Link to comment
Share on other sites

Updated - would have had this out yesterday but life. *nods*



Downed the resolution to 208. This is mostly to free up cycles for AI and other things, and admittedly I may need to go down to 192 by the end of it, but I'll try to resist as long as possible!


Increased size of the players. When I rework the movement routine some later I'll likely be adding a few more frames of animation.


Removed the background pattern on the status bar, at least for now. Those testing on mess/hardware let me know if all of the important data is showing now. :) Given the 80 bytes of data it's no longer reading/writing for the pattern, I'm expecting it to work!


Two extra additions made aren't really visible - but I have some debug code active. First, enemies now detect when they've been grazed. This means I can award bonus points at the end of a wave for how many enemies you've managed to graze and AI can now do... more fun things when I get around to it. Secondly, the system keeps track on whether or not a player dies during the wave. Thus a Survival bonus can be awarded at the end of a wave among other things.


The two digits displayed below the status bar is the debug code. It shows the flags for when a player has been killed during the round. First digit will change as the player dies the first time in the round to show they lost their survival bonus - second byte is tracking who's currently dead.


Also, the stationary enemy is part of the debug code - I used it to help refine the grazing for the larger sprites. Grazing is easier now - although some would argue it was too hard originally. (I certainly thought so once the death code was added!)


As always, let me know what you think and if at all possible try it on hardware for me. MESS is closer to hardware than prosystem but it crashes both of my computers, regardless of OS being used.

Link to comment
Share on other sites

I can see all of the text now. When it runs first time high score says 02A900. When the game ends high score changes to 000000. Sometimes one of the vortex just sits in the middle so I can walk over and touch it.




Thank you for making the player bigger ☺


Have I got the world record score on"Awesome Title" yet?



Edited by SIO2
Link to comment
Share on other sites

I can see all of the text now. When it runs first time high score says 02A900. When the game ends high score changes to 000000. Sometimes one of the vortex just sits in the middle so I can walk over and touch it.


Thank you for making the player bigger ☺


Have I got the world record score on"Awesome Title" yet?



I'll be sure to zero the high score on startup to see if that clears it up. The stationary enemy is just a debug critter used to help adjust the grazing collisions - the fact that it'll sometimes take off and go somewhere at the start of a new game is quite perplexing.


But no, your score isn't a world record - I've rolled it several times already!


A question about the display on real hardware - does it look pretty much like what my screenshot from prosystem looks like now? Looking at some of them it kind of looks like some of the pixels in the letters that should be colored in are blackened. Some screenshots I've seen from MESS look like it too. I really need to get me a dev cart at some point. :ponder:

Link to comment
Share on other sites

For the record, I do have the CPUWIZ MCP DevCart in which I utilized to test under the real hardware, and how I was able to take the capture from a real CRT earlier. ;) I highly recommend reaching out to him, via PM, to see about the possibility of obtaining one.

ProSystem emulator is not a good gauge to judge display output for a few reasons: 1. RGB output only. 2. Default color palette is derived from hand picked values incorporating a hybrid mix of NTSC/PAL observations. 3. Incorrect aspect ratio - Falling between a 4:3 and a 16:9 display. Everything is stretched more horizontally.

MESS contains an accurate base color palette of a factory adjusted console, different for each region, and more faithfully represents what you will see under real hardware with HLSL enabled (Think CRT S-Video quality), and even more so when YIQ is enabled (CRT Composite/RF) with a 4:3 aspect ratio.


You even have phosphor trails, and can control how weak or strong they are:


Link to comment
Share on other sites

Yeah, I plan on asking CPUWiz about his devcarts later when I have a little more cash on hand in the event he has one available. ;)


I was doing some testing with Usotsuki earlier, bugging him to run things on mess which (show up far more closer to hardware) for me since my computer takes a dive whenever I try to get it to run it, and it seems that all the missing colors occur whenever palette entry P0C1 (The red) takes up a full pixel-pair. In that situation, it displays black instead of the intended color. Changing the lum value didn't seem to have any effect, although I didn't test with other other hues (yet). In situations where the pixel-pair is half red and half another color (in particular, white - the P0C3) they both get displayed properly. P0C3 and P0C2 both seem to display properly all the time as well. Same deal happens when using P4C1 - which is used on the enemies, but they don't have too many pixels dropped. And in their case some of the pixels dropped are single pixels as well (Things that should have displayed) I don't know if a pixelpair that's half P0C1/P4C1 and half background color will get drowned to background as well, but that seems to be what happened on the enemies.

Link to comment
Share on other sites

I tried a couple different brands of CRT. Yes, red part of letters does not display on either. Also the clipping at the top margin looked the same for both sets. Photos of player attached.





Edited by SIO2
Link to comment
Share on other sites

Thanks for checking on hardware. Next build, probably over the weekend, I'll attempt to rewire the graphics some to minimize/remove this apparent effect with PXC1. Apparently MESS now has a problem with displaying the score on time as well - with only 3 digits showing up for player 1, and nothing for player2/highscore. (On my test build anyway, I don't think it shows up in the last posted rom) I can only assume it's running out of time again after changing all the text in the status bar to plotchars (thus indirect mode). I'll have to look into it a bit more to try to verify what's going on.

  • Like 1
Link to comment
Share on other sites


I'll be sure to zero the high score on startup to see if that clears it up. The stationary enemy is just a debug critter used to help adjust the grazing collisions - the fact that it'll sometimes take off and go somewhere at the start of a new game is quite perplexing.


But no, your score isn't a world record - I've rolled it several times already!


A question about the display on real hardware - does it look pretty much like what my screenshot from prosystem looks like now? Looking at some of them it kind of looks like some of the pixels in the letters that should be colored in are blackened. Some screenshots I've seen from MESS look like it too. I really need to get me a dev cart at some point. :ponder:

I'd like to get a DevCart myself but I'll have to ask CPUWIZ to make a special one that handles 512K.

Link to comment
Share on other sites

Some thoughts on characters not showing up. You need to figure out if it's MARIA or the 6502 hitting a shortfall, because the workarounds are different...


Maria is a sprite beast, but very slow at drawing characters/tiles. You can't plot much more than a screen width of characters in any row before MARIA runs out of DMA time to render them, so attempts to plot more than a screen width of characters generally fail. This is a MARIA limit, rather than a 6502 one, so it has nothing to do with 6502 code efficiency. This situation can be avoided by not layering so many characters, or worked around by using sprites instead of characters where possible.


If the 6502 is the cause of the non-displaying characters, its the result of clearing the screen but not making it to the code that draws the score before the frame has to be drawn. If this is the case it should be fairly obvious, because you'll see the game running at 30FPS instead of 60FPS. There are a few workarounds if this is the cause:


1. Any plot* command will wait until the visible screen isn't being drawn to avoid display corruption, potentially wasting a lot of CPU cycles. Ensure you organize your code so all "game logic" happens right after the drawscreen command, followed by all plot* commands. Simplify any logic the plot* commands require, pushing that complexity back to the "game logic" area.


2. Use "set plotvalueonscreen on", and ensure your plotvalue for the score and any other plotvalues are in the first bit of code after the drawscreen. This setting tells 7800basic that the plotvalue can happen during the visible screen, where cycles are more plentiful. Calling plotvalue during on-screen time won't cause display corruption if you do it right after drawscreen, and ensure each plotvalue command happens in the same order from frame to frame.

Link to comment
Share on other sites

Maria is a sprite beast, but very slow at drawing characters/tiles.


Trust me I've been noticing that as I do some tests with MESS/MAME (Apparently MESS has been merged with MAME since the last update).


In some of the tests I tried to swap out the bitmaps I'm using in the status bar to use plotchars to save on space but it quickly ran out of cycles again and dropped 9 of the 12 score digits. :)



Been a bit busy this week thus don't have anything ready to update today. I'm reworking the graphics to avoid using P0C1 or P4C1 in the instances where it seemed to blacken out. (Any pixel-pair that consisted only of P0C1/P4C1 & a background pixel, or two P0C1/P4C1 pixels together.) I have the players done, but still need to adjust scoredigits/alphabet and the enemies. Luckily the current enemy sprite wasn't affected by it very much.


I do have the start of a dash ability added, although it'll probably endanger players more than save them. I also noticed the hit sound effect wasn't playing so moved it around a bit and it seems to be fixed...

Link to comment
Share on other sites

Got what I wanted done for this version finished so here it is:


Modified the graphics to minimize/remove the pixel dropping issue with the P0C1, P4C1 indices. Haven't tested this on mame/hardware, but did the edits based on what was noticed in earlier versions. You should see full sprites now... should. (This actually took most of my time...)


Added the ability to dash. Currently I think the dash is a little fast so that may slow down a bit. Extra sprites added to show the dash.


In the code the firebuttons can be changed by the user, although since I don't have a configuration screen setup it's currently still "hardwired". Even though only one button is currently in use, I do have plans for the second button later.


I started using Palette 4 for some of the status bar but in the end I might attempt doing some palette changes during the active screen later if there's enough time for it.

  • Like 2
Link to comment
Share on other sites

Nothing to post yet due to known bugs to iron out but as an idea of what to expect, hopefully by the weekend:


1. Ability to slow down with the second fire button. Won't be able to slow down while in a dash, or start a dash while slowing down.

2. Ability to charge your graze suit with successful grazes!

3. When the graze suit is sufficiently charged, the next enemy to hit you will be destroyed instead of you!

4. Some enemies can be flagged as no-graze. If they touch you at all then BOOM! This is mostly intended for shots fired by enemies. A charged graze suit can save you from those but it still loses energy to do so.

5. Added shots for enemies and a couple of enemy AI routines for using it.


Now that I have more than one enemy, I'm going to revisit how I do the collision detection to have it check the ID then adjust the graze box accordingly from a table. Right now the tiny bullets will just outright kill you long before they hit you, thus one of the reasons why I'm going to wait til this weekend to iron it out. :) These particular enemies normally won't shoot, but I don't have graphics done for those that will so... ;)



  • Like 6
Link to comment
Share on other sites

Updated roms in the first post as usual.


Mostly a reiteration of what I said would be in this update but here it is:

1. Dash has been refined (mostly slowed a bit.)

2. Slow down ability added. (needs work.)

3. Abililty to charge the graze suit with successful grazes. At 40+ power, you can take a hit, destroying the enemy instead for bonus points but losing 40pts from the power. Max Power is 99.

4. Enemies can be set as no-graze. There isn't any surprises here, it's mostly for projectiles and potentially "electrically charged" enemies. You should know them when you see them (no electrically charged enemies yet though!)

5. Added small and large bullets. Right now the debug enemy will be shooting up a storm until a player dies or the first wave clears. No other enemies will be shooting after that. I doubt enemies in the main game will shoot anywhere near as fast as that one!

6. Reworked graze/hit detection routines so enemies can be of different sizes (like the bullets for instance!)

7. Added some support code to allow Speed Up powerups later on. Since it's hardwired for now, players start a new game with maximum speed (4 levels). When they die you lose all your bonus speed - and of course there's no way to regain it for now.


The slowdown function currently ignores bonus speed entirely which makes for a drastic speed drop when at max speed. Next revision I'll be adjusting it so that slowdown will still benefit from probably half the bonus speed.


Some vacation time coming up so hopefully I'll have more time to work on this.

  • Like 4
Link to comment
Share on other sites

Updated rom in first post.


1. Added two more dash sprites for going straight up or down.

2. Fixed issue with enemies changing speed when changing direction.

3. Altered graze/hit effect with the background color. It'll now fade out instead of blink on/off.

4. Added extra color (white) when a player destroys an enemy with a charged graze suit.

5. Fixed bug with bonus points from destroying enemies with the graze suit. (Wasn't giving any bonus before!)

6. Slowed enemies down to a more constant speed. Eventually they will slowly speed up as waves progress.

7. Slowdown now applies half of the player's bonus speed.


I took the machine gun away from the debug enemy. The enemies in wave 3, for anyone who got to it before, still fire off the occasional bullet. I slowed down their attack rate to try to fire off a shot once per second, but they only shoot if there's an available enemy slot.


There's a couple other things added in the code already that I've started working on, including powerups. Right now three powerups I have planned and have a good idea how to implement include the speedup, regen, and invincibility. The way I'm organizing the data would allow up to 8 different effects, but powerups could activate any/all of them at the same time as each individual powerup is checked by a different bit. Invincibility is just a hyper powered regen, so in those cases the regen will simply be ignored. Some powerups are instantaneous, others will have timed durations.


Still not entirely decided on how to implement the powerups themselves (how to obtain them) but working on that - it's one of the main reasons I'm being slow to work on them. ;)

  • Like 3
Link to comment
Share on other sites

Just got back from a 3 day anime/video game convention, so naturally not a lot of work done yet since the update. There's just a couple of little things in there right now so no point in doing another rom release yet.


The little things I fixed were mostly bugs/oversights. For instance, when a wave ended, if you were in a graze then the background color just snapped back to black. It wasn't affected by the color fade that was added in the last version. That's now fixed. Additionally I noticed that graze levels were not resetting if you hit game select to jump back to the title screen. That's also fixed.


Also, there's two new rules/modes for 2-player games. In addition to the regular mode that solo games have, there is to be Coop and Competitive rules.


In Co-op mode (Already coded) you can help the other player charge their suit. If you have enough energy to withstand a hit from an enemy (40+) then the graze charge you collect will be shared out with the other player if they're total is lower than yours. This basically helps keep both players alive longer in theory!


In Competitive mode (Not coded yet, since it needs the below) the two players compete to see who can graze the most/destroy the most enemies within a wave. The player with the lowest bonus point scores at the end of the round is the loser and loses 1 life which is awarded to the winner. In the case where the loser doesn't have spare lives to lose, instead of getting a game over I'm thinking they'll lose any powerups they currently have. (timed powerups will be zeroed and bonus speed will be negated)


Right now I'm preparing to revamp the mid-wave loop to work more cleanly (It's just sooo hackish right now.) and so it'll do the mid-wave bonus point calculation/adding. Then I'll move on to competitive mode and hopefully start to code in powerups.

Edited by Mord
  • Like 2
Link to comment
Share on other sites

Updated roms in first post.


I didn't get around to powerups yet, although code is added for a couple more effects.


Changes in this version:

- Fixed background fade not working correctly during mid-wave. (It would instantly go to black.)

- Graze charge levels are now reset when game-select is pressed to bring the player back to the title screen. Previously it was keeping them from the last game.

- Fixed enemy speed bug where after the player died or wave ended, some enemies would start moving much faster.

- Added 2-player Coop mode. Graze charge levels will attempt to balance out between the players so long as they have enough to withstand a hit stored up for themselves.

- Added 2-player Versus mode. Players compete with each other to get the largest bonus score during a wave. The loser will give a reserve life to the winner so long as they have one to spare. (Will do more after powerups are in.)

- Each player has their own unique survival bonus which goes from minimum (1000) to maximum (2500). Grazing enemies make this go up during the round. The more you graze, the higher it goes!

- For every unique enemy you graze, that safely leaves the screen, will earn an extra 25pts to the wave bonus. If the enemy is destroyed by a player it won't add to the graze bonus. Currently.


Enemies can now leave the top of the screen. They use to bounce off the status bar unconditionally since letting them go up there had the chance of causing graphical glitches with the status bar, and because it looked ugly to do so. It's using some new zone locking code that clips enemies trying to go into the locked zone. :)

Edited by Mord
  • Like 2
Link to comment
Share on other sites

Hey Mord...Great update! Real hardware results are matching the same issues I am experiencing under MESS/MAME, including numbers (Seems to be a combination of Wave, Time, and some added zeros) shortly after the wave summary, and sometimes partial enemy glitches popping up. Additionally, the occasional line/dash glitch pops up too, possibly/probably related to the similar partial enemy and/or number glitch.


A few captures of the aforementioned from are captured below. Regardless, development is pacing along very nicely, keep up the great work and thanks for sharing it with the community! :)



Link to comment
Share on other sites

I saw some things similar to that once in a while as I was testing it but was hoping it was just my computer crapping out. Honestly unsure how it's showing those digits, although I saw it happen before. This might be something for Rev to look into as well since those digits showing up aren't together in ram. Wave & WaveTimer are the first two variables (one is assigned to "a" the other to $2400. I suspect those zeros are probably the first digits in score0. I was running into issues with overrunning the reserved space for plotvalues on this release - which is why during mid-wave I don't bother plotting the scores or graze charges as bonus points are calculated.


I'm going to attempt to switch the plotvalues over to plotchars using a method Rev showed me which should avoid it. If this is the cause of those mysterious numbers then hopefully they'll stop showing up after that.


As for the partial enemies, I'm not sure what's causing them. Shouldn't be the zone locking as only the top zone is ever locked - although admittedly it is locked during the enemy plotting. Something to keep an eye open for certainly.


Keep a note on how often you see those glitches show up, how long they last, and what's going on at the time. (is it during the wave, between waves, during gameover, or while player is being revived)


Going to release another rom shortly that'll be beta-testing the powerups. (have 4 done, room for another 4 to be added as time/space/ideas permit. :))

Link to comment
Share on other sites

Updated first post with new roms/screenshot.


Only one addition this time, although it is a big one. Powerups are now in the game, currently four of them. To obtain a powerup you must destroy the enemy it's attached to.


P: Points. Obtaining this one simply gives a point bonus, currently set to 2000.


S: Speed: This increases your bonus speed slightly. The bonus stays until you die. After the 4th speed up, it won't increase your speed anymore, but instead give 1000pts.


G: Graze Bonus: This increases the graze bonus you get per mob at the end of a wave by 9pts. Default is now 9pts, maximum is 99/mob. The benefit resets when you die. If you have max, it'll give 1000pts instead.


R: Regeneration: Your graze suit will begin to charge for about 10 seconds. If you pick up another Regeneration, it simply resets the duration to 10 seconds. In 2-player Co-op games, the other player will gain some advantage from the regeneration as well.


There's a different sound effect when points are gained compared to the bonuses being applied.


Normally during the game most enemies will NOT have a powerup attached to them. I just have debug code added to make sure a random powerup is added to each one as it's spawned. Helps with stress testing. ;)


The two debug values at the top of the screen are tied to player 2. It shows the GrazeBonus and the top byte of the bonus speed. If bonus speed = 1 then it's maxed out.


I fully expect to see more glitching like what Trebor showed above as I haven't done anything to fix them yet. There's nothing explicitly in the code that should cause them however so I'm not entirely sure how to fix it up. We'll see how the plotvalue conversion does next release. :)

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.

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.

  • Recently Browsing   0 members

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