Fixes #51 - Replace Apple2Forever font with original character rom (#54)

This commit is contained in:
Stefan Arentz 2016-12-01 09:34:36 -05:00 committed by GitHub
parent 7f66bbccdf
commit 1a26f30350
5 changed files with 221 additions and 88 deletions

View File

@ -25,9 +25,9 @@ CFLAGS=-std=c11 -O0 -Wpedantic -Wall -Wshadow -Werror -Wshadow -Wno-gnu-binary-
LDFLAGS=-g -L/usr/local/lib
EWM_EXECUTABLE=ewm
EWM_SOURCES=cpu.c ins.c pia.c mem.c ewm.c fmt.c a2p.c scr.c dsk.c
EWM_SOURCES=cpu.c ins.c pia.c mem.c ewm.c fmt.c a2p.c scr.c dsk.c chr.c
EWM_OBJECTS=$(EWM_SOURCES:.c=.o)
EWM_LIBS=-lcurses -lSDL2 -lSDL2_ttf
EWM_LIBS=-lcurses -lSDL2
CPU_TEST_EXECUTABLE=cpu_test
CPU_TEST_SOURCES=cpu.c ins.c mem.c fmt.c cpu_test.c

159
chr.c Normal file
View File

@ -0,0 +1,159 @@
// 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 <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <SDL2/SDL.h>
#include "chr.h"
static int _load_rom_data(char *rom_path, uint8_t rom_data[2048]) {
int fd = open(rom_path, O_RDONLY);
if (fd == -1) {
return -1;
}
struct stat file_info;
if (fstat(fd, &file_info) == -1) {
close(fd);
return -1;
}
if (file_info.st_size != 2048) {
close(fd);
return -1;
}
if (read(fd, rom_data, file_info.st_size) != file_info.st_size) {
close(fd);
return -1;
}
close(fd);
return 0;
}
struct ewm_chr_t* ewm_chr_create(char *rom_path, int rom_type, SDL_Renderer *renderer) {
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);
if (ret != 0) {
free(chr);
chr = NULL;
}
return chr;
}
static void _set_pixel(SDL_Surface * surface, int x, int y, Uint32 color) {
uint32_t *pixel = (uint32_t*) ((uint8_t*) surface->pixels + (y * surface->pitch) + (x * sizeof(uint32_t)));
*pixel = color;
}
static SDL_Texture *_generate_texture(SDL_Renderer *renderer, uint8_t rom_data[2048], int c, bool inverse) {
SDL_Texture *texture = NULL;
uint8_t character_data[8];
for (int i = 0; i < 8; i++) {
character_data[i] = rom_data[(c * 8) + i + 1];
if (inverse) {
character_data[i] ^= 0xff;
}
}
SDL_Surface *surface = SDL_CreateRGBSurface(0, 7, 8, 32, 0x000000ff, 0x0000ff00, 0x00ff0000, 0xff000000);
if (surface != NULL) {
for (int y = 0; y < 8; y++) {
for (int x = 0; x < 7; x++) {
if (character_data[y] & (1 << x)) {
_set_pixel(surface, (6-x), y, 0xff00ff00);
}
}
}
texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
}
return texture;
}
int ewm_chr_init(struct ewm_chr_t *chr, char *rom_path, int rom_type, SDL_Renderer *renderer) {
if (rom_type != EWM_CHR_ROM_TYPE_2716) {
return -1;
}
memset(chr, 0x00, sizeof(struct ewm_chr_t));
uint8_t rom_data[2048];
if (_load_rom_data(rom_path, rom_data) != 0) {
return -1;
}
// Normal Text
for (int c = 0; c < 32; c++) {
chr->characters[0xc0 + c] = _generate_texture(renderer, rom_data, c, false);
}
for (int c = 32; c < 64; c++) {
chr->characters[0xa0 + (c-32)] = _generate_texture(renderer, rom_data, c, false);
}
// Inverse Text
for (int c = 0; c < 32; c++) {
chr->characters[0x00 + c] = _generate_texture(renderer, rom_data, c, true);
}
for (int c = 32; c < 64; c++) {
chr->characters[0x20 + (c-32)] = _generate_texture(renderer, rom_data, c, true);
}
// TODO Flashing - Currently simply rendered as inverse
for (int c = 0; c < 32; c++) {
chr->characters[0x40 + c] = _generate_texture(renderer, rom_data, c, true);
}
for (int c = 32; c < 64; c++) {
chr->characters[0x60 + (c-32)] = _generate_texture(renderer, rom_data, c, true);
}
return 0;
}
/* for (int i = 0; i < 8; i++) { */
/* for (int b = 0; b < 8; b++) { */
/* printf("%s", (character_data[i] & (1 << b)) ? "X" : " "); */
/* } */
/* printf("\n"); */
/* } */
#if 0
int main() {
struct ewm_chr_t *chr = ewm_chr_create("roms/3410036.bin", EWM_CHR_ROM_TYPE_2716);
if (chr == NULL) {
printf("Failed to load character ROM %s\n", "roms/3410036.bin");
exit(1);
}
return 0;
}
#endif

