mirror of
https://github.com/st3fan/ewm.git
synced 2025-04-18 09:37:56 +00:00
Fixes #74 Implement Paddle/Joystick Support
This commit is contained in:
parent
5596fc4555
commit
236208a99c
17
src/cpu.c
17
src/cpu.c
@ -170,6 +170,8 @@ static int cpu_execute_instruction(struct cpu_t *cpu) {
|
||||
pc, bytes, trace_instruction, trace_state, trace_stack);
|
||||
}
|
||||
|
||||
cpu->counter += i->cycles;
|
||||
|
||||
return i->cycles;
|
||||
}
|
||||
|
||||
@ -408,21 +410,6 @@ int cpu_nmi(struct cpu_t *cpu) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int cpu_run(struct cpu_t *cpu) {
|
||||
uint64_t instruction_count = 0;
|
||||
int err = 0;
|
||||
while ((err = cpu_execute_instruction(cpu)) == 0) {
|
||||
/* TODO: Tick? */
|
||||
instruction_count++;
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int cpu_boot(struct cpu_t *cpu) {
|
||||
cpu_reset(cpu);
|
||||
return cpu_run(cpu);
|
||||
}
|
||||
|
||||
int cpu_step(struct cpu_t *cpu) {
|
||||
return cpu_execute_instruction(cpu);
|
||||
}
|
||||
|
@ -53,6 +53,7 @@ struct cpu_t {
|
||||
bool strict;
|
||||
struct mem_t *mem;
|
||||
struct cpu_instruction_t *instructions;
|
||||
uint64_t counter;
|
||||
};
|
||||
|
||||
#define MEM_FLAGS_READ 0x01
|
||||
@ -105,8 +106,6 @@ void cpu_reset(struct cpu_t *cpu);
|
||||
int cpu_irq(struct cpu_t *cpu);
|
||||
int cpu_nmi(struct cpu_t *cpu);
|
||||
|
||||
int cpu_run(struct cpu_t *cpu);
|
||||
int cpu_boot(struct cpu_t *cpu);
|
||||
int cpu_step(struct cpu_t *cpu);
|
||||
|
||||
uint16_t cpu_memory_get_word(struct cpu_t *cpu, uint16_t addr);
|
||||
|
@ -116,7 +116,7 @@ int main() {
|
||||
|
||||
// Setup the CPU, Apple ][+ and it's screen.
|
||||
|
||||
struct ewm_two_t *two = ewm_two_create(EWM_TWO_TYPE_APPLE2PLUS, renderer);
|
||||
struct ewm_two_t *two = ewm_two_create(EWM_TWO_TYPE_APPLE2PLUS, renderer, NULL);
|
||||
|
||||
test(two->scr, "txt_full_refresh", txt_full_refresh_setup, txt_full_refresh_test);
|
||||
test(two->scr, "lgr_full_refresh", lgr_full_refresh_setup, lgr_full_refresh_test);
|
||||
|
97
src/two.c
97
src/two.c
@ -62,6 +62,13 @@
|
||||
#define EWM_A2P_SS_PB2 0xC063
|
||||
#define EWM_A2P_SS_PB3 0xC060 // TODO On the gs only?
|
||||
|
||||
#define EWM_TWO_SS_PTRIG 0xc070
|
||||
#define EWM_TWO_SS_PADL0 0xc064
|
||||
#define EWM_TWO_SS_PADL1 0xc065
|
||||
#define EWM_TWO_SS_PADL3 0xc066
|
||||
#define EWM_TWO_SS_PADL4 0xc067
|
||||
|
||||
|
||||
static uint8_t ewm_two_iom_read(struct cpu_t *cpu, struct mem_t *mem, uint16_t addr) {
|
||||
struct ewm_two_t *two = (struct ewm_two_t*) mem->obj;
|
||||
switch (addr) {
|
||||
@ -138,6 +145,31 @@ static uint8_t ewm_two_iom_read(struct cpu_t *cpu, struct mem_t *mem, uint16_t a
|
||||
case EWM_A2P_SS_CLRAN3:
|
||||
break;
|
||||
|
||||
case EWM_TWO_SS_PTRIG: {
|
||||
if (two->joystick != NULL) {
|
||||
int x = 128 + (SDL_JoystickGetAxis(two->joystick, 0) / 256);
|
||||
two->padl0_time = two->cpu->counter + (x * (2820 / 255)); // TODO Remove magic values
|
||||
two->padl0_value = 0xff;
|
||||
int y = 128 + (SDL_JoystickGetAxis(two->joystick, 1) / 256);
|
||||
two->padl1_time = two->cpu->counter + (y * (2820 / 255)); // TODO Remove magic values
|
||||
two->padl1_value = 0xff;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case EWM_TWO_SS_PADL0: {
|
||||
if (two->padl0_time != 0 && two->cpu->counter >= two->padl0_time) {
|
||||
two->padl0_time = 0;
|
||||
two->padl0_value = 0;
|
||||
}
|
||||
return two->padl0_value;
|
||||
}
|
||||
case EWM_TWO_SS_PADL1: {
|
||||
if (two->padl1_time != 0 && two->cpu->counter >= two->padl1_time) {
|
||||
two->padl1_value = 0;
|
||||
}
|
||||
return two->padl1_value;
|
||||
}
|
||||
|
||||
default:
|
||||
printf("[A2P] Unexpected read at $%.4X\n", addr);
|
||||
break;
|
||||
@ -239,7 +271,7 @@ static void ewm_two_screen_hgr_write(struct cpu_t *cpu, struct mem_t *mem, uint1
|
||||
two->screen_dirty = true;
|
||||
}
|
||||
|
||||
static int ewm_two_init(struct ewm_two_t *two, int type, SDL_Renderer *renderer) {
|
||||
static int ewm_two_init(struct ewm_two_t *two, int type, SDL_Renderer *renderer, SDL_Joystick *joystick) {
|
||||
memset(two, 0, sizeof(struct ewm_two_t));
|
||||
|
||||
two->type = type;
|
||||
@ -297,12 +329,14 @@ static int ewm_two_init(struct ewm_two_t *two, int type, SDL_Renderer *renderer)
|
||||
two->screen_hgr_data = malloc(16 * 1024);
|
||||
two->screen_hgr_iom = cpu_add_iom(two->cpu, 0x2000, 0x5fff, two, ewm_two_screen_hgr_read, ewm_two_screen_hgr_write);
|
||||
|
||||
two->joystick = joystick;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct ewm_two_t *ewm_two_create(int type, SDL_Renderer *renderer) {
|
||||
struct ewm_two_t *ewm_two_create(int type, SDL_Renderer *renderer, SDL_Joystick *joystick) {
|
||||
struct ewm_two_t *two = malloc(sizeof(struct ewm_two_t));
|
||||
if (ewm_two_init(two, type, renderer) != 0) {
|
||||
if (ewm_two_init(two, type, renderer, joystick) != 0) {
|
||||
free(two);
|
||||
two = NULL;
|
||||
}
|
||||
@ -330,34 +364,28 @@ static bool ewm_two_poll_event(struct ewm_two_t *two, SDL_Window *window) { // T
|
||||
two->screen_dirty = true;
|
||||
break;
|
||||
|
||||
case SDL_JOYBUTTONDOWN:
|
||||
if (event.jbutton.button < EWM_A2P_BUTTON_COUNT) {
|
||||
two->buttons[event.jbutton.button] = 1;
|
||||
}
|
||||
break;
|
||||
case SDL_JOYBUTTONUP:
|
||||
if (event.jbutton.button < EWM_A2P_BUTTON_COUNT) {
|
||||
two->buttons[event.jbutton.button] = 0;
|
||||
case SDL_CONTROLLERBUTTONDOWN:
|
||||
case SDL_CONTROLLERBUTTONUP:
|
||||
switch (event.cbutton.button) {
|
||||
case SDL_CONTROLLER_BUTTON_A:
|
||||
case SDL_CONTROLLER_BUTTON_LEFTSHOULDER:
|
||||
two->buttons[0] = event.cbutton.state == SDL_PRESSED ? 0x80 : 0x00;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_B:
|
||||
case SDL_CONTROLLER_BUTTON_RIGHTSHOULDER:
|
||||
two->buttons[1] = event.cbutton.state == SDL_PRESSED ? 0x80 : 0x00;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_X:
|
||||
two->buttons[2] = event.cbutton.state == SDL_PRESSED ? 0x80 : 0x00;
|
||||
break;
|
||||
case SDL_CONTROLLER_BUTTON_Y:
|
||||
two->buttons[3] = event.cbutton.state == SDL_PRESSED ? 0x80 : 0x00;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SDL_KEYDOWN:
|
||||
if (event.key.keysym.mod & KMOD_ALT) {
|
||||
switch (event.key.keysym.sym) {
|
||||
case SDLK_1:
|
||||
two->buttons[0] = 1;
|
||||
break;
|
||||
case SDLK_2:
|
||||
two->buttons[1] = 1;
|
||||
break;
|
||||
case SDLK_3:
|
||||
two->buttons[2] = 1;
|
||||
break;
|
||||
case SDLK_4:
|
||||
two->buttons[3] = 1;
|
||||
break;
|
||||
}
|
||||
} else if (event.key.keysym.mod & KMOD_CTRL) {
|
||||
if (event.key.keysym.mod & KMOD_CTRL) {
|
||||
if (event.key.keysym.sym >= SDLK_a && event.key.keysym.sym <= SDLK_z) {
|
||||
two->key = (event.key.keysym.sym - SDLK_a) | 0x80;
|
||||
} else {
|
||||
@ -497,7 +525,7 @@ int ewm_two_main(int argc, char **argv) {
|
||||
|
||||
// Initialize SDL
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS) < 0) {
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_TIMER | SDL_INIT_EVENTS | SDL_INIT_GAMECONTROLLER) < 0) {
|
||||
fprintf(stderr, "Failed to initialize SDL: %s\n", SDL_GetError());
|
||||
exit(1);
|
||||
}
|
||||
@ -516,9 +544,20 @@ int ewm_two_main(int argc, char **argv) {
|
||||
|
||||
SDL_RenderSetLogicalSize(renderer, 280*3, 192*3);
|
||||
|
||||
// If we have a joystick, open it
|
||||
|
||||
SDL_GameController *controller = NULL;
|
||||
SDL_Joystick *joystick = NULL;
|
||||
|
||||
if (SDL_NumJoysticks() != 0) {
|
||||
controller = SDL_GameControllerOpen(0);
|
||||
SDL_GameControllerEventState(SDL_ENABLE);
|
||||
joystick = SDL_GameControllerGetJoystick(controller);
|
||||
}
|
||||
|
||||
// Create and configure the Apple II
|
||||
|
||||
struct ewm_two_t *two = ewm_two_create(EWM_TWO_TYPE_APPLE2PLUS, renderer);
|
||||
struct ewm_two_t *two = ewm_two_create(EWM_TWO_TYPE_APPLE2PLUS, renderer, joystick);
|
||||
|
||||
if (color) {
|
||||
ewm_scr_set_color_scheme(two->scr, EWM_SCR_COLOR_SCHEME_COLOR);
|
||||
|
13
src/two.h
13
src/two.h
@ -80,9 +80,20 @@ struct ewm_two_t {
|
||||
|
||||
uint8_t key;
|
||||
uint8_t buttons[EWM_A2P_BUTTON_COUNT];
|
||||
|
||||
uint64_t padl0_time;
|
||||
uint8_t padl0_value;
|
||||
uint64_t padl1_time;
|
||||
uint8_t padl1_value;
|
||||
uint64_t padl2_time; // Are 2 and 3 actually used? Not sure what to map them to.
|
||||
uint8_t padl2_value;
|
||||
uint64_t padl3_time;
|
||||
uint8_t padl3_value;
|
||||
|
||||
SDL_Joystick *joystick;
|
||||
};
|
||||
|
||||
struct ewm_two_t *ewm_two_create(int type, SDL_Renderer *renderer);
|
||||
struct ewm_two_t *ewm_two_create(int type, SDL_Renderer *renderer, SDL_Joystick *joystick);
|
||||
void ewm_two_destroy(struct ewm_two_t *two);
|
||||
|
||||
int ewm_two_load_disk(struct ewm_two_t *two, int drive, char *path);
|
||||
|
Loading…
x
Reference in New Issue
Block a user