mirror of
https://codeberg.org/hkzlab/TK2000_floppicator.git
synced 2025-12-26 01:22:30 +11:00
Implement basic graphic routines
This commit is contained in:
parent
be70ff936e
commit
5c6994b253
10 changed files with 109 additions and 467 deletions
2
Makefile
2
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)
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -1,418 +0,0 @@
|
|||
#include "game_graphics.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef _GAME_GRAPHICS_HEADER_
|
||||
#define _GAME_GRAPHICS_HEADER_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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_ */
|
||||
69
src/graphics.c
Normal file
69
src/graphics.c
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
#include "graphics.h"
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#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];
|
||||
}
|
||||
}
|
||||
}
|
||||
18
src/graphics.h
Normal file
18
src/graphics.h
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
#ifndef _GRAPHICS_HEADER_
|
||||
#define _GRAPHICS_HEADER_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#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_ */
|
||||
13
src/main.c
13
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 {
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue