diff --git a/Makefile b/Makefile index 6793950..721d57b 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ PRG=master LIBS=clib-6502.a ASM_SRCS = tk2k_startup.s preserve_zero_pages.s disk2.s -C_SRCS = main.c +C_SRCS = main.c graphics.c utility.c line_data.c # Object files OBJS = $(ASM_SRCS:%.s=%.o) $(C_SRCS:%.c=%.o) diff --git a/linker-files/linker.scm b/linker-files/linker.scm index 67482fb..8ad7016 100644 --- a/linker-files/linker.scm +++ b/linker-files/linker.scm @@ -7,10 +7,9 @@ (section (programStart #x800) (dii_critical_wr_code #x803) (dii_critical_rd_code #x90b) startup code switch idata cdata data_init_table)) (memory dataMem (address (#x1600 . #x1fff)) (type ram) (section cstack zdata data heap zpsave)) (memory displayPage1 (address (#x2000 . #x3fff)) (type ram)) - (memory upperMem (address (#x4000 . #x9bff)) (type ram)) - (memory diskBuffer (address (#x9c00 . #x9eff)) (type ram)) ;;; This memory will be used by the disk II routines as buffer - (memory zeroPageBackup (address (#x9f00 . #x9fff)) (type ram) (section (zpsave #x9f00))) - (memory displayPage2 (address (#xa000 . #xbfff)) (type ram)) + (memory upperMem (address (#x4000 . #xbbff)) (type ram)) + (memory diskBuffer (address (#xbc00 . #xbeff)) (type ram)) ;;; This memory will be used by the disk II routines as buffer + (memory zeroPageBackup (address (#xbf00 . #xbfff)) (type ram) (section (zpsave #xbf00))) (memory io (address (#xc000 . #xc0ff)) (type ram)) (memory rombank (address (#xc100 . #xffff)) (type rom)) diff --git a/src/charset.h b/src/charset.h index 3006afb..43bb920 100644 --- a/src/charset.h +++ b/src/charset.h @@ -13,8 +13,9 @@ // Then graphic characters follow #define CHAR_HEIGHT 8 +#define CHAR_WIDTH 7 -#define ALPHA_OFFSET (1 * CHAR_HEIGHT +#define ALPHA_OFFSET (1 * CHAR_HEIGHT) #define SYMBOL_OFFSET (28 * CHAR_HEIGHT) #define NUM_OFFSET (48 * CHAR_HEIGHT) #define GRAPH_OFFSET (58 * CHAR_HEIGHT) diff --git a/src/disk2.h b/src/disk2.h index 4238f06..d85a338 100644 --- a/src/disk2.h +++ b/src/disk2.h @@ -5,9 +5,9 @@ #define DII_MAX_TRACK 96 #define DECODING_MAPPING_TABLE_DEFAULT_ADDRESS 0x0356 -#define ENCODING_MAPPING_TABLE_DEFAULT_ADDRESS 0x9D56 -#define WRITE_SIXES_BUFFER_DEFAULT_ADDRESS 0x9C00 -#define WRITE_TWOS_BUFFER_DEFAULT_ADDRESS 0x9D00 +#define ENCODING_MAPPING_TABLE_DEFAULT_ADDRESS 0xBD56 +#define WRITE_SIXES_BUFFER_DEFAULT_ADDRESS 0xBC00 +#define WRITE_TWOS_BUFFER_DEFAULT_ADDRESS 0xBD00 void dii_generate_6bit_decoding_mapping_table(uint8_t* dest); void dii_generate_6bit_encoding_mapping_table(uint8_t* dest); diff --git a/src/disk2.s b/src/disk2.s index f29f44a..8136d3b 100644 --- a/src/disk2.s +++ b/src/disk2.s @@ -525,9 +525,9 @@ wr_err_return: dii_write_sector: RETRIES$: .equ 0xff ; Note that the following buffers MUST be at the start of a page for write timing to be respected -__BUF2S: .equ 0x9D00 ; Default to this, it'll be overwritten when modifying this code. 86 entries. -__BUF6S: .equ 0x9C00 ; 256 entries. -__NIBTAB: .equ 0x9D56 ; This will contain the translation table for writing nibbles. 63 entries. +__BUF2S: .equ 0xBD00 ; Default to this, it'll be overwritten when modifying this code. 86 entries. +__BUF6S: .equ 0xBC00 ; 256 entries. +__NIBTAB: .equ 0xBD56 ; This will contain the translation table for writing nibbles. 63 entries. __OFFSETP6 .equ 0x0678 __T_VOL: .equ _Zp+9 diff --git a/src/game_graphics.c b/src/game_graphics.c deleted file mode 100644 index 9aa1818..0000000 --- a/src/game_graphics.c +++ /dev/null @@ -1,418 +0,0 @@ -#include "game_graphics.h" - -#include - -#include "utility.h" -#include "mem_map.h" -#include "mem_registers.h" -#include "line_data.h" -#include "game_logic.h" -#include "tiles.h" -#include "charset.h" -#include "monitor_subroutines.h" -#include "graph_misc_data.h" -#include "arrows_pic.h" - -#define SCREEN_WIDTH 280 -#define SCREEN_HEIGHT 192 - -#define SCREEN_WIDTH_B 40 -#define GRID_CELL_SIDE 35 - -#define TOP_OFFSET 7 -#define LEFT_OFFSET_B 1 // Left is offset by 1 bytes (7 pixels) - -static uint8_t *front_buf; -static uint8_t *back_buf; - -#define BOX_WIDTH 32 -#define BOX_HEIGHT 17 -#define BOX_CONTENT_SIZE (BOX_WIDTH * BOX_HEIGHT) - -static const uint8_t box_content_win[BOX_CONTENT_SIZE] = { - 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, 0, 0, 0, 0, - 0, 0, 0, 0, 77, 0, 77, 0, 83, 77, 84, 0, 77, 0, 77, 0, 0, 77, 0, 0, 0, 77, 0, 77, 0, 77, 0, 77, 0, 0, 0, 0, - 0, 0, 0, 0, 77, 0, 77, 0, 77, 0, 77, 0, 77, 0, 77, 0, 0, 77, 0, 77, 0, 77, 0, 77, 0, 77, 84, 77, 0, 0, 0, 0, - 0, 0, 0, 0,212, 77,211, 0, 77, 0, 77, 0, 77, 0, 77, 0, 0, 77, 0, 77, 0, 77, 0, 77, 0, 77, 0, 77, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 77, 0, 0,212, 77,211, 0,212, 77,211, 0, 0,212,211, 0,212,211, 0, 77, 0, 77, 0, 77, 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, 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, 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, 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, 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, 25, 15, 21, 18, 0, 19, 3, 15, 18, 5, 0, 9, 19, 58, 0, 48, 48, 48, 48, 48, 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, 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, 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, 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, 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, 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, 0, 0, 16, 21, 19, 8, 0, 1, 14, 25, 0, 11, 5, 25, 0, 20, 15, 0, 3, 15, 14, 20, 9, 14, 21, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const uint8_t box_content_lose[BOX_CONTENT_SIZE] = { - 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 1, 13, 5, 0, 0, 15, 22, 5, 18, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 77, 0, 77, 0, 83, 77, 84, 0, 77, 0, 77, 0, 0, 77, 0, 0, 0, 83, 77, 84, 0, 83, 77,192, 0, 77, 77, 77, 0, 0, - 0, 0, 77, 0, 77, 0, 77, 0, 77, 0, 77, 0, 77, 0, 0, 77, 0, 0, 0, 77, 0, 77, 0,212, 77, 84, 0, 77, 0, 0, 0, 0, - 0, 0,212, 77,211, 0, 77, 0, 77, 0, 77, 0, 77, 0, 0, 77, 0, 0, 0, 77, 0, 77, 0, 0,203, 77, 0, 77,193, 0, 0, 0, - 0, 0, 0, 77, 0, 0,212, 77,211, 0,212, 77,211, 0, 0,212, 77, 77, 0,212, 77,211, 0, 77, 77,211, 0, 77, 77, 77, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 25, 15, 21, 18, 0, 19, 3, 15, 18, 5, 0, 9, 19, 58, 0, 48, 48, 48, 48, 48, 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, 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, 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, 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, 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, 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, 0, 0, 16, 21, 19, 8, 0, 1, 14, 25, 0, 11, 5, 25, 0, 20, 15, 0, 3, 15, 14, 20, 9, 14, 21, 5, 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, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const uint8_t box_content_start[BOX_CONTENT_SIZE] = { - 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, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 16, 21, 19, 8, 0, 1, 14, 25, 0, 11, 5, 25, 0, 20, 15, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 83, 77,192, 0, 77, 77, 77, 0, 83, 77, 84, 0, 77, 77, 84, 0, 77, 77, 77, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0,212, 77, 84, 0, 0, 77, 0, 0, 77, 0, 77, 0, 77, 0, 77, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0,203, 77, 0, 0, 77, 0, 0, 77,192, 77, 0, 77, 77,211, 0, 0, 77, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 77, 77,211, 0, 0, 77, 0, 0, 77, 0, 77, 0, 77,198, 84, 0, 0, 77, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 20, 11, 50, 48, 52, 56, 0, 0, 0, 0, 0, 0, 0, 0, 0, 22, 50, 46, 48, 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, 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, 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, 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, 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, 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, 0, 0, 0, 0, 0, 8, 9, 7, 8, 45, 19, 3, 15, 18, 5, 58, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -}; - -static const uint8_t box_new_hi_score[BOX_WIDTH] = { - 0, 0,102, 0, 23, 5, 0, 7, 15, 20, 0, 1, 0, 14, 5, 23, 0, 8, 9, 7, 8, 45, 19, 3, 15, 18, 5, 33, 0,102, 0, 0 -}; - -#define INSTR_BOX_WIDTH 12 -#define INSTR_BOX_HEIGHT 8 -#define INSTR_BOX_SIZE (INSTR_BOX_HEIGHT * INSTR_BOX_WIDTH) -#define INSTR_BOX_X 28 -#define INSTR_BOX_Y 127 -static const uint8_t instruction_box[INSTR_BOX_SIZE] = { - 3, 20, 18, 12, 45, 18, 0, 18, 5, 19, 5, 20, - 3, 20, 18, 12, 45, 19, 0, 19, 1, 22, 5, 0, - 3, 20, 18, 12, 45, 12, 0, 12, 15, 1, 4, 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, - 18, 5, 1, 3, 8, 0, 0, 50, 48, 52, 56, 33, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 79, 0, 50, 48, 50, 53, 0, 50, 46, 48, 0, 79 -}; - - -// The grid is 5x5 squares, -// It is offset on the left side by 7 pixels and on the top by 14 -// Every square is 35x35 pixels - -void draw_field_borders_on_buffer(uint8_t brd, uint8_t* buf); -void draw_picture(uint8_t w, uint8_t h, uint8_t x, uint8_t y, const uint8_t *data, uint8_t *dest); -void direct_draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y, uint8_t *disp_buf); -void draw_graph_char_box(uint8_t x_offset, uint8_t y_offset, uint8_t width, uint8_t height, uint8_t const *data, uint8_t* buf); - -void ddraw_field_borders_on_buffer(uint8_t brd) { - draw_field_borders_on_buffer(brd, front_buf); -} - - -#define HIGH_TEXT_X 32 -#define HIGH_TEXT_Y 107 -#define HIGH_TEXT_WIDTH 5 - -void draw_game_background(uint16_t hi_score) { - // Draw the background on display page 1 - uint8_t* buf = (uint8_t*)DISPLAY_PAGE_1; - - // Draw the borders - draw_field_borders_on_buffer(0x0F, buf); - - // Draw required pics - draw_picture(SCORE_PIC_WIDTH_BYTES, SCORE_PIC_HEIGHT, 31, 14, score_pic_data, buf); - draw_picture(MOVES_PIC_WIDTH_BYTES, MOVES_PIC_HEIGHT, 31, 45, moves_pic_data, buf); - draw_picture(HIGH_PIC_WIDTH_BYTES, HIGH_PIC_HEIGHT, 31, 76, high_pic_data, buf); - draw_picture(SCORE_PIC_WIDTH_BYTES, SCORE_PIC_HEIGHT, 31, 90, score_pic_data, buf); - - // Draw the high-score. This won't change at every turn, so makes sense to just draw once - direct_draw_number(hi_score, HIGH_TEXT_WIDTH, HIGH_TEXT_X, HIGH_TEXT_Y, front_buf); - - // Draw instruction box - draw_graph_char_box(INSTR_BOX_X, INSTR_BOX_Y, INSTR_BOX_WIDTH, INSTR_BOX_HEIGHT, instruction_box, front_buf); - - // Copy the data from display page 1 to 2 - memcpy((void*)DISPLAY_PAGE_2, (void*)DISPLAY_PAGE_1, DISPLAY_PAGE_SIZE); - -} - -// This will draw directly to the front buffer -void ddraw_single_tile(uint8_t offset) { - uint8_t* grid = get_front_grid(); - if(!grid[offset]) return; // The tile is not there, nothing to do - - const uint8_t *tile_data = tiles + (TILE_WIDTH_BYTES * TILE_HEIGHT * (grid[offset] - 1)); - - uint8_t col = offset % GRID_SIDE; - uint8_t row = offset / GRID_SIDE; - - uint8_t delay = 0xFF; - - for(uint8_t h = 0; h < TILE_HEIGHT; h++) { - memcpy(front_buf + line_offset_map[TOP_OFFSET + 7 + (row * GRID_CELL_SIDE) + h] + LEFT_OFFSET_B + 1 + (col * GRID_CELL_SIDE/7), - tile_data + (TILE_WIDTH_BYTES * h), TILE_WIDTH_BYTES); - WAIT(48); - } -} - -void direct_draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y, uint8_t *disp_buf) { - uint8_t buf[len]; - - // Decode the number into the buffer - num_to_decbuf(n, len, buf); - - for(uint8_t row = 0; row < CHAR_HEIGHT; row++) { - uint16_t offset = line_offset_map[y + row]; - for(uint8_t col = 0; col < len; col++) { - disp_buf[(offset + (len - 1) - col) + x] = CHARSET[NUM_OFFSET + (buf[col] * CHAR_HEIGHT) + row]; - } - } -} - -void draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y) { - direct_draw_number(n, len, x, y, back_buf); -} - -void draw_tiles(void) { - uint8_t* grid = get_front_grid(); - - // Clear the grid so we'll be able to draw the boxes on - clear_box(GRID_SIDE * (GRID_CELL_SIDE/7) + 1, (GRID_SIDE * GRID_CELL_SIDE) + 4, LEFT_OFFSET_B, TOP_OFFSET + 1, back_buf); - - for (uint8_t tile = 0; tile < GRID_SIDE * GRID_SIDE; tile++) { - if(grid[tile]) { - const uint8_t *tile_data = tiles + (TILE_WIDTH_BYTES * TILE_HEIGHT * (grid[tile] - 1)); - uint8_t col = tile % GRID_SIDE; - uint8_t row = tile / GRID_SIDE; - - draw_picture(TILE_WIDTH_BYTES, TILE_HEIGHT, LEFT_OFFSET_B + 1 + (col * GRID_CELL_SIDE/7), TOP_OFFSET + 7 + (row * GRID_CELL_SIDE), tile_data, back_buf); - } - } - - // Re-draw the borders, to restore the correct width - draw_field_borders_on_buffer(0x0F, back_buf); -} - -#define ENDGAME_BOX_X_OFFSET 2 -#define ENDGAME_BOX_Y_OFFSET 16 -#define ENDGAME_BOX_SCORE_LEN 5 -void ddraw_endgame_box(int8_t done, uint16_t score, uint16_t hi_score) { - // Clear the part of the screen where we'll draw - clear_box((SCREEN_WIDTH_B - (ENDGAME_BOX_X_OFFSET * 2)) + 1, (SCREEN_HEIGHT - (ENDGAME_BOX_Y_OFFSET * 2)) + CHAR_HEIGHT, ENDGAME_BOX_X_OFFSET, ENDGAME_BOX_Y_OFFSET, front_buf); - - // Horizontal lines - for(uint8_t row = 0; row < CHAR_HEIGHT; row++) { - uint16_t offset_top = line_offset_map[ENDGAME_BOX_Y_OFFSET + CHAR_HEIGHT + row] + ENDGAME_BOX_X_OFFSET + 1; - uint16_t offset_bottom = line_offset_map[SCREEN_HEIGHT - ENDGAME_BOX_Y_OFFSET - CHAR_HEIGHT + row] + ENDGAME_BOX_X_OFFSET + 1; - for(uint8_t col = 0; col < SCREEN_WIDTH_B - ((ENDGAME_BOX_X_OFFSET * 2) + 2); col++) { - front_buf[offset_top + col] = CHARSET[GRAPH_OFFSET + (12 * CHAR_HEIGHT) + row]; - front_buf[offset_bottom + col] = CHARSET[GRAPH_OFFSET + (12 * CHAR_HEIGHT) + row]; - } - } - - // Corners - for(uint8_t row = 0; row < CHAR_HEIGHT; row++) { - uint16_t offset_top = line_offset_map[ENDGAME_BOX_Y_OFFSET + CHAR_HEIGHT + row] + ENDGAME_BOX_X_OFFSET + 1; - uint16_t offset_bottom = line_offset_map[SCREEN_HEIGHT - ENDGAME_BOX_Y_OFFSET - CHAR_HEIGHT + row] + ENDGAME_BOX_X_OFFSET + 1; - - front_buf[offset_top] = CHARSET[GRAPH_OFFSET + (25 * CHAR_HEIGHT) + row]; - front_buf[offset_bottom] = CHARSET[GRAPH_OFFSET + (27 * CHAR_HEIGHT) + row]; - front_buf[offset_top + (SCREEN_WIDTH_B - ((ENDGAME_BOX_X_OFFSET * 2) + 2))] = CHARSET[GRAPH_OFFSET + (26 * CHAR_HEIGHT) + row]; - front_buf[offset_bottom + (SCREEN_WIDTH_B - ((ENDGAME_BOX_X_OFFSET * 2) + 2))] = CHARSET[GRAPH_OFFSET + (28 * CHAR_HEIGHT) + row]; - } - - // Vertical lines - for(uint8_t row = 0; row < ((SCREEN_HEIGHT - (ENDGAME_BOX_Y_OFFSET * 3) - CHAR_HEIGHT)) + 1; row++) { - uint16_t offset = line_offset_map[ENDGAME_BOX_Y_OFFSET + (CHAR_HEIGHT * 2) + row] + ENDGAME_BOX_X_OFFSET + 1; - - front_buf[offset] = CHARSET[GRAPH_OFFSET + (19 * CHAR_HEIGHT) + (row % CHAR_HEIGHT)]; - front_buf[offset + (SCREEN_WIDTH_B - ((ENDGAME_BOX_X_OFFSET * 2) + 2))] = CHARSET[GRAPH_OFFSET + (19 * CHAR_HEIGHT) + (row % CHAR_HEIGHT)]; - } - - uint8_t const *content; - - // Decide which type of content to show - if(done == 0) content = box_content_start; - else if (done > 0) content = box_content_win; - else content = box_content_lose; - - // And now, the content!!! - draw_graph_char_box(ENDGAME_BOX_X_OFFSET + 2, (ENDGAME_BOX_Y_OFFSET + (2 * CHAR_HEIGHT)), BOX_WIDTH, BOX_HEIGHT, content, front_buf); - - if(done != 0) { // Print the score - direct_draw_number(score, ENDGAME_BOX_SCORE_LEN, ENDGAME_BOX_X_OFFSET + 23, ENDGAME_BOX_Y_OFFSET + (11 * CHAR_HEIGHT), front_buf); - - if(score > hi_score) { - draw_graph_char_box(ENDGAME_BOX_X_OFFSET + 2, (ENDGAME_BOX_Y_OFFSET + (2 * CHAR_HEIGHT) + (13 * CHAR_HEIGHT)), BOX_WIDTH, 1, box_new_hi_score, front_buf); - } - } else { // Print the loaded high score - direct_draw_number(hi_score, ENDGAME_BOX_SCORE_LEN, ENDGAME_BOX_X_OFFSET + 22, ENDGAME_BOX_Y_OFFSET + (16 * CHAR_HEIGHT), front_buf); - } -} - -void draw_graph_char_box(uint8_t x_offset, uint8_t y_offset, uint8_t width, uint8_t height, uint8_t const *data, uint8_t* buf) { - // Draw box - for(uint16_t tile = 0; tile < width * height; tile++) { - if(!data[tile]) continue; - - uint8_t x = tile % width; - uint8_t y = tile / width; - uint8_t invert = data[tile] & 0x80; - uint8_t ch_num = data[tile] & 0x7F; - - for(uint8_t row = 0; row < CHAR_HEIGHT; row++) { - uint16_t offset = line_offset_map[y_offset + (y * CHAR_HEIGHT) + row] + x_offset + x; - buf[offset] = invert ? ((~CHARSET[(ch_num * CHAR_HEIGHT) + row]) & 0x7F) : CHARSET[(ch_num * CHAR_HEIGHT) + row]; - } - } -} - -// Note that the horizontal values here are in group of 7 pixels -void clear_box(uint8_t w, uint8_t h, uint8_t off_x, uint8_t off_y, uint8_t *disp_buf) { - for(uint8_t y = off_y; y < off_y + h; y++) { - uint16_t line_counter = line_offset_map[y]; - - for(uint8_t x = off_x; x < off_x + w; x++) { - disp_buf[line_counter + x] = 0; - } - } -} - -void swap_display_buffers(void) { - uint8_t *temp = front_buf; - front_buf = back_buf; - back_buf = temp; - - // Show the current buffer - PEEK(((uint16_t)front_buf == DISPLAY_PAGE_1) ? IO_DISPLAY_PAGE1 : IO_DISPLAY_PAGE2); -} - -void sync_display1_buffer(void) { - if(((uint16_t)front_buf == DISPLAY_PAGE_1)) return; // We're already displaying buffer 1 - - // We need to copy from the secondary display to the primary - memcpy(back_buf, front_buf, DISPLAY_PAGE_SIZE); -} - -void initialize_display_buffers(void) { - PEEK(IO_DISPLAY_PAGE1); // Select the first display page - - // Restore the buffer ordering - front_buf = (uint8_t*)DISPLAY_PAGE_1; - back_buf = (uint8_t*)DISPLAY_PAGE_2; -} - -void clear_display_buffers(void) { - // Clear the buffers - memset((void*)DISPLAY_PAGE_1, 0, DISPLAY_PAGE_SIZE); - memset((void*)DISPLAY_PAGE_2, 0, DISPLAY_PAGE_SIZE); - - initialize_display_buffers(); -} - -void draw_field_borders_on_buffer(uint8_t brd, uint8_t* buf) { - // Horizontal borders - for(uint8_t col = 0; col < (GRID_SIDE * (GRID_CELL_SIDE/7)) + 1; col++) { - buf[line_offset_map[TOP_OFFSET - 1] + col + LEFT_OFFSET_B] = BRD_SKIP_UP(brd) ? 0x00: 0x7F; - buf[line_offset_map[TOP_OFFSET - 0] + col + LEFT_OFFSET_B] = BRD_DOUBLING_UP(brd) && !BRD_SKIP_UP(brd) ? 0x7F : 0x00; - - buf[line_offset_map[TOP_OFFSET + (GRID_CELL_SIDE * GRID_SIDE) + 7] + col + LEFT_OFFSET_B] = BRD_SKIP_DOWN(brd) ? 0x00: 0x7F; - buf[line_offset_map[TOP_OFFSET + (GRID_CELL_SIDE * GRID_SIDE) + 6] + col + LEFT_OFFSET_B] = BRD_DOUBLING_DOWN(brd) && !BRD_SKIP_DOWN(brd) ? 0x7F : 0x00; - } - - // Vertical borders - for(uint8_t row = 0; row < (GRID_CELL_SIDE * GRID_SIDE) + 7; row++) { - buf[line_offset_map[row + TOP_OFFSET] + LEFT_OFFSET_B - 1] = BRD_SKIP_LEFT(brd) ? 0x00 : (BRD_DOUBLING_LEFT(brd) ? 0x60 : 0x40); - buf[line_offset_map[row + TOP_OFFSET] + LEFT_OFFSET_B + (GRID_SIDE * (GRID_CELL_SIDE/7)) + 1] = BRD_SKIP_RIGHT(brd) ? 0x00 : (BRD_DOUBLING_RIGHT(brd) ? 0x03 : 0x01); - } -} - -void draw_picture(uint8_t w, uint8_t h, uint8_t x, uint8_t y, const uint8_t *data, uint8_t *dest) { - for(uint8_t row = 0; row < h; row++) { - memcpy(dest + line_offset_map[row + y] + x, data + (w * row), w); - } -} - -void ddraw_direction_arrows(uint8_t dir) { - uint8_t pic_buffer[ARROWS_HEIGHT]; - - int8_t start, step, end, flip; - uint8_t ext, x, y; - - switch(dir) { - case GRAPH_ARROW_UP: - x = 2; - y = TOP_OFFSET + 1; - ext = 1; - start = 1; - step = 1; - end = ARROWS_HEIGHT; - flip = 0; - break; - case GRAPH_ARROW_DOWN: - x = 2; - y = TOP_OFFSET + (GRID_SIDE * GRID_CELL_SIDE); - ext = 1; - start = ARROWS_HEIGHT - 1; - step = -1; - end = 0; - flip = 0; - break; - case GRAPH_ARROW_LEFT: - x = 1; - y = TOP_OFFSET + 7; - ext = 0; - start = ARROWS_HEIGHT; - step = 1; - end = (ARROWS_HEIGHT * 2); - flip = 0; - break; - case GRAPH_ARROW_RIGHT: - x = 1 + (GRID_SIDE * (GRID_CELL_SIDE/7)); - y = TOP_OFFSET + 7; - ext = 0; - start = ARROWS_HEIGHT; - step = 1; - end = (ARROWS_HEIGHT * 2); - flip = 1; - break; - default: - return; - } - - uint8_t tot_arrows = (GRID_SIDE * (GRID_CELL_SIDE/7)) - 1; - - if(ext) { // Horizontal lines - uint8_t s_start = x; - for(uint8_t cur_arrow = 0; cur_arrow < tot_arrows; cur_arrow++) { - for(int8_t s = start, row = 0; s != end; s += step, row++) { - front_buf[line_offset_map[y + row] + s_start] = arrows_pic[s]; - } - s_start++; - } - } else { - uint8_t s_start = y; - for(uint8_t cur_arrow = 0; cur_arrow < tot_arrows; cur_arrow++) { - for(int8_t s = start, row = 0; s != end; s += step, row++) { - front_buf[line_offset_map[s_start + row] + x] = flip ? (bit_reverse(arrows_pic[s]) >> 1) : arrows_pic[s]; - } - s_start += ARROWS_HEIGHT; - } - } -} diff --git a/src/game_graphics.h b/src/game_graphics.h deleted file mode 100644 index 72fcf99..0000000 --- a/src/game_graphics.h +++ /dev/null @@ -1,34 +0,0 @@ -#ifndef _GAME_GRAPHICS_HEADER_ -#define _GAME_GRAPHICS_HEADER_ - -#include - -#define BRD_DOUBLING_UP(a) (a & 0x01) -#define BRD_DOUBLING_DOWN(a) (a & 0x02) -#define BRD_DOUBLING_LEFT(a) (a & 0x04) -#define BRD_DOUBLING_RIGHT(a) (a & 0x08) - -#define BRD_SKIP_UP(a) (a & 0x10) -#define BRD_SKIP_DOWN(a) (a & 0x20) -#define BRD_SKIP_LEFT(a) (a & 0x40) -#define BRD_SKIP_RIGHT(a) (a & 0x80) - -#define GRAPH_ARROW_UP 0 -#define GRAPH_ARROW_DOWN 1 -#define GRAPH_ARROW_LEFT 2 -#define GRAPH_ARROW_RIGHT 3 - -void initialize_display_buffers(void); -void ddraw_field_borders_on_buffer(uint8_t brd); -void draw_game_background(uint16_t hi_score); -void draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y); -void draw_tiles(void); -void ddraw_single_tile(uint8_t offset); -void swap_display_buffers(void); -void clear_display_buffers(void); -void clear_box(uint8_t w, uint8_t h, uint8_t off_x, uint8_t off_y, uint8_t *disp_buf); -void ddraw_direction_arrows(uint8_t dir); -void ddraw_endgame_box(int8_t done, uint16_t score, uint16_t hi_score); -void sync_display1_buffer(void); - -#endif /* _GAME_GRAPHICS_HEADER_ */ diff --git a/src/graphics.c b/src/graphics.c new file mode 100644 index 0000000..8b58fa2 --- /dev/null +++ b/src/graphics.c @@ -0,0 +1,69 @@ +#include "graphics.h" + +#include + +#include "utility.h" +#include "mem_map.h" +#include "mem_registers.h" +#include "line_data.h" +#include "charset.h" +#include "monitor_subroutines.h" + + +static uint8_t *front_buf; + +// The grid is 5x5 squares, +// It is offset on the left side by 7 pixels and on the top by 14 +// Every square is 35x35 pixels + +void direct_draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y, uint8_t *disp_buf); +void draw_graph_char_box(uint8_t x_offset, uint8_t y_offset, uint8_t width, uint8_t height, uint8_t const *data, uint8_t* buf); + +void initialize_display_buffer(void) { + PEEK(IO_DISPLAY_PAGE1); // Select the first display page + + // Restore the buffer ordering + front_buf = (uint8_t*)DISPLAY_PAGE_1; +} + +void clear_display_buffer(void) { + // Clear the buffers + memset((void*)DISPLAY_PAGE_1, 0, DISPLAY_PAGE_SIZE); + + initialize_display_buffer(); +} + +void draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y) { + uint8_t buf[len]; + + // Decode the number into the buffer + num_to_decbuf(n, len, buf); + + for(uint8_t row = 0; row < CHAR_HEIGHT; row++) { + uint16_t offset = line_offset_map[y + row]; + for(uint8_t col = 0; col < len; col++) { + front_buf[(offset + (len - 1) - col) + x] = CHARSET[NUM_OFFSET + (buf[col] * CHAR_HEIGHT) + row]; + } + } +} + +// Note that the horizontal values here are in group of 7 pixels +void clear_box(uint8_t w, uint8_t h, uint8_t off_x, uint8_t off_y) { + for(uint8_t y = off_y; y < off_y + h; y++) { + uint16_t line_counter = line_offset_map[y]; + + for(uint8_t x = off_x; x < off_x + w; x++) { + front_buf[line_counter + x] = 0; + } + } +} + +void draw_chars(uint8_t x, uint8_t y, uint8_t invert, uint8_t *buf, uint8_t len) { + for(uint8_t row = 0; row < CHAR_HEIGHT && (row + y) < SCREEN_HEIGHT; row++) { + uint16_t offset = line_offset_map[row + y]; + + for(uint8_t col = 0; col < len && (col + x) < SCREEN_CHAR_WIDTH; col++) { + front_buf[offset + x + col] = invert ? (~CHARSET[(buf[col] * CHAR_HEIGHT) + row]) & 0x7F : CHARSET[(buf[col] * CHAR_HEIGHT) + row]; + } + } +} diff --git a/src/graphics.h b/src/graphics.h new file mode 100644 index 0000000..3b95b54 --- /dev/null +++ b/src/graphics.h @@ -0,0 +1,18 @@ +#ifndef _GRAPHICS_HEADER_ +#define _GRAPHICS_HEADER_ + +#include + +#define SCREEN_WIDTH 280 +#define SCREEN_HEIGHT 192 + +#define SCREEN_CHAR_WIDTH 40 +#define SCREEN_CHAR_HEIGHT 24 + +void initialize_display_buffer(void); +void clear_display_buffer(void); +void draw_number(uint16_t n, uint8_t len, uint8_t x, uint8_t y); +void clear_box(uint8_t w, uint8_t h, uint8_t off_x, uint8_t off_y); +void draw_chars(uint8_t x, uint8_t y, uint8_t invert, uint8_t *buf, uint8_t len); + +#endif /* _GRAPHICS_HEADER_ */ diff --git a/src/main.c b/src/main.c index 82c7d66..68f42c9 100644 --- a/src/main.c +++ b/src/main.c @@ -8,6 +8,7 @@ #include "utility.h" #include "mem_map.h" #include "mem_registers.h" +#include "graphics.h" #include "disk2.h" // External initialization requirements @@ -22,18 +23,19 @@ static void init(void); static void init(void) { POKE(P3_PWRDUP, 0); // Dirty the value checked by the reset vector PEEK(IO_ROMSEL); // Make sure the ROM is selected - PEEK(DISPLAY_PAGE_1); // Select display page 1 PEEK(IO_DISPLAY_BW); // Disable colors // Generate the decoding table dii_generate_6bit_decoding_mapping_table((uint8_t*)DECODING_MAPPING_TABLE_DEFAULT_ADDRESS); // Generate the encoding table dii_generate_6bit_encoding_mapping_table((uint8_t*)ENCODING_MAPPING_TABLE_DEFAULT_ADDRESS); + + // Clear the screen + clear_display_buffer(); } __task int main(void) { - uint8_t cur_trk = 0; - uint8_t cur_file = 0; + uint8_t cur_trk_1, cur_trk_2 = 0; uint8_t keep_going = 1; __disable_interrupts(); @@ -42,6 +44,11 @@ __task int main(void) { __enable_interrupts(); + uint8_t chars[] = {1, 2, 3, 32, 4}; + + draw_chars(0, 0, 1, chars, 5); + draw_chars(1, 8, 0, chars, 5); + draw_chars(2, 16, 1, chars, 5); do {