mirror of
https://github.com/st3fan/ewm.git
synced 2025-01-03 09:29:45 +00:00
Fixes #178 - Allow the emulator to be paused
This commit is contained in:
parent
7a68e0909b
commit
d2a8386f72
@ -15,7 +15,7 @@ set(SDL_SOURCES sdl.c)
|
||||
|
||||
set(BOO_SOURCES boo.c tty.c chr.c)
|
||||
set(ONE_SOURCES one.c tty.c chr.c pia.c)
|
||||
set(TWO_SOURCES two.c scr.c dsk.c chr.c alc.c)
|
||||
set(TWO_SOURCES two.c scr.c dsk.c chr.c alc.c tty.c)
|
||||
|
||||
add_executable(cpu_test ${CPU_SOURCES} cpu_test.c)
|
||||
|
||||
|
@ -61,7 +61,7 @@ CPU_TEST_OBJECTS=$(CPU_TEST_SOURCES:.c=.o)
|
||||
CPU_TEST_LIBS=$(LUA_LIBS)
|
||||
|
||||
SCR_TEST_EXECUTABLE=scr_test
|
||||
SCR_TEST_SOURCES=$(CPU_SOURCES) two.c scr.c dsk.c chr.c alc.c scr_test.c sdl.c
|
||||
SCR_TEST_SOURCES=$(CPU_SOURCES) two.c scr.c dsk.c chr.c alc.c scr_test.c sdl.c tty.c
|
||||
SCR_TEST_OBJECTS=$(SCR_TEST_SOURCES:.c=.o)
|
||||
SCR_TEST_LIBS=-lSDL2 $(LUA_LIBS)
|
||||
|
||||
|
@ -85,7 +85,8 @@ int ewm_boo_main(int argc, char **argv) {
|
||||
|
||||
// We only need a tty to display the menu
|
||||
|
||||
struct ewm_tty_t *tty = ewm_tty_create(renderer);
|
||||
SDL_Color green = {255,255,0,255};
|
||||
struct ewm_tty_t *tty = ewm_tty_create(renderer, green);
|
||||
|
||||
// Main loop
|
||||
|
||||
|
12
src/one.c
12
src/one.c
@ -45,24 +45,28 @@ static int ewm_one_init(struct ewm_one_t *one, int model, SDL_Renderer *renderer
|
||||
memset(one, 0, sizeof(struct ewm_one_t));
|
||||
one->model = model;
|
||||
switch (model) {
|
||||
case EWM_ONE_MODEL_APPLE1:
|
||||
case EWM_ONE_MODEL_APPLE1: {
|
||||
one->cpu = cpu_create(EWM_CPU_MODEL_6502);
|
||||
cpu_add_ram(one->cpu, 0x0000, 8 * 1024 - 1);
|
||||
cpu_add_rom_file(one->cpu, 0xff00, "rom/apple1.rom");
|
||||
one->tty = ewm_tty_create(renderer);
|
||||
SDL_Color green = {0,255,0,255};
|
||||
one->tty = ewm_tty_create(renderer, green);
|
||||
one->pia = ewm_pia_create(one->cpu);
|
||||
one->pia->callback = ewm_one_pia_callback;
|
||||
one->pia->callback_obj = one;
|
||||
break;
|
||||
case EWM_ONE_MODEL_REPLICA1:
|
||||
}
|
||||
case EWM_ONE_MODEL_REPLICA1: {
|
||||
one->cpu = cpu_create(EWM_CPU_MODEL_65C02);
|
||||
cpu_add_ram(one->cpu, 0x0000, 32 * 1024 - 1);
|
||||
cpu_add_rom_file(one->cpu, 0xe000, "rom/krusader.rom");
|
||||
one->tty = ewm_tty_create(renderer);
|
||||
SDL_Color green = {0,255,0,255};
|
||||
one->tty = ewm_tty_create(renderer, green);
|
||||
one->pia = ewm_pia_create(one->cpu);
|
||||
one->pia->callback = ewm_one_pia_callback;
|
||||
one->pia->callback_obj = one;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
38
src/tty.c
38
src/tty.c
@ -24,7 +24,7 @@
|
||||
#include "sdl.h"
|
||||
#include "tty.h"
|
||||
|
||||
struct ewm_tty_t *ewm_tty_create(SDL_Renderer *renderer) {
|
||||
struct ewm_tty_t *ewm_tty_create(SDL_Renderer *renderer, SDL_Color color) {
|
||||
struct ewm_tty_t *tty = malloc(sizeof(struct ewm_tty_t));
|
||||
memset(tty, 0, sizeof(struct ewm_tty_t));
|
||||
tty->renderer = renderer;
|
||||
@ -35,6 +35,8 @@ struct ewm_tty_t *ewm_tty_create(SDL_Renderer *renderer) {
|
||||
EWM_ONE_TTY_ROWS * ewm_chr_height(tty->chr), 32, 4 * EWM_ONE_TTY_COLUMNS * ewm_chr_width(tty->chr),
|
||||
ewm_sdl_pixel_format(renderer));
|
||||
|
||||
tty->screen_cursor_enabled = 1;
|
||||
tty->color = SDL_MapRGBA(tty->surface->format, color.r, color.g, color.b, color.a);
|
||||
ewm_tty_reset(tty);
|
||||
return tty;
|
||||
}
|
||||
@ -67,7 +69,15 @@ static inline void ewm_tty_render_character(struct ewm_tty_t *tty, int row, int
|
||||
uint32_t *dst = tty->pixels + ((40 * 7 * 8) * row) + (7 * column);
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < 7; x++) {
|
||||
*dst++ = *src++;
|
||||
*dst++ = *src++ ? tty->color : 0; // TODO Can be optimized by moving color into chr
|
||||
}
|
||||
dst += (40 * 7) - 7;
|
||||
}
|
||||
} else {
|
||||
uint32_t *dst = tty->pixels + ((40 * 7 * 8) * row) + (7 * column);
|
||||
for (int y = 0; y < 8; y++) {
|
||||
for (int x = 0; x < 7; x++) {
|
||||
*dst++ = 0;
|
||||
}
|
||||
dst += (40 * 7) - 7;
|
||||
}
|
||||
@ -114,6 +124,14 @@ void ewm_tty_reset(struct ewm_tty_t *tty) {
|
||||
tty->screen_dirty = true;
|
||||
}
|
||||
|
||||
void ewm_tty_set_line(struct ewm_tty_t *tty, int v, char *line) {
|
||||
if (v < 24) {
|
||||
char buf[41];
|
||||
snprintf(buf, 40, "%-40s", line);
|
||||
memcpy(tty->screen_buffer + (v * 40), buf, 40);
|
||||
}
|
||||
}
|
||||
|
||||
void ewm_tty_refresh(struct ewm_tty_t *tty, uint32_t phase, uint32_t fps) {
|
||||
for (int row = 0; row < 24; row++) {
|
||||
for (int column = 0; column < 40; column++) {
|
||||
@ -121,13 +139,17 @@ void ewm_tty_refresh(struct ewm_tty_t *tty, uint32_t phase, uint32_t fps) {
|
||||
}
|
||||
}
|
||||
|
||||
if ((phase % (fps / 4)) == 0) {
|
||||
tty->screen_cursor_blink = !tty->screen_cursor_blink;
|
||||
if (phase != 0 && fps != 0) {
|
||||
if ((phase % (fps / 4)) == 0) {
|
||||
tty->screen_cursor_blink = !tty->screen_cursor_blink;
|
||||
}
|
||||
}
|
||||
|
||||
if (tty->screen_cursor_blink) {
|
||||
ewm_tty_render_character(tty, tty->screen_cursor_row, tty->screen_cursor_column, EWM_ONE_TTY_CURSOR_ON);
|
||||
} else {
|
||||
ewm_tty_render_character(tty, tty->screen_cursor_row, tty->screen_cursor_column, EWM_ONE_TTY_CURSOR_OFF);
|
||||
if (tty->screen_cursor_enabled) {
|
||||
if (tty->screen_cursor_blink) {
|
||||
ewm_tty_render_character(tty, tty->screen_cursor_row, tty->screen_cursor_column, EWM_ONE_TTY_CURSOR_ON);
|
||||
} else {
|
||||
ewm_tty_render_character(tty, tty->screen_cursor_row, tty->screen_cursor_column, EWM_ONE_TTY_CURSOR_OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -40,18 +40,22 @@ struct ewm_tty_t {
|
||||
struct ewm_chr_t *chr;
|
||||
bool screen_dirty;
|
||||
uint8_t screen_buffer[EWM_ONE_TTY_ROWS * EWM_ONE_TTY_COLUMNS];
|
||||
|
||||
int screen_cursor_enabled;
|
||||
int screen_cursor_row;
|
||||
int screen_cursor_column;
|
||||
int screen_cursor_blink;
|
||||
|
||||
uint32_t *pixels;
|
||||
SDL_Surface *surface;
|
||||
uint32_t color;
|
||||
};
|
||||
|
||||
struct ewm_tty_t *ewm_tty_create(SDL_Renderer *renderer);
|
||||
struct ewm_tty_t *ewm_tty_create(SDL_Renderer *renderer, SDL_Color color);
|
||||
void ewm_tty_destroy(struct ewm_tty_t *tty);
|
||||
void ewm_tty_write(struct ewm_tty_t *tty, uint8_t v);
|
||||
void ewm_tty_reset(struct ewm_tty_t *tty);
|
||||
void ewm_tty_set_line(struct ewm_tty_t *tty, int v, char *line);
|
||||
void ewm_tty_refresh(struct ewm_tty_t *tty, uint32_t phase, uint32_t fps);
|
||||
|
||||
#endif // EWM_TTY_H
|
||||
|
49
src/two.c
49
src/two.c
@ -37,6 +37,7 @@
|
||||
#if defined(EWM_LUA)
|
||||
#include "lua.h"
|
||||
#endif
|
||||
#include "tty.h"
|
||||
#include "two.h"
|
||||
|
||||
|
||||
@ -303,6 +304,14 @@ static int ewm_two_init(struct ewm_two_t *two, int type, SDL_Renderer *renderer,
|
||||
return -1;
|
||||
}
|
||||
|
||||
SDL_Color red = {255,0,0,255};
|
||||
two->tty = ewm_tty_create(renderer, red);
|
||||
if (two->tty == NULL) {
|
||||
fprintf(stderr, "[TWO] Could not create status tty\n");
|
||||
return -1;
|
||||
}
|
||||
two->tty->screen_cursor_enabled = 0;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
@ -522,6 +531,13 @@ static bool ewm_two_poll_event(struct ewm_two_t *two, SDL_Window *window) { // T
|
||||
SDL_SetWindowSize(window, 40*7*3, 24*8*3 + (two->status_bar_visible ? (9*3) : 0));
|
||||
SDL_RenderSetLogicalSize(two->scr->renderer, 40*7*3, 24*8*3 + (two->status_bar_visible ? (9*3) : 0));
|
||||
break;
|
||||
case SDLK_p:
|
||||
if (two->state == EWM_TWO_STATE_PAUSED) {
|
||||
two->state = EWM_TWO_STATE_RUNNING;
|
||||
} else {
|
||||
two->state = EWM_TWO_STATE_PAUSED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else if (event.key.keysym.mod == KMOD_NONE) {
|
||||
switch (event.key.keysym.sym) {
|
||||
@ -706,6 +722,28 @@ static void usage() {
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ewm_two_render_status(struct ewm_two_t *two, char *msg) {
|
||||
SDL_SetRenderDrawColor(two->scr->renderer, 0, 0, 0, 224);
|
||||
SDL_RenderFillRect(two->scr->renderer, NULL);
|
||||
|
||||
ewm_tty_reset(two->tty);
|
||||
|
||||
ewm_tty_set_line(two->tty, 8, " ******************** ");
|
||||
ewm_tty_set_line(two->tty, 9, " * * ");
|
||||
ewm_tty_set_line(two->tty, 10, " * -+- PAUSED -+- * ");
|
||||
ewm_tty_set_line(two->tty, 11, " * * ");
|
||||
ewm_tty_set_line(two->tty, 12, " ******************** ");
|
||||
|
||||
ewm_tty_refresh(two->tty, 0, 0);
|
||||
|
||||
SDL_Texture *texture = SDL_CreateTextureFromSurface(two->tty->renderer, two->tty->surface);
|
||||
if (texture != NULL) {
|
||||
SDL_SetRenderDrawBlendMode(two->scr->renderer, SDL_BLENDMODE_BLEND);
|
||||
SDL_RenderCopy(two->tty->renderer, texture, NULL, NULL);
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
}
|
||||
|
||||
int ewm_two_main(int argc, char **argv) {
|
||||
// Parse options
|
||||
|
||||
@ -910,8 +948,11 @@ int ewm_two_main(int argc, char **argv) {
|
||||
}
|
||||
|
||||
if ((SDL_GetTicks() - ticks) >= (1000 / fps)) {
|
||||
if (!ewm_two_step_cpu(two, EWM_TWO_SPEED / fps)) {
|
||||
break;
|
||||
|
||||
if (two->state == EWM_TWO_STATE_RUNNING) {
|
||||
if (!ewm_two_step_cpu(two, EWM_TWO_SPEED / fps)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Update the screen when it is flagged dirty or if we enter
|
||||
@ -936,6 +977,10 @@ int ewm_two_main(int argc, char **argv) {
|
||||
SDL_DestroyTexture(texture);
|
||||
}
|
||||
|
||||
if (two->state == EWM_TWO_STATE_PAUSED) {
|
||||
ewm_two_render_status(two, "PAUSED");
|
||||
}
|
||||
|
||||
SDL_RenderPresent(two->scr->renderer);
|
||||
}
|
||||
|
||||
|
@ -53,10 +53,14 @@
|
||||
#define EWM_TWO_FPS_DEFAULT (30)
|
||||
#define EWM_TWO_SPEED (1023000)
|
||||
|
||||
#define EWM_TWO_STATE_RUNNING (0)
|
||||
#define EWM_TWO_STATE_PAUSED (1)
|
||||
|
||||
struct mem_t;
|
||||
struct ewm_dsk_t;
|
||||
struct scr;
|
||||
struct ewm_lua_t;
|
||||
struct ewm_tty_t;
|
||||
|
||||
struct ewm_two_t {
|
||||
int type;
|
||||
@ -96,6 +100,9 @@ struct ewm_two_t {
|
||||
|
||||
int lua_key_down_fn;
|
||||
int lua_key_up_fn;
|
||||
|
||||
int state;
|
||||
struct ewm_tty_t *tty;
|
||||
};
|
||||
|
||||
struct ewm_two_t *ewm_two_create(int type, SDL_Renderer *renderer, SDL_Joystick *joystick);
|
||||
|
Loading…
Reference in New Issue
Block a user