diff --git a/src/bss.h b/src/bss.h index e50f4cf..f5ed824 100644 --- a/src/bss.h +++ b/src/bss.h @@ -21,7 +21,13 @@ #include "screens/title.h" #include "sprites.h" -unsigned char playfield[PLAYFIELD_WIDTH * PLAYFIELD_HEIGHT]; +#define PLAYFIELD_BYTES ((PLAYFIELD_WIDTH * PLAYFIELD_HEIGHT) >> 2) + +// The state of every tile in the playfield. +unsigned char playfield_tiles[PLAYFIELD_BYTES]; + +// The line-related flags for each playfield tile. +unsigned char playfield_line_flags[PLAYFIELD_BYTES]; #if ENABLE_CHEATS unsigned char enable_ball_line_collisions; diff --git a/src/data.h b/src/data.h index 9cf0160..264cd5f 100644 --- a/src/data.h +++ b/src/data.h @@ -27,10 +27,6 @@ #define set_temp_ptr(p) (temp_ptr_1 = (unsigned char*)(p)) #define get_temp_ptr(type) ((type*)temp_ptr_1) -#define get_playfield_index() (temp_int_3) -#define set_playfield_index(a) (temp_int_3 = (a)) -#define inc_playfield_index() (++temp_int_3) - #define get_should_initialize_clear_sweep() (temp_byte_6) #define set_should_initialize_clear_sweep(a) (temp_byte_6 = (a)) @@ -90,7 +86,4 @@ #define get_y_compare_pixel_coord() (temp_byte_4) #define set_y_compare_pixel_coord(a) (temp_byte_4 = (a)) -#define get_playfield_tile_value() (temp_byte_4) -#define set_playfield_tile_value(a) (temp_byte_4 = (a)) - #endif // __JEZNES_DATA_H__ diff --git a/src/debug.h b/src/debug.h index 76eb235..46247bf 100644 --- a/src/debug.h +++ b/src/debug.h @@ -9,7 +9,7 @@ // These macros enable various debugging features and should probably be turned // off before release. -#define DEBUG 0 +#define DEBUG 1 // DEBUG macro gates all the debug features. #if DEBUG @@ -18,14 +18,18 @@ // screen. The vertical position of this line indicates how much CPU was used // by the game loop logic. // ie: A line drawn lower down on the screen consumed more CPU. -#define DRAW_GRAY_LINE 1 +#define DRAW_GRAY_LINE 0 // Draw a highlight tile on the playfield at the nearest tile location to each // ball sprite. #define DRAW_BALL_NEAREST_TILE_HIGHLIGHT 0 // Enable the use of cheat code input sequences. -#define ENABLE_CHEATS 1 +#define ENABLE_CHEATS 0 + +// Put perf-sensitive code blocks into functions instead of macros. +// Use to enable profiling critical code blocks by isolating them. +#define PUT_CRITICAL_CODE_IN_FUNCTIONS 1 #endif diff --git a/src/flags/playfield.h b/src/flags/playfield.h index 150487f..450dd73 100644 --- a/src/flags/playfield.h +++ b/src/flags/playfield.h @@ -8,112 +8,120 @@ #define __JEZNES_FLAGS_PLAYFIELD_H__ #include "base.h" +#include "lib/nesdoug.h" -#define PLAYFIELD_BIT_LINE_ORIENTATION 7 -#define PLAYFIELD_BITMASK_LINE_ORIENTATION (1 << PLAYFIELD_BIT_LINE_ORIENTATION) -#define PLAYFIELD_BIT_LINE_INDEX 6 +#define PLAYFIELD_BITMASK_ALL 0b11 + +#define PLAYFIELD_TILE_TABLE(name, base_value) \ +const unsigned char name##_table[] = { \ + base_value << 0, \ + base_value << 2, \ + base_value << 4, \ + base_value << 6, \ +}; + +#define PLAYFIELD_TILE_TYPE_TABLE(name, base_value) PLAYFIELD_TILE_TABLE(playfield_tile_type_##name, base_value) + +PLAYFIELD_TILE_TABLE(playfield_bitmask_tile, PLAYFIELD_BITMASK_ALL) + +#define PLAYFIELD_TILE_TYPE_UNCLEARED_UNMARKED 0b00 +#define PLAYFIELD_TILE_TYPE_UNCLEARED_MARKED 0b01 +#define PLAYFIELD_TILE_TYPE_LINE 0b10 +#define PLAYFIELD_TILE_TYPE_WALL 0b11 + +PLAYFIELD_TILE_TYPE_TABLE(uncleared_unmarked, PLAYFIELD_TILE_TYPE_UNCLEARED_UNMARKED) +PLAYFIELD_TILE_TYPE_TABLE(uncleared_marked, PLAYFIELD_TILE_TYPE_UNCLEARED_MARKED) +PLAYFIELD_TILE_TYPE_TABLE(line, PLAYFIELD_TILE_TYPE_LINE) +PLAYFIELD_TILE_TYPE_TABLE(wall, PLAYFIELD_TILE_TYPE_WALL) + +#define PLAYFIELD_BIT_LINE_INDEX 0 #define PLAYFIELD_BITMASK_LINE_INDEX (1 << PLAYFIELD_BIT_LINE_INDEX) -#define PLAYFIELD_BIT_LINE_DIRECTION 5 +#define PLAYFIELD_BIT_LINE_DIRECTION 1 #define PLAYFIELD_BITMASK_LINE_DIRECTION (1 << PLAYFIELD_BIT_LINE_DIRECTION) -#define PLAYFIELD_BIT_MARK 4 -#define PLAYFIELD_BITMASK_MARK (1 << PLAYFIELD_BIT_MARK) - -// Bitmask for playfield byte which separates only the flag bits. -#define PLAYFIELD_BITMASK_ALL \ - (PLAYFIELD_BITMASK_LINE_ORIENTATION | PLAYFIELD_BITMASK_LINE_INDEX | \ - PLAYFIELD_BITMASK_LINE_DIRECTION | PLAYFIELD_BITMASK_MARK) - -// Bitmask for playfield byte which removes the flag bits. -#define PLAYFIELD_BITMASK_NONE (~PLAYFIELD_BITMASK_ALL) - -#define get_playfield_flag(playfield_index, bitmask) \ - get_flag(playfield[(playfield_index)], (bitmask)) -#define set_playfield_flag(playfield_index, bitmask) \ - set_flag(playfield[(playfield_index)], (bitmask)) -#define unset_playfield_flag(playfield_index, bitmask) \ - unset_flag(playfield[(playfield_index)], (bitmask)) - -#define get_playfield_is_marked_flag_from_byte(flags_byte) \ - get_flag((flags_byte), PLAYFIELD_BITMASK_MARK) - -#define unset_playfield_is_marked_flag_in_byte(flags_byte) \ - unset_flag((flags_byte), PLAYFIELD_BITMASK_MARK) - -#define get_playfield_is_marked_flag(playfield_index) \ - get_playfield_flag((playfield_index), PLAYFIELD_BITMASK_MARK) -#define set_playfield_is_marked_flag(playfield_index) \ - set_playfield_flag((playfield_index), PLAYFIELD_BITMASK_MARK) -#define unset_playfield_is_marked_flag(playfield_index) \ - unset_playfield_flag((playfield_index), PLAYFIELD_BITMASK_MARK) - -// Returns the line direction for a playfield byte which will be either -// LINE_DIRECTION_POSITIVE or LINE_DIRECTION_NEGATIVE -#define get_playfield_line_direction_flag_from_byte(flags_byte) \ - (((flags_byte)&PLAYFIELD_BITMASK_LINE_DIRECTION) >> \ - PLAYFIELD_BIT_LINE_DIRECTION) - -// Returns the line direction for a playfield tile at |playfield_index| which -// will be either LINE_DIRECTION_POSITIVE or LINE_DIRECTION_NEGATIVE -#define get_playfield_line_direction_flag(playfield_index) \ - get_playfield_line_direction_flag_from_byte((playfield_index)) - -// Returns the line orientation for a playfield byte which will be either -// ORIENTATION_HORIZ or ORIENTATION_VERT -#define get_playfield_line_orientation_flag_from_byte(flags_byte) \ - (((flags_byte)&PLAYFIELD_BITMASK_LINE_ORIENTATION) >> \ - PLAYFIELD_BIT_LINE_ORIENTATION) - -// Returns the line orientation for a playfield tile at |playfield_index| which -// will be either ORIENTATION_HORIZ or ORIENTATION_VERT -#define get_playfield_line_orientation_flag(playfield_index) \ - (get_playfield_line_orientation_flag_from_byte(playfield[(playfield_index)])) - -// Sets the line orientation for |playfield_index| to |orientation| which must -// be either ORIENTATION_HORIZ or ORIENTATION_VERT -#define set_playfield_line_orientation_flag(playfield_index, orientation) \ - (playfield[(playfield_index)] = \ - playfield[(playfield_index)] & ~PLAYFIELD_BITMASK_LINE_ORIENTATION | \ - ((orientation) << PLAYFIELD_BIT_LINE_ORIENTATION)) - -// Returns the line index from a playfield byte which will be either 0 or 1 -#define get_playfield_line_index_flag_from_byte(flags_byte) \ - (((flags_byte)&PLAYFIELD_BITMASK_LINE_INDEX) >> PLAYFIELD_BIT_LINE_INDEX) - -// Returns the line index for a playfield tile at |playfield_index| which will -// be either 0 or 1 -#define get_playfield_line_index_flag(playfield_index) \ - (get_playfield_line_index_flag_from_byte(playfield[(playfield_index)])) - -// Sets the line index for |playfield_index| to |index| which must be either 0 -// or 1 -#define set_playfield_line_index_flag(playfield_index, index) \ - (playfield[(playfield_index)] = \ - playfield[(playfield_index)] & ~PLAYFIELD_BITMASK_LINE_INDEX | \ - ((index) << PLAYFIELD_BIT_LINE_INDEX)) - -// Returns the playfield tile type from a playfield byte |flags_byte| by -// removing the bit-flags from the playfield byte -#define get_playfield_tile_type_from_byte(flags_byte) \ - ((flags_byte)&PLAYFIELD_BITMASK_NONE) - -// Returns the playfield tile type for |playfield_index| by removing the -// bit-flags from the playfield byte -#define get_playfield_tile_type(playfield_index) \ - get_playfield_tile_type_from_byte(playfield[(playfield_index)]) - -// Update the playfield in-memory structure. -#define set_playfield_tile_type(playfield_index, tile_type) \ - (playfield[(playfield_index)] = (tile_type)) - -// Get the playfield tile type for lines. -// Indicate horizontal or vertical via |orientation| which should be -// ORIENTATION_HORIZ or ORIENTATION_VERT. Indicate the line index via -// |line_index| which must be 0 or 1. Indicate the line direction via -// |line_direction| which should be LINE_DIRECTION_POSITIVE or -// LINE_DIRECTION_NEGATIVE. -#define get_playfield_tile_type_line(orientation, line_index, line_direction) \ - (PLAYFIELD_LINE | ((orientation) << PLAYFIELD_BIT_LINE_ORIENTATION) | \ - ((line_index) << PLAYFIELD_BIT_LINE_INDEX) | \ - ((line_direction) << PLAYFIELD_BIT_LINE_DIRECTION)) + +#define PLAYFIELD_TILE_LINE_FLAG_TABLE(name, base_value) PLAYFIELD_TILE_TABLE(playfield_tile_line_##name, base_value) + +PLAYFIELD_TILE_LINE_FLAG_TABLE(index, PLAYFIELD_BITMASK_LINE_INDEX) +PLAYFIELD_TILE_LINE_FLAG_TABLE(direction, PLAYFIELD_BITMASK_LINE_DIRECTION) + +#define get_playfield_tile_byte_index(playfield_tile_index) ((unsigned char)((playfield_tile_index) >> 2)) +#define get_playfield_tile_in_byte_index(playfield_tile_index) (((unsigned char)(playfield_tile_index)) & 0b11) + +#define get_playfield_tile_position(playfield_tile_index) (make_word(get_playfield_tile_byte_index(get_current_position()), get_playfield_tile_in_byte_index(get_current_position()))) + +// Playfield tile accessor macros + +#define get_playfield_tile_raw_value_from_byte_index(playfield_tile_byte_index, playfield_tiles_array) (playfield_tiles_array[(playfield_tile_byte_index)]) +#define get_playfield_tile_raw_value(playfield_tile_index, playfield_tiles_array) (get_playfield_tile_raw_value_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), (playfield_tiles_array))) + +#define get_playfield_tile_masked_value_from_raw_byte_and_bitmask(raw_byte, bitmask) ((raw_byte) & (bitmask)) +#define get_playfield_tile_masked_value_from_raw_byte(raw_byte, playfield_tile_in_byte_index) (get_playfield_tile_masked_value_from_raw_byte_and_bitmask((raw_byte), playfield_bitmask_tile_table[(playfield_tile_in_byte_index)])) +#define get_playfield_tile_masked_value_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index, playfield_tiles_array) (get_playfield_tile_masked_value_from_raw_byte(get_playfield_tile_raw_value_from_byte_index((playfield_tile_byte_index), (playfield_tiles_array)), (playfield_tile_in_byte_index))) +#define get_playfield_tile_masked_value(playfield_tile_index, playfield_tiles_array) (get_playfield_tile_masked_value_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)), (playfield_tiles_array))) + +#define get_playfield_tile_value_from_masked_byte(masked_byte, playfield_tile_in_byte_index) ((masked_byte) >> ((playfield_tile_in_byte_index) << 1)) +#define get_playfield_tile_value_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index, playfield_tiles_array) (get_playfield_tile_value_from_masked_byte(get_playfield_tile_masked_value_from_byte_index((playfield_tile_byte_index), (playfield_tile_in_byte_index), (playfield_tiles_array)), (playfield_tile_in_byte_index))) +#define get_playfield_tile_value(playfield_tile_index, playfield_tiles_array) (get_playfield_tile_value_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)), (playfield_tiles_array))) + +#define is_playfield_tile_mask_set_from_masked_byte(masked_byte, bitmask) ((masked_byte) == (bitmask)) +#define is_playfield_tile_mask_set_from_masked_byte_table(masked_byte, playfield_tile_in_byte_index, bitmask_table) (is_playfield_tile_mask_set_from_masked_byte((masked_byte), (bitmask_table)[(playfield_tile_in_byte_index)])) +#define is_playfield_tile_mask_set_from_raw_byte(raw_byte, playfield_tile_in_byte_index, bitmask) (get_playfield_tile_masked_value_from_raw_byte((raw_byte), (playfield_tile_in_byte_index)) == (bitmask)) +#define is_playfield_tile_mask_set_from_raw_byte_table(raw_byte, playfield_tile_in_byte_index, bitmask_table) (is_playfield_tile_mask_set_from_raw_byte((raw_byte), (playfield_tile_in_byte_index), (bitmask_table)[(playfield_tile_in_byte_index)])) +#define is_playfield_tile_mask_set_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index, playfield_tiles_array, bitmask) (is_playfield_tile_mask_set_from_raw_byte(get_playfield_tile_raw_value_from_byte_index((playfield_tile_byte_index), (playfield_tiles_array)), (playfield_tile_in_byte_index), (bitmask))) +#define is_playfield_tile_mask_set_from_byte_index_table(playfield_tile_byte_index, playfield_tile_in_byte_index, playfield_tiles_array, bitmask_table) (is_playfield_tile_mask_set_from_byte_index((playfield_tile_byte_index), (playfield_tile_in_byte_index), (playfield_tiles_array), (bitmask_table)[(playfield_tile_in_byte_index)])) +#define is_playfield_tile_mask_set(playfield_tile_index, playfield_tiles_array, bitmask) (is_playfield_tile_mask_set_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)), (playfield_tiles_array), (bitmask))) +#define is_playfield_tile_mask_set_table(playfield_tile_index, playfield_tiles_array, bitmask_table) (is_playfield_tile_mask_set_from_byte_index_table(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)), (playfield_tiles_array), (bitmask_table))) + +#define set_playfield_tile_value_in_raw_byte(raw_byte, playfield_tile_in_byte_index, value_bitmask) ((raw_byte) = (raw_byte & ~(playfield_bitmask_tile_table[(playfield_tile_in_byte_index)])) | (value_bitmask)) +#define set_playfield_tile_value_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index, playfield_tiles_array, value_bitmask) (set_playfield_tile_value_in_raw_byte(get_playfield_tile_raw_value_from_byte_index((playfield_tile_byte_index), (playfield_tiles_array)), (playfield_tile_in_byte_index), (value_bitmask))) +#define set_playfield_tile_value_from_byte_index_table(playfield_tile_byte_index, playfield_tile_in_byte_index, playfield_tiles_array, value_bitmask_table) (set_playfield_tile_value_from_byte_index((playfield_tile_byte_index), (playfield_tile_in_byte_index), (playfield_tiles_array), (value_bitmask_table)[(playfield_tile_in_byte_index)])) +#define set_playfield_tile_value(playfield_tile_index, playfield_tiles_array, value_bitmask) (set_playfield_tile_value_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)), (playfield_tiles_array), (value_bitmask))) +#define set_playfield_tile_value_table(playfield_tile_index, playfield_tiles_array, value_bitmask_table) (set_playfield_tile_value_from_byte_index_table(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)), (playfield_tiles_array), (value_bitmask_table))) + +// Playfield tile type accessor macros + +#define is_playfield_tile_type_uncleared_unmarked_from_masked_byte(masked_byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_masked_byte_table((masked_byte), (playfield_tile_in_byte_index), playfield_tile_type_uncleared_unmarked_table)) +#define is_playfield_tile_type_uncleared_unmarked_from_raw_byte(raw_byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_raw_byte_table((raw_byte), (playfield_tile_in_byte_index), playfield_tile_type_uncleared_unmarked_table)) +#define is_playfield_tile_type_uncleared_unmarked_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_byte_index_table((playfield_tile_byte_index), (playfield_tile_in_byte_index), playfield_tiles, playfield_tile_type_uncleared_unmarked_table)) +#define is_playfield_tile_type_uncleared_unmarked(playfield_tile_index) (is_playfield_tile_mask_set_table((playfield_tile_index), playfield_tiles, playfield_tile_type_uncleared_unmarked_table)) + +#define is_playfield_tile_type_uncleared_marked_from_masked_byte(masked_byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_masked_byte_table((masked_byte), (playfield_tile_in_byte_index), playfield_tile_type_uncleared_marked_table)) +#define is_playfield_tile_type_uncleared_marked_from_raw_byte(raw_byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_raw_byte_table((raw_byte), (playfield_tile_in_byte_index), playfield_tile_type_uncleared_marked_table)) +#define is_playfield_tile_type_uncleared_marked_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_byte_index_table((playfield_tile_byte_index), (playfield_tile_in_byte_index), playfield_tiles, playfield_tile_type_uncleared_marked_table)) +#define is_playfield_tile_type_uncleared_marked(playfield_tile_index) (is_playfield_tile_mask_set_table((playfield_tile_index), playfield_tiles, playfield_tile_type_uncleared_marked_table)) + +#define is_playfield_tile_type_wall_from_masked_byte(masked_byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_masked_byte_table((masked_byte), (playfield_tile_in_byte_index), playfield_tile_type_wall_table)) +#define is_playfield_tile_type_wall_from_raw_byte(raw_byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_raw_byte_table((raw_byte), (playfield_tile_in_byte_index), playfield_tile_type_wall_table)) +#define is_playfield_tile_type_wall_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_byte_index_table((playfield_tile_byte_index), (playfield_tile_in_byte_index), playfield_tiles, playfield_tile_type_wall_table)) +#define is_playfield_tile_type_wall(playfield_tile_index) (is_playfield_tile_mask_set_table((playfield_tile_index), playfield_tiles, playfield_tile_type_wall_table)) + +#define is_playfield_tile_type_line_from_masked_byte(masked_byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_masked_byte_table((masked_byte), (playfield_tile_in_byte_index), playfield_tile_type_line_table)) +#define is_playfield_tile_type_line_from_raw_byte(raw_byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_raw_byte_table((raw_byte), (playfield_tile_in_byte_index), playfield_tile_type_line_table)) +#define is_playfield_tile_type_line_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_byte_index_table((playfield_tile_byte_index), (playfield_tile_in_byte_index), playfield_tiles, playfield_tile_type_line_table)) +#define is_playfield_tile_type_line(playfield_tile_index) (is_playfield_tile_mask_set_table((playfield_tile_index), playfield_tiles, playfield_tile_type_line_table)) + +#define set_playfield_tile_type_uncleared_unmarked_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (playfield_tiles[(playfield_tile_byte_index)] &= ~(playfield_bitmask_tile_table[(playfield_tile_in_byte_index)])) +#define set_playfield_tile_type_wall_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (playfield_tiles[(playfield_tile_byte_index)] |= playfield_bitmask_tile_table[(playfield_tile_in_byte_index)]) +#define set_playfield_tile_type_uncleared_marked_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (set_playfield_tile_value_from_byte_index_table((playfield_tile_byte_index), (playfield_tile_in_byte_index), playfield_tiles, playfield_tile_type_uncleared_marked_table)) +#define set_playfield_tile_type_line_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (set_playfield_tile_value_from_byte_index_table((playfield_tile_byte_index), (playfield_tile_in_byte_index), playfield_tiles, playfield_tile_type_line_table)) + +#define set_playfield_tile_type_uncleared_unmarked(playfield_tile_index) (set_playfield_tile_type_uncleared_unmarked_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)))) +#define set_playfield_tile_type_wall(playfield_tile_index) (set_playfield_tile_type_wall_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)))) +#define set_playfield_tile_type_uncleared_marked(playfield_tile_index) (set_playfield_tile_type_uncleared_marked_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)))) +#define set_playfield_tile_type_line(playfield_tile_index) (set_playfield_tile_type_line_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)))) + +// Playfield tile line flags accessor macros + +#define is_playfield_tile_line_index_from_byte(byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_raw_byte_table((byte), (playfield_tile_in_byte_index), playfield_tile_line_index_table)) +#define is_playfield_tile_line_index_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_byte_index_table((playfield_tile_byte_index), (playfield_tile_in_byte_index), playfield_line_flags, playfield_tile_line_index_table)) +#define is_playfield_tile_line_index(playfield_tile_index) (is_playfield_tile_mask_set_table((playfield_tile_index), playfield_line_flags, playfield_tile_line_index_table)) + +#define is_playfield_tile_line_direction_from_byte(byte, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_raw_byte_table((byte), (playfield_tile_in_byte_index), playfield_tile_line_direction_table)) +#define is_playfield_tile_line_direction_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index) (is_playfield_tile_mask_set_from_byte_index_table((playfield_tile_byte_index), (playfield_tile_in_byte_index), playfield_line_flags, playfield_tile_line_direction_table)) +#define is_playfield_tile_line_direction(playfield_tile_index) (is_playfield_tile_mask_set_table((playfield_tile_index), playfield_line_flags, playfield_tile_line_direction_table)) + +#define set_playfield_tile_line_flags_in_byte(byte, playfield_tile_in_byte_index, line_index, line_direction) (set_playfield_tile_value_in_raw_byte((byte), (playfield_tile_in_byte_index), ((line_index) ? playfield_tile_line_index_table[(playfield_tile_in_byte_index)] : 0x0) | ((line_direction) ? playfield_tile_line_direction_table[(playfield_tile_in_byte_index)] : 0x0))) +#define set_playfield_tile_line_flags_from_byte_index(playfield_tile_byte_index, playfield_tile_in_byte_index, line_index, line_direction) (set_playfield_tile_line_flags_in_byte(playfield_line_flags[(playfield_tile_byte_index)], (playfield_tile_in_byte_index), (line_index), (line_direction))) +#define set_playfield_tile_line_flags(playfield_tile_index, line_index, line_direction) (set_playfield_tile_line_flags_from_byte_index(get_playfield_tile_byte_index((playfield_tile_index)), get_playfield_tile_in_byte_index((playfield_tile_index)), (line_index), (line_direction))) #endif // __JEZNES_FLAGS_PLAYFIELD_H__ diff --git a/src/flood_fill.c b/src/flood_fill.c index 2d36690..0d8f247 100644 --- a/src/flood_fill.c +++ b/src/flood_fill.c @@ -18,27 +18,25 @@ void compute_playfield_mark_bit_one_region(void) { // If the playfield tile at |get_current_position()| is marked, the region // containing the tile has already been marked. There's no point in remarking // the region. - if (!inside(get_current_position())) { + if (!is_current_inside()) { return; } // Set cur-dir to default direction set_cur_dir(MOVE_DIRECTION_DEFAULT); // Clear mark and mark2 (set values to null) - set_mark_null(TRUE); - set_mark2_null(TRUE); + set_mark1_null(); + set_mark2_null(); // Set backtrack and findloop to false - set_backtrack(FALSE); - set_findloop(FALSE); + unset_backtrack(); + unset_findloop(); // Move forward until the playfield tile in front is marked or not uncleared // (ie: it is not inside). // Note: This function does not do bounds checking, we assume the playfield // has a border of wall tiles on all sides. - set_temp_forward_iterator(get_front()); - while (inside(get_temp_forward_iterator())) { - set_current_position(get_temp_forward_iterator()); - set_temp_forward_iterator(get_front()); + while (is_front_inside()) { + move_forward(); } goto PAINTER_ALGORITHM_START; @@ -46,10 +44,10 @@ void compute_playfield_mark_bit_one_region(void) { while (1) { move_forward(); - if (inside(get_right())) { - if (get_backtrack() == TRUE && get_findloop() == FALSE && - (inside(get_front()) || inside(get_left()))) { - set_findloop(TRUE); + if (is_right_inside()) { + if (get_backtrack() && !get_findloop() && + (is_front_inside() || is_left_inside())) { + set_findloop(); } turn_right(); @@ -60,101 +58,101 @@ void compute_playfield_mark_bit_one_region(void) { PAINTER_ALGORITHM_START: // Count number of non-diagonally adjacent marked playfield tiles. set_adjacent_marked_tile_count(0); - if (!inside(playfield_index_move_up(get_current_position()))) { + if (!is_above_tile_inside()) { inc_adjacent_marked_tile_count(); } - if (!inside(playfield_index_move_down(get_current_position()))) { + if (!is_below_tile_inside()) { inc_adjacent_marked_tile_count(); } - if (!inside(playfield_index_move_left(get_current_position()))) { + if (!is_left_tile_inside()) { inc_adjacent_marked_tile_count(); } - if (!inside(playfield_index_move_right(get_current_position()))) { + if (!is_right_tile_inside()) { inc_adjacent_marked_tile_count(); } if (get_adjacent_marked_tile_count() != 4) { do { turn_right(); - } while (inside(get_front())); + } while (is_front_inside()); do { turn_left(); - } while (!inside(get_front())); + } while (!is_front_inside()); } switch (get_adjacent_marked_tile_count()) { case 1: - if (get_backtrack() == TRUE) { - set_findloop(TRUE); - } else if (get_findloop() == TRUE) { - if (get_mark_null() == TRUE) { - set_mark_null(FALSE); + if (get_backtrack()) { + set_findloop(); + } else if (get_findloop()) { + if (get_mark1_null()) { + unset_mark1_null(); } - } else if (inside(get_front_left()) && inside(get_back_left())) { - set_mark_null(TRUE); - set_playfield_is_marked_flag(get_current_position()); + } else if (is_front_left_inside() && is_back_left_inside()) { + set_mark1_null(); + paint_current_position(); goto PAINTER_ALGORITHM_PAINT; } break; case 2: - if (!inside(get_back())) { - if (inside(get_front_left())) { - set_mark_null(TRUE); - set_playfield_is_marked_flag(get_current_position()); + if (!is_back_inside()) { + if (is_front_left_inside()) { + set_mark1_null(); + paint_current_position(); goto PAINTER_ALGORITHM_PAINT; } - } else if (get_mark_null() == TRUE) { - set_mark(get_current_position()); - set_mark_null(FALSE); - set_mark_dir(get_cur_dir()); - set_mark2_null(TRUE); - set_findloop(FALSE); - set_backtrack(FALSE); + } else if (get_mark1_null()) { + set_mark1(get_current_position()); + unset_mark1_null(); + set_mark1_dir(get_cur_dir()); + set_mark2_null(); + unset_findloop(); + unset_backtrack(); } else { - if (get_mark2_null() == TRUE) { - if (get_current_position() == get_mark()) { - if (get_cur_dir() == get_mark_dir()) { - set_mark_null(TRUE); + if (get_mark2_null()) { + if (get_current_position() == get_mark1()) { + if (get_cur_dir() == get_mark1_dir()) { + set_mark1_null(); reverse_direction(); - set_playfield_is_marked_flag(get_current_position()); + paint_current_position(); goto PAINTER_ALGORITHM_PAINT; } else { - set_backtrack(TRUE); - set_findloop(FALSE); - set_cur_dir(get_mark_dir()); + set_backtrack(); + unset_findloop(); + set_cur_dir(get_mark1_dir()); } - } else if (get_findloop() == TRUE) { + } else if (get_findloop()) { set_mark2(get_current_position()); - set_mark2_null(FALSE); + unset_mark2_null(); set_mark2_dir(get_cur_dir()); } } else { - if (get_current_position() == get_mark()) { + if (get_current_position() == get_mark1()) { set_current_position(get_mark2()); set_cur_dir(get_mark2_dir()); - set_mark_null(TRUE); - set_mark2_null(TRUE); - set_backtrack(FALSE); + set_mark1_null(); + set_mark2_null(); + unset_backtrack(); reverse_direction(); - set_playfield_is_marked_flag(get_current_position()); + paint_current_position(); goto PAINTER_ALGORITHM_PAINT; } else if (get_current_position() == get_mark2()) { - set_mark(get_current_position()); - set_mark_null(FALSE); + set_mark1(get_current_position()); + unset_mark1_null(); set_cur_dir(get_mark2_dir()); - set_mark_dir(get_mark2_dir()); - set_mark2_null(TRUE); + set_mark1_dir(get_mark2_dir()); + set_mark2_null(); } } } break; case 3: - set_mark_null(TRUE); - set_playfield_is_marked_flag(get_current_position()); + set_mark1_null(); + paint_current_position(); goto PAINTER_ALGORITHM_PAINT; break; case 4: - set_playfield_is_marked_flag(get_current_position()); + paint_current_position(); return; } } diff --git a/src/flood_fill.h b/src/flood_fill.h index c363b8c..937beff 100644 --- a/src/flood_fill.h +++ b/src/flood_fill.h @@ -7,18 +7,9 @@ #ifndef __JEZNES_FLOOD_FILL_H__ #define __JEZNES_FLOOD_FILL_H__ -#define playfield_index_move_up(i) ((i)-32) -#define playfield_index_move_down(i) ((i) + 32) -#define playfield_index_move_left(i) ((i)-1) -#define playfield_index_move_right(i) ((i) + 1) - -#define playfield_index_move_right_up(i) ((i)-31) -#define playfield_index_move_left_down(i) ((i) + 31) -#define playfield_index_move_left_up(i) ((i)-33) -#define playfield_index_move_right_down(i) ((i) + 33) - -#define inside(i) \ - ((playfield[(i)] & (PLAYFIELD_WALL | PLAYFIELD_BITMASK_MARK)) == 0) +#include "debug.h" +#include "flags/base.h" +#include "zeropage.h" enum { MOVE_DIRECTION_RIGHT, @@ -49,93 +40,397 @@ const unsigned char turn_left_table[] = { MOVE_DIRECTION_LEFT, }; -#define get_current_position() (temp_int_1) -#define set_current_position(a) (temp_int_1 = (a)) -#define get_mark() (temp_int_2) -#define set_mark(a) (temp_int_2 = (a)) -#define get_mark2() (temp_int_3) -#define set_mark2(a) (temp_int_3 = (a)) +#define set_current_position_from_tile_index(tile_index) \ + set_current_playfield_byte_index(get_playfield_tile_byte_index(tile_index)); \ + set_current_playfield_in_byte_index(get_playfield_tile_in_byte_index(tile_index)); + +// The current position is a byte-index into the playfield_tiles array and a number [0-3] indicating the offset into the byte data belonging to the current tile. +// The byte-index is stored in the low-byte and the in-byte offset is stored in the high-byte. +#define get_current_position() (*((unsigned int*)&temp_int_3_byte_1)) +#define set_current_position(a) ((*((unsigned int*)&temp_int_3_byte_1)) = (a)) + +// Gets the playfield_tiles byte index of the current position. +#define get_current_playfield_byte_index() (temp_int_3_byte_1) +#define set_current_playfield_byte_index(a) (temp_int_3_byte_1 = (a)) +#define inc_current_playfield_byte_index() (++temp_int_3_byte_1) +#define dec_current_playfield_byte_index() (--temp_int_3_byte_1) + +// Gets the playfield_tiles byte data in-byte index of the current position. [0,3] +#define get_current_playfield_in_byte_index() (temp_int_3_byte_2) +#define set_current_playfield_in_byte_index(a) (temp_int_3_byte_2 = (a)) +#define inc_current_playfield_in_byte_index() (++temp_int_3_byte_2) +#define dec_current_playfield_in_byte_index() (--temp_int_3_byte_2) + +#define FLOOD_FILL_BIT_BACKTRACK 0 +#define FLOOD_FILL_BITMASK_BACKTRACK (1 << FLOOD_FILL_BIT_BACKTRACK) +#define FLOOD_FILL_BIT_FINDLOOP 1 +#define FLOOD_FILL_BITMASK_FINDLOOP (1 << FLOOD_FILL_BIT_FINDLOOP) +#define FLOOD_FILL_BIT_MARK1_NULL 2 +#define FLOOD_FILL_BITMASK_MARK1_NULL (1 << FLOOD_FILL_BIT_MARK1_NULL) +#define FLOOD_FILL_BIT_MARK2_NULL 3 +#define FLOOD_FILL_BITMASK_MARK2_NULL (1 << FLOOD_FILL_BIT_MARK2_NULL) + +#define get_flood_fill_flags_byte() (temp_byte_2) + +#define get_backtrack_macro() (get_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_BACKTRACK)) +#define set_backtrack_macro() (set_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_BACKTRACK)) +#define unset_backtrack_macro() (unset_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_BACKTRACK)) + +#define get_findloop_macro() (get_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_FINDLOOP)) +#define set_findloop_macro() (set_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_FINDLOOP)) +#define unset_findloop_macro() (unset_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_FINDLOOP)) + +#define get_mark1_null_macro() (get_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_MARK1_NULL)) +#define set_mark1_null_macro() (set_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_MARK1_NULL)) +#define unset_mark1_null_macro() (unset_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_MARK1_NULL)) + +#define get_mark2_null_macro() (get_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_MARK2_NULL)) +#define set_mark2_null_macro() (set_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_MARK2_NULL)) +#define unset_mark2_null_macro() (unset_flag(get_flood_fill_flags_byte(), FLOOD_FILL_BITMASK_MARK2_NULL)) + +#define get_mark1() (temp_int_2) +#define set_mark1(a) (temp_int_2 = (a)) +#define get_mark2() (temp_int_1) +#define set_mark2(a) (temp_int_1 = (a)) #define get_cur_dir() (temp_byte_1) -#define set_cur_dir(a) (temp_byte_1 = (a)) -#define get_mark_dir() (temp_byte_4) -#define set_mark_dir(a) (temp_byte_4 = (a)) +#define set_cur_dir_macro(a) (temp_byte_1 = (a)) +#define get_mark1_dir() (temp_byte_4) +#define set_mark1_dir(a) (temp_byte_4 = (a)) #define get_mark2_dir() (temp_byte_5) #define set_mark2_dir(a) (temp_byte_5 = (a)) -#define get_backtrack() (temp_byte_2) -#define set_backtrack(a) (temp_byte_2 = (a)) -#define get_findloop() (temp_byte_3) -#define set_findloop(a) (temp_byte_3 = (a)) -#define get_mark_null() (temp_byte_7) -#define set_mark_null(a) (temp_byte_7 = (a)) -#define get_mark2_null() (temp_byte_8) -#define set_mark2_null(a) (temp_byte_8 = (a)) - -#define get_temp_forward_iterator() (temp_int_2) -#define set_temp_forward_iterator(a) (temp_int_2 = (a)) +// #define get_backtrack() (temp_byte_2) +// #define set_backtrack(a) (temp_byte_2 = (a)) +// #define get_findloop() (temp_byte_3) +// #define set_findloop(a) (temp_byte_3 = (a)) +// #define get_mark_null() (temp_byte_7) +// #define set_mark_null(a) (temp_byte_7 = (a)) +// #define get_mark2_null() (temp_byte_8) +// #define set_mark2_null(a) (temp_byte_8 = (a)) #define set_adjacent_marked_tile_count(a) (temp_byte_6 = (a)) #define get_adjacent_marked_tile_count() (temp_byte_6) #define inc_adjacent_marked_tile_count() (++temp_byte_6) -#define reverse_direction() \ - (set_cur_dir(reverse_direction_table[get_cur_dir()])) -#define turn_right() (set_cur_dir(turn_right_table[get_cur_dir()])) -#define turn_left() (set_cur_dir(turn_left_table[get_cur_dir()])) -#define move_forward() (set_current_position(get_front())) +#define paint_current_position() (set_playfield_tile_type_uncleared_marked_from_byte_index(get_current_playfield_byte_index(), get_current_playfield_in_byte_index())) + +#define reverse_direction_macro() (set_cur_dir(reverse_direction_table[get_cur_dir()])) +#define turn_right_macro() (set_cur_dir(turn_right_table[get_cur_dir()])) +#define turn_left_macro() (set_cur_dir(turn_left_table[get_cur_dir()])) + +#define move_to_above_tile() (get_current_playfield_byte_index() -= 8) +#define move_to_below_tile() (get_current_playfield_byte_index() += 8) +#define move_to_right_tile() \ + if (get_current_playfield_in_byte_index() == 3) { \ + inc_current_playfield_byte_index(); \ + set_current_playfield_in_byte_index(0); \ + } else { \ + inc_current_playfield_in_byte_index(); \ + } +#define move_to_left_tile() \ + if (get_current_playfield_in_byte_index() == 0) { \ + dec_current_playfield_byte_index(); \ + set_current_playfield_in_byte_index(3); \ + } else { \ + dec_current_playfield_in_byte_index(); \ + } + +#define move_forward_macro() \ + switch(get_cur_dir()) { \ + case MOVE_DIRECTION_RIGHT: \ + move_to_right_tile(); \ + break; \ + case MOVE_DIRECTION_DOWN: \ + move_to_below_tile(); \ + break; \ + case MOVE_DIRECTION_LEFT: \ + move_to_left_tile(); \ + break; \ + case MOVE_DIRECTION_UP: \ + move_to_above_tile(); \ + break; \ + } + +// Returns true when tile at position |byte_index, in_byte_index| is uncleared and unmarked. +#define is_inside_macro(byte_index, in_byte_index) (is_playfield_tile_type_uncleared_unmarked_from_byte_index((byte_index), (in_byte_index))) +#define is_current_inside_with_byte_index_and_in_byte_index_offset_macro(byte_index_offset, in_byte_index_offset) (is_inside(get_current_playfield_byte_index()+(byte_index_offset), get_current_playfield_in_byte_index()+(in_byte_index_offset))) +#define is_current_inside_with_byte_index_offset_macro(byte_index_offset) (is_inside(get_current_playfield_byte_index()+(byte_index_offset), get_current_playfield_in_byte_index())) +#define is_current_inside_with_in_byte_index_offset_macro(in_byte_index_offset) (is_inside(get_current_playfield_byte_index(), get_current_playfield_in_byte_index()+(in_byte_index_offset))) +#define is_current_inside_macro() (is_inside(get_current_playfield_byte_index(), get_current_playfield_in_byte_index())) + +unsigned char is_right_tile_inside_table[] = { + 0b001, + 0b010, + 0b011, + 0b100, +}; +unsigned char is_left_tile_inside_table[] = { + 0b011, + 0b000, + 0b001, + 0b010, +}; + +#define is_above_tile_inside_macro() (is_current_inside_with_byte_index_offset(-8)) +#define is_below_tile_inside_macro() (is_current_inside_with_byte_index_offset(8)) +#define is_right_tile_inside_macro() (is_inside(get_current_playfield_byte_index()+((set_temp_byte_10(is_right_tile_inside_table[get_current_playfield_in_byte_index()])) >> 2), get_temp_byte_10() & 0b11)) +#define is_left_tile_inside_macro() (is_inside(get_current_playfield_in_byte_index() == 0 ? (get_current_playfield_byte_index()-1) : get_current_playfield_byte_index(), is_left_tile_inside_table[get_current_playfield_in_byte_index()])) + +#define is_left_tile_inside_macro3() (is_inside(get_current_playfield_byte_index()-((set_temp_byte_10(is_left_tile_inside_table[get_current_playfield_in_byte_index()])) >> 2), get_temp_byte_10() & 0b11)) + +#define is_right_tile_inside_macro2() (get_current_playfield_in_byte_index() == 3 ? \ + is_inside(get_current_playfield_byte_index()+1, 0) : \ + is_current_inside_with_in_byte_index_offset(1)) +#define is_left_tile_inside_macro2() (get_current_playfield_in_byte_index() == 0 ? \ + is_inside(get_current_playfield_byte_index()-1, 3) : \ + is_current_inside_with_in_byte_index_offset(-1)) -#define get_front() \ +#define is_above_right_tile_inside_macro() (get_current_playfield_in_byte_index() == 3 ? \ + is_inside(get_current_playfield_byte_index()-7, 0) : \ + is_current_inside_with_byte_index_and_in_byte_index_offset(-8, 1)) +#define is_above_left_tile_inside_macro() (get_current_playfield_in_byte_index() == 0 ? \ + is_inside(get_current_playfield_byte_index()-9, 3) : \ + is_current_inside_with_byte_index_and_in_byte_index_offset(-8, -1)) +#define is_below_right_tile_inside_macro() (get_current_playfield_in_byte_index() == 3 ? \ + is_inside(get_current_playfield_byte_index()+9, 0) : \ + is_current_inside_with_byte_index_and_in_byte_index_offset(8, 1)) +#define is_below_left_tile_inside_macro() (get_current_playfield_in_byte_index() == 0 ? \ + is_inside(get_current_playfield_byte_index()+7, 3) : \ + is_current_inside_with_byte_index_and_in_byte_index_offset(8, -1)) + +#define get_temp_byte_10() (*((unsigned char*)&temp_ptr_1)) +#define set_temp_byte_10(a) (get_temp_byte_10() = a) +#define get_temp_byte_11() (*(((unsigned char*)&temp_ptr_1)+1)) +#define set_temp_byte_11(a) (get_temp_byte_11() = a) + +#define is_current_offset_inside_2(byte_index_table, in_byte_index_table) \ + set_temp_byte_11(in_byte_index_table[get_cur_dir()]); \ + set_temp_byte_10(get_current_playfield_in_byte_index()+get_temp_byte_11()); \ + return ((get_temp_byte_10() > 3) ? \ + (get_temp_byte_10() == 4) ? \ + is_inside(get_current_playfield_byte_index()+byte_index_table[get_cur_dir()]+1, 0) : \ + is_inside(get_current_playfield_byte_index()+byte_index_table[get_cur_dir()]-1, 3) : \ + is_inside(get_current_playfield_byte_index()+byte_index_table[get_cur_dir()], get_temp_byte_10())); + +const signed char is_front_inside_byte_index_offset_table[] = { + 0, // MOVE_DIRECTION_RIGHT + 8, // MOVE_DIRECTION_DOWN + 0, // MOVE_DIRECTION_LEFT + -8, // MOVE_DIRECTION_UP +}; +const signed char is_front_inside_in_byte_index_offset_table[] = { + 1, // MOVE_DIRECTION_RIGHT + 0, // MOVE_DIRECTION_DOWN + -1, // MOVE_DIRECTION_LEFT + 0, // MOVE_DIRECTION_UP +}; + +#define is_front_inside_macro2() is_current_offset_inside_2(is_front_inside_byte_index_offset_table, is_front_inside_in_byte_index_offset_table) +#define is_front_inside_macro() \ (get_cur_dir() == MOVE_DIRECTION_RIGHT \ - ? playfield_index_move_right(get_current_position()) \ + ? is_right_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_LEFT \ - ? playfield_index_move_left(get_current_position()) \ + ? is_left_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_DOWN \ - ? playfield_index_move_down(get_current_position()) \ - : playfield_index_move_up(get_current_position())) - -#define get_back() \ + ? is_below_tile_inside() \ + : is_above_tile_inside()) +#define is_back_inside_macro() \ (get_cur_dir() == MOVE_DIRECTION_RIGHT \ - ? playfield_index_move_left(get_current_position()) \ + ? is_left_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_LEFT \ - ? playfield_index_move_right(get_current_position()) \ + ? is_right_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_DOWN \ - ? playfield_index_move_up(get_current_position()) \ - : playfield_index_move_down(get_current_position())) - -#define get_right() \ + ? is_above_tile_inside() \ + : is_below_tile_inside()) +#define is_right_inside_macro() \ (get_cur_dir() == MOVE_DIRECTION_RIGHT \ - ? playfield_index_move_down(get_current_position()) \ + ? is_below_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_LEFT \ - ? playfield_index_move_up(get_current_position()) \ + ? is_above_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_DOWN \ - ? playfield_index_move_left(get_current_position()) \ - : playfield_index_move_right(get_current_position())) - -#define get_left() \ + ? is_left_tile_inside() \ + : is_right_tile_inside()) +#define is_left_inside_macro() \ (get_cur_dir() == MOVE_DIRECTION_RIGHT \ - ? playfield_index_move_up(get_current_position()) \ + ? is_above_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_LEFT \ - ? playfield_index_move_down(get_current_position()) \ + ? is_below_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_DOWN \ - ? playfield_index_move_right(get_current_position()) \ - : playfield_index_move_left(get_current_position())) - -#define get_front_left() \ + ? is_right_tile_inside() \ + : is_left_tile_inside()) +#define is_front_left_inside_macro() \ (get_cur_dir() == MOVE_DIRECTION_RIGHT \ - ? playfield_index_move_right_up(get_current_position()) \ + ? is_above_right_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_LEFT \ - ? playfield_index_move_left_down(get_current_position()) \ + ? is_below_left_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_DOWN \ - ? playfield_index_move_right_down(get_current_position()) \ - : playfield_index_move_left_up(get_current_position())) - -#define get_back_left() \ + ? is_below_right_tile_inside() \ + : is_above_left_tile_inside()) +#define is_back_left_inside_macro() \ (get_cur_dir() == MOVE_DIRECTION_RIGHT \ - ? playfield_index_move_left_up(get_current_position()) \ + ? is_above_left_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_LEFT \ - ? playfield_index_move_right_down(get_current_position()) \ + ? is_below_right_tile_inside() \ : get_cur_dir() == MOVE_DIRECTION_DOWN \ - ? playfield_index_move_right_up(get_current_position()) \ - : playfield_index_move_left_down(get_current_position())) + ? is_above_right_tile_inside() \ + : is_below_left_tile_inside()) + +#if PUT_CRITICAL_CODE_IN_FUNCTIONS +void set_cur_dir(unsigned char a) { + set_cur_dir_macro(a); +} +unsigned char get_backtrack(void) { + return get_backtrack_macro(); +} +void set_backtrack(void) { + set_backtrack_macro(); +} +void unset_backtrack(void) { + unset_backtrack_macro(); +} +unsigned char get_findloop(void) { + return get_findloop_macro(); +} +void set_findloop(void) { + set_findloop_macro(); +} +void unset_findloop(void) { + unset_findloop_macro(); +} +unsigned char get_mark1_null(void) { + return get_mark1_null_macro(); +} +void set_mark1_null(void) { + set_mark1_null_macro(); +} +void unset_mark1_null(void) { + unset_mark1_null_macro(); +} +unsigned char get_mark2_null(void) { + return get_mark2_null_macro(); +} +void set_mark2_null(void) { + set_mark2_null_macro(); +} +void unset_mark2_null(void) { + unset_mark2_null_macro(); +} +void reverse_direction(void) { + reverse_direction_macro(); +} +void turn_right(void) { + turn_right_macro(); +} +void turn_left(void) { + turn_left_macro(); +} +void move_forward(void) { + move_forward_macro(); +} +unsigned char is_inside(unsigned char byte_index, unsigned char in_byte_index) { + return is_inside_macro(byte_index, in_byte_index); +} +unsigned char is_current_inside_with_byte_index_and_in_byte_index_offset(signed char byte_index_offset, signed char in_byte_index_offset) { + return is_current_inside_with_byte_index_and_in_byte_index_offset_macro(byte_index_offset, in_byte_index_offset); +} +unsigned char is_current_inside_with_byte_index_offset(signed char byte_index_offset) { + return is_current_inside_with_byte_index_offset_macro(byte_index_offset); +} +unsigned char is_current_inside_with_in_byte_index_offset(signed char in_byte_index_offset) { + return is_current_inside_with_in_byte_index_offset_macro(in_byte_index_offset); +} +unsigned char is_current_inside(void) { + return is_current_inside_macro(); +} +unsigned char is_above_tile_inside(void) { + return is_above_tile_inside_macro(); +} +unsigned char is_below_tile_inside(void) { + return is_below_tile_inside_macro(); +} +unsigned char is_right_tile_inside(void) { + return is_right_tile_inside_macro(); +} +unsigned char is_left_tile_inside(void) { + return is_left_tile_inside_macro(); +} +unsigned char is_above_right_tile_inside(void) { + return is_above_right_tile_inside_macro(); +} +unsigned char is_above_left_tile_inside(void) { + return is_above_left_tile_inside_macro(); +} +unsigned char is_below_right_tile_inside(void) { + return is_below_right_tile_inside_macro(); +} +unsigned char is_below_left_tile_inside(void) { + return is_below_left_tile_inside_macro(); +} +unsigned char is_front_inside(void) { + return is_front_inside_macro(); +} +unsigned char is_back_inside(void) { + return is_back_inside_macro(); +} +unsigned char is_right_inside(void) { + return is_right_inside_macro(); +} +unsigned char is_left_inside(void) { + return is_left_inside_macro(); +} +unsigned char is_front_left_inside(void) { + return is_front_left_inside_macro(); +} +unsigned char is_back_left_inside(void) { + return is_back_left_inside_macro(); +} +#else +#define set_cur_dir(a) set_cur_dir_macro(a) + +#define get_backtrack() get_backtrack_macro() +#define set_backtrack() set_backtrack_macro() +#define unset_backtrack() unset_backtrack_macro() + +#define get_findloop() get_findloop_macro() +#define set_findloop() set_findloop_macro() +#define unset_findloop() unset_findloop_macro() + +#define get_mark1_null() get_mark1_null_macro() +#define set_mark1_null() set_mark1_null_macro() +#define unset_mark1_null() unset_mark1_null_macro() + +#define get_mark2_null() get_mark2_null_macro() +#define set_mark2_null() set_mark2_null_macro() +#define unset_mark2_null() unset_mark2_null_macro() + +#define reverse_direction() reverse_direction_macro() +#define turn_right() turn_right_macro() +#define turn_left() turn_left_macro() + +#define move_forward() move_forward_macro() + +#define is_inside(byte_index, in_byte_index) is_inside_macro(byte_index, in_byte_index) +#define is_current_inside_with_byte_index_and_in_byte_index_offset(byte_index_offset, in_byte_index_offset) is_current_inside_with_byte_index_and_in_byte_index_offset_macro(byte_index_offset, in_byte_index_offset) +#define is_current_inside_with_byte_index_offset(byte_index_offset) is_current_inside_with_byte_index_offset_macro(byte_index_offset) +#define is_current_inside_with_in_byte_index_offset(in_byte_index_offset) is_current_inside_with_in_byte_index_offset_macro(in_byte_index_offset) +#define is_current_inside() is_current_inside_macro() + +#define is_above_tile_inside() is_above_tile_inside_macro() +#define is_below_tile_inside() is_below_tile_inside_macro() +#define is_right_tile_inside() is_right_tile_inside_macro() +#define is_left_tile_inside() is_left_tile_inside_macro() + +#define is_above_right_tile_inside() is_above_right_tile_inside_macro() +#define is_above_left_tile_inside() is_above_left_tile_inside_macro() +#define is_below_right_tile_inside() is_below_right_tile_inside_macro() +#define is_below_left_tile_inside() is_below_left_tile_inside_macro() + +#define is_front_inside() is_front_inside_macro() +#define is_back_inside() is_back_inside_macro() +#define is_right_inside() is_right_inside_macro() +#define is_left_inside() is_left_inside_macro() +#define is_front_left_inside() is_front_left_inside_macro() +#define is_back_left_inside() is_back_left_inside_macro() +#endif // Uses a constant-memory usage implementation of the painters algorithm to walk // the playfield starting at the playfield tile returned via diff --git a/src/jeznes.c b/src/jeznes.c index 97efb51..7094088 100644 --- a/src/jeznes.c +++ b/src/jeznes.c @@ -385,8 +385,7 @@ void init_game(void) { } void load_playfield(void) { - memcpy(&playfield, playfield_patterns[get_playfield_pattern()], - PLAYFIELD_WIDTH * PLAYFIELD_HEIGHT); + memcpy(&playfield_tiles, playfield_patterns[get_playfield_pattern()], sizeof(playfield_tiles)); } void read_controllers(void) { @@ -785,10 +784,10 @@ void move_and_draw_balls(void) { #if DRAW_BALL_NEAREST_TILE_HIGHLIGHT // Calculate nearest playfield tile - center of the ball in sprite-coords. - temp_int_1 = playfield_tile_from_pixel_coords( - get_temp_ptr(struct Ball)->x + 4, get_temp_ptr(struct Ball)->y + 4); - oam_spr(playfield_index_pixel_coord_x(temp_int_1), - playfield_index_pixel_coord_y(temp_int_1) - 1, + set_current_playfield_index(playfield_tile_from_pixel_coords( + get_temp_ptr(struct Ball)->x + 4, get_temp_ptr(struct Ball)->y + 4)); + oam_spr(playfield_index_pixel_coord_x(get_current_playfield_index()), + playfield_index_pixel_coord_y(get_current_playfield_index()) - 1, SPRITE_INDEX_TILE_HIGHLIGHT, 1); #endif } @@ -819,9 +818,8 @@ void move_ball() { // Find x-direction candidate playfield tile index. set_current_playfield_index(playfield_tile_from_pixel_coords( get_x_compare_pixel_coord(), get_y_candidate_pixel_coord())); - set_playfield_tile_value(playfield[get_current_playfield_index()]); // Bounce off a left or right wall tile. - if (get_playfield_tile_value() == PLAYFIELD_WALL) { + if (is_playfield_tile_type_wall(get_current_playfield_index())) { // Move the ball such that it's in the non-wall tile opposite the candidate. if (get_x_direction() == BALL_DIRECTION_POSITIVE) { // We inc'd the candidate pixel coord above so now dec it to move in the @@ -864,9 +862,8 @@ void move_ball() { // Find y-direction candidate playfield tile index. set_current_playfield_index(playfield_tile_from_pixel_coords( get_x_candidate_pixel_coord(), get_y_compare_pixel_coord())); - set_playfield_tile_value(playfield[get_current_playfield_index()]); // Bounce off a top or bottom wall tile. - if (get_playfield_tile_value() == PLAYFIELD_WALL) { + if (is_playfield_tile_type_wall(get_current_playfield_index())) { // Move the ball such that it's in the non-wall tile opposite the candidate. if (get_y_direction() == BALL_DIRECTION_POSITIVE) { // We inc'd the candidate pixel coord above so now dec it to move in the @@ -909,8 +906,7 @@ void draw_player(void) { } void draw_tile_highlight(void) { - if (playfield[get_temp_ptr(struct Player)->nearest_playfield_tile] == - PLAYFIELD_UNCLEARED) { + if (is_playfield_tile_type_uncleared_unmarked(get_temp_ptr(struct Player)->nearest_playfield_tile)) { oam_spr(get_temp_ptr(struct Player)->nearest_tile_x, get_temp_ptr(struct Player)->nearest_tile_y - 1, SPRITE_INDEX_TILE_HIGHLIGHT, 1); @@ -979,10 +975,8 @@ unsigned char update_line(unsigned char line_index) { // and bg tile. Note: The origin tile already has the playfield flags (and // bg tile) set. We can ignore that one. if (!get_line_is_first_step_flag_from_byte(get_flags_byte())) { - set_playfield_tile_type( - get_current_playfield_index(), - get_playfield_tile_type_line(get_line_orientation(), line_index, - LINE_DIRECTION_NEGATIVE)); + set_playfield_tile_type_line(get_current_playfield_index()); + set_playfield_tile_line_flags(get_current_playfield_index(), line_index, LINE_DIRECTION_NEGATIVE); set_playfield_bg_tile( get_sprite_x(), get_sprite_y(), get_playfield_bg_tile_line(get_line_orientation(), @@ -996,16 +990,14 @@ unsigned char update_line(unsigned char line_index) { // If the next tile is not an uncleared tile, that means we hit the end // for the line segment. Walk back over the tiles until we reach line // segment origin and update them to cleared. - if (get_playfield_tile_type(get_current_playfield_index()) == - PLAYFIELD_WALL) { + if (is_playfield_tile_type_wall(get_current_playfield_index())) { while (1) { // Walk back towards origin by one tile. set_current_playfield_index(get_current_playfield_index() + get_tile_index_delta()); // Update the tile to cleared. cleared_tile_count++; - set_playfield_tile_type(get_current_playfield_index(), - PLAYFIELD_WALL); + set_playfield_tile_type_wall(get_current_playfield_index()); set_playfield_bg_tile(get_sprite_x(), get_sprite_y(), TILE_INDEX_PLAYFIELD_CLEARED); add_score_for_cleared_tiles(1); @@ -1060,10 +1052,8 @@ unsigned char update_line(unsigned char line_index) { // and bg tile. Note: The origin tile already has the playfield flags (and // bg tile) set. We can ignore that one. if (!get_line_is_first_step_flag_from_byte(get_flags_byte())) { - set_playfield_tile_type( - get_current_playfield_index(), - get_playfield_tile_type_line(get_line_orientation(), line_index, - LINE_DIRECTION_POSITIVE)); + set_playfield_tile_type_line(get_current_playfield_index()); + set_playfield_tile_line_flags(get_current_playfield_index(), line_index, LINE_DIRECTION_POSITIVE); set_playfield_bg_tile( get_sprite_x(), get_sprite_y(), get_playfield_bg_tile_line(get_line_orientation(), @@ -1077,8 +1067,7 @@ unsigned char update_line(unsigned char line_index) { // If the next tile is not an uncleared tile, that means we hit the end // for the line segment. Walk back over the tiles until we reach line // segment origin and update them to cleared. - if (get_playfield_tile_type(get_current_playfield_index()) == - PLAYFIELD_WALL) { + if (is_playfield_tile_type_wall(get_current_playfield_index())) { // Calculate positive-direction line segment origin based // on negative-direction line segment origin. set_positive_line_segment_origin(get_temp_ptr(struct Line)->origin + @@ -1090,8 +1079,7 @@ unsigned char update_line(unsigned char line_index) { get_tile_index_delta()); // Update the tile to cleared. cleared_tile_count++; - set_playfield_tile_type(get_current_playfield_index(), - PLAYFIELD_WALL); + set_playfield_tile_type_wall(get_current_playfield_index()); set_playfield_bg_tile(get_sprite_x(), get_sprite_y(), TILE_INDEX_PLAYFIELD_CLEARED); add_score_for_cleared_tiles(1); @@ -1164,8 +1152,7 @@ void start_line(unsigned char player_index) { players[player_index].nearest_playfield_tile); // We only want to start a line if the origin tile is not already cleared. - if (get_playfield_tile_type(get_negative_line_segment_origin()) == - PLAYFIELD_WALL) { + if (is_playfield_tile_type_wall(get_negative_line_segment_origin())) { return; } @@ -1174,10 +1161,8 @@ void start_line(unsigned char player_index) { set_line_orientation(get_player_orientation_flag(player_index)); // Update the playfield origin tile. - set_playfield_tile_type( - get_negative_line_segment_origin(), - get_playfield_tile_type_line(get_line_orientation(), player_index, - LINE_DIRECTION_NEGATIVE)); + set_playfield_tile_type_line(get_negative_line_segment_origin()); + set_playfield_tile_line_flags(get_negative_line_segment_origin(), player_index, LINE_DIRECTION_NEGATIVE); set_sprite_x( playfield_index_pixel_coord_x(get_negative_line_segment_origin())); set_sprite_y( @@ -1201,13 +1186,10 @@ void start_line(unsigned char player_index) { // We can only start the positive-direction line segment if it would have // origin on an uncleared playfield tile. - if (get_playfield_tile_type(get_positive_line_segment_origin()) != - PLAYFIELD_WALL) { + if (!is_playfield_tile_type_wall(get_positive_line_segment_origin())) { // Update the positive-direction line segment origin playfield tile. - set_playfield_tile_type( - get_positive_line_segment_origin(), - get_playfield_tile_type_line(get_line_orientation(), player_index, - LINE_DIRECTION_POSITIVE)); + set_playfield_tile_type_line(get_positive_line_segment_origin()); + set_playfield_tile_line_flags(get_positive_line_segment_origin(), player_index, LINE_DIRECTION_POSITIVE); set_sprite_x( playfield_index_pixel_coord_x(get_positive_line_segment_origin())); set_sprite_y( @@ -1284,7 +1266,6 @@ void check_ball_line_collisions(void) { get_x_candidate_pixel_coord(), get_y_candidate_pixel_coord())); get_temp_ptr(struct Ball)->nearest_playfield_tile = get_current_playfield_index(); - temp_byte_2 = playfield[get_current_playfield_index()]; // If we're cheating and ignoring collisions, wait until we computed the // nearest_playfield_tile for each ball before bailing out. Without this, @@ -1297,20 +1278,19 @@ void check_ball_line_collisions(void) { // The ball collides with a line if the playfield tile under the ball is a // line tile. - if (get_playfield_tile_type_from_byte(temp_byte_2) != PLAYFIELD_LINE) { + if (!is_playfield_tile_type_line(get_current_playfield_index())) { // No collision. continue; } - temp_byte_3 = get_playfield_line_index_flag_from_byte(temp_byte_2); + temp_byte_3 = is_playfield_tile_line_index(get_current_playfield_index()) ? 1 : 0; set_temp_ptr(&lines[temp_byte_3]); set_negative_line_segment_origin(get_temp_ptr(struct Line)->origin); set_line_orientation( get_line_orientation_flag_from_byte(get_temp_ptr(struct Line)->flags)); set_tile_index_delta(compute_tile_index_delta(get_line_orientation())); - if (get_playfield_line_direction_flag_from_byte(temp_byte_2) == - LINE_DIRECTION_NEGATIVE) { + if (!is_playfield_tile_line_direction(get_current_playfield_index())) { // Playfield tile index of the line segment front tile. // This is drawn as a sprite and we haven't updated the playfield // metadata to include the line flags for this tile so we don't need @@ -1332,8 +1312,7 @@ void check_ball_line_collisions(void) { set_sprite_y(get_sprite_y() + 8); } // Reset the tile to uncleared. - set_playfield_tile_type(get_current_playfield_index(), - PLAYFIELD_UNCLEARED); + set_playfield_tile_type_uncleared_unmarked(get_current_playfield_index()); set_playfield_bg_tile(get_sprite_x(), get_sprite_y(), TILE_INDEX_PLAYFIELD_UNCLEARED); // Stop when we reach the origin. @@ -1379,8 +1358,7 @@ void check_ball_line_collisions(void) { set_sprite_y(get_sprite_y() - 8); } // Reset the tile to uncleared. - set_playfield_tile_type(get_current_playfield_index(), - PLAYFIELD_UNCLEARED); + set_playfield_tile_type_uncleared_unmarked(get_current_playfield_index()); set_playfield_bg_tile(get_sprite_x(), get_sprite_y(), TILE_INDEX_PLAYFIELD_UNCLEARED); // Stop when we reach the origin. @@ -1466,7 +1444,7 @@ void update_nearest_tile(void) { void line_completed(void) { for (temp_byte_9 = 0; temp_byte_9 < get_ball_count(); ++temp_byte_9) { - set_current_position(balls[temp_byte_9].nearest_playfield_tile); + set_current_position_from_tile_index(balls[temp_byte_9].nearest_playfield_tile); compute_playfield_mark_bit_one_region(); } @@ -1481,23 +1459,64 @@ void line_completed(void) { game_state = GAME_STATE_UPDATING_PLAYFIELD; } -// Updates the playfield in-memory data structure and sets |tile_index| to -// |playfield_tile_type|. Sets the bg tile graphic for |tile_index| to -// |playfield_bg_tile|. -// -// |playfield_tile_type| has the new playfield tile type (ie: PLAYFIELD_WALL) -// |playfield_bg_tile| has the new bg tile graphic index (ie: -// TILE_INDEX_PLAYFIELD_CLEARED) -void set_playfield_tile(unsigned int tile_index, - unsigned char playfield_tile_type, - unsigned char playfield_bg_tile) { - // Update the playfield in-memory structure. - playfield[tile_index] = playfield_tile_type; - // Set the bg tile graphic - one_vram_buffer(playfield_bg_tile, - get_ppu_addr(0, playfield_index_pixel_coord_x(tile_index), - playfield_index_pixel_coord_y(tile_index))); -} +#define get_temp_playfield_tile_byte_index() (temp_byte_1) +#define set_temp_playfield_tile_byte_index(a) (temp_byte_1 = (a)) +#define inc_temp_playfield_tile_byte_index() (++temp_byte_1) + +#define get_tiles_cleared_this_sweep() (temp_byte_3) +#define set_tiles_cleared_this_sweep(a) (temp_byte_3 = (a)) +#define inc_tiles_cleared_this_sweep() (++temp_byte_3) + +#define get_playfield_tile_byte_value() (temp_byte_5) +#define set_playfield_tile_byte_value(a) (temp_byte_5 = (a)) + +#define get_temp_playfield_tile_masked_value() (temp_byte_4) +#define set_temp_playfield_tile_masked_value(a) (temp_byte_4 = (a)) + +#define update_one_cleared_playfield_tile(tile_in_byte_index) \ + set_temp_playfield_tile_masked_value(get_playfield_tile_masked_value_from_raw_byte(get_playfield_tile_byte_value(), tile_in_byte_index)); \ + /* If the tile was marked, we aren't supposed to clear it. Mark implies there is a ball inside the same region. */ \ + if (is_playfield_tile_type_uncleared_marked_from_masked_byte(get_temp_playfield_tile_masked_value(), tile_in_byte_index)) { \ + /* While we're here... let's remove all the mark bits from uncleared tiles. We won't revisit this tile index during this sweep of the playfield. */ \ + set_playfield_tile_type_uncleared_unmarked_from_byte_index(get_temp_playfield_tile_byte_index(), tile_in_byte_index); \ + } else if (is_playfield_tile_type_uncleared_unmarked_from_masked_byte(get_temp_playfield_tile_masked_value(), tile_in_byte_index)) { \ + /* TODO(boingoing): What about PLAYFIELD_LINE tiles from the other player? */ \ + /* Unmarked, uncleared playfield tile. Let's reset it to cleared and track the count for this sweep as well as all-time for the level. */ \ + inc_tiles_cleared_this_sweep(); \ + /* Update the playfield in-memory structure to mark the tile as wall. */ \ + set_playfield_tile_type_wall_from_byte_index(get_temp_playfield_tile_byte_index(), tile_in_byte_index); \ + /* Calculate the ppu addr for the current tile and set the bg tile graphic. */ \ + one_vram_buffer(TILE_INDEX_PLAYFIELD_CLEARED, get_temp_ppu_address() + (get_temp_playfield_tile_byte_index() << 2) + (tile_in_byte_index)); \ + /* We can only queue about 40 tile updates per v-blank. */ \ + if (get_tiles_cleared_this_sweep() == MAX_TILE_UPDATES_PER_FRAME) { \ + /* We aren't going to increment |get_temp_playfield_tile_byte_index()| when we return early which means that we may revisit already-cleared tiles in this byte. To avoid clearing tiles in the next sweep which were originally marked, let's just mark all the tiles in this byte which we've already visited. */ \ + switch(tile_in_byte_index) { \ + case 3: \ + /* If this is the final tile in the byte, let's increment the byte index and avoid this issue. */ \ + inc_temp_playfield_tile_byte_index(); \ + break; \ + case 2: \ + /* We just unmarked tile 2 in the current byte. Let's remark it so we don't clear it in the next sweep pass. */ \ + set_playfield_tile_type_uncleared_marked_from_byte_index(get_temp_playfield_tile_byte_index(), 2); \ + /* Intentional fall-through */ \ + case 1: \ + /* We just unmarked tile 1 in the current byte. Let's remark it so we don't clear it in the next sweep pass. */ \ + set_playfield_tile_type_uncleared_marked_from_byte_index(get_temp_playfield_tile_byte_index(), 1); \ + /* Intentional fall-through */ \ + case 0: \ + /* We just unmarked tile 0 in the current byte. Let's remark it so we don't clear it in the next sweep pass. */ \ + set_playfield_tile_type_uncleared_marked_from_byte_index(get_temp_playfield_tile_byte_index(), 0); \ + break; \ + }; \ + add_score_for_cleared_tiles(get_tiles_cleared_this_sweep()); \ + cleared_tile_count += get_tiles_cleared_this_sweep(); \ + return FALSE; \ + } \ + } + +// Use these to skip scanning the first and last blocks of continuous wall playfield tiles. +#define FIRST_NON_WALL_PLAYFIELD_TILE_BYTE_INDEX 8 +#define LAST_NON_WALL_PLAYFIELD_TILE_BYTE_INDEX 168 // Update uncleared, unmarked playfield tiles to be cleared. Returns TRUE when // all uncleared tiles have been updated. Note: This function can potentially @@ -1512,64 +1531,28 @@ unsigned char update_cleared_playfield_tiles(void) { // If this is the first sweep over the playfield, we need to init the // counters. if (get_should_initialize_clear_sweep() == TRUE) { - // Keep pointer to the playfield in-memory structure. - set_temp_ptr(playfield); // First ppu address of the playfield tiles. - set_temp_ppu_address(get_ppu_addr(0, playfield_pixel_coord_x[0], - playfield_pixel_coord_y[0])); + set_temp_ppu_address(get_ppu_addr(0, playfield_pixel_coord_x[0], playfield_pixel_coord_y[0])); + // Reset the playfield tile byte index. + set_temp_playfield_tile_byte_index(FIRST_NON_WALL_PLAYFIELD_TILE_BYTE_INDEX); // Turn off the initialization flag for subsequent sweeps. set_should_initialize_clear_sweep(FALSE); } // Reset per-sweep cleared counter. - temp_byte_3 = 0; - - // Look over all tiles in the playfield and for each uncleared, unmarked tile - // change it to cleared. - for (; get_temp_ptr(unsigned char) != - (unsigned char*)(playfield + PLAYFIELD_WIDTH * PLAYFIELD_HEIGHT); - ++temp_ptr_1) { - set_playfield_tile_value(*get_temp_ptr(unsigned char)); - - // Skip tiles which are not uncleared. These are walls or cleared tiles and - // we don't care if they're marked. - // TODO(boingoing): What about PLAYFIELD_LINE tiles from the other player? - if (get_playfield_tile_type_from_byte(get_playfield_tile_value()) != - PLAYFIELD_UNCLEARED) { - continue; - } + set_tiles_cleared_this_sweep(0); - // If the tile was marked, we aren't supposed to clear it. Mark implies - // there is a ball inside the same region. - if (get_playfield_is_marked_flag_from_byte(get_playfield_tile_value())) { - // While we're here... let's remove all the mark bits from uncleared - // tiles. We won't revisit this tile index during this sweep of the - // playfield. - *get_temp_ptr(unsigned char) &= ~(PLAYFIELD_BITMASK_MARK); - continue; - } - - // Unmarked, uncleared playfield tile. Let's reset it to cleared and track - // the count for this sweep as well as all-time for the level. - ++temp_byte_3; + // Look over all tiles in the playfield and for each uncleared, unmarked tile change it to cleared (wall). + for (; get_temp_playfield_tile_byte_index() != LAST_NON_WALL_PLAYFIELD_TILE_BYTE_INDEX; inc_temp_playfield_tile_byte_index()) { + set_playfield_tile_byte_value(playfield_tiles[get_temp_playfield_tile_byte_index()]); - // Update the playfield in-memory structure. - *get_temp_ptr(unsigned char) = PLAYFIELD_WALL; - - // Calculate the ppu addr for the current tile and set the bg tile graphic. - one_vram_buffer(TILE_INDEX_PLAYFIELD_CLEARED, - get_temp_ppu_address() + temp_ptr_1 - playfield); - - // We can only queue about 40 tile updates per v-blank. - if (temp_byte_3 == MAX_TILE_UPDATES_PER_FRAME) { - add_score_for_cleared_tiles(temp_byte_3); - cleared_tile_count += temp_byte_3; - ++temp_ptr_1; - return FALSE; - } + update_one_cleared_playfield_tile(0); + update_one_cleared_playfield_tile(1); + update_one_cleared_playfield_tile(2); + update_one_cleared_playfield_tile(3); } - add_score_for_cleared_tiles(temp_byte_3); - cleared_tile_count += temp_byte_3; + add_score_for_cleared_tiles(get_tiles_cleared_this_sweep()); + cleared_tile_count += get_tiles_cleared_this_sweep(); return TRUE; } diff --git a/src/playfield.h b/src/playfield.h index 073e22a..326817e 100644 --- a/src/playfield.h +++ b/src/playfield.h @@ -24,105 +24,105 @@ enum { // The title screen includes a playfield section which is this pattern. const unsigned char title_screen_pattern[] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, }; // The game over screen includes a playfield section which is this pattern. const unsigned char game_over_screen_pattern[] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, }; // The level up screen includes a playfield section which is this pattern. const unsigned char level_up_screen_pattern[] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11111111, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, }; const unsigned char playfield_pattern_1[] = { - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1, - 1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b00001111,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b00000000,0b11110000, + 0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111,0b11111111, }; const unsigned char * const playfield_patterns[] = { diff --git a/src/types.h b/src/types.h index 4e17b1b..b3f6eb3 100644 --- a/src/types.h +++ b/src/types.h @@ -22,8 +22,6 @@ enum { ORIENTATION_HORIZ, ORIENTATION_VERT }; enum { LINE_DIRECTION_NEGATIVE, LINE_DIRECTION_POSITIVE }; -enum { PLAYFIELD_UNCLEARED, PLAYFIELD_WALL, PLAYFIELD_LINE }; - enum { GAME_OVER_RETRY, GAME_OVER_QUIT }; enum { TITLE_1_PLAYER, TITLE_2_PLAYERS }; diff --git a/src/zeropage.h b/src/zeropage.h index bc7c070..e39eb97 100644 --- a/src/zeropage.h +++ b/src/zeropage.h @@ -76,7 +76,9 @@ unsigned char temp_byte_9; unsigned int temp_int_1; unsigned int temp_int_2; -unsigned int temp_int_3; + +unsigned int temp_int_3_byte_1; +unsigned int temp_int_3_byte_2; unsigned char* temp_ptr_1;