Files
RISC-B/util/cpustatusui.c
2025-02-18 14:44:08 +01:00

173 lines
5.5 KiB
C

//
// Created by bruno on 8.2.2025.
//
#include <SDL2/SDL_render.h>
#include "cpustatusui.h"
#include "font.h"
void renderVals(CPU *cpu, BitmapFont *titleFont, BitmapFont *valueFont,
SDL_Renderer *renderer, SDL_Texture **out) {
CPUStatusPart *stats = NULL;
int statsCount = 0;
getStats(cpu, &stats, &statsCount);
const int padding = 4;
const int oneFieldW = (titleFont->size + 1) * (sizeof(stats[0].value)) + padding - 1;
const int oneFieldH = (titleFont->size + 1) * 2 + (valueFont->size + 1);
if (!*out) {
*out = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
oneFieldW * statsCount, oneFieldH);
}
SDL_SetRenderTarget(renderer, *out);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
for (int i = 0; i < statsCount; i++) {
int x = i * oneFieldW;
SDL_Rect rect = {x, 0, oneFieldW, oneFieldH};
SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
SDL_RenderFillRect(renderer, &rect);
SDL_SetRenderDrawColor(renderer, 255, 255, 255, 255);
SDL_RenderDrawRect(renderer, &rect);
// Render the title
int textX = x + padding;
int textY = padding;
for (int j = 0; j < 6 && stats[i].name[j] != '\0'; j++) {
SDL_Texture *charTex = titleFont->texture[(uint8_t) stats[i].name[j]];
if (charTex) {
SDL_Rect dstRect = {textX, textY, titleFont->size, titleFont->size};
SDL_RenderCopy(renderer, charTex, NULL, &dstRect);
textX += titleFont->size;
}
}
// Render the value
char valueStr[12];
snprintf(valueStr, sizeof(valueStr), "%u", stats[i].value);
textX = x + padding;
textY += titleFont->size + padding;
for (int j = 0; valueStr[j] != '\0'; j++) {
SDL_Texture *charTex = valueFont->texture[(uint8_t) valueStr[j]];
if (charTex) {
SDL_Rect dstRect = {textX, textY, valueFont->size, valueFont->size};
SDL_RenderCopy(renderer, charTex, NULL, &dstRect);
textX += valueFont->size;
}
}
}
SDL_SetRenderTarget(renderer, NULL);
free(stats);
}
void getStats(CPU *cpu, CPUStatusPart **cpuStatus, int *cpuStatusCount) {
if (!cpu || !cpuStatus || !cpuStatusCount) return;
int count = 5 + REG_COUNT; // PC, SP, FLAGS, MODE, CYCLE + registers
// Free existing memory if allocated
if (*cpuStatus) {
free(*cpuStatus);
*cpuStatus = NULL;
}
// Allocate the required memory
*cpuStatus = (CPUStatusPart *) malloc(count * sizeof(CPUStatusPart));
if (!*cpuStatus) return; // Memory allocation failed
int index = 0;
strncpy((*cpuStatus)[index].name, "PCNT", sizeof((*cpuStatus)[index].name));
(*cpuStatus)[index].value = cpu->pc;
index++;
strncpy((*cpuStatus)[index].name, "SPTR", sizeof((*cpuStatus)[index].name));
(*cpuStatus)[index].value = cpu->stack_ptr;
index++;
strncpy((*cpuStatus)[index].name, "FLAG", sizeof((*cpuStatus)[index].name));
(*cpuStatus)[index].value = cpu->flags;
index++;
strncpy((*cpuStatus)[index].name, "MODE", sizeof((*cpuStatus)[index].name));
(*cpuStatus)[index].value = cpu->mode;
index++;
strncpy((*cpuStatus)[index].name, "CYCL", sizeof((*cpuStatus)[index].name));
(*cpuStatus)[index].value = cpu->cycle;
index++;
for (int i = 0; i < 18; i++) {
snprintf((*cpuStatus)[index].name, sizeof((*cpuStatus)[index].name), "R%d", i);
(*cpuStatus)[index].value = cpu->regs[i];
index++;
}
*cpuStatusCount = index; // Store the actual number of status parts
}
void renderState(CPU *cpu, BitmapFont *titleFont, SDL_Renderer *renderer, SDL_Texture **out) {
// Render the value
char valueStr[20] = "";
if (cpu->mode & CPU_MODE_ERROR) {
strcat(valueStr, "ERR ");
} else if (cpu->mode & CPU_MODE_HALTED) {
strcat(valueStr, "HLT ");
} else if (cpu->mode & CPU_MODE_PAUSED) {
strcat(valueStr, "PAU ");
} else {
strcat(valueStr, "RUN ");
}
if (cpu->mode & CPU_MODE_LOOP) {
strcat(valueStr, "LOOP ");
} else {
strcat(valueStr, "ONCE ");
}
if (cpu->mode & CPU_MODE_STEP) {
strcat(valueStr, "STP");
} else if (cpu->mode & CPU_MODE_SECOND) {
strcat(valueStr, "SEC");
} else if (cpu->mode & CPU_MODE_FRAME) {
strcat(valueStr, "FRM");
} else {
strcat(valueStr, "BRR");
}
const int oneFieldW = (titleFont->size + 1);
const int allFieldW = oneFieldW * strlen(valueStr);
const int oneFieldH = (titleFont->size + 1);
if (!*out) {
*out = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_TARGET,
allFieldW, oneFieldH);
}
SDL_SetRenderTarget(renderer, *out);
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderClear(renderer);
SDL_Rect rect = {0, 0, allFieldW, oneFieldH};
SDL_SetRenderDrawColor(renderer, 50, 50, 50, 255);
SDL_RenderFillRect(renderer, &rect);
int x = 0;
for (int j = 0; valueStr[j] != '\0'; j++) {
SDL_Texture *charTex = titleFont->texture[(uint8_t) valueStr[j]];
if (charTex) {
SDL_Rect dstRect = {x, 0, titleFont->size, titleFont->size};
x += titleFont->size + 1;
SDL_RenderCopy(renderer, charTex, NULL, &dstRect);
}
}
SDL_SetRenderTarget(renderer, NULL);
}