-
Content Count
2,433 -
Joined
-
Last visited
-
Days Won
2
Blog Comments posted by cd-w
-
-
I think it is sometimes best to keep a bit of distance between your hobby and your career. Having to work 9 to 5 on something can really suck the life out of it, and having management dictate the direction of something that you really care about can be soul destroying. I worked as a programmer in the games industry for a short time and didn't enjoy it. I now work as a web developer and program games in my spare time, which works much better for me.
Chris
-
2
-
-
Thanks for the review. The rocket scene at the end comes from the Gameboy version, e.g: http://www.youtube.com/watch?v=a-NgyryrB2U
-
Ah - I see the Space Rocks label contest thread now. I hope you get some good entries (although Nathan will probably win as usual
) -
Are you aiming for a release at the Houston Arcade Expo? That doesn't leave much time to get things ready

Chris
-
Those mockups look very impressive - I'll look at implementing them after PoP and Project Bruce

I haven't played 2600 Turbo yet (no PAL version) so I'm unclear how the corner works. Does it go from a straight road to a curve immediately or are there various intermediate stages of curvature?
Chris
-
Thanks! There's a couple of cosmetic things left like the new menu title graphic, which is going to be redone to match the label.
So there is a label already?!
Chris
-
Very nice work - I think it is now done!
Using the ARM in this way is very interesting - it makes some things easier, but you still have to worry about every byte and cycle just as with normal Atari 2600 programming. I always find the game logic to be a pain to program in 6502, so it is cool to be able to do that in C, while still doing the tricky kernel programming in 6502.
-
The heartbeat sound perfect to me now.
Chris
-
I got to 40,000 while playtesting and the heartbeat speed was pretty fast.
In the arcade game, the heartbeat speed depends (I think) on the number of remaining asteroids, so it gets faster in every wave, not just depending on your total score:
http://www.youtube.com/watch?v=WYSupJ5r2zo
Chris
-
The game looks and sounds great. I think the heartbeat sound could be more noticeably faster towards the end of each wave, but otherwise I think the sounds are perfect.
There is a possible bug with killer satellite. In one game the left half was missing entirely as it moved around the screen (before it had been shot). In another game there seemed to be a column of pixels missing from the right half of the satellite, so that there was a noticeable gap between the halves. In both cases the satellite appeared on the left of the screen moving right. Unfortunately I couldn't find the pause button quickly enough to take a screenshot.
Chris
-
I have to admit I didn't do much work on Star Castle lately, but with the darker days coming, I am sure this will change. I will post the progress in my own blog.
Thanks - I appreciate your efforts to make the game as close to the arcade version as possible.
A demo version of Star Castle is going to be available on the AA stand at PRGE, but it will be the older version before your changes.
Chris
-
One small feature request - can you add a "blip" sound when an option is changed on the menu screen. Sometimes it can be difficult to be sure the option has actually changed, particularly the color options. I think AUDC=5, AUDF=24, AUDV=8 for a few frames makes a reasonably nice sound.
Chris
-
Good point - I keep forgetting that the ARM in the Harmony doesn't have a divide unit.
How about:
1) Dropping the "bonus life" option from the menu and just hard-wiring it to 10K, or making it a feature of the level type (kids=2K, easy=5K, normal=10K, hard=20K).
2) Storing the easter-egg text as non-ASCII? If you have less than 64 letters you could pack 4 characters into every 3 bytes, i.e: AAAAAABB BBBBCCCC CCDDDDDD
Chris
-
The new sound effects are awesome - they complement the game nicely.
How about:
int HexToBCD(int value) { return ((value / 10) << 4) | (value % 10); }EDIT: I just noticed this function isn't actually used

