mirror of
https://github.com/st3fan/ewm.git
synced 2024-06-19 06:29:34 +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
|
LDFLAGS=-g -L/usr/local/lib
|
||||||
|
|
||||||
EWM_EXECUTABLE=ewm
|
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_OBJECTS=$(EWM_SOURCES:.c=.o)
|
||||||
EWM_LIBS=-lcurses -lSDL2 -lSDL2_ttf
|
EWM_LIBS=-lcurses -lSDL2
|
||||||
|
|
||||||
CPU_TEST_EXECUTABLE=cpu_test
|
CPU_TEST_EXECUTABLE=cpu_test
|
||||||
CPU_TEST_SOURCES=cpu.c ins.c mem.c fmt.c cpu_test.c
|
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 <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#include <SDL2/SDL_ttf.h>
|
|
||||||
#include <SDL2/SDL.h>
|
#include <SDL2/SDL.h>
|
||||||
|
|
||||||
#include "mem.h"
|
#include "mem.h"
|
||||||
#include "cpu.h"
|
#include "cpu.h"
|
||||||
#include "a2p.h"
|
#include "a2p.h"
|
||||||
|
#include "chr.h"
|
||||||
#include "scr.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_Window *window;
|
||||||
SDL_Renderer *renderer;
|
SDL_Renderer *renderer;
|
||||||
|
|
||||||
|
struct ewm_chr_t *chr = NULL;
|
||||||
|
|
||||||
void scr_init() {
|
void scr_init() {
|
||||||
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
if (SDL_Init(SDL_INIT_VIDEO) < 0) {
|
||||||
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
|
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
|
||||||
|
@ -97,49 +58,11 @@ void scr_init() {
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
||||||
TTF_Init();
|
chr = ewm_chr_create("roms/3410036.bin", EWM_CHR_ROM_TYPE_2716, renderer);
|
||||||
TTF_Font *font = TTF_OpenFont("Apple2Forever.ttf", 48);
|
if (chr == NULL) {
|
||||||
|
fprintf(stderr, "[SCR] Failed to initialize character generator\n");
|
||||||
memset(characters, 0x00, sizeof(characters));
|
exit(1);
|
||||||
|
|
||||||
// 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// 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] = {
|
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;
|
uint16_t row_offset = screen1_offsets[row] - 0x0400;
|
||||||
for (int column = 0; column < 40; column++) {
|
for (int column = 0; column < 40; column++) {
|
||||||
uint8_t c = a2p->screen1_data[row_offset + 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;
|
uint16_t row_offset = screen2_offsets[row] - 0x0800;
|
||||||
for (int column = 0; column < 40; column++) {
|
for (int column = 0; column < 40; column++) {
|
||||||
uint8_t c = a2p->screen2_data[row_offset + 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