Skip to content

Commit

Permalink
Add Robotic *_prefix constants, fix REL COUNTERS/COPY behavior for 1.x (
Browse files Browse the repository at this point in the history
#442)

The combination of `REL COUNTERS` and `COPY` behaved sensibly in
MegaZeux 1.x—it applied `XPOS` and `YPOS` to both sets of coordinates,
which is the same as what the 2.00 help file *claimed* to do. However,
this is not how MegaZeux 2.x actually behaves, so the old behavior
needed a compatibility hack.
  • Loading branch information
AliceLR authored May 12, 2024
1 parent 7b197c5 commit 1aff085
Show file tree
Hide file tree
Showing 9 changed files with 82 additions and 50 deletions.
1 change: 1 addition & 0 deletions docs/changelog.txt
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ USERS
code from the previous row (as if there had been no clipping)
instead of whatever the last color code displayed was. The old
behavior is version locked to <2.93.
+ Fixed COPY when used with REL COUNTERS for 1.x worlds.

DEVELOPERS

Expand Down
4 changes: 2 additions & 2 deletions src/counter.c
Original file line number Diff line number Diff line change
Expand Up @@ -304,7 +304,7 @@ static int thisx_read(struct world *mzx_world,
int thisx, thisy;
get_robot_position(cur_robot, &thisx, &thisy);

if(mzx_world->mid_prefix == 2)
if(mzx_world->mid_prefix == REL_TO_PLAYER)
return thisx - mzx_world->player_x;

return thisx;
Expand All @@ -317,7 +317,7 @@ static int thisy_read(struct world *mzx_world,
int thisx, thisy;
get_robot_position(cur_robot, &thisx, &thisy);

if(mzx_world->mid_prefix == 2)
if(mzx_world->mid_prefix == REL_TO_PLAYER)
return thisy - mzx_world->player_y;

return thisy;
Expand Down
62 changes: 31 additions & 31 deletions src/robot.c
Original file line number Diff line number Diff line change
Expand Up @@ -2007,31 +2007,31 @@ void prefix_first_last_xy(struct world *mzx_world, int *fx, int *fy,

switch(mzx_world->first_prefix)
{
case 1:
case 5:
case REL_TO_SELF:
case REL_TO_SELF_FIRST_OR_LAST:
{
tfx += robotx;
tfy += roboty;
break;
}

case 2:
case 6:
case REL_TO_PLAYER:
case REL_TO_PLAYER_FIRST_OR_LAST:
{
find_player(mzx_world);
tfx += mzx_world->player_x;
tfy += mzx_world->player_y;
break;
}

case 3:
case REL_TO_XPOS_YPOS_FIRST_OR_LAST:
{
tfx += get_counter(mzx_world, "FIRSTXPOS", 0);
tfy += get_counter(mzx_world, "FIRSTYPOS", 0);
break;
}

case 7:
case REL_TO_XPOS_YPOS:
{
tfx += get_counter(mzx_world, "XPOS", 0);
tfy += get_counter(mzx_world, "YPOS", 0);
Expand All @@ -2041,31 +2041,31 @@ void prefix_first_last_xy(struct world *mzx_world, int *fx, int *fy,

switch(mzx_world->last_prefix)
{
case 1:
case 5:
case REL_TO_SELF:
case REL_TO_SELF_FIRST_OR_LAST:
{
tlx += robotx;
tly += roboty;
break;
}

case 2:
case 6:
case REL_TO_PLAYER:
case REL_TO_PLAYER_FIRST_OR_LAST:
{
find_player(mzx_world);
tlx += mzx_world->player_x;
tly += mzx_world->player_y;
break;
}

case 3:
case REL_TO_XPOS_YPOS_FIRST_OR_LAST:
{
tlx += get_counter(mzx_world, "LASTXPOS", 0);
tly += get_counter(mzx_world, "LASTYPOS", 0);
break;
}

case 7:
case REL_TO_XPOS_YPOS:
{
tlx += get_counter(mzx_world, "XPOS", 0);
tly += get_counter(mzx_world, "YPOS", 0);
Expand Down Expand Up @@ -2116,31 +2116,31 @@ void prefix_first_xy_var(struct world *mzx_world, int *fx, int *fy,

switch(mzx_world->first_prefix)
{
case 1:
case 5:
case REL_TO_SELF:
case REL_TO_SELF_FIRST_OR_LAST:
{
tfx += robotx;
tfy += roboty;
break;
}

case 2:
case 6:
case REL_TO_PLAYER:
case REL_TO_PLAYER_FIRST_OR_LAST:
{
find_player(mzx_world);
tfx += mzx_world->player_x;
tfy += mzx_world->player_y;
break;
}

case 3:
case REL_TO_XPOS_YPOS_FIRST_OR_LAST:
{
tfx += get_counter(mzx_world, "FIRSTXPOS", 0);
tfy += get_counter(mzx_world, "FIRSTYPOS", 0);
break;
}

case 7:
case REL_TO_XPOS_YPOS:
{
tfx += get_counter(mzx_world, "XPOS", 0);
tfy += get_counter(mzx_world, "YPOS", 0);
Expand Down Expand Up @@ -2172,31 +2172,31 @@ void prefix_last_xy_var(struct world *mzx_world, int *lx, int *ly,

switch(mzx_world->last_prefix)
{
case 1:
case 5:
case REL_TO_SELF:
case REL_TO_SELF_FIRST_OR_LAST:
{
tlx += robotx;
tly += roboty;
break;
}

case 2:
case 6:
case REL_TO_PLAYER:
case REL_TO_PLAYER_FIRST_OR_LAST:
{
find_player(mzx_world);
tlx += mzx_world->player_x;
tly += mzx_world->player_y;
break;
}

case 3:
case REL_TO_XPOS_YPOS_FIRST_OR_LAST:
{
tlx += get_counter(mzx_world, "LASTXPOS", 0);
tly += get_counter(mzx_world, "LASTYPOS", 0);
break;
}

case 7:
case REL_TO_XPOS_YPOS:
{
tlx += get_counter(mzx_world, "XPOS", 0);
tly += get_counter(mzx_world, "YPOS", 0);
Expand Down Expand Up @@ -2226,24 +2226,24 @@ void prefix_mid_xy_var(struct world *mzx_world, int *mx, int *my,
int tmx = *mx;
int tmy = *my;

switch(mzx_world->first_prefix)
switch(mzx_world->mid_prefix)
{
case 1:
case REL_TO_SELF:
{
tmx += robotx;
tmy += roboty;
break;
}

case 2:
case REL_TO_PLAYER:
{
find_player(mzx_world);
tmx += mzx_world->player_x;
tmy += mzx_world->player_y;
break;
}

case 3:
case REL_TO_XPOS_YPOS:
{
tmx += get_counter(mzx_world, "XPOS", 0);
tmy += get_counter(mzx_world, "YPOS", 0);
Expand Down Expand Up @@ -2275,22 +2275,22 @@ void prefix_mid_xy_unbound(struct world *mzx_world, int *mx, int *my, int x, int

switch(mzx_world->mid_prefix)
{
case 1:
case REL_TO_SELF:
{
tmx += x;
tmy += y;
break;
}

case 2:
case REL_TO_PLAYER:
{
find_player(mzx_world);
tmx += mzx_world->player_x;
tmy += mzx_world->player_y;
break;
}

case 3:
case REL_TO_XPOS_YPOS:
{
tmx += get_counter(mzx_world, "XPOS", 0);
tmy += get_counter(mzx_world, "YPOS", 0);
Expand Down
11 changes: 11 additions & 0 deletions src/robot.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,17 @@ enum builtin_label
LABEL_PLAYERDIED
};

enum rel_prefix
{
REL_NONE = 0,
REL_TO_SELF = 1,
REL_TO_PLAYER = 2,
REL_TO_XPOS_YPOS = 3,
REL_TO_SELF_FIRST_OR_LAST = 5,
REL_TO_PLAYER_FIRST_OR_LAST = 6,
REL_TO_XPOS_YPOS_FIRST_OR_LAST = 7,
};

#ifdef CONFIG_DEBYTECODE

CORE_LIBSPEC void change_robot_name(struct board *src_board,
Expand Down
48 changes: 31 additions & 17 deletions src/run_robot.c
Original file line number Diff line number Diff line change
Expand Up @@ -1999,7 +1999,7 @@ void run_robot(context *ctx, int id, int x, int y)
// If REL PLAYER or REL COUNTERS, use special code
switch(mzx_world->mid_prefix)
{
case 2:
case REL_TO_PLAYER:
{
// Give an ID of -1 to throw it off from not
// allowing global robot.
Expand All @@ -2009,7 +2009,7 @@ void run_robot(context *ctx, int id, int x, int y)
break;
}

case 3:
case REL_TO_XPOS_YPOS:
{
// Give an ID of -1 to throw it off from not
// allowing global robot.
Expand Down Expand Up @@ -3211,6 +3211,8 @@ void run_robot(context *ctx, int id, int x, int y)
dest_height = src_board->board_height;
}

// Note: due to a bug between 2.80 and 2.93, using a REL FIRST
// command after a REL command prevented this from working.
prefix_mid_xy_var(mzx_world, &put_x, &put_y, x, y,
dest_width, dest_height);

Expand Down Expand Up @@ -4505,9 +4507,9 @@ void run_robot(context *ctx, int id, int x, int y)
{
if(id)
{
mzx_world->first_prefix = 1;
mzx_world->mid_prefix = 1;
mzx_world->last_prefix = 1;
mzx_world->first_prefix = REL_TO_SELF;
mzx_world->mid_prefix = REL_TO_SELF;
mzx_world->last_prefix = REL_TO_SELF;
lines_run--;
goto next_cmd_prefix;
}
Expand All @@ -4516,18 +4518,28 @@ void run_robot(context *ctx, int id, int x, int y)

case ROBOTIC_CMD_REL_PLAYER: // rel player
{
mzx_world->first_prefix = 2;
mzx_world->mid_prefix = 2;
mzx_world->last_prefix = 2;
mzx_world->first_prefix = REL_TO_PLAYER;
mzx_world->mid_prefix = REL_TO_PLAYER;
mzx_world->last_prefix = REL_TO_PLAYER;
lines_run--;
goto next_cmd_prefix;
}

case ROBOTIC_CMD_REL_COUNTERS: // rel counters
{
mzx_world->first_prefix = 3;
mzx_world->mid_prefix = 3;
mzx_world->last_prefix = 3;
mzx_world->first_prefix = REL_TO_XPOS_YPOS;
mzx_world->mid_prefix = REL_TO_XPOS_YPOS;
mzx_world->last_prefix = REL_TO_XPOS_YPOS;

// The REL COUNTERS commands are broken in 2.00+ - the usage of
// XPOS/YPOS and FIRSTXPOS/FIRSTYPOS/LASTXPOS/LASTYPOS are reversed.
// This seems to be intentional but is completely backwards from what
// the 2.00 help file claimed (and what would be sensible).
if(mzx_world->version >= V200)
{
mzx_world->first_prefix = REL_TO_XPOS_YPOS_FIRST_OR_LAST;
mzx_world->last_prefix = REL_TO_XPOS_YPOS_FIRST_OR_LAST;
}
lines_run--;
goto next_cmd_prefix;
}
Expand Down Expand Up @@ -4952,7 +4964,7 @@ void run_robot(context *ctx, int id, int x, int y)
{
if(id)
{
mzx_world->first_prefix = 5;
mzx_world->first_prefix = REL_TO_SELF_FIRST_OR_LAST;
lines_run--;
goto next_cmd_prefix;
}
Expand All @@ -4963,7 +4975,7 @@ void run_robot(context *ctx, int id, int x, int y)
{
if(id)
{
mzx_world->last_prefix = 5;
mzx_world->last_prefix = REL_TO_SELF_FIRST_OR_LAST;
lines_run--;
goto next_cmd_prefix;
}
Expand All @@ -4972,28 +4984,30 @@ void run_robot(context *ctx, int id, int x, int y)

case ROBOTIC_CMD_REL_PLAYER_FIRST: // Rel player first
{
mzx_world->first_prefix = 6;
mzx_world->first_prefix = REL_TO_PLAYER_FIRST_OR_LAST;
lines_run--;
goto next_cmd_prefix;
}

case ROBOTIC_CMD_REL_PLAYER_LAST: // Rel player last
{
mzx_world->last_prefix = 6;
mzx_world->last_prefix = REL_TO_PLAYER_FIRST_OR_LAST;
lines_run--;
goto next_cmd_prefix;
}

case ROBOTIC_CMD_REL_COUNTERS_FIRST: // Rel counters first
{
mzx_world->first_prefix = 7;
// BUG: should be REL_TO_XPOS_YPOS_FIRST_OR_LAST (see REL COUNTERS).
mzx_world->first_prefix = REL_TO_XPOS_YPOS;
lines_run--;
goto next_cmd_prefix;
}

case ROBOTIC_CMD_REL_COUNTERS_LAST: // Rel counters last
{
mzx_world->last_prefix = 7;
// BUG: should be REL_TO_XPOS_YPOS_FIRST_OR_LAST (see REL COUNTERS).
mzx_world->last_prefix = REL_TO_XPOS_YPOS;
lines_run--;
goto next_cmd_prefix;
}
Expand Down
Binary file added testworlds/1.00/010 rel counters copy.mzx
Binary file not shown.
3 changes: 3 additions & 0 deletions testworlds/1.00/010 rel counters copy.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Title: REL COUNTERS COPY Test
Author: Alice Rowan
Desc: REL COUNTERS on COPY behaves sanely in 1.x: it applies XPOS and YPOS to both sets of coordinates. If only someone had checked what 1.x did when adding the 2.00 behavior!
Binary file added testworlds/2.51/015 rel counters copy.mzx
Binary file not shown.
3 changes: 3 additions & 0 deletions testworlds/2.51/015 rel counters copy.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
Title: REL COUNTERS COPY Test
Author: Alice Rowan
Desc: REL COUNTERS and REL COUNTERS FIRST/LAST on COPY and COPY BLOCK have been broken since 2.00 in a possibly intentional and very pointless way: REL COUNTERS, despite it being claimed to apply XPOS and YPOS to both coordinate sets, instead applies FIRSTXPOS, FIRSTYPOS, LASTXPOS, and LASTYPOS. REL COUNTERS FIRST/LAST, despite them being claimed to apply the latter to either the first or last set of coordinates, applies XPOS and YPOS to their respective set of coordinates instead.

0 comments on commit 1aff085

Please sign in to comment.