-
I'm glad you could save a few more bytes. I can't see any more optimisations without rewriting the code.
The main area for optimisation is probably still the menu, as it is taking up a lot of space. It feels like it should be possible to replace most of the menu code with a function like this:
void set_menu_option(char *datastream, char *options, int case)
{
my_memcpy(datastream, options + (case << 4), 4*sizeof(short));
}
And you would just call it for each section of the menu:
set_menu_option(gMenuOptionsDatastream[MENU_LEVEL_ID], &menu_level_options, MM_LEVEL);
However, I'm not sure if this could be made to work for all the different options ...
Chris
-
Some more very small optimisations:
1) saucer_respawn_time could be done as 240-(x*40)
2) Use loops for this code:
// make sure we don't conflict with a reposition of Player 1, which takes 2 scanlines
if ((gEventBallDataStream[y-1] & 0xA1) == 0xA1) position = -3;
if ((gEventBallDataStream[y-2] & 0xA1) == 0xA1) position = -4;
if ((gEventBallDataStream[y-3] & 0xA1) == 0xA1) position = -5;
// make sure we don't conflict with a reposition of Player 0, which takes 2 scanlines
if ((gEventBallDataStream[y-1] & 0xC1) == 0xC1) position = -3;
if ((gEventBallDataStream[y-2] & 0xC1) == 0xC1) position = -4;
if ((gEventBallDataStream[y-3] & 0xC1) == 0xC1) position = -5;
e.g:
for (i = 0; i < 3; ++i) {
if ((gEventBallDataStream[y-(i+1)] & 0xA1) == 0xA1) position = -(i+3);
}
3) Use an inner loop:
for(i=0;i<3;i++)
{
SCORE_PF0L[2+i] = SCORE_PF0L[1];
SCORE_PF0L[7+i] = SCORE_PF0L[6];
SCORE_PF1L[2+i] = SCORE_PF1L[1];
SCORE_PF1L[7+i] = SCORE_PF1L[6];
SCORE_PF2L[2+i] = SCORE_PF2L[1];
SCORE_PF2L[7+i] = SCORE_PF2L[6];
SCORE_PF0R[2+i] = SCORE_PF0R[1];
SCORE_PF0R[7+i] = SCORE_PF0R[6];
SCORE_PF1R[2+i] = SCORE_PF1R[1];
SCORE_PF1R[7+i] = SCORE_PF1R[6];
SCORE_PF2R[2+i] = SCORE_PF2R[1];
SCORE_PF2R[7+i] = SCORE_PF2R[6];
}
becomes:
for(i=0;i<3;++i) {
for (j = 7; j >0; j-=5) {
SCORE_PF0L[j+i] = SCORE_PF0L[j-1];
SCORE_PF1L[j+i] = SCORE_PF1L[j-1];
...
}
}
4) PF_1_DIGIT_MASK and PF_02_DIGIT_MASK are basically the same values but with 2->1 and 1->2. There must be an optimisation in there but I'm not sure exactly how! Alternatively you could use the upper 4 bits for PF_1_DIGIT_MASK and the lower 4 bits for PF_02_DIGIT_MASK and mask/shift depending on which value you need. Since you are already shifting, the compiler can hopefully optimise without needing more instructions, e.g:
(PF_1_DIGIT_MASK[display[1] + i] >> 4) << 5; // compiler optimises to << 1
-
I couldn't find any large wins this time, but I think you may be able to save some bytes by doing:
1) Moving the shift operation inside the random function, so you would call it like Random32(15):
unsigned int Random32( unsigned int mask) { static unsigned int random = 0x02468ace; random = (random >> 1) ^ (unsigned int)(-(random & 1u) & 0xd0000001u); return (random & mask); }2) Packing the arrays to save bytes, e.g. the values in PF_1_DIGIT_MASK only require 2 bits each to store, so you could pack 16 of them into a single 32-bit integer:
2<<30 | 0 <<28 | 3<<26 .... 1<<4 | 2<<2 | 1<<0
You can then extract the value using a small function, e.g:
unsigned char extract_pf1_data(int[] packed, int position) { return (packed[position/16] >> ((position%16) * 2)) & 0x3; }Hopefully the bytes needed to call this function will be less than the number originally used!
3) The vector_three_on array could be calculated (2^(x+3))-(2^x) I think.
4) In the InitSpriteShotDatastreams function - if the queues are contiguous then a single memset could be used to zero all of them?
5) When calling InitShip, the x & y values are always shifted by FRACTION_BITS. You could move this shift inside the function:
gSpriteX[player] = x << FRACTION_BITS; gSpriteY[player] = (y- << FRACTION_BITS;
6) In the PrepSpeedRange function, the SPEED_RANGE and SPEED_BASE calculations could be moved inside the loop:
for (i=0;i<3;++i) { SPEED_RANGE[i] = (level >> (2-i)) + 4; SPEED_BASE[i] = (level >> (6-i) + base_adjust; ... } -
Red for Communism (and also a hint for an upcoming game release)!
-
Some space optimization suggestions:
1) Make ship_shot_x and ship_shot_y unsigned char arrays, and shift by FRACTION_BITS after loading the value, i.e. (ship_shot_x[direction] << FRACTION_BITS)
2) In the menu, replace the cases with memcpy, e.g:
case 1:
gMenuOptionsDatastream[MENU_PLAYERS_ID*10 + 0] = OPTION_2PLAYER_1;
gMenuOptionsDatastream[MENU_PLAYERS_ID*10 + 1] = OPTION_2PLAYER_B;
gMenuOptionsDatastream[MENU_PLAYERS_ID*10 + 2] = OPTION_2PLAYER_A;
becomes:
static const unsigned short player_options[][3] =
{{OPTION_2PLAYER_1, OPTION_2PLAYER_B, OPTION_2PLAYER_A},
{OPTION_2PLAYER_2, OPTION_2PLAYER_B, OPTION_2PLAYER_A},
...};
my_memcpy(gMenuOptionsDatastream[MENU_PLAYERS_ID*10], player_options[MM_PLAYERS], 3*sizeof(unsigned short));
3) When loading PF data use a loop instead of expanding every case, e.g:
SCORE_PF1L[0] = (PF_1_DIGIT_MASK[display[1] + 0] << 5) +
(PF_1_DIGIT_MASK[display[2] + 0] << 3) +
(PF_1_DIGIT_MASK[display[3] + 0] << 1) +
(PF_1_DIGIT_MASK[display[4] + 0] >> 1);
becomes:
static const char position[] = {0, 1, 5, 6, 10};
for (i = 0; i < 5; ++i) {
SCORE_PF1L[position] = (PF_1_DIGIT_MASK[display[1] + i] << 5) +
(PF_1_DIGIT_MASK[display[2] + i] << 3) +
(PF_1_DIGIT_MASK[display[3] + i] << 1) +
(PF_1_DIGIT_MASK[display[4] + i] >> 1);
SCORE_PF2L[position] = (PF_02_DIGIT_MASK[display[4] + i] >> 1) +
(PF_02_DIGIT_MASK[display[5] + i] << 1) +
(PF_02_DIGIT_MASK[display[6] + i] << 3);
SCORE_PF0R[position] = (PF_02_DIGIT_MASK[display[7] + i] << 7);
SCORE_PF1R[position] = (PF_1_DIGIT_MASK[display[7] + i] << 7) +
(PF_1_DIGIT_MASK[display[8] + i] << 5) +
(PF_1_DIGIT_MASK[display[9] + i] << 3) +
(PF_1_DIGIT_MASK[display[10] + i] << 1) +
(PF_1_DIGIT_MASK[display[11] + i] >> 1);
...
}
4) The vector_one_on array is just ^2, i.e. vector_one_on[x] -> (x+1)^2;
-
The ship warp-in effect and slower explosion look great now.
-
The warp-in looks good, but I think it needs to be offset slightly as the ship appears to the right of the effect?
The fast asteroid explosions look great, but I preferred the slower animation on the ship explosion. Perhaps you could start the ship explosion quickly and have the final frames a bit slower?
I can't wait for the arcade sound effects and then this game will be close to a perfect port.
Chris
-
The explosions look awesome - I really like how this game is turning out.
-
Just played the Gameboy version again on the Harmony today, and this is great. Can't wait for the full-color version on cart. I know this won't be cost-effective, but wouldn't it be cool to do a cart release in grey plastic, to mimic the GB?
Than would be nice, but I don't think anyone has produced new Atari cases for some time. Curt said something about considering it, and I think Fred (batari) has had managed to make one using Makerbot ...
-
The ship acceleration feels perfect now. The game looks really nice - the large high-rez rotating sprites are very different for the 2600 (even with ARM assistance).
My only complaint now is that the ship explosion looks a bit weak - is there any space for a better effect?
I really hope you finish this one and don't get distracted

Cheers,
Chris

Star Castle Developments
in For whom it may concern
A blog by Thomas Jentzsch
Posted
The rotating mines look good - much better than I was expecting! The updated siren also sounds great - nice work Ivan.
Chris