-
Posts
304 -
Joined
-
Last visited
Content Type
Profiles
Forums
Blogs
Gallery
Events
Store
Community Map
Blog Comments posted by brpocock
-
-
D'oh! Better. So, logic something like:
If field is odd/even, inject player-character (sprite 0);
Regardless as to whether that has happened, proceed to process drawing-lists starting from ( inc first_pick_sprite / bcc .ncar / lda #1 / sta first_pick_sprite )
... That saves on figuring out where the player-character falls in rotation.
-
P.S. to my just-prior notes.
Hitting a RESPx line as I've just declared would require it to be on a venetian blinds line (skipped line), since timing is too tight when drawing the playfield to wedge them in at specific clock-points.
That means potentially costing two additional sleep lines after the prior sprite.
Also, hitting RESPx for both player graphics at once would be impossible (at the same 1/3 marker).
That just means that I'll need to detect this (relatively unlikely) circumstance and introduce one extra sleep line for one of the player-graphics, costing an extra couple of lines.
Oh -- and, of course, the first sprite in each player graphic is positioned using RESPx precisely, since I have a few lines before I start drawing the playfield to "waste."
-
That style of sprite relocation will avoid having to blow any scan lines on RESxx timing loops, but repositioning a sprite that way will take eleven scan lines. It may be useful to have a few variations of one of your sub-kernels, each of which has a RESxx in a different place. You could use one of those to get the positioning close to where it should be (say within 30 pixels), and then use HMOVEs to get it to its final place within five scan lines (rather than eleven).
OK ... I did some math and I'm leaning towards your interpretation on RESPx hits.
Each HMPx hit could potentially yield effectively +/- 7 clocks movement. (Yes, 8 one way, 7 the other, the math is easier pretending orthogonality.) The effective sprite positioning range is based upon 9 columns into which the first pixel of a sprite might go ... a sprite could be left of the playfield proper, or hanging off the right edge, as long as one pixel is within the playfield boundaries, and I'm being cheap on the logic and not trying to mask the part falling into the blank PF0 areas, although the omnipresent HMOVE bars do that very thing on the left ... So 9 columns times 4 playfield pixels of 4 clocks each ... minus one playfield pixel at the far left, since the 8 pixels double clocked sprite would be completely outside of the playfield at that point ... so that's (8 * 4 * 4 + 3 * 4 ) = 140 clocks potential display range. Worst-case scenario is moving from a sprite at position 0 to a sprite at position 139, giving a requirement to whack HMOVE 20 times. That's 20 scanlines wasted, or about one row (6 rows of 24 scanlines each in the "24-line kernel." Yes, it's insane.)
Giving the option to whack RESPx at the 1/3 marks -- i.e. at positions 46 or 93 -- makes the maximum possible distance required about 46 clocks, which could be done in 7 lines, plus the one line for the RESPx.
This would alter the drawing list to resemble the C code:
struct drawing_list_entry { bits verb : 2; /* enum 0, 1, 2, 3 */ union direct_object { struct resp_hit { bits position : 1; bits unused : 5; }; struct hmp_hit { bits hmp_value : 4; bits repeat_count : 2; }; struct draw { bits start_line : 3; bits num_lines : 3; }; struct sleep { bits sleep_lines : 6; }; }; bits sprite_index : 3; bits wasted : 5; }In a perfect world I could only include the sprite_index value after drawing starts, only wasting 5 bits when in a draw phase. In my world, I probably can't afford that logic.
This upsets the tea table in a beneficial way. Thanks for the brainstorming assistance.
With any luck, I'll have a stable sprite drawing kernel later this week, as time permits. (80 h/w at first job and about 20h/w at second job get first priority.)
Incidentally, I have on paper (!!) the status screen display code rewritten to use missiles to show boss locations on the level map ... I have to key it all in to get the damned centre-of-screen timings worked out, since the "keys you are holding" and "map of the level" displays are in a split screen, but I think it will work. I think I'll have a "you are here" dot as well.
I'm cheating and just setting COLUPF to blank out the map if you don't have the map item for the current level.
Incidentally, all level-specific variables are wiped out by leaving the level (dungeon), so you will have to more or less play through the levels in order, making the overworld map not entirely useful, but . . . there's 128 bytes of RAM, damn it.
-
Regarding the player sprite and no flicker, I have a slightly different oppion.
IMO flicker is less noticable when it is constant. E.g. a sprite constantly flickering at 30 Hz looks better than a sprite switching between flicker and no flicker.
That being said, maybe you a allow the player sprite to constantly flicker at 30 Hz and give the other 50% to the other sprites.
This puzzled me until re-reading. You're refering to the non-player sprites, i.e. that they will have more visible flickering due to the fact that they may enter/leave "bad areas" vertically causing such flicker?
I see the point, there. I think I'm taking that to heart, in a way: I'll try to work in that the player-character only gets preferential treatment on odd frames, or something to that effect, giving it a guaranteed 50% display time with fair competition for the other 50%.
-
It may be useful to have a few variations of one of your sub-kernels, each of which has a RESxx in a different place.
I've played around with something like this, but it's been inefficient on the overall. It may work its way back in, but I don't have much time in kernel for branching and such, and the kernel is unrolled, so any variation would have to be replicated 8 or 24 times. Not to say something with RESPx won't make it in -- just that it seems unlikely.
Depending upon your exact register and RAM usage, the simplest way to handle this might be to use two bytes in RAM for each major line of display as a code pointer; after displaying each major line, perform an RTS to go to the routine for the next line. This will only cost six cycles, and eliminates the need for other looping constructs.That would be nice, but there are 48 effective lines per screen, so that would be 96 bytes of RAM right there... of course, that's impossible.
-
Long time since I've updated here, but sincce my web colo is down, it's a good time for a status report.
Little Dipper -- now officially titled SKYLINE -- is on track. Major infos:
Skyline is an Action RPG, meaning real time, along the lines of classic/Game Boy Zelda titles. I've sacrificed some colour and background detail operations to permit more insane sprite-handling -- nothing too special, but a different format for the VCS.
"Real Artists Ship" (Steve Jobs)
The release party for Skyline will be held at the Metro Entertainment Complex on 21 October, 2007, to co-incide with my 30th birthday, and the month of the 30th anniversary of the VCS. The party was booked in The Loft, one of our bars, bt The Loft will be clsibg this month in preparation for the 1 August opening of Club Sappho, a new lesbian bar, so the precise location within the complex is TBA for now. Party runs from 8p to 2a. Anyone near Jacksonville, FL is of course welcome to attend. RSVP:s encouraged but not required.
The new Skyline designs and such are beig done by myself and Ricky "Black Cat" Harnden. The Ursa and map compilers are pretty fantastic -- it even does tile usage determination -- and the new kernel mods are about 6 critical bugs and 5 or 10 FIXME's from running. MemCard support is dropped for now (the fire ate mine :-( ) along with a few other things, due to time onstraintts also.
Looks like 32kiB.
Alpha will, of course, be posted ASAP -- since a lot of code is Perl-generated and m4-compiled, just building is rough, but progress seems fast -- if sporadic.
The rest is history I suppose ... we'll see if it's anything worth playing.
Oh, as for plt, there isn't much of one -- but it does involve Nazis and vicious dogs and drag queens. Before tryingbto make that make sense, ask why a plumber is chasing a bunch of mushrooms and turtles. Besides, I'm writing what I know -- I'm the barback manager for a queer bar now, may as well embrace it in the game.
btw, personal note to all expressinng concerns, thanks, alive and well and recuperated more or less from job layoff/landlady arson/car theft bull$#!^ of the past year.
Apologies if I missed typos -- posting from my NDS.
Inventory/stats and text/menu code are major hurdles once the core game kernel rewrite is done. Build utilities are almost worth being proud of now. Sound is for $#!^.
I'll be doing something like raffling off a few copies of Skyline and t-shirts or sommat at the release/birthday party. Yay Café Press. If Albert is still interested, the game should make its way into the AtariAge store.
Thanks all -- more to come -- I'l try to start updating here more often, too.
-
Yep, Perl. It's mostly oriented to sprites and tiles... that clever HMOVE gimmick is well out of its repertoire.
-
I can send you the php code if you'd like. Or if you can wait until this weekend I'll be putting the code online after I make it interactive.
Sure, I'd 'preciate it. I'm actually modifying my nasty "mkart." I'll jot you a PM with my evil secret plans for world domination

