// // Created by bruno on 8.2.2025. // #include #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); }