//////////////////////////////////////////////////////////////////////////////// // Main emulation loop //////////////////////////////////////////////////////////////////////////////// // // // // // // ////////////////////////////////////////////////////////////////////////////// #include #include #include #include #include #include #include /* UNIX standard function definitions */ #include /* Error number definitions */ #include /* POSIX terminal control definitions */ #include #include "SDL.h" #include "SDLptc.h" #include "log.h" #include "io.h" #include "ws.h" #include "rom.h" #include "./nec/nec.h" #include "./nec/necintrf.h" #include "gpu.h" #include "audio.h" #include "memory.h" SDL_Joystick *joystick=NULL; char app_window_title[256]; int app_gameRunning=0; int app_terminate=0; int app_fullscreen=0; SDL_Event app_input_event; int app_rotated=0; int ws_key_esc = 0; static void read_keys() { static int testJoystick=1; if (testJoystick==1) { testJoystick=0; fprintf(log_get(),"%i joysticks were found.\n\n", SDL_NumJoysticks() ); fprintf(log_get(),"The names of the joysticks are:\n"); for(int tti=0; tti < SDL_NumJoysticks(); tti++ ) { fprintf(log_get()," %s\n", SDL_JoystickName(tti)); } SDL_JoystickEventState(SDL_ENABLE); joystick = SDL_JoystickOpen(0); } else { if (joystick!=NULL) { SDL_JoystickClose(0); SDL_JoystickEventState(SDL_ENABLE); joystick = SDL_JoystickOpen(0); } } while ( SDL_PollEvent(&app_input_event) ) { if ( app_input_event.type == SDL_QUIT ) { ws_key_esc = 1; } } if (joystick) { if (SDL_JoystickGetButton(joystick,0)) { ws_key_start=1; } else { ws_key_start=0; } if (SDL_JoystickGetButton(joystick,1)) { ws_key_button_a=1; } else { ws_key_button_a=0; } if (SDL_JoystickGetButton(joystick,2)) { ws_key_button_b=1; } else { ws_key_button_b=0; } if (SDL_JoystickGetAxis(joystick,0)<-7000) { ws_key_x4=1; } else { ws_key_x4=0; } if (SDL_JoystickGetAxis(joystick,0)>7000) { ws_key_x2=1; } else { ws_key_x2=0; } if (SDL_JoystickGetAxis(joystick,1)<-7000) { ws_key_x1=1; } else { ws_key_x1=0; } if (SDL_JoystickGetAxis(joystick,1)>7000) { ws_key_x3=1; } else { ws_key_x3=0; } ws_key_y4=0; ws_key_y2=0; ws_key_y1=0; ws_key_y3=0; } else { ws_key_start=0; ws_key_x4=0; ws_key_x2=0; ws_key_x1=0; ws_key_x3=0; ws_key_y4=0; ws_key_y2=0; ws_key_y1=0; ws_key_y3=0; ws_key_button_a=0; ws_key_button_b=0; } uint8_t *keystate = SDL_GetKeyState(NULL); if ( keystate[SDLK_e]) { dump_memory(); } if ( keystate[SDLK_r]) { printf("Boop\n"); ws_reset(); } if ( keystate[SDLK_ESCAPE] ) { ws_key_esc = 1; } if ( keystate[SDLK_UP] ) { ws_key_x1=1; } if ( keystate[SDLK_DOWN] ) { ws_key_x3=1; } if ( keystate[SDLK_RIGHT] ) { ws_key_x2=1; } if ( keystate[SDLK_LEFT] ) { ws_key_x4=1; } if (keystate[SDLK_RETURN]) { ws_key_start=1; } if (keystate[SDLK_c]) { ws_key_button_a=1; } if (keystate[SDLK_x]) { ws_key_button_b=1; } if (keystate[SDLK_w]) { ws_key_y1=1; } if (keystate[SDLK_a]) { ws_key_y4=1; } if (keystate[SDLK_s]) { ws_key_y3=1; } if (keystate[SDLK_d]) { ws_key_y2=1; } if (keystate[SDLK_o]) { ws_cyclesByLine+=10; } if (keystate[SDLK_l]) { ws_cyclesByLine-=10; } } //////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// // // // // // // // //////////////////////////////////////////////////////////////////////////////// static void ws_drawDoubledScanline(int16_t *vs, int16_t *backbuffer_alias) { register int32_t *vs_alias = (int32_t *)vs; register int32_t data; for (int pixel = 0 ; pixel < 224 ; pixel += 8) { data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; } } //////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// // // // // // // // //////////////////////////////////////////////////////////////////////////////// static void ws_drawDoubledRotatedScanline(int16_t *vs, int16_t *backbuffer_alias) { register int32_t *vs_alias = (int32_t *)vs; register int32_t data; for (int pixel = 0 ; pixel < 144 ; pixel += 8) { data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; data = *backbuffer_alias++; data |= (data << 16); *vs_alias++ = data; } } //////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// // // // // // // // //////////////////////////////////////////////////////////////////////////////// void ws_rotate_backbuffer(int16_t *backbuffer) { static int16_t temp[224*144]; memcpy(temp,backbuffer,224*144*2); for (int line=0; line<144; line++) for (int column=0; column<224; column++) { backbuffer[line+((223-column)<<7)+((223-column)<<4)]=temp[column+(line<<7)+(line<<6)+(line<<5)]; } } //////////////////////////////////////////////////////////////////////////////// // //////////////////////////////////////////////////////////////////////////////// // // // // // // // //////////////////////////////////////////////////////////////////////////////// void ws_emulate(void) { int32_t nCount = 0; int i = 0; double dTime = 0.0, dNormalLast = 0.0, dTemp; int32_t surfacePitch; // 15 bits RGB555 Format format(16, 0x007c00, 0x00003e0, 0x0000001f); Console console; Surface *surface; if (app_rotated) { surface = new Surface(144 * 2, 224 * 2, format); int16_t *backbuffer = (int16_t *)malloc(224 * 144 * sizeof(int16_t)); memset(backbuffer, 0x00, 224 * 144 * sizeof(int16_t)); surfacePitch = (surface->pitch() >> 1); dNormalLast = (double)SDL_GetTicks(); console.open(app_window_title, 144 * 2, 224 * 2, format); while (1) { dTemp = (double)SDL_GetTicks(); dTime = dTemp - dNormalLast; nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense? if (nCount <= 0) { SDL_Delay(2); } // No need to do anything for a bit else { dNormalLast += nCount * (1 / 0.07547); if (nCount > 10) { nCount = 10; } read_keys(); if (ws_key_esc) { console.close(); app_terminate = 1; if ((ws_rom_path != NULL) || (app_terminate)) { break; } console.open(app_window_title, 144 * 2, 224 * 2, format); } for (i = 0 ; i < nCount - 1 ; i++) { while (!ws_executeLine(backbuffer, 0)) { } } while (!ws_executeLine(backbuffer, 1)) { } ws_rotate_backbuffer(backbuffer); int16_t *vs = (int16_t *)surface->lock(); int16_t *backbuffer_alias = backbuffer; for (int line = 0 ; line < 224 ; line++) { ws_drawDoubledRotatedScanline(vs, backbuffer_alias); vs += surfacePitch; ws_drawDoubledRotatedScanline(vs, backbuffer_alias); vs += surfacePitch; backbuffer_alias += 144; } surface->unlock(); surface->copy(console); console.update(); } } console.close(); delete surface; } else { surface = new Surface(224 * 2, 144 * 2, format); int16_t *backbuffer = (int16_t *)malloc(224 * 144 * sizeof(int16_t)); memset(backbuffer, 0x00, 224 * 144 * sizeof(int16_t)); surfacePitch = (surface->pitch() >> 1); dNormalLast = (double)SDL_GetTicks(); console.open(app_window_title, 224 * 2, 144 * 2, format); while (1) { dTemp = (double)SDL_GetTicks(); dTime = dTemp - dNormalLast; nCount = (int32_t)(dTime * 0.07547); // does this calculation make sense? if (nCount <= 0) { SDL_Delay(2); } // No need to do anything for a bit else { dNormalLast += nCount * (1 / 0.07547); if (nCount > 10) { nCount = 10; } read_keys(); if (ws_key_esc) { console.close(); app_terminate = 1; if ((ws_rom_path != NULL) || (app_terminate)) { break; } console.open(app_window_title, 224 * 2, 144 * 2, format); } for (i = 0 ; i < nCount - 1 ; i++) { while (!ws_executeLine(backbuffer, 0)) { } } while (!ws_executeLine(backbuffer, 1)) { } int16_t *vs = (int16_t *)surface->lock(); int16_t *backbuffer_alias = backbuffer; for (int line = 0 ; line < 144 ; line++) { ws_drawDoubledScanline(vs, backbuffer_alias); vs += surfacePitch; ws_drawDoubledScanline(vs, backbuffer_alias); vs += surfacePitch; backbuffer_alias += 224; } surface->unlock(); surface->copy(console); console.update(); } } console.close(); delete surface; } }