Fixes #120 Implement a software renderer

This commit is contained in:
Stefan Arentz 2017-01-08 04:38:03 +00:00
parent 29346949cc
commit 78182309a3
6 changed files with 69 additions and 30 deletions

View File

@ -60,9 +60,9 @@ static int _load_rom_data(char *rom_path, uint8_t rom_data[2048]) {
return 0;
}
struct ewm_chr_t* ewm_chr_create(char *rom_path, int rom_type, SDL_Renderer *renderer) {
struct ewm_chr_t* ewm_chr_create(char *rom_path, int rom_type, SDL_Renderer *renderer, uint32_t color) {
struct ewm_chr_t *chr = (struct ewm_chr_t*) malloc(sizeof(struct ewm_chr_t));
int ret = ewm_chr_init(chr, rom_path, rom_type, renderer);
int ret = ewm_chr_init(chr, rom_path, rom_type, renderer, color);
if (ret != 0) {
free(chr);
chr = NULL;
@ -75,13 +75,15 @@ static void _set_pixel(SDL_Surface * surface, int x, int y, Uint32 color) {
*pixel = color;
}
static SDL_Surface *_generate_surface(SDL_Renderer *renderer, uint8_t rom_data[2048], int c, bool inverse) {
static SDL_Surface *_generate_surface(SDL_Renderer *renderer, uint8_t rom_data[2048], int c, bool inverse, uint32_t color) {
SDL_Surface *surface = SDL_CreateRGBSurfaceWithFormat(0, 7*3, 8*3, 32, SDL_PIXELFORMAT_ARGB8888);
if (surface == NULL) {
fprintf(stderr, "[CHR] Cannot create RGBSurface: %s\n", SDL_GetError());
return NULL;
}
SDL_SetSurfaceBlendMode(surface, SDL_BLENDMODE_NONE);
uint8_t character_data[8];
for (int i = 0; i < 8; i++) {
character_data[i] = rom_data[(c * 8) + i + 1];
@ -95,17 +97,17 @@ static SDL_Surface *_generate_surface(SDL_Renderer *renderer, uint8_t rom_data[2
if (character_data[y] & (1 << x)) {
int px = (6-x) * 3, py = y * 3;
_set_pixel(surface, px+0, py+0, 0xffffffff);
_set_pixel(surface, px+1, py+0, 0xffffffff);
_set_pixel(surface, px+2, py+0, 0xffffffff);
_set_pixel(surface, px+0, py+0, color);
_set_pixel(surface, px+1, py+0, color);
_set_pixel(surface, px+2, py+0, color);
_set_pixel(surface, px+0, py+1, 0xffffffff);
_set_pixel(surface, px+1, py+1, 0xffffffff);
_set_pixel(surface, px+2, py+1, 0xffffffff);
_set_pixel(surface, px+0, py+1, color);
_set_pixel(surface, px+1, py+1, color);
_set_pixel(surface, px+2, py+1, color);
_set_pixel(surface, px+0, py+2, 0xffffffff);
_set_pixel(surface, px+1, py+2, 0xffffffff);
_set_pixel(surface, px+2, py+2, 0xffffffff);
_set_pixel(surface, px+0, py+2, color);
_set_pixel(surface, px+1, py+2, color);
_set_pixel(surface, px+2, py+2, color);
}
}
}
@ -122,7 +124,7 @@ static SDL_Texture *_generate_texture(SDL_Renderer *renderer, SDL_Surface *surfa
return texture;
}
int ewm_chr_init(struct ewm_chr_t *chr, char *rom_path, int rom_type, SDL_Renderer *renderer) {
int ewm_chr_init(struct ewm_chr_t *chr, char *rom_path, int rom_type, SDL_Renderer *renderer, uint32_t color) {
if (rom_type != EWM_CHR_ROM_TYPE_2716) {
return -1;
}
@ -143,31 +145,31 @@ int ewm_chr_init(struct ewm_chr_t *chr, char *rom_path, int rom_type, SDL_Render
// Normal Text
for (int c = 0; c < 32; c++) {
chr->surfaces[0xc0 + c] = _generate_surface(renderer, rom_data, c, false);
chr->surfaces[0xc0 + c] = _generate_surface(renderer, rom_data, c, false, color);
chr->textures[0xc0 + c] = _generate_texture(renderer, chr->surfaces[0xc0 + c]);
}
for (int c = 32; c < 64; c++) {
chr->surfaces[0xa0 + (c-32)] = _generate_surface(renderer, rom_data, c, false);
chr->surfaces[0xa0 + (c-32)] = _generate_surface(renderer, rom_data, c, false, color);
chr->textures[0xa0 + (c-32)] = _generate_texture(renderer, chr->surfaces[0xa0 + (c-32)]);
}
// Inverse Text
for (int c = 0; c < 32; c++) {
chr->surfaces[0x00 + c] = _generate_surface(renderer, rom_data, c, true);
chr->surfaces[0x00 + c] = _generate_surface(renderer, rom_data, c, true, color);
chr->textures[0x00 + c] = _generate_texture(renderer, chr->surfaces[0x00 + c]);
}
for (int c = 32; c < 64; c++) {
chr->surfaces[0x20 + (c-32)] = _generate_surface(renderer, rom_data, c, true);
chr->surfaces[0x20 + (c-32)] = _generate_surface(renderer, rom_data, c, true, color);
chr->textures[0x20 + (c-32)] = _generate_texture(renderer, chr->surfaces[0x20 + (c-32)]);
}
// TODO Flashing - Currently simply rendered as inverse
for (int c = 0; c < 32; c++) {
chr->surfaces[0x40 + c] = _generate_surface(renderer, rom_data, c, true);
chr->surfaces[0x40 + c] = _generate_surface(renderer, rom_data, c, true, color);
chr->textures[0x40 + c] = _generate_texture(renderer, chr->surfaces[0x40 + c]);
}
for (int c = 32; c < 64; c++) {
chr->surfaces[0x60 + (c-32)] = _generate_surface(renderer, rom_data, c, true);
chr->surfaces[0x60 + (c-32)] = _generate_surface(renderer, rom_data, c, true, color);
chr->textures[0x60 + (c-32)] = _generate_texture(renderer, chr->surfaces[0x60 + (c-32)]);
}

View File

@ -32,7 +32,7 @@ struct ewm_chr_t {
SDL_Texture* textures[256];
};
struct ewm_chr_t* ewm_chr_create(char *rom_path, int rom_type, SDL_Renderer *renderer);
int ewm_chr_init(struct ewm_chr_t *chr, char *rom_path, int rom_type, SDL_Renderer *renderer);
struct ewm_chr_t* ewm_chr_create(char *rom_path, int rom_type, SDL_Renderer *renderer, uint32_t color);
int ewm_chr_init(struct ewm_chr_t *chr, char *rom_path, int rom_type, SDL_Renderer *renderer, uint32_t color);
#endif

View File

@ -45,7 +45,9 @@ int main() {
exit(1);
}
struct ewm_chr_t *chr = ewm_chr_create("rom/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer);
uint32_t color = SDL_MapRGB(SDL_GetWindowSurface(window)->format, 47, 249, 64);
struct ewm_chr_t *chr = ewm_chr_create("rom/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer, color);
if (chr == NULL) {
fprintf(stderr, "[CHR] Failed to load Character ROM %s\n", "rom/3410036.bin");
exit(1);

View File

@ -85,9 +85,40 @@ static inline void scr_render_character(struct scr_t *scr, int row, int column,
}
static inline void scr_render_txt_screen(struct scr_t *scr, bool flash) {
SDL_Surface *surface = SDL_GetWindowSurface(scr->window);
uint8_t *base = scr->two->screen_txt_data + (scr->two->screen_page == EWM_A2P_SCREEN_PAGE1 ? 0x0000 : 0x0400);
SDL_Surface **surfaces = scr->chr->surfaces;
SDL_Rect src;
src.x = 0;
src.y = 0;
src.w = 21;
src.h = 24;
SDL_Rect dst;
dst.x = 0;
dst.y = 0;
dst.w = 21;
dst.h = 24;
for (int row = 0; row < 24; row++) {
uint8_t *p = base + txt_line_offsets[row];
for (int column = 0; column < 40; column++) {
scr_render_character(scr, row, column, flash);
uint8_t c = *p++;
if (surfaces[c] != NULL) {
if (c >= 0x40 && c <= 0x7f) {
if (flash) {
c -= 0x40;
} else {
if (c <= 0x5f) {
c += 0x80;
} else {
c += 0x40;
}
}
}
dst.x = column * 21;
dst.y = row * 24;
SDL_BlitSurface(surfaces[c], &src, surface, &dst);
}
}
}
}
@ -353,14 +384,10 @@ inline static void scr_render_hgr_screen(struct scr_t *scr, bool flash) {
int ewm_scr_init(struct scr_t *scr, struct ewm_two_t *two, SDL_Window *window, SDL_Renderer *renderer) {
memset(scr, 0x00, sizeof(struct scr_t));
scr->two = two;
scr->window = window;
scr->renderer = renderer;
scr->chr = ewm_chr_create("rom/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer);
if (scr->chr == NULL) {
fprintf(stderr, "[SCR] Failed to initialize character generator\n");
return -1;
}
// Cache colors for speed, to avoid calls to SDL_MapRGB
SDL_Surface *surface = SDL_GetWindowSurface(window);
@ -377,7 +404,13 @@ int ewm_scr_init(struct scr_t *scr, struct ewm_two_t *two, SDL_Window *window, S
lores_colors_color[i].g, lores_colors_color[i].b);
scr->lores_colors_green[i] = SDL_MapRGB(surface->format, lores_colors_green[i].r,
lores_colors_green[i].g, lores_colors_green[i].b);
}
}
scr->chr = ewm_chr_create("rom/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer, scr->text_color);
if (scr->chr == NULL) {
fprintf(stderr, "[SCR] Failed to initialize character generator\n");
return -1;
}
return 0;
}

View File

@ -28,7 +28,8 @@ struct ewm_tty_t *ewm_tty_create(SDL_Window *window, SDL_Renderer *renderer) {
memset(tty, 0, sizeof(struct ewm_tty_t));
tty->window = window;
tty->renderer = renderer;
tty->chr = ewm_chr_create("rom/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer);
tty->text_color = SDL_MapRGB(SDL_GetWindowSurface(window)->format, 47, 249, 64);
tty->chr = ewm_chr_create("rom/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer, tty->text_color);
ewm_tty_reset(tty);
return tty;
}

View File

@ -42,6 +42,7 @@ struct ewm_tty_t {
uint8_t screen_buffer[EWM_ONE_TTY_ROWS * EWM_ONE_TTY_COLUMNS];
int screen_cursor_row;
int screen_cursor_column;
uint32_t text_color;
};
struct ewm_tty_t *ewm_tty_create(SDL_Window *window, SDL_Renderer *renderer);