Doubt that would help with the jittering.
You're remembering to truncate to single bytes, right? Nothing can be greater than 255 in an NES game, remember. SNES may give you a little more leeway, but you'd still need to watch your truncations.
Did you do what I've been doing and handle the carry bit manually? I mean, if you really want to use fractions, you'd take the fractional speed denominator value, divide it by 256, then add the integral speed. So if you have horz_2=$40 and horz_3=$01, hspeed would be $01+$40/$100 or $140/$100 or 5/4. In GM8, at least on my computers, that suffices to prevent jitteriness (I never use decimals because that's always caused jitters for me). Gravity, friction, and other acceleration is almost always fractional and follows the same rule. If you apply a gravity of $10 each step (as CV3 does with Living Armors and zombies), you'd set gravity to $10/$100 or 1/16.
Actually I'm veering away from the carry bit. In most situations it's not necessary. The only time you really need it is when dealing with bitwise rotations. For adding and subtracting, you can just compare the previous result to what was added. So if x+$10 < $10 would mean the carry bit was set, so you'd use y+=x+$10<$10 to increase y only when x+$10 is greater than $FF. For subtraction, you'd use y+=x-$10&$FF<$FF-$10. (Edit: Had to reverse the sign. Carry bit gets set when the subtraction
doesn't cause an overflow. That's why CMP->BCC is used for less-than conditionals.)
Also, I'm feeling really happy with myself because while working on the Axe Knights (god, I hate their actual code) I thought up some codes for boomerangs. I had an idea for a boomerang that simply rises up if thrown from a crouch or down when thrown from a standing position so it still returns to the enemy that threw it (like the Quick Boomerang in MM2). I also had an idea for a boomerange that would be thrown downward and then arches back up subtly. I am quite pleased with that idea.

I'm kinda interested in the programming methods used by NR&D1 and NEAD, especially NR&D1 though. Think it'd be interesting to see how pioneers of console gaming used to program. Konami's "phase" system in CV3 is kinda hard to read even with a GM translation, but I like it. Logically, it's fairly sound -- increase a variable and only process the code defined by that variable. Even though all the code still gets dumped into the RAM, the CPU skips most of it. I think it also makes AI easier to interpret once you get past the messiness of it all.
To illustrate this, here's my translated Axe Knight code:
switch path_speed
{
case 0:
path_speed += 1;
state_set($40);
sprite_index = spr_AxeKnight;
image_speed = 1/$E;
image_index = image_speed;
state_clear($20);
if !(path_orientation & $80)
{
if !(path_orientation & $30)
{
state_set($20);
state_clear($40);
if seed_x + x & 1
sprite_index = spr_AxeKnight_dkat;
else
sprite_index = spr_AxeKnight_stat;
path_speed += 1;
path_orientation |= $10;
}
else
path_orientation = (path_orientation & $CF)|((path_orientation>>4)-1<<4);
}
path_endaction = $21;
image_xscale = sign(x-obj_Belmont.x-x)|1;
if abs(x-obj_Belmont.x) >= $60
{
horz_3 = $FF * (x > obj_Belmont.x);
horz_2 = $60 ^ $FF*(x > obj_Belmont.x) + (x > obj_Belmont.x);
}
else
{
horz_3 = $FF * (x < obj_Belmont.x);
horz_2 = $60 ^ $FF*(x < obj_Belmont.x) + (x < obj_Belmont.x);
}
break;
case 1:
//Check if axe is thrown
if path_orientation & $80
//Check if axe has returned
if abs(x-my_axe.x)<$4
{
//Destroy the axe
path_orientation &= $7F;
with my_axe
instance_destroy();
}
switch tile_map_read(0,2,$08,$00,-1)
{
case 0:
case 4:
move_horz_rev();
break;
}
if tile_map_read(0,2,$08,$F8,-1)
move_horz_rev();
case 2:
path_scale = $0A;
path_speed += 1;
break;
case 3:
case 6:
step_scale_dec();
break;
case 4:
image_index += 1;
path_speed += 1;
break;
case 5:
path_scale = $08;
path_speed += 1;
break;
case 7:
//Throw axe if ducking
if sprite_index = spr_AxeKnight_dkat
{
my_axe = instance_create(x+( $08^$FF*(image_xscale>0)+(image_xscale>0) ),
y+$09,obj_KnightAxe);
with my_axe
{
move_stop(1);
horz_3 = $01 ^ $FF*(image_xscale > 0);
horz_2 = $80;
state_set($60);
image_xscale = -1;
damage = $10+$10*(hard_mode || stage>=$0A);
}
}
else
{
my_axe = instance_create(x+( $14^$FF*(image_xscale>0)+(image_xscale>0) ),
y+$F6,obj_KnightAxe);
}
path_orientation = path_orientation & $70 | $80;
path_speed = 0;
break;
}
As much as I hate it, it's one of the simpler codes. Compare that to something as deceptively simple as a fuzzy:
//You can set path_orientation to [0,3] in Instance Creation Code to vary motion
var j;
switch path_speed
{
case 0:
sprite_index = spr_Fuzzy;
image_speed = 1/$04;
image_index = image_speed;
path_speed += 1;
state_set($40);
move_stop(1);
break;
case 1:
switch path_orientation
{
case 0:
path_scale = 0;
path_endaction = 0;
path_orientation = 2;
break;
case 1:
case 2:
path_scale = 1;
path_endaction = 2;
break;
case 3:
path_scale = 0;
path_endaction = 0;
break;
case 4:
path_scale = 0;
path_endaction = 1;
path_orientation = 3;
break;
}
path_speed += 1;
j = (path_orientation << 2) + path_endaction
horz_3 = data_h3[j];
horz_2 = data_h2[j];
vert_3 = data_v3[j];
vert_2 = data_v2[j];
break;
case 2:
case 3:
j = path_endaction + (path_scale << 3);
if !tile_map_read(1,0,data_x[j],data_y[j],-1)
{
path_speed += (path_speed == 2) - (path_speed == 3);
path_endaction = data_e[j];
j = (path_orientation << 2) + path_endaction
horz_3 = data_h3[j];
horz_2 = data_h2[j];
vert_3 = data_v3[j];
vert_2 = data_v2[j];
}
else
{
if tile_map_read(1,0,data_x[j+4],data_y[j+4],-1)
{
path_endaction = data_e[j+4];
j = (path_orientation << 2) + path_endaction
horz_3 = data_h3[j];
horz_2 = data_h2[j];
vert_3 = data_v3[j];
vert_2 = data_v2[j];
}
}
break;
}
Each of those arrays had to be defined in a separate script and contain 16 indices each!
And then there's my favorite so far, the owls.
switch path_speed
{
case 0: //Disable animation
state_set($20);
path_speed += 1;
break;
case 1: //Disable interactivity
state_set($10);
path_speed += 1;
break;
case 2: //Set sprite
sprite_index = spr_Owl;
image_index = 1;
path_speed = 0;
break;
case 3: //Set delay before appearing
path_speed += 1;
path_scale = $0F;
path_endaction = 0;
switch ((x-view_xview+y & $FF)>>3)+seed_y & $07
{
case 0:
path_orientation = $7C;
break;
case 1:
case 2:
path_orientation = $48;
break;
case 3:
path_orientation = $65;
break;
case 4:
path_orientation = $63;
break;
case 5:
path_orientation = $5C;
break;
case 6:
path_orientation = $8F;
break;
case 7:
path_orientation = $54;
break;
}
break;
case 4:
if state & 1
break;
path_scale -= 1;
if !path_scale
//Blink eyes (really just toggling visibility)
{
path_endaction ^= 1;
path_scale = $07+$21*!(path_endaction & 1);
state_toggle($08);
}
//Restore visibility and attack
path_orientation -= path_orientation>0;
if !path_orientation
state_clear($08);
path_speed += path_orientation == 0;
break;
case 5:
case 8:
case 12:
case 23:
image_index += 1;
path_speed += 1;
break;
case 6:
path_scale = $03;
path_speed += 1;
break;
case 7:
case 10:
case 14:
case 18:
case 21:
case 30:
step_scale_dec();
break;
case 9:
case 13:
path_scale = $10;
path_speed += 1;
break;
case 11: //Restore interactivity
state_clear($10);
path_speed += 1;
break;
case 15: //Set vertical speed to upward
path_speed += 1;
move_stop(1);
vert_3 = $FF;
break;
case 16:
case 22:
case 32: //Enable movement
state_set($40);
path_speed += 1;
break;
case 17:
path_scale = $06;
path_speed += 1;
break;
case 19: //Stop movement
case 27:
state_clear($40);
path_speed += 1;
break;
case 20:
path_scale = $04;
path_speed += 1;
break;
case 24: //Set motion toward Belmont relative to distance
case 33:
path_speed += 1;
image_xscale = sign(x-obj_Belmont.x)|1;
switch (abs(x-obj_Belmont.x) & $F0)>>4
{
case 0:
horz_3 = $00;
horz_2 = $C0;
break;
case 1:
horz_3 = $01;
horz_2 = $80;
break;
case 2:
horz_3 = $01;
horz_2 = $C0;
break;
case 3:
horz_3 = $02;
horz_2 = $00;
break;
case 4:
horz_3 = $02;
horz_2 = $80;
break;
case 5:
horz_3 = $02;
horz_2 = $C0;
break;
case 6:
horz_3 = $03;
horz_2 = $00;
break;
case 7:
horz_3 = $03;
horz_2 = $80;
break;
case 8:
horz_3 = $03;
horz_2 = $C0;
break;
case 9:
horz_3 = $04;
horz_2 = $80;
break;
}
if image_xscale
move_horz_rev();
switch (abs(y-obj_Belmont.y) & $F0)>>4
{
case 0:
vert_3 = $01;
vert_2 = $80;
break;
case 1:
vert_3 = $01;
vert_2 = $C0;
break;
case 2:
vert_3 = $02;
vert_2 = $00;
break;
case 3:
vert_3 = $02;
vert_2 = $80;
break;
case 4:
vert_3 = $02;
vert_2 = $C0;
break;
case 5:
vert_3 = $03;
vert_2 = $00;
break;
case 6:
vert_3 = $03;
vert_2 = $80;
break;
case 7:
vert_3 = $03;
vert_2 = $C0;
break;
case 8:
vert_3 = $04;
vert_2 = $00;
break;
case 9:
vert_3 = $04;
vert_2 = $80;
break;
}
break;
case 25: //Swoop down
case 34:
if vert_3 < $80
move_vert_inc($10,1);
else
//Flap wings to gain altitude
{
sprite_index = spr_Owl_flap;
image_index = 0;
image_speed = 1/$8
path_scale = $30;
state_clear($20);
path_speed += 1;
}
break;
case 26: //Fly upwards
path_scale -= 1;
if path_scale
move_vert_inc($10,1);
else
path_speed += 1;
break;
case 28:
image_xscale = sign(x-obj_Belmont.x)|1;
path_speed += 1;
break;
case 29:
path_scale = $20;
path_speed += 1;
break;
case 31: //Swoop down
sprite_index = spr_Owl;
image_index = 4;
state_set($20);
path_speed += 1;
break;
case 35: //Fly away off screen
move_horz_inc($10,image_xscale > 0);
if y-view_yview < $28 || y-view_yview >= $E8
instance_destroy();
break;
}
OMG BRAINSTORM! DISCUS SKELETON! He throws it down toward the ground and it bounces up then arches back toward the ground (or off the screen, whichever). Like skipping a Frisbee. I could so totally program that in CV3's style!