173 lines
5.5 KiB
C
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, "PS ");
|
|
} 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);
|
|
} |