mirror of
https://github.com/st3fan/ewm.git
synced 2025-03-24 11:31:31 +00:00
Fixes #120 Implement a software renderer
This commit is contained in:
parent
29346949cc
commit
78182309a3
40
src/chr.c
40
src/chr.c
@ -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)]);
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
@ -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);
|
||||
|
47
src/scr.c
47
src/scr.c
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user