-
Content Count
1,156 -
Joined
-
Last visited
-
Days Won
5
Posts posted by jrok
-
-
Glad to see you still plugging away at this.
Cheers, GroovyBee. I kept tinkering with other projects, but Charge is really the game I've really been itching to finish.
-
Very nice improvements!
Thanks!
-
Excellent Jarod!
I tested it (PAL console + Harmony cart).
All perfect but when the evil knight appears the flicker is too much (IMHO).
After a while vertical strips appears from the top.
Thanks, Philsan. Curious about the strips. Could you describe these more?
Not sure what to do about the flicker, except maybe fool with the color a little. It's 30hz now, so I don't see how it could get much better than that. I guess the only thing I could do is revise the knights' graphics to 8-wide single sprites to eliminate the flicker... which I'd hate to do because I was fairly pleased with the look of the big, multicolored horsies.

-
Your text in #3 asked "why is it part of the demo?" - that's what I was responding to.
I suppose I was wondering what the difference was between masking a sprite stored in RAM (as I've done before with sprites stored in Sara RAM) and the technique being shown in the demo. Although I gess I wasn't really 'wondering' that aloud, so fair enough.
It wasn't meant as an offense or anything. I was asking Scumsoft to elaborate on his reply a little, so I could understand the difference. Moreover, I posted this in the bB section, and explained I was trying to understand whether the technique could be appropriated for batari's kernel, and did everything except write "Please don't come over here and yell at me, Darrell!"
But, alas...

-
You're posting this in the bB forms - are you overlooking that my DPC+ demo was not a demo for bB?
Um... no. That's why I specified the "Batari DPC+" kernel in the topic title. I was just wondering if a similar runtime write could be done to mask sprites in that kernel.
-
The demo manually masks the sprite data based on sprite location...
Hmmm. So do you mean that it manually loads and repositions shapes at positions 0 and 160 to simulate a smooth exit/entry? It just surprises me a little, since I assumed that its inclusion in the demo was demonstrating a dynamic mask of some sort. In other words, since we could do this manually sans the chip, why is it part of the demo? What's the advantage being shown?
-
Very nice work!
Reminds me a bit of Space Taxi

-
Would it be possible in the batari DPC+ kernel to mask-wrap the multiplexed P1 sprite similar to Demo 4 of the Harmony DPC+ programming thread?
Demo 4 - Data Writer Demo
* Unlike the DPC cartridge, the DPC+ Display Data ends up in RAM and can be modified at run time.
* Joystick to move snowman - notice when he moves on/off screen he is masked to smoothly enter/exit the display. (compare with Demo 0)
* Fire to flip snowman - this shows the difference between DFxWRITE and DFxPUSH.
* Attached Image: DPC+ demo.bin_4.png
Thanks,
J
-
Hey gang,
Haven't signed on in a long while, but I thought I'd share an early demo of what I've been working on. This is a DPC+ kernel adaptation of a project I started a few years ago, although I think this version is different enough to constitute an entirely different game. I'll include the instructions in this first post, and update them with each build.
CHARGE!
by J.D. Kitchen
THE STORY:
The kingdom of Nirata is under attack! Armed with your lance, your bow and your trusty steed, you must defend the realm from the relentless hordes of soldiers, horsemen and fire-breathing dragons.
Patrol the road that encircles your kingdom, using your arrows to slay the dragons in the sky and footmen advancing through the fields. But beware the dragons' fiery breath, the lances of enemy knights, and other deadly hazards and foes which may befall you.
PLAYING THE GAME
Your objective is to destroy marauding Dragons, Wizards and other foes while defending your Castles from harm. You begin the game with three Castles and three Paladins to defend them with. Each Paladin comes equipped with Armor that is gradually depleted by enemy attacks, a Lance for jousting Knights and a magic bow that can fire an unlimited number of arrows into the sky. The number of remaining Armor Points and Paladins is displayed at the bottom of the screen, along with the player's current score.
Use the left joystick to maneuver your Paladin's horse around the dark gray road area. The road is a loop around the kingdom, so moving in one direction long enough will bring you back to where you started. Pressing the joystick's fire button will draw your bow, and releasing it shoots an arrow into the air on a slight forward arc. If you hold the joystick left or right while holding down the fire button, your horse will charge at a fast gallop. Your galloping Paladin will automatically engage his Lance, making it possible for you to kill advancing enemy knights.
Charge! includes multiple attack waves. In each wave, you must first clear the sky of enemies and then destroy any enemies that remain on the road. After the road is cleared of enemies, there will be a brief interlude, during which your castles and armor are repaired slightly, and any bonus men you earned during the wave are applied. After the interlude, the next wave begins, gradually increasing the challenge to the player.
You score points whenever you kill a Dragon, with various breeds earning different point values. As waves progress, you will meet sturdier, faster, and deadlier breeds. You can also score points by killing any other enemy as long, as all of your Castles are still intact. Some waves feature special foes who must be defeated to advance, with unique rewards for doing so.
When a Paladin's Armor Points are fully depleted, the current hero dies. A new one will appear until all your remaining Paladins are lost.
At the beginning of each new wave, the kingdom will fortify itself for the next attack in the following ways:
- Your Paladin will recover an Armor Point for each surviving Castle.
- At 500 points, you will recieve a bonus Paladin
- Each of your surviving Castles will undergo repairs, recovering eight hit points per round.
- If a Castle was destroyed in the previous wave, the flaming ruins will be extinguished. The Castle's smoking rubble will be able to be rebuilt after the conclusion of the current wave.
The game ends either of the following conditions:
- You have lost all your remaining Paladins.
- All of your Castles are destroyed and the current Paladin dies.
Press [Reset] or the left joystick fire button to begin a new game.
CONTROLS:
Joystick - Move horse in 8 directions along the road.
Press Fire Button - Draw bow.
Release Fire Button - Shoot arrow.
Hold Fire Button and Joystick Left/Right - Charge!
SCREEN LAYOUT:

A. Paladin
B. Dragon
C. Dragon's Breath
D. Bats
E. Castle
F. Foot Soldier
G. Knight
H: Armor Remaining
I: Remaining Paladins
J: Score
GAME OBJECTS
THE KINGDOM
The Paladin

The player's Paladin can attack enemies in the fields and the skies by shooting arrows at them, and attack enemies on the road by charging them with his Lance. Arrows can be shot at any time by pressing and releasing the fire button, but the Lance can only be used when the Paladin's horse is moving at full speed. A charging maneuver increases the top speed for the duration that the player holds down the fire button while pressing the joystick in left or right direction. If a player switches the joystick direction mid-charge, the Lance will become inactive again until the horse achieves maximum speed in the new direction. Each Paladin can receive seven wounds before death, indicated by the red bars on either side of the score. A Paladin will heal one Armor Point per Castle that survives a wave.
The Castles

The primary goal of the game is to defend your kingdom's three Castles: Purple, Yellow and Red. As each Castle takes damage from Dragons and Footmen, it becomes shorter. When its last hit point is lost, it becomes a Flaming Ruin. At the conclusion of each wave, surviving Castles are repaired slightly, while Flaming Ruins turn into Smoking Rubble. Smoking Rubble can be rebuilt into a Castle at the end of the next wave.
Castle Damage States:

Princesses
If you can defend a Castle well enough, a Princess will appear at the top of it during the Repair Phase. If a Dragon swoops down and captures a Princess, it will attempt to bring her to the top of the screen for a quick snack. Shoot the beast before suppertime, and then rescue the falling damsel for bonus points.

ENEMIES
Dragon

Dragons are the player's primary foe. Sweeping down from the sky, they attempt to bathe the player's Paladins and Castles in flames. There are several breeds of Dragon, distinguished by different colored hides and varying abilities. Dragons travel in packs of between 1 and 5 per wave, attacking the kingdom one at a time. When all the Dragons in the current pack have been slain, the game progresses to the next wave.
Footman

Foot Soldiers of various armies and tribes will charge upon the fields to lay siege to your castles. They vary in uniform, speed, number (not implemented yet) and attack strength, but they all share the same purpose: to burn your Castles to the ground! Dispatch them with your arrows, yea, verily.
Bats
(Not implemented)

These flying pests patrol the skies in swarms, attacking any Castles they find along the way.
Knight

Renegade Knights prowl the road, looking to make a name for themselves... by writing it in your Paladin's blood. These horsemen will challenge you continually as you protect your Castles from other foes. To defeat them, look for signs of their approach on the battlefield, align your Lance with theirs, and charge!
Grendel

These large, bloodthirsty monsters occasionally are lured from their lairs by the smell of the Paladin's blood. Grendels have thick hides that are impervious from attack, unless you can locate their weak point. If that wasn't bad enough, they will sometimes lurk just out of your reach alongside the road, and they require two direct lance hits to defeat.
Wizard

The Evil Wizard sails through the skies, wreaking destruction with big blasts of mystical energy. He is a tricky target to hit, and sometimes will use a barrier of green mist to protect himself from your arrows.
TERRAIN

TIPS:
- .
- Listen to the sound of the Dragon's fire and the Soldier's sword to track your enemies' positions (louder equals closer; quieter equals farther away).
- If one of your Castles is successfully attacked, you will hear an explosion sound.
- Your bow fires Arrows on a slight forward angle, so try to anticipate a Dragon's movements when firing at one. A good tactic is to try to keep your horse in motion and either match the Dragon's speed or charge beneath it while firing.
- Enemy Soldiers roam the fields beyond the road, laying siege to any Castle they find. Kill them on sight whenever possible.
- When a Lance appears on the road at either side of the screen, it means that an enemy Knight is close. The longer the Lance is, the closer the Knight is to your current position.
- When charging, try to align your Lance to the enemy Knight's Lance to defeat him in a joust. The closer you are to aligning with Enemy Knight's path when you clash, the more likely you are to kill him, and avoid injury yourself.
- As the waves proceed, Dragons will become faster, more damaging and more durable, sustaining multiple bow hits before death. Enemy Soldiers and Knights will also become faster, stronger and more aggressive as waves progress.
- Dragons are primarily concerned with destroying your Castles, but with a little coaxing you can lure them away with your Paladin, and get them to come after him instead.
- You begin the game with three lives (represented by the series of vertical bars next to the the score area). The red bars on either side of in the score represents the current Paladin's Armor Points. Each of your Paladins can sustain seven wounds (either from dragon fire or jousts) before death, at which point a new Paladin is re-spawned at the nearest Castle. If all three Castles are destroyed (either flaming of smoking) and the current Paladin is killed, the game immediately ends, even if more lives are left in reserve.
- At the conclusion of each wave, each surviving Castle will be rebuilt slightly. If a Castle is destroyed before the end of the wave, you will have to complete an additional wave to wait for the flames to die out and turn into smoke before it can begin being repaired again.
- Beware of Giant Dragons, Evil Wizards and other powerful foes.
- The final wave in this demo will repeat until the player loses the game.
Playing in an Emulator:
Since this is DPC+, you'll have to play using the latest Stella build (3.4.1). I'd suggest setting Options> Game Properties>> Display>>> Use Phosphor to "On" (77%) to compensate for flicker.
Playing on Harmony:
I'd be curious to know how the flicker is looking on TVs when both the Paladin and the Knight are on screen.
----
I've deleted all other archived versions, and will start labeling releases with dates from now on. Thanks for any feedback, bug reports or ideas you have to offer. High Scores would also be appreciated, so I can gauge the level of challenge.
Cheers,
Jarod
Newest Version:
-
7
- Your Paladin will recover an Armor Point for each surviving Castle.
-
I've noticed that fixed-point operation seem to be natively supported in the kernel, but that sub-pixeling for sprite updates isn't (i.e. incrementing a sprite's position in fractional amounts produces a "jerky" movement, rather than a smooth one). Is this something that might be included in the final version?
I realized this probably wasn't the best explanation. Basically, it seems like fixed-point addition and subtraction works fine, but sprites update only at whole number intervals. So if I incremented a sprite's x position by 0.125 every drawscreen, it would only update visually on drawscreens where the value is equal to a whole number (i.e. 1.0, 2.0, 3.0...)
Basically, I was trying to see if I could port my work on Charge to the DPC+ kernel, which requires smooth acceleration of sprite objects.
Thanks!
J
-
I've noticed that fixed-point operation seem to be natively supported in the kernel, but that sub-pixeling for sprite updates isn't (i.e. incrementing a sprite's position in fractional amounts produces a "jerky" movement, rather than a smooth one). Is this something that might be included in the final version?
-
Wow, this is very cool! Thank you Fred!

Is there a separate beta thread you want us to post bug reports to, or should we just use the regular pinned thread?
-
Looks good, Jarod!
One nitpick - I'd prefer it if the character selection and level selection worked with the joystick too.
This one's ripe for Vox support. Did you ever pick one up, like you planned?
Cheers, RevEng

No, unfortunately I haven't had the chance yet. Yeah, it might be a really nice touch to put in some synthesized taunts.
EDIT: I agree with you and Philsan. I'll try to include joystick control for the selection screen in the next build.
-
Awesome, Jarod!
Thanks

-
Here's an updated playable demo. I'm not even sure how many incremental changes this is from the last one, but here's a general summary:
Title Screen:
- Press Select Switch to select which level to start at (levels 0-7 are selectable, out of 16 levels)
- Press Fire to go to the Character Selection Screen.
Character Selection Screen:
- Press the Select Switch to scroll through the available characters
- Characters vary by shields, range and speed.
- Press Fire to start the fight.
Fight Screen
- Press fire to Begin
- Hold Joystick to Move
- Press Fire to shoot.
- Hold Fire to lock aiming direction and autofire
- Tap Joystick to Slide/Roll
Post-Fight
- Press fire to return to Character Selection Screen (In this demo, you can pick a different gladiator for each match)
I've made the early levels a bit easy, although I added a few tougher guys towards the end. Ultimately, I think I can squeeze in about 42 preset matches, followed by eternal randomized title defenses. I still have quite a bit of work to do on obstacles and traps, but I thought I'd try to get some feedback on the new format.
Cheers,
Jarod
-
2
- Press Select Switch to select which level to start at (levels 0-7 are selectable, out of 16 levels)
-
Sure, that would definitely be better.
The only hitch here is we now need to change come of the memory locations around - player1colors takes up the memory that would normally be used by missile1height and missile1y, and now it needs to use missile0height and missile0y instead. So I've included the 2600basic.h file with that change. (be sure to stick in the directory with your basic file.)
Here's v2, with missiles from P0 being sacrificed...
D'oh! Okay, yeah, and this all actually makes a lot more sense, now. Wow, thanks for solving this one, RevEng! Maybe a final step would be to try to pretty-up the revised kernel (instead of switching between two full, separate kernels), but it works very well as is.
I think your solution should absolutely be included as a fully fledged kernel option if there is ever an official redraft of the standard kernel. I know that the desire to color the priority sprite (without losing both missiles) has come up quite often on these forums.
-
I started down the same road as SeaGtGruff, but after a while it became apparent I'd need to conditionally re-jigsaw much of the kernel to get it to work. It was easier just to make a second kernel (modified mostly with search and replacing) and enable each kernel conditionally based on the "player0colors" constant...
To use it, remove the .txt extension from the .asm file and add it your basic project's directory. Then add a "const player0colors=0" line to your basic file.
Ah, okay. Thanks!
I think I understand the changes in the top kernel. But I guess what I was really curious about was whether there could be a full swap of the default kernel, where P0 is multicolered, M0 is sacificed, and monocolor P1 and M1 are both available. It seems as though in this kernel, the priority sprite and it's missile are both available, which makes M0 share the color table with P0. -
I've been attempting a kernel mod for this on my own lately, but the farthest I've gotten is to manually swap which player is colored. The trouble is that even after making the switch, player0 color table always aligns with player1's pointer. So in other words, player0 is colored, but it's color table is drawn at player1's y position rather than it's own.
From what I read above, it seems as if Michael's attempt had a similar problem. Where in the kernel is the y value of each color table set?
EDT: I attached a binary to demonstrate the result I'm getting. Press up-left or up-right and the fire button to jump.
-
Pong
in batari Basic
Got a problem. Batari doesn't like ' if ballx<8 | ballx>155 then goto gamea' I'm guessing I've got the wrong or statement?
The syntax for OR is "||"
-
Pong
in batari Basic
1500 bytes of Pong and I can't even get that to work. Oh, boy.
Okay, my problem is that not only does the enemy not move, I get an error message about ' if joy0fire then g=1'. (which starts/unpauses a game)
There a couple of things which aren't causing errors but I think could be improved. For one, the paddles are both the same sprite (flipped for the second one) is it possible to address them both at the same time?
Also, the collision is quite messy, but I don't know how to make an if statement do more than one code - how do you do this?
Finally, the playfield is just two bars, so is there a way to cut down on that code?
Thanks very much.
PS. It's unrelated to this game, but I've been having little success doing smooth movement, like in Reactor or Defender. Is there a way to increase these variables little by little?
rem Pong, by SuperNESFreak, 2-1-11 set romsize 2k playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end player0: 000011 000011 000011 000011 000011 000011 000011 000011 end player1: 000011 000011 000011 000011 000011 000011 000011 000011 end ready a = 75 : rem playery b = 75 : rem opponenty c = 75 : rem ballx d = 75 : rem bally e = 255 : rem ballhspeed f = 255 : rem ballvspeed g = 0 : rem pause gamea player0x = 16 player1x = 140 player0y = a player1y = b ballx = c bally = d COLUBK = 0 COLUPF = 14 COLUP0 = 14 COLUP1 = 14 REFP1 = 8 scorecolor = 14 if joy0fire then g=1 if g = 0 then goto ready if switchreset then reboot gameb if joy0up then a=a-1 if joy0down then a=a+1 if a<16 then a=16 if a>80 then a=80 if b<d then b=b-1 if b>d then b=b+1 if b<1 then b=1 if b>88 then B=88 if collision(ball,playfield) then f=0-f if collision(ball,player0) then e=0-e if collision(ball,player1) then e=0-e if collision(ball,player0) then f=0-f if collision(ball,player1) then f=0-f if c<4 then score=score-1 if c>251 then score=score+1 if c<4 | c>251 then goto game drawscreen goto game
There were a few things wrong with the code. First, you have an endless loop without drawing the screen ("if g=0 then goto ready") and then you send to a label that doesn't exist ("game"). You also forgot to separate your sprite lines with "%." You also didn't include updates for sprite positions in your "gameb" loop (which wasn't a loop, since it was trying to jump to "game", which didn't exist). I'm actually not sure why you assigned "player0y" and "player1y" to "a" and "b", since player0x,player0y,player1x and player1y are already themselves assigned to RAM addresses, so I changed that.
There were also some other weird things about the way it was set up, and certain stuff where I wasn't sure what you intended. Anyway, try compiling the following code and then compare it to yours. You press fire to begin the gameb loop (I'm thinking that's what you intended?)
rem Pong, by SuperNESFreak, 2-1-11 set romsize 2k playfield: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ ................................ XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX end player0: 0011 0011 0011 0011 0011 0011 0011 0011 end player1: 0011 0011 0011 0011 0011 0011 0011 0011 end ready COLUBK = 0 COLUPF = 14 COLUP0 = 14 COLUP1 = 14 player0y = 75 : rem playery player1y = 75 : rem opponenty ballx = 75 : rem ballx bally = 75 : rem bally e = 255 : rem ballhspeed f = 255 : rem ballvspeed g = 0 : rem pause player0x = 16 player1x = 140 ballx = 75 bally = 75 scorecolor = 14 gamea if switchreset then reboot if joy0fire then goto gameb REFP1 = 8 player0y = 75 : rem playery player1y = 75 : rem opponenty ballx = 75 : rem ballx bally = 75 : rem bally e = 255 : rem ballhspeed f = 255 : rem ballvspeed player0x = 16 player1x = 140 ballx = 75 bally = 75 drawscreen goto gamea gameb if joy0up then player0y=player0y-1 if joy0down then player0y=player0y+1 if player0y<16 then player0y=16 if player0y>80 then player0y=80 if player1y<bally then player1y=player1y-1 if player1y>bally then player1y=player1y+1 if player1y<1 then player1y=1 if player1y>88 then player1y=88 if collision(ball,playfield) then f=0-f if collision(ball,player0) then e=0-e if collision(ball,player1) then e=0-e if collision(ball,player0) then f=0-f if collision(ball,player1) then f=0-f ballx = ballx + e + f if ballx<4 then score=score-1 : goto gamea if ballx>251 then score=score+1 : goto gamea REFP1 = 8 drawscreen goto gameb
-
You need to put your drawscreen before the collision check - the 2600 actually has to draw the frame for the collision registers to get triggered.
As your code is now, you're checking collisions on the previous frame, which is why it works when you do things based on the wrong frame.
Not a stupid error... it's a pretty common mistake for those new to the 2600.

Hey RevEng, thanks for the help. I really took drawscreen for granted there - but now it makes sense (it did solve another problem of mine also).
Let me take this opportunity and ask you about flickering: the way I did it it's how it usually go?
You should probably consider not going with native collision detection if you are going to use flicker in your program. Instead, you could set up bounding boxes for them to track whether or not one object has intersected with another. That way, you don't have to be concerned what frame you're in when testing collisions. This is especially helpful when you want to test collisions between two objects that share the same sprite, like the crab and the square.
-
It could probably look even less flickery if I used a dimmer color (the same would be true for the yoshi demo) but truthfully I didn't tweak the demo's all that much.
This is probably a little off-topic, but I am a little curious about lum value as pertains to flicker (and human perceptions of it). You mentioned color constancy before, which I'm familiar with, and which makes logical sense to me... and yet for some reason my (wrong) instinct keeps screaming that it is better to contrast a bright flickering color against a dark one.
I guess some wire gets crossed in my brain because there seem to be a couple of different concepts wrapped up in what makes flicker "good" or "bad." Besides the refresh rate and perceptual color, which I think I grasp, doesn't contrast also play into it? And if so, how? I think I keep getting hung up on "bright sprite/dark background" because something tells me that a low lum sprite on a low lum background would result in a game that was practically invisible. I don't know if that's because I'm thinking of it the way I think of chroma relationships, or if it's some other shortcircuit or brain bias. I do know that I'm wrong, but I've never really been sure why I'm wrong.
-
Latest Version:
- Added 7 horizontal rooms. Player enters next room at screen edges.
- Added a playfield enemy, "Field Mouse" that roves back and forth along the floor of each deck and emits a vertical laser field at timed intervals. Up to two per screen for now, but I will try to include as many as four
- Added a p0 enemy, "Robot," that appears on a random deck when the screen is drawn. By default it roves back and forth across the deck, but it moves in the direction of the player whenever they share the same deck.
This is basically still a sandbox without any death or danger, and I just scattered around the pits without much thought to design, but I'm starting to get interested in the possibilities here. I'm using CurtisP's background colors hack to achieve a multicolored static background behind multicolored playfield pixels, but now I'm wondering if I should try to store the background rows, playfield colors and heights in the superchip RAM.
Also, if I go with 30hz flicker on P0 and P1, I could potentially have quite a lot going on in each screen so I might try something like that for the next version.
- Added 7 horizontal rooms. Player enters next room at screen edges.
-
I like the engine very much. With careful level design, I think the timing of jumps won't be so frustrating. And I like how you fit 3 floors. You can put a lot of gameplay into 3 floors per screen.
Thanks, Piggles.

What would be really cool is if we could run multiple batari display kernels. With one kernel running the display for each third of the screen, each floor could contain two flicker-free sprites (or 4 30hz ones). I think a fairly cool action-adventure game could be accomplished in such a framework.
What might fit with the limitations of the Bb engine is a game with hidden enemies. Your line of sight restricted to the floor of the building that you're on. Combined with a theme of stealth, perhaps the bland lack of graphical data on the other floors wouldn't be a problem. Your enemy and terrain data could be handled via software until it's time to fall through a hole or climb down a ladder to the next floor. Using "pfcolors background" perhaps you could just blackout the levels of the screen you're not currently on, bringing focus to the current floor with whatever colors are appropriate for the situation.
And all this is easy for me to say because it's not my project.

No, these are all good ideas. It's funny - I was actually thinking of something similar, including the "blackout" of non-visible levels, which would actually add an interesting "Wizard of Wor" wrinkle to gameplay that I haven't seen in games of this type (not saying those games don't exist, it's just that I haven't seen one.)

Charge!
in batari Basic
Posted
Thanks RevEng! If the flicker for the jousting portions is too distracting, I may have to downgrade the graphics a bit unfortunately.