37
chr.h Normal file
View File

@ -0,0 +1,37 @@
// 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_CHR_H
#define EWM_CHR_H
#include <SDL2/SDL.h>
#define EWM_CHR_ROM_TYPE_2716 (2716)
struct ewm_chr_t {
SDL_Texture* characters[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);
#endif

BIN
roms/3410036.bin Executable file

Binary file not shown.

107
scr.c
View File

@ -23,58 +23,19 @@
#include <stdint.h>
#include <stdbool.h>
#include <SDL2/SDL_ttf.h>
#include <SDL2/SDL.h>
#include "mem.h"
#include "cpu.h"
#include "a2p.h"
#include "chr.h"
#include "scr.h"
SDL_Texture *prerender_character(SDL_Renderer *renderer, TTF_Font *font, char c, bool inverse) {
char text[2];
text[0] = c;
text[1] = 0x00;
SDL_Color white;
white.a = 0;
white.r = 255;
white.g = 255;
white.b = 255;
SDL_Color black;
black.a = 0;
black.r = 0;
black.g = 0;
black.b = 0;
SDL_Surface *surface;
if (inverse) {
surface = TTF_RenderText_Shaded(font, text, black, white);
} else {
surface = TTF_RenderText_Shaded(font, text, white, black);
}
SDL_Texture *texture = SDL_CreateTextureFromSurface(renderer, surface);
SDL_FreeSurface(surface);
return texture;
}
SDL_Texture *characters[256];
void render_character(SDL_Texture *texture, SDL_Renderer *renderer, int x, int y) {
SDL_Rect dst;
dst.x = x * 21;
dst.y = y * 24;
dst.w = 21;
dst.h = 24;
SDL_RenderCopy(renderer, texture, NULL, &dst);
}
SDL_Window *window;
SDL_Renderer *renderer;
struct ewm_chr_t *chr = NULL;
void scr_init() {
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
@ -97,49 +58,11 @@ void scr_init() {
//
TTF_Init();
TTF_Font *font = TTF_OpenFont("Apple2Forever.ttf", 48);
memset(characters, 0x00, sizeof(characters));
// normal text
for (int c = 0x20; c <= 0x60; c++) {
SDL_Texture *texture = prerender_character(renderer, font, (char) c, false);
if (texture == NULL) {
fprintf(stderr, "Failed to create character texture (%.2x): %s\n", c, SDL_GetError());
chr = ewm_chr_create("roms/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer);
if (chr == NULL) {
fprintf(stderr, "[SCR] Failed to initialize character generator\n");
exit(1);
}
characters[0xa0 + (c - 0x20)] = texture;
}
// inverse text
for (int c = 0x40; c <= 0x60; c++) {
SDL_Texture *texture = prerender_character(renderer, font, (char) c, true);
if (texture == NULL) {
fprintf(stderr, "Failed to create character texture: %s\n", SDL_GetError());
exit(1);
}
characters[0x00 + (c - 0x40)] = texture;
}
for (int c = 0x20; c <= 0x3f; c++) {
SDL_Texture *texture = prerender_character(renderer, font, (char) c, true);
if (texture == NULL) {
fprintf(stderr, "Failed to create character texture: %s\n", SDL_GetError());
exit(1);
}
characters[0x20 + (c - 0x20)] = texture;
}
//
/* SDL_Surface *surface = SDL_GetWindowSurface(window); */
/* if (surface == NULL) { */
/* fprintf(stderr, "Could not get window surface: %s\n", SDL_GetError()); */
/* exit(1); */
/* } */
/* SDL_FillRect(surface, NULL, SDL_MapRGB(surface->format, 0x00, 0x00, 0x00)); */
/* SDL_UpdateWindowSurface(window); */
}
static int screen1_offsets[24] = {
@ -254,7 +177,14 @@ void scr_main(struct cpu_t *cpu, struct a2p_t *a2p) {
uint16_t row_offset = screen1_offsets[row] - 0x0400;
for (int column = 0; column < 40; column++) {
uint8_t c = a2p->screen1_data[row_offset + column];
render_character(characters[c], renderer, column, row);
if (chr->characters[c] != NULL) {
SDL_Rect dst;
dst.x = column * 21;
dst.y = row * 24;
dst.w = 21;
dst.h = 24;
SDL_RenderCopy(renderer, chr->characters[c], NULL, &dst);
}
}
}
}
@ -265,7 +195,14 @@ void scr_main(struct cpu_t *cpu, struct a2p_t *a2p) {
uint16_t row_offset = screen2_offsets[row] - 0x0800;
for (int column = 0; column < 40; column++) {
uint8_t c = a2p->screen2_data[row_offset + column];
render_character(characters[c], renderer, column, row);
if (chr->characters[c] != NULL) {
SDL_Rect dst;
dst.x = column * 21;
dst.y = row * 24;
dst.w = 21;
dst.h = 24;
SDL_RenderCopy(renderer, chr->characters[c], NULL, &dst);
}
}
}
}