mirror of
https://github.com/st3fan/ewm.git
synced 2024-12-28 15:29:45 +00:00
This commit is contained in:
parent
7f66bbccdf
commit
1a26f30350
4
Makefile
4
Makefile
@ -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
159
chr.c
Normal 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
37
chr.h
Normal 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
BIN
roms/3410036.bin
Executable file
Binary file not shown.
109
scr.c
109
scr.c
@ -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());
|
||||
exit(1);
|
||||
}
|
||||
characters[0xa0 + (c - 0x20)] = texture;
|
||||
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);
|
||||
}
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user