-
Regarding the 6502, things sure are clear in hindsight. But even such, it's hard to see how anyone saw real utility for (ZP,X) addressing. I'd like to see the logic diagram for the 6502, so I could see how much logic was wasted on this.
Actually, the Commodore 64 KERNAL keeps a table of indirect vectors in ZP RAM for various service routines, including (IIRC) keyscan, print a character, and so forth. So, at least in their case, there's a good case for having a jump table in RAM indexed to find a service routine.
-
Funding, hmmm... What's a couple of hundred hours at minimum wage? A couple of thousand dollars? At contract programmer wages? Tens of thousands? Consider that Glenn Saunders put up US$1000 of his own money for the SuperCharger Contest and there have only been a couple of entries I'm aware of. (And there's less than 2 months to go.)
Yeah, ... I don't think anyone gets into game programming for the money. (Managers at Mc Donald's make more.) And Atari programming, less so. (I rather suspect the average Hemming Plaza panhandler makes more.)
However, a designer who has a good concept and is willing to learn enough about the platform's limitations/features to come up with a reasonable design plan, detailed design documents, and the like ... that's worth the effort.
Incidentally, as relates to advertising, think about things like vertical screen zones (score, playfield, whatever) or windows (on a machine newer than the 2600) and learn a little about the target machine's limitations, take what you learn into account. EG, don't plan on a VCS game having giant multicoloured characters as a critical part of the design
... but then, "slightly impossible" things may be well worth asking-for. What you'd end up with will be a lot like an animatic, a storyboard, but with notes about interactions and so forth.Something else that's often useful in formulating a design is to write the "fine" manual... having to explain how the game is played to an imaginary user can help gell the ideas.
PS: I dunno who else may have "won" that game, but it should be noted that Mayday was an "idea peddler" and I'm the programmer who picked up with his idea, i.e. CiE. And before Batari's insinuations
are taken into account, I've not the slightest idea what he looks like ... 
-
Have you remembered about page boundary crossings? They can add one cycle to your carefully timed code and are a real pain to avoid in unrolled kernels like this.
Chris
Thanks to the wonders of M4, and my total inability to perform long strings of arithmetic, and the joys of Stella, ... no

I was worried about it at first. In fact, you'll see an earlier blog screenshot where I was having problems on I think it was line (4,1) because of boundary crossings. There's only exactly one branch in the kernel -- on every second line -- and it's always taken (i.e. one of two branches are taken, so there's always a branch). The thing is, I set all my timings experimentally, running in Stella and deciding to add (n) cycles to each line with a bunch of special-case code like
if [ $1 == 7 && $2 == 0 ] SLEEP 8 endif
When M4 unrolls the loop, it does so with the variables $1, $2, and $3 set to the triplet, the offset within the triplet, and odds-or-evens (I have an example in one of past couple days' blog entries)
To make sure that minor code tweaks never do "nudget" where the boundary falls, though, I did put in this monstrosity:
jmp draw_rows align 256 draw_rows:
Thus guaranteeing that whatever I do to the prior code, the kernel will always start on a page boundary. That's fine for now (development); once I declare a "code freeze" I could probably compress out that gap and deal with the consequences once, but right now the rest of the kernel's in a state of flux, too, and I'm not as pressed for space now as I shall be, shortly.
Incidentally, the kernel (unrolled) for tile drawing is weighing in around 1K, which is terrible because it constantly accesses map data, thus preventing me from sharing it across memory banks. (I can't do mad amounts of bankswitching within the kernel).
Here's the frightening but plausible thing I thought of ... splitting map data such that the data referenced during the first 6 scanlines was found always in bank 1, the next 6 in bank 2, the next 6 in bank 3, the last 6 in bank 4. But even with Perl compiling my data and M4 composing my code, I'm not insane enough to want to split the data up like that. It'd be a logistical nightmare, more so than it is already. So i've to bite the bullet and duplicate about 1kiB of "identical" (or nearly so) code in each memory bank that's to display tile-based data. Including support stuff, that's really closed to 6 pages, possibly more, of the 16 pages banked in. 10 pages isn't a lot of space, especially given that there are alignments needed for several data

-
My goal there was originally to do matched-cycle work on every frame, i.e. have joystick and sound code that was constant-execution-time, but when I got down to it, it's probably going to be easier to just cap it off with the timer

PS: Yes, I realize that my above post is probably one that I'll be laughing about in a few weeks. "No need to use the overscan, but I forgot all about (---nightmare-here----)..."
-
You have this giant, complicated, tiled RPG and you don't use (and/or don't plan to use) the overscan for game logic as well?

Every game I've done has used the overscan for game logic, though perhaps Go Fish! didn't need to; probably it did. M-4 and Reindeer Rescue definitely needed that extra time. In fact, I had to do a lot of optimizing and juggling to fit all the game logic in!
Actually, the drawing is complicated, the script interpreter is complicated, but ultimately the game logic is downright pedestrian.
EG: The tile draw code has one moving object under joystick control. That's it. Almost everything else is static.
The combat code is turn-based. The drawing is complex, but the logic involved boils down to rolling a dice once every 10 seconds or so.
At the moment, about 1/2 of the vblank is idle time. I think I had 20+ WSYNC's in a loop to pad it out... plus a couple of others embedded to do HMOVE's.
I wouldn't rule out using it, but ... it's so little time ... *shrug*
-
Holy hell, man, you are using WSYNCs to time VBLANK!? Are you using WSYNCs to time the overscan as well?
Switch to using the RIOT timer immediately!
OK, now, I understand the objection during VBLANK, as there's game logic running concurrently and it's extremely difficult to get the timing right on that sort of code.
But, why would it bother overscan?
-
Before I realized this was for CiE, I was going to post a link to the "Combat" ROM in the AA database.
Sadly, I read that about 3 times before realizing the connection.
Amazing how I can put the blinders on, like that.
-
Not sure if this is for the Atari 2600? However, if you post the source code I'm sure that someone round here will suggest some optimisations and may be able to get it back to 2LK.
It's the tile lookups, I'm afraid. But really, the 3lk look is growing on me because it fills the screen more nicely. 8x8 tiles of 16 clocks by 24 scanlines treated as an 8x8 pixels region... means I have 4 clocks by 3 scanlines pixels...
The player and decorations are still 2lk.
The little demo I just posted the binary for is also 3,097 lines of code (excluding comments and commented-out code sections but including less than a page of graphics used in the demo)... I'll impose the gnarled nastiness of a fully unrolled kernel on the world only after I give up on it

-
I can confirm the "attachment issues"
Added another post with 'em. Or, they're in the Forums finally.
grr.
-
I like the Colony 7 demo you have posted. How do you plan to implement the secondary "Destroy all Enemies" weapon with a one button joystick?...
I did some research and it seems like some classic 2600 games just require the fire button of the second controller, like Spy Hunter and Stargate. I don't know how widespread footpedals are, but that might be a cool option then.
...
Other than that, I probably have to implement some sequence of joystick input to trigger it

Slightly (perhaps) better than reaching for a second joystick... is the Select switch... Which, of course, would require making it active for Game Select purposes only when the game is not actually being played.
Just 2¢ from the peanut gallery...

sprites suck.
in The Upward Spiral
A blog by brpocock in General
Posted
Indeed.
As my deadline looms, this drawing-list stuff is increasingly getting marked as "features for the 1.1 release" and some sketchier but easier to debug stuff getting pushed into its place. :-(
Imperfect code that mostly works is better than optimal code that mostly doesn't. Or something.
EDIT: To clarify, that is: If you don't have time to debug, rewrite it more simply and save a draft.