From d55108f6362778a7b1c8d6533fb4c24b3ba03559 Mon Sep 17 00:00:00 2001 From: Stefan Arentz Date: Sun, 4 Dec 2016 23:09:36 -1000 Subject: [PATCH] Fixes #53 Implement High Resolution Graphics --- a2p.c | 4 ++-- a2p.h | 4 ++++ scr.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++- 3 files changed, 79 insertions(+), 3 deletions(-) diff --git a/a2p.c b/a2p.c index e00bd92..ac4ae57 100644 --- a/a2p.c +++ b/a2p.c @@ -166,8 +166,8 @@ void a2p_init(struct a2p_t *a2p, struct cpu_t *cpu) { a2p->screen_txt_data = malloc(2 * 1024); a2p->screen_txt_iom = cpu_add_iom(cpu, 0x0400, 0x0bff, a2p, a2p_screen_txt_read, a2p_screen_txt_write); - //a2p->screen_hgr_data = malloc(16 * 1024); - //a2p->screen_hgr_iom = cpu_add_iom(cpu, 0x2000, 0x7fff, a2p, a2p_screen_hgr_read, a2p_screen_hgr_write); + a2p->screen_hgr_data = malloc(16 * 1024); + a2p->screen_hgr_iom = cpu_add_iom(cpu, 0x2000, 0x5fff, a2p, a2p_screen_hgr_read, a2p_screen_hgr_write); } int a2p_load_disk(struct a2p_t *a2p, int drive, char *path) { diff --git a/a2p.h b/a2p.h index 434b837..a5f0eae 100644 --- a/a2p.h +++ b/a2p.h @@ -49,6 +49,10 @@ struct a2p_t { uint8_t *screen_txt_data; struct mem_t *screen_txt_iom; + uint8_t *screen_hgr_data; + struct mem_t *screen_hgr_iom; + int screen_hgr_page; + int screen_mode; int screen_graphics_mode; int screen_graphics_style; diff --git a/scr.c b/scr.c index 865a6f6..9ca25bd 100644 --- a/scr.c +++ b/scr.c @@ -182,6 +182,78 @@ static void _render_lgr_screen2(struct a2p_t *a2p, bool mixed) { } } +static uint16_t hgr_page_offsets[2] = { + 0x0000, // $0000 in our buffer, $2000 in emulator + 0x2000 // $2000 in our buffer, $4000 in emulator +}; + +static uint16_t hgr_line_offsets[192] = { + 0x0000, 0x0400, 0x0800, 0x0c00, 0x1000, 0x1400, 0x1800, 0x1c00, + 0x0080, 0x0480, 0x0880, 0x0c80, 0x1080, 0x1480, 0x1880, 0x1c80, + 0x0100, 0x0500, 0x0900, 0x0d00, 0x1100, 0x1500, 0x1900, 0x1d00, + 0x0180, 0x0580, 0x0980, 0x0d80, 0x1180, 0x1580, 0x1980, 0x1d80, + 0x0200, 0x0600, 0x0a00, 0x0e00, 0x1200, 0x1600, 0x1a00, 0x1e00, + 0x0280, 0x0680, 0x0a80, 0x0e80, 0x1280, 0x1680, 0x1a80, 0x1e80, + 0x0300, 0x0700, 0x0b00, 0x0f00, 0x1300, 0x1700, 0x1b00, 0x1f00, + 0x0380, 0x0780, 0x0b80, 0x0f80, 0x1380, 0x1780, 0x1b80, 0x1f80, + 0x0028, 0x0428, 0x0828, 0x0c28, 0x1028, 0x1428, 0x1828, 0x1c28, + 0x00a8, 0x04a8, 0x08a8, 0x0ca8, 0x10a8, 0x14a8, 0x18a8, 0x1ca8, + 0x0128, 0x0528, 0x0928, 0x0d28, 0x1128, 0x1528, 0x1928, 0x1d28, + 0x01a8, 0x05a8, 0x09a8, 0x0da8, 0x11a8, 0x15a8, 0x19a8, 0x1da8, + 0x0228, 0x0628, 0x0a28, 0x0e28, 0x1228, 0x1628, 0x1a28, 0x1e28, + 0x02a8, 0x06a8, 0x0aa8, 0x0ea8, 0x12a8, 0x16a8, 0x1aa8, 0x1ea8, + 0x0328, 0x0728, 0x0b28, 0x0f28, 0x1328, 0x1728, 0x1b28, 0x1f28, + 0x03a8, 0x07a8, 0x0ba8, 0x0fa8, 0x13a8, 0x17a8, 0x1ba8, 0x1fa8, + 0x0050, 0x0450, 0x0850, 0x0c50, 0x1050, 0x1450, 0x1850, 0x1c50, + 0x00d0, 0x04d0, 0x08d0, 0x0cd0, 0x10d0, 0x14d0, 0x18d0, 0x1cd0, + 0x0150, 0x0550, 0x0950, 0x0d50, 0x1150, 0x1550, 0x1950, 0x1d50, + 0x01d0, 0x05d0, 0x09d0, 0x0dd0, 0x11d0, 0x15d0, 0x19d0, 0x1dd0, + 0x0250, 0x0650, 0x0a50, 0x0e50, 0x1250, 0x1650, 0x1a50, 0x1e50, + 0x02d0, 0x06d0, 0x0ad0, 0x0ed0, 0x12d0, 0x16d0, 0x1ad0, 0x1ed0, + 0x0350, 0x0750, 0x0b50, 0x0f50, 0x1350, 0x1750, 0x1b50, 0x1f50, + 0x03d0, 0x07d0, 0x0bd0, 0x0fd0, 0x13d0, 0x17d0, 0x1bd0, 0x1fd0 +}; + +static void _render_hgr_line(struct a2p_t *a2p, int line, uint16_t line_base) { + int x = 0; + for (int i = 0; i < 40; i++) { + uint8_t c = a2p->screen_hgr_data[line_base + i]; + for (int j = 0; j < 7; j++) { + SDL_Rect dst; + dst.x = x * 3; + dst.y = line * 3; + dst.w = 3; + dst.h = 3; + if (c & (1 << j)) { + SDL_SetRenderDrawColor(renderer, 0, 255, 0, 0); + } else { + SDL_SetRenderDrawColor(renderer, 0, 0, 0, 0); + } + SDL_RenderFillRect(renderer, &dst); + x++; + } + } +} + +static void _render_hgr_screen(struct a2p_t *a2p) { + // Render graphics + int lines = (a2p->screen_graphics_style == EWM_A2P_SCREEN_GRAPHICS_STYLE_MIXED) ? 168 : 192; + uint16_t hgr_base = hgr_page_offsets[a2p->screen_page]; + for (int line = 0; line < lines; line++) { + uint16_t line_base = hgr_base + hgr_line_offsets[line]; + _render_hgr_line(a2p, line, line_base); + } + + // Render bottom 4 lines of text + if (a2p->screen_graphics_style == EWM_A2P_SCREEN_GRAPHICS_STYLE_MIXED) { + for (int row = 20; row < 24; row++) { + for (int column = 0; column < 40; column++) { + _render_character(a2p, row, column, screen1_offsets); + } + } + } +} + void scr_main(struct cpu_t *cpu, struct a2p_t *a2p) { bool quit = false; //bool running = true; @@ -301,7 +373,7 @@ void scr_main(struct cpu_t *cpu, struct a2p_t *a2p) { } break; case EWM_A2P_SCREEN_GRAPHICS_MODE_HGR: - // TODO Implement + _render_hgr_screen(a2p); break; } break;