2025-01-31 14:39:38 -07:00
|
|
|
#include <ui.h>
|
|
|
|
#include <emu.h>
|
2025-02-01 19:05:25 -07:00
|
|
|
#include <ppu.h>
|
|
|
|
#include <gamepad.h>
|
2025-02-08 13:08:34 -07:00
|
|
|
#include <bus.h>
|
2025-02-14 16:44:22 -07:00
|
|
|
#include <audio.h>
|
2025-01-31 14:39:38 -07:00
|
|
|
|
|
|
|
#include <SDL.h>
|
|
|
|
#include <SDL_ttf.h>
|
|
|
|
|
|
|
|
SDL_Window *sdlWindow;
|
|
|
|
SDL_Renderer *sdlRenderer;
|
|
|
|
SDL_Texture *sdlTexture;
|
|
|
|
SDL_Surface *screen;
|
|
|
|
|
2025-02-01 00:48:49 -07:00
|
|
|
SDL_Window *sdlDebugWindow;
|
|
|
|
SDL_Renderer *sdlDebugRenderer;
|
|
|
|
SDL_Texture *sdlDebugTexture;
|
|
|
|
SDL_Surface *debugScreen;
|
|
|
|
|
|
|
|
static int scale = 4;
|
|
|
|
|
2025-01-31 14:39:38 -07:00
|
|
|
void ui_init(){
|
|
|
|
SDL_Init(SDL_INIT_VIDEO);
|
|
|
|
printf("SDL INIT\n");
|
|
|
|
TTF_Init();
|
|
|
|
printf("TTF INIT\n");
|
|
|
|
|
|
|
|
SDL_CreateWindowAndRenderer(SCREEN_WIDTH, SCREEN_HEIGHT, 0, &sdlWindow, &sdlRenderer);
|
2025-02-01 19:05:25 -07:00
|
|
|
|
|
|
|
screen = SDL_CreateRGBSurface(0, SCREEN_WIDTH,
|
|
|
|
SCREEN_HEIGHT, 32,
|
|
|
|
0x00FF0000,
|
|
|
|
0x0000FF00,
|
|
|
|
0x000000FF,
|
|
|
|
0xFF000000);
|
|
|
|
sdlTexture = SDL_CreateTexture(sdlRenderer,
|
|
|
|
SDL_PIXELFORMAT_ARGB8888,
|
|
|
|
SDL_TEXTUREACCESS_STREAMING,
|
|
|
|
SCREEN_WIDTH,
|
|
|
|
SCREEN_HEIGHT);
|
|
|
|
|
2025-02-01 00:48:49 -07:00
|
|
|
SDL_CreateWindowAndRenderer(16 * 8 * scale, 32 * 8 * scale, 0, &sdlDebugWindow, &sdlDebugRenderer);
|
|
|
|
debugScreen = SDL_CreateRGBSurface(0, (16 * 8 * scale) + (16 * scale),
|
|
|
|
(32 * 8 * scale) + (64 * scale), 32,
|
|
|
|
0x00FF0000,
|
|
|
|
0x0000FF00,
|
|
|
|
0x000000FF,
|
|
|
|
0xFF000000);
|
|
|
|
sdlDebugTexture = SDL_CreateTexture(sdlDebugRenderer,
|
|
|
|
SDL_PIXELFORMAT_ARGB8888,
|
|
|
|
SDL_TEXTUREACCESS_STREAMING,
|
|
|
|
(16 * 8 * scale) + (16 * scale),
|
|
|
|
(32 * 8 * scale) + (64 * scale));
|
|
|
|
int x, y;
|
|
|
|
SDL_GetWindowPosition(sdlWindow, &x, &y);
|
|
|
|
SDL_SetWindowPosition(sdlDebugWindow, x+SCREEN_WIDTH, y);
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned long tile_colors[4] = {0xFFFFFFFF, 0xFFAAAAAA, 0xFF555555, 0xFF000000};
|
|
|
|
|
|
|
|
void display_tile(SDL_Surface *surface, u16 startLocation, u16 tileNum, int x, int y) {
|
|
|
|
SDL_Rect rc;
|
|
|
|
for(int tileY = 0; tileY < 16; tileY += 2) {
|
|
|
|
u8 b1 = bus_read(startLocation+(tileNum * 16) + tileY);
|
|
|
|
u8 b2 = bus_read(startLocation+(tileNum * 16) + tileY + 1);
|
|
|
|
|
|
|
|
for (int bit=7; bit >= 0; bit--) {
|
|
|
|
u8 hi = !!(b1 & (1 << bit)) << 1;
|
|
|
|
u8 lo = !!(b2 & (1 << bit));
|
|
|
|
|
|
|
|
u8 color = hi | lo;
|
|
|
|
rc.x = x + ((7 - bit) * scale);
|
|
|
|
rc.y = y + (tileY/2 * scale);
|
|
|
|
rc.w = scale;
|
|
|
|
rc.h = scale;
|
|
|
|
SDL_FillRect(surface, &rc, tile_colors[color]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void update_debug_window() {
|
|
|
|
int xDraw = 0;
|
|
|
|
int yDraw = 0;
|
|
|
|
int tileNum = 0;
|
|
|
|
|
|
|
|
SDL_Rect rc;
|
|
|
|
rc.x = 0;
|
|
|
|
rc.y = 0;
|
|
|
|
rc.w = debugScreen->w;
|
|
|
|
rc.h = debugScreen->h;
|
|
|
|
SDL_FillRect(debugScreen, &rc, 0xFF111111);
|
|
|
|
|
|
|
|
u16 addr = 0x8000;
|
|
|
|
|
|
|
|
//384 tiles, 24 x 16
|
|
|
|
|
|
|
|
for(int y = 0; y < 24; y++) {
|
|
|
|
for(int x = 0; x < 16; x++) {
|
|
|
|
display_tile(debugScreen, addr, tileNum, xDraw + (x * scale), yDraw + (y * scale));
|
|
|
|
xDraw += (8 * scale);
|
|
|
|
tileNum++;
|
|
|
|
}
|
|
|
|
yDraw += (8 * scale);
|
|
|
|
xDraw = 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_UpdateTexture(sdlDebugTexture, NULL, debugScreen->pixels, debugScreen->pitch);
|
|
|
|
SDL_RenderClear(sdlDebugRenderer);
|
|
|
|
SDL_RenderCopy(sdlDebugRenderer, sdlDebugTexture, NULL, NULL);
|
|
|
|
SDL_RenderPresent(sdlDebugRenderer);
|
|
|
|
}
|
|
|
|
|
|
|
|
void ui_update() {
|
2025-02-01 19:05:25 -07:00
|
|
|
SDL_Rect rc;
|
|
|
|
rc.x = rc.y = 0;
|
|
|
|
rc.w = rc.h = 2048;
|
|
|
|
|
|
|
|
u32 *video_buffer = ppu_get_context()->video_buffer;
|
|
|
|
|
|
|
|
for(int line_num = 0; line_num < YRES; line_num++) {
|
|
|
|
for(int x = 0; x < XRES; x++) {
|
|
|
|
rc.x = x * scale;
|
|
|
|
rc.y = line_num * scale;
|
|
|
|
rc.w = scale;
|
|
|
|
rc.h = scale;
|
|
|
|
|
|
|
|
SDL_FillRect(screen, &rc, video_buffer[x + (line_num * XRES)]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
SDL_UpdateTexture(sdlTexture, NULL, screen->pixels, screen->pitch);
|
|
|
|
SDL_RenderClear(sdlRenderer);
|
|
|
|
SDL_RenderCopy(sdlRenderer, sdlTexture, NULL, NULL);
|
2025-02-14 16:44:22 -07:00
|
|
|
int yOffset = 50;
|
|
|
|
int lastY = (yOffset) + (audio_get_context()->sq1_history[0] * 50);
|
|
|
|
int xOffset = XRES*scale;
|
|
|
|
SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, 255);
|
|
|
|
for(int x = 1; x < 882; x++){
|
|
|
|
int y = (yOffset) + (audio_get_context()->sq1_history[x*5] * 50);
|
|
|
|
SDL_RenderDrawLine(sdlRenderer, x-1+xOffset, lastY, x+xOffset, y);
|
|
|
|
lastY = y;
|
|
|
|
if(x+xOffset == SCREEN_WIDTH) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
yOffset = 150;
|
|
|
|
lastY = (yOffset) + (audio_get_context()->sq2_history[0] * 50);
|
|
|
|
SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, 255);
|
|
|
|
for(int x = 1; x < 882; x++){
|
|
|
|
int y = (yOffset) + (audio_get_context()->sq2_history[x*5] * 50);
|
|
|
|
SDL_RenderDrawLine(sdlRenderer, x-1+xOffset, lastY, x+xOffset, y);
|
|
|
|
lastY = y;
|
|
|
|
if(x+xOffset == SCREEN_WIDTH) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
yOffset = 250;
|
|
|
|
lastY = (yOffset) + (audio_get_context()->ch3_history[0] * 50);
|
|
|
|
SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, 255);
|
|
|
|
for(int x = 1; x < 882; x++){
|
|
|
|
int y = (yOffset) + (audio_get_context()->ch3_history[x*5] * 50);
|
|
|
|
SDL_RenderDrawLine(sdlRenderer, x-1+xOffset, lastY, x+xOffset, y);
|
|
|
|
lastY = y;
|
|
|
|
if(x+xOffset == SCREEN_WIDTH) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
yOffset = 350;
|
|
|
|
lastY = (yOffset) + (audio_get_context()->ch4_history[0] * 50);
|
|
|
|
SDL_SetRenderDrawColor(sdlRenderer, 0, 255, 0, 255);
|
|
|
|
for(int x = 1; x < 882; x++){
|
|
|
|
int y = (yOffset) + (audio_get_context()->ch4_history[x*5] * 50);
|
|
|
|
SDL_RenderDrawLine(sdlRenderer, x-1+xOffset, lastY, x+xOffset, y);
|
|
|
|
lastY = y;
|
|
|
|
if(x+xOffset == SCREEN_WIDTH) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
yOffset = 450;
|
|
|
|
lastY = (yOffset) + (audio_get_context()->left_history[0] * 50);
|
|
|
|
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 255, 255);
|
|
|
|
for(int x = 1; x < 882; x++){
|
|
|
|
int y = (yOffset) + (audio_get_context()->left_history[x*5] * 50);
|
|
|
|
SDL_RenderDrawLine(sdlRenderer, x-1+xOffset, lastY, x+xOffset, y);
|
|
|
|
lastY = y;
|
|
|
|
if(x+xOffset == SCREEN_WIDTH) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
yOffset = 550;
|
|
|
|
lastY = (yOffset) + (audio_get_context()->right_history[0] * 50);
|
|
|
|
SDL_SetRenderDrawColor(sdlRenderer, 0, 0, 255, 255);
|
|
|
|
for(int x = 1; x < 882; x++){
|
|
|
|
int y = (yOffset) + (audio_get_context()->right_history[x*5] * 50);
|
|
|
|
SDL_RenderDrawLine(sdlRenderer, x-1+xOffset, lastY, x+xOffset, y);
|
|
|
|
lastY = y;
|
|
|
|
if(x+xOffset == SCREEN_WIDTH) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2025-02-01 19:05:25 -07:00
|
|
|
SDL_RenderPresent(sdlRenderer);
|
|
|
|
|
2025-02-01 00:48:49 -07:00
|
|
|
update_debug_window();
|
2025-01-31 14:39:38 -07:00
|
|
|
}
|
|
|
|
|
2025-02-01 19:05:25 -07:00
|
|
|
static bool ff = false;
|
|
|
|
|
|
|
|
void ui_on_key(bool down, u32 key_code) {
|
|
|
|
if(key_code == SDLK_SPACE && down == true) {
|
|
|
|
ff = !ff;
|
|
|
|
if(ff){
|
2025-02-14 16:44:22 -07:00
|
|
|
ppu_get_context()->target_frame_time = 1000/300;
|
2025-02-01 19:05:25 -07:00
|
|
|
} else {
|
2025-02-14 16:44:22 -07:00
|
|
|
ppu_get_context()->target_frame_time = 1000/60;
|
2025-02-01 19:05:25 -07:00
|
|
|
}
|
2025-02-14 16:44:22 -07:00
|
|
|
printf("target frame time: %d\n", ppu_get_context()->target_frame_time);
|
2025-02-01 19:05:25 -07:00
|
|
|
}
|
|
|
|
switch(key_code){
|
|
|
|
case SDLK_z: gamepad_get_state()->b = down; break;
|
|
|
|
case SDLK_x: gamepad_get_state()->a = down; break;
|
|
|
|
case SDLK_RETURN: gamepad_get_state()->start = down; break;
|
|
|
|
case SDLK_TAB: gamepad_get_state()->select = down; break;
|
|
|
|
|
|
|
|
case SDLK_UP: gamepad_get_state()->up = down; break;
|
|
|
|
case SDLK_DOWN: gamepad_get_state()->down = down; break;
|
|
|
|
case SDLK_LEFT: gamepad_get_state()->left = down; break;
|
|
|
|
case SDLK_RIGHT: gamepad_get_state()->right = down; break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2025-01-31 14:39:38 -07:00
|
|
|
void ui_handle_events(){
|
|
|
|
SDL_Event e;
|
|
|
|
while(SDL_PollEvent(&e) > 0) {
|
2025-02-01 19:05:25 -07:00
|
|
|
|
|
|
|
if(e.type == SDL_KEYDOWN) {
|
|
|
|
ui_on_key(true, e.key.keysym.sym);
|
|
|
|
}
|
|
|
|
|
|
|
|
if(e.type == SDL_KEYUP) {
|
|
|
|
ui_on_key(false, e.key.keysym.sym);
|
|
|
|
}
|
|
|
|
|
2025-01-31 14:39:38 -07:00
|
|
|
if(e.type == SDL_WINDOWEVENT && e.window.event == SDL_WINDOWEVENT_CLOSE) {
|
|
|
|
emu_get_context()->die = true;
|
|
|
|
}
|
2025-02-01 19:05:25 -07:00
|
|
|
|
2025-01-31 14:39:38 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void delay(u32 ms) {
|
|
|
|
SDL_Delay(ms);
|
2025-02-01 00:48:49 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
u32 get_ticks() {
|
|
|
|
return SDL_GetTicks();
|
2025-02-08 13:08:34 -07:00
|
|
|
}
|