Fixes #171 - Support software rendering in tty

This commit is contained in:
Stefan Arentz 2017-10-01 16:27:37 -04:00
parent 4a7d7056d2
commit ed3093784d
9 changed files with 174 additions and 46 deletions

View File

@ -42,32 +42,32 @@ ifeq ($(UNAME), Linux)
endif
EWM_EXECUTABLE=ewm
EWM_SOURCES=cpu.c ins.c pia.c mem.c ewm.c fmt.c two.c scr.c dsk.c chr.c alc.c one.c tty.c utl.c boo.c lua.c
EWM_SOURCES=cpu.c ins.c pia.c mem.c ewm.c fmt.c two.c scr.c dsk.c chr.c alc.c one.c tty.c utl.c boo.c lua.c sdl.c
EWM_OBJECTS=$(EWM_SOURCES:.c=.o)
EWM_LIBS=-lSDL2 $(LUA_LIBS)
CPU_TEST_EXECUTABLE=cpu_test
CPU_TEST_SOURCES=cpu.c ins.c mem.c fmt.c utl.c cpu_test.c lua.c
CPU_TEST_SOURCES=cpu.c ins.c mem.c fmt.c utl.c cpu_test.c lua.c sdl.c
CPU_TEST_OBJECTS=$(CPU_TEST_SOURCES:.c=.o)
CPU_TEST_LIBS=$(LUA_LIBS)
SCR_TEST_EXECUTABLE=scr_test
SCR_TEST_SOURCES=cpu.c ins.c mem.c fmt.c two.c scr.c dsk.c chr.c alc.c utl.c scr_test.c lua.c
SCR_TEST_SOURCES=cpu.c ins.c mem.c fmt.c two.c scr.c dsk.c chr.c alc.c utl.c scr_test.c lua.c sdl.c
SCR_TEST_OBJECTS=$(SCR_TEST_SOURCES:.c=.o)
SCR_TEST_LIBS=-lSDL2 $(LUA_LIBS)
TTY_TEST_EXECUTABLE=tty_test
TTY_TEST_SOURCES=cpu.c ins.c mem.c fmt.c one.c tty.c pia.c chr.c utl.c tty_test.c lua.c
TTY_TEST_SOURCES=cpu.c ins.c mem.c fmt.c one.c tty.c pia.c chr.c utl.c tty_test.c lua.c sdl.c
TTY_TEST_OBJECTS=$(TTY_TEST_SOURCES:.c=.o)
TTY_TEST_LIBS=-lSDL2 $(LUA_LIBS)
CPU_BENCH=cpu_bench
CPU_BENCH_SOURCES=cpu.c ins.c mem.c fmt.c utl.c cpu_bench.c lua.c
CPU_BENCH_SOURCES=cpu.c ins.c mem.c fmt.c utl.c cpu_bench.c lua.c sdl.c
CPU_BENCH_OBJECTS=$(CPU_BENCH_SOURCES:.c=.o)
CPU_BENCH_LIBS=$(LUA_LIBS)
MEM_BENCH=mem_bench
MEM_BENCH_SOURCES=cpu.c ins.c mem.c fmt.c utl.c mem_bench.c lua.c
MEM_BENCH_SOURCES=cpu.c ins.c mem.c fmt.c utl.c mem_bench.c lua.c sdl.c
MEM_BENCH_OBJECTS=$(MEM_BENCH_SOURCES:.c=.o)
MEM_BENCH_LIBS=$(LUA_LIBS)

View File

@ -25,6 +25,7 @@
#include <SDL2/SDL.h>
#include "tty.h"
#include "sdl.h"
#include "boo.h"
static char *menu[24] = {
@ -62,7 +63,8 @@ int ewm_boo_main(int argc, char **argv) {
return 1;
}
SDL_Window *window = SDL_CreateWindow("EWM v0.1 / Apple 1", 400, 60, 280*3, 192*3, SDL_WINDOW_SHOWN);
SDL_Window *window = SDL_CreateWindow("EWM v0.1 - Bootloader", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
280*3, 192*3, SDL_WINDOW_SHOWN);
if (window == NULL) {
fprintf(stderr, "Failed create window: %s\n", SDL_GetError());
return 1;
@ -74,7 +76,12 @@ int ewm_boo_main(int argc, char **argv) {
return 1;
}
SDL_RenderSetLogicalSize(renderer, 280*3, 192*3);
if (ewm_sdl_check_renderer(renderer) != 0) {
fprintf(stderr, "ewm: boo: unsupported renderer\n");
return 1;
}
SDL_RenderSetLogicalSize(renderer, 280, 192);
// We only need a tty to display the menu
@ -125,7 +132,6 @@ int ewm_boo_main(int argc, char **argv) {
SDL_SetRenderDrawColor(tty->renderer, 0, 0, 0, 255);
SDL_RenderClear(tty->renderer);
for (int i = 0; i < 24; i++) {
char *p = (char*) tty->screen_buffer;
p += (i * 40);
@ -135,12 +141,15 @@ int ewm_boo_main(int argc, char **argv) {
tty->screen_cursor_column = 34;
tty->screen_cursor_row = 9;
//strcpy((char*) tty->screen_buffer, "1) APPLE 1 2) REPLICA 1 3) APPLE ][+");
ewm_tty_refresh(tty, phase, EWM_BOO_FPS);
tty->screen_dirty = false;
SDL_Texture *texture = SDL_CreateTextureFromSurface(tty->renderer, tty->surface);
if (texture != NULL) {
SDL_RenderCopy(tty->renderer, texture, NULL, NULL);
SDL_DestroyTexture(texture);
}
SDL_RenderPresent(tty->renderer);
}

View File

@ -31,6 +31,7 @@
#include <SDL2/SDL.h>
#include "sdl.h"
#include "chr.h"
static int _load_rom_data(char *rom_path, uint8_t rom_data[2048]) {
@ -113,7 +114,7 @@ static uint32_t *_generate_bitmap(struct ewm_chr_t *chr, uint8_t rom_data[2048],
for (int y = 0; y < 8; y++) {
for (int x = 6; x >= 0; x--) {
if (character_data[y] & (1 << x)) {
*p++ = 0x00ff00ff;
*p++ = chr->green;
} else {
*p++ = 0x00000000;
}
@ -130,6 +131,9 @@ static int ewm_chr_init(struct ewm_chr_t *chr, char *rom_path, int rom_type, SDL
}
memset(chr, 0x00, sizeof(struct ewm_chr_t));
chr->renderer = renderer;
chr->green = ewm_sdl_green(renderer);
uint8_t rom_data[2048];
if (_load_rom_data(rom_path, rom_data) != 0) {
return -1;
@ -137,15 +141,29 @@ static int ewm_chr_init(struct ewm_chr_t *chr, char *rom_path, int rom_type, SDL
// Bitmaps
// Normal Text
for (int c = 0; c < 32; c++) {
chr->bitmaps[0xc0 + c] = _generate_bitmap(chr, rom_data, c, false);
}
for (int c = 32; c < 64; c++) {
chr->bitmaps[0xa0 + (c-32)] = _generate_bitmap(chr, rom_data, c, false);
}
// TODO The others?
// Inverse Text
for (int c = 0; c < 32; c++) {
chr->bitmaps[0x00 + c] = _generate_bitmap(chr, rom_data, c, true);
}
for (int c = 32; c < 64; c++) {
chr->bitmaps[0x20 + (c-32)] = _generate_bitmap(chr, rom_data, c, true);
}
// TODO Flashing - Currently simply rendered as inverse
for (int c = 0; c < 32; c++) {
chr->bitmaps[0x40 + c] = _generate_bitmap(chr, rom_data, c, true);
}
for (int c = 32; c < 64; c++) {
chr->bitmaps[0x60 + (c-32)] = _generate_bitmap(chr, rom_data, c, true);
}
// Textures
@ -193,14 +211,3 @@ int ewm_chr_width(struct ewm_chr_t* chr) {
int ewm_chr_height(struct ewm_chr_t* chr) {
return 8; // TODO Should be based on the ROM type?
}
#if 0
int main() {
struct ewm_chr_t *chr = ewm_chr_create("rom/3410036.bin", EWM_CHR_ROM_TYPE_2716);
if (chr == NULL) {
printf("Failed to load character ROM %s\n", "rom/3410036.bin");
exit(1);
}
return 0;
}
#endif

View File

@ -28,9 +28,10 @@
#define EWM_CHR_ROM_TYPE_2716 (2716)
struct ewm_chr_t {
SDL_Texture* textures[256];
SDL_Renderer *renderer;
SDL_Texture *textures[256];
uint32_t *bitmaps[256];
uint32_t green;
};
struct ewm_chr_t* ewm_chr_create(char *rom_path, int rom_type, SDL_Renderer *renderer);

View File

@ -26,6 +26,7 @@
#include <SDL2/SDL.h>
#include "sdl.h"
#include "cpu.h"
#include "mem.h"
#include "pia.h"
@ -253,7 +254,8 @@ int ewm_one_main(int argc, char **argv) {
return 1;
}
SDL_Window *window = SDL_CreateWindow("EWM v0.1 / Apple 1", 400, 60, 280*3, 192*3, SDL_WINDOW_SHOWN);
SDL_Window *window = SDL_CreateWindow("EWM v0.1 - Apple 1", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED,
280*3, 192*3, SDL_WINDOW_SHOWN);
if (window == NULL) {
fprintf(stderr, "Failed create window: %s\n", SDL_GetError());
return 1;
@ -265,7 +267,12 @@ int ewm_one_main(int argc, char **argv) {
return 1;
}
SDL_RenderSetLogicalSize(renderer, 280*3, 192*3);
if (ewm_sdl_check_renderer(renderer) != 0) {
fprintf(stderr, "ewm: boo: unsupported renderer\n");
return 1;
}
SDL_RenderSetLogicalSize(renderer, 280, 192);
// Create the machine
@ -314,6 +321,12 @@ int ewm_one_main(int argc, char **argv) {
ewm_tty_refresh(one->tty, phase, EWM_ONE_FPS);
one->tty->screen_dirty = false;
SDL_Texture *texture = SDL_CreateTextureFromSurface(one->tty->renderer, one->tty->surface);
if (texture != NULL) {
SDL_RenderCopy(one->tty->renderer, texture, NULL, NULL);
SDL_DestroyTexture(texture);
}
SDL_RenderPresent(one->tty->renderer);
}

72
src/sdl.c Normal file
View File

@ -0,0 +1,72 @@
// The MIT License (MIT)
//
// Copyright (c) 2015 Stefan Arentz - http://github.com/st3fan/ewm
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#include <stdio.h>
#include <SDL2/SDL.h>
int ewm_sdl_pixel_format(SDL_Renderer *renderer) {
SDL_RendererInfo info;
if (SDL_GetRendererInfo(renderer, &info) != 0) {
return -1;
}
for (Uint32 i = 0; i < info.num_texture_formats; i++) {
int format = info.texture_formats[i];
if (format == SDL_PIXELFORMAT_ARGB8888 || format == SDL_PIXELFORMAT_RGBA8888 || format == SDL_PIXELFORMAT_RGB888) {
return format;
}
}
return -1;
}
int ewm_sdl_check_renderer(SDL_Renderer *renderer) {
SDL_RendererInfo info;
if (SDL_GetRendererInfo(renderer, &info) != 0) {
printf("ewm: sdl: cannot get renderer info: %s\n", SDL_GetError());
return -1;
}
if ((info.flags & SDL_RENDERER_ACCELERATED) == 0) {
printf("ewm: sdl: require accelerated renderer\n");
return -1;
}
if (ewm_sdl_pixel_format(renderer) == -1) {
printf("ewm: sdl: cannot find supported pixel format (ARGB888, RGBA8888, RGB888)\n");
return -1;
}
return 0;
}
uint32_t ewm_sdl_green(SDL_Renderer *renderer) {
switch (ewm_sdl_pixel_format(renderer)) {
case SDL_PIXELFORMAT_RGBA8888:
return 0x00ff00ff;
case SDL_PIXELFORMAT_ARGB8888:
return 0xff00ff00;
case SDL_PIXELFORMAT_RGB888:
return 0x00ff0000;
}
return 0xffffff;
}

32
src/sdl.h Normal file
View File

@ -0,0 +1,32 @@
// The MIT License (MIT)
//
// Copyright (c) 2015 Stefan Arentz - http://github.com/st3fan/ewm
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to deal
// in the Software without restriction, including without limitation the rights
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all
// copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
// SOFTWARE.
#ifndef EWM_SDL
#define EWM_SDL
#include <SDL2/SDL.h>
int ewm_sdl_pixel_format(SDL_Renderer *renderer);
int ewm_sdl_check_renderer(SDL_Renderer *renderer);
uint32_t ewm_sdl_green(SDL_Renderer *renderer);
#endif // EWM_SDL

View File

@ -21,6 +21,7 @@
// SOFTWARE.
#include "chr.h"
#include "sdl.h"
#include "tty.h"
struct ewm_tty_t *ewm_tty_create(SDL_Renderer *renderer) {
@ -29,14 +30,10 @@ struct ewm_tty_t *ewm_tty_create(SDL_Renderer *renderer) {
tty->renderer = renderer;
tty->chr = ewm_chr_create("rom/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer);
// TODO Call SDL_RendererInfo() and decide if we need to do this. Also figure out the most optimal pixel format.
tty->pixels = malloc(4 * EWM_ONE_TTY_COLUMNS * ewm_chr_width(tty->chr) * EWM_ONE_TTY_ROWS * ewm_chr_height(tty->chr));
tty->surface = SDL_CreateRGBSurfaceWithFormatFrom(tty->pixels,
EWM_ONE_TTY_COLUMNS * ewm_chr_width(tty->chr),
EWM_ONE_TTY_ROWS * ewm_chr_height(tty->chr),
32,
4 * EWM_ONE_TTY_COLUMNS * ewm_chr_width(tty->chr),
SDL_PIXELFORMAT_RGB888);
tty->surface = SDL_CreateRGBSurfaceWithFormatFrom(tty->pixels, EWM_ONE_TTY_COLUMNS * ewm_chr_width(tty->chr),
EWM_ONE_TTY_ROWS * ewm_chr_height(tty->chr), 32, 4 * EWM_ONE_TTY_COLUMNS * ewm_chr_width(tty->chr),
ewm_sdl_pixel_format(renderer));
ewm_tty_reset(tty);
return tty;
@ -111,6 +108,7 @@ void ewm_tty_reset(struct ewm_tty_t *tty) {
tty->screen_buffer[(row * EWM_ONE_TTY_COLUMNS) + column] = 0x00;
}
}
tty->screen_cursor_row = 0;
tty->screen_cursor_column = 0;
tty->screen_dirty = true;
@ -128,13 +126,8 @@ void ewm_tty_refresh(struct ewm_tty_t *tty, uint32_t phase, uint32_t fps) {
}
if (tty->screen_cursor_blink) {
ewm_tty_render_character(tty, tty->screen_cursor_row, tty->screen_cursor_column, EWM_ONE_TTY_CURSOR);
ewm_tty_render_character(tty, tty->screen_cursor_row, tty->screen_cursor_column, EWM_ONE_TTY_CURSOR_ON);
} else {
ewm_tty_render_character(tty, tty->screen_cursor_row, tty->screen_cursor_column, EWM_ONE_TTY_CURSOR_OFF);
}
#if 0
uint32_t *p = tty->pixels;
for (int i = 0; i < 280 * 192; i++) {
*p++ = 0xff0000ff;
}
#endif
}

View File

@ -30,7 +30,8 @@
#define EWM_ONE_TTY_ROWS 24
#define EWM_ONE_TTY_COLUMNS 40
#define EWM_ONE_TTY_CURSOR '@'
#define EWM_ONE_TTY_CURSOR_ON '@'
#define EWM_ONE_TTY_CURSOR_OFF ' '
struct ewm_chr_t;