commit 69703af83497c78e4d2ee219116869f9217d6db3 Author: Maxwell Jeffress Date: Sun Feb 23 15:04:16 2025 +1100 first commit diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..5b4e61e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,9 @@ +cmake_minimum_required(VERSION 3.10) +project(DingusComputer) + +find_package(SDL2 REQUIRED) +include_directories(${SDL2_INCLUDE_DIRS}) + +add_executable(dinguser src/main.cpp) +target_link_libraries(dinguser ${SDL2_LIBRARIES}) + diff --git a/src/main.cpp b/src/main.cpp new file mode 100644 index 0000000..5d1bfce --- /dev/null +++ b/src/main.cpp @@ -0,0 +1,348 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; + +void log(string e) { + cout << e << endl; +} + +int pixelPos(int x, int y) { + return y * 640 + x; +} + +int64_t fixedstoi(string e) { + int64_t outnum = 0; + for (int i = 0; i < e.size(); i++) { + if (e[i] == '1') { + outnum += 1; + } + if (e[i] == '2') { + outnum += 2; + } + if (e[i] == '3') { + outnum += 3; + } + if (e[i] == '4') { + outnum += 4; + } + if (e[i] == '5') { + outnum += 5; + } + if (e[i] == '6') { + outnum += 6; + } + if (e[i] == '7') { + outnum += 7; + } + if (e[i] == '8') { + outnum += 8; + } + if (e[i] == '9') { + outnum += 9; + } + outnum *= 10; + } + outnum /= 10; + return outnum; +} + +int getRed(int i) { + switch(i) { + case 0: return 0; + case 1: return 157; + case 2: return 255; + case 3: return 190; + case 4: return 224; + case 5: return 73; + case 6: return 164; + case 7: return 235; + case 8: return 247; + case 9: return 47; + case 10: return 68; + case 11: return 163; + case 12: return 27; + case 13: return 0; + case 14: return 49; + case 15: return 178; + default: return 0; + } +} + +int getGreen(int i) { + switch(i) { + case 0: return 0; + case 1: return 157; + case 2: return 255; + case 3: return 38; + case 4: return 111; + case 5: return 60; + case 6: return 100; + case 7: return 137; + case 8: return 226; + case 9: return 72; + case 10: return 137; + case 11: return 206; + case 12: return 38; + case 13: return 87; + case 14: return 162; + case 15: return 220; + default: return 0; + } +} + +int getBlue(int i) { + switch(i) { + case 0: return 0; + case 1: return 157; + case 2: return 255; + case 3: return 51; + case 4: return 139; + case 5: return 43; + case 6: return 34; + case 7: return 49; + case 8: return 107; + case 9: return 78; + case 10: return 26; + case 11: return 39; + case 12: return 50; + case 13: return 132; + case 14: return 242; + case 15: return 239; + default: return 0; + } +} + +int main() { + log("Starting the thingymajig..."); + // RAM and VRAM for the virtual computer + // auto memory = make_unique[]>(4194304); + auto vram = make_unique(307200); + + log("Created ram and vram"); + + // Display colours + uint32_t palette[16]; + + log("Created colour palette"); + + // Put stuff in the VRAM for testing purposes + for (int i = 0; i < 307200; i++) { + vram[i] = 0; + } + + log("Filled VRAM"); + + // SDL initialisation + SDL_Window* window = nullptr; + SDL_Renderer* renderer = nullptr; + + if (SDL_Init(SDL_INIT_VIDEO) < 0) { + throw runtime_error("SDL Init Failed: " + string(SDL_GetError())); + } + + log("SDL Initialised"); + + window = SDL_CreateWindow( + "DingusComputer", + SDL_WINDOWPOS_CENTERED, + SDL_WINDOWPOS_CENTERED, + 640, + 480, + SDL_WINDOW_SHOWN + ); + + if (!window) { + SDL_Quit(); + throw runtime_error("SDL Window Creation Failed: " + string(SDL_GetError())); + } + + log("SDL Window Created"); + + renderer = SDL_CreateRenderer( + window, + -1, + SDL_RENDERER_ACCELERATED + ); + + if (!renderer) { + SDL_DestroyWindow(window); + SDL_Quit(); + throw runtime_error("SDL Renderer Creation Failed: " + string(SDL_GetError())); + } + + log("SDL Renderer Created"); + + bool quit = false; + SDL_Event event; + + // Read the cartrige and do what we need to do + ifstream cartrige("../cartrige.dingus"); + string bytecode; + string bytecodeline; + while(getline(cartrige, bytecodeline)) bytecode += bytecodeline; + + cout << "Bytecode length is " << to_string(bytecode.size()) << endl; + + int queuepos = 0; + + vector vars; + int nextVarIndex = 0; + vector processed(bytecode.size(), false); + + log("Entering main loop"); + while (!quit) { + while (SDL_PollEvent(&event)) { + if (event.type == SDL_QUIT) { + log("Quitting, goodbye!"); + quit = true; + continue; + } + } + SDL_Surface* surface = SDL_GetWindowSurface(window); + if (!surface) { + throw runtime_error("SDL Surface Creation Failed: " + string(SDL_GetError())); + quit = true; + continue; + } + + int nextOperationIndex = 0; + int pos = queuepos; + + while (pos < bytecode.length()) { + if (processed[pos]) { + pos++; + continue; + } + string operationArgs; + + if (pos + 1 >= bytecode.length()) break; + + int operation = fixedstoi(string() + bytecode[pos] + bytecode[pos + 1]); + pos += 2; + + string varBuffer; + string bytecodeVarBuffer; + bool isVar = false; + + for (int i = 0; i < bytecode.length(); i++) { + if (bytecode[i] == 'V') { + log("Something to do with variables is happening"); + if (isVar) { + if (vars.size() > fixedstoi(varBuffer)) { + cout << "Variable exists" << endl; + try {bytecodeVarBuffer += to_string(vars[stoi(varBuffer)]);} + catch(...){cout << "idngus did not dongus" << endl;} + } else { + cout << "Variable does not exist" << endl; + bytecodeVarBuffer += ("V" + varBuffer + "V"); + } + varBuffer = ""; + } + isVar = !isVar; + continue; + } else if (isVar) { + varBuffer += bytecode[i]; + } else { + bytecodeVarBuffer += bytecode[i]; + } + } + bytecode = bytecodeVarBuffer; + + int argLength = 8; + + if (pos + argLength > bytecode.length()) break; + + operationArgs = bytecode.substr(pos, argLength); + pos += argLength; + + nextOperationIndex += 10; + + if (operation == 0) { + int x = fixedstoi(operationArgs.substr(0, 3)); + int y = fixedstoi(operationArgs.substr(3, 3)); + int colour = fixedstoi(operationArgs.substr(6, 2)); + + if (x >= 0 && x < 640 && y >= 0 && y < 480) { + vram[pixelPos(x, y)] = colour; + } else { + cout << "Pixel failed bounds checking, x is " << x << " and y is " << y << endl; + } + } else if (operation == 1) { + int jumpPos = fixedstoi(operationArgs); + if (jumpPos * 10 < bytecode.length()) { + pos = jumpPos * 10; + } else { + cout << "Hell nah are you trying to go out of bounds, " << jumpPos << " is strictly off limits" << endl; + } + } else if (operation == 2) { + queuepos = pos; + break; + } else if (operation == 3) { + pos -= argLength; + argLength = 14; + operationArgs = bytecode.substr(pos, argLength); + pos += 6; + try { + cout << operationArgs << endl; + int ax = fixedstoi(operationArgs.substr(0, 3)); + int ay = fixedstoi(operationArgs.substr(3, 3)); + int bx = fixedstoi(operationArgs.substr(6, 3)); + int by = fixedstoi(operationArgs.substr(9, 3)); + int width = abs(bx - ax); + int height = abs(by - ay); + int colour = fixedstoi(operationArgs.substr(12, 2)); + if (ax >= 0 && ax < 640 && ay >= 0 && ay < 480 && bx >= 0 && bx < 640 && by >= 0 && by < 480) { + for (int i = 0; i < width; i++) { + for (int j = 0; j < height; j++) { + int x = min(ax, bx) + i; + int y = min(ay, by) + j; + vram[pixelPos(x, y)] = colour; + } + } + } else { + cout << "Pixel failed bounds checking" << endl; + } + } catch (...) { + cout << "mingus did not mongus" << endl; + } + } else if (operation == 4) { + int varContents = fixedstoi(operationArgs); + cout << "Declaring variable " << nextVarIndex << " with contents " << varContents << endl; + try {vars.push_back(stoi(operationArgs));} + catch(...){cout << "bingus did not bongus" << endl;}; + nextVarIndex++; + processed[pos - argLength - 2] = true; + processed[pos - argLength - 1] = true; + } + } + + + for (int i = 0; i < 16; i++) { + palette[i] = SDL_MapRGB(surface->format, + getRed(i), + getGreen(i), + getBlue(i) + ); + } + + uint32_t* pixels = static_cast(surface->pixels); + + for (int i = 0; i < 640 * 480; i++) { + pixels[i] = palette[vram[i]]; + } + + SDL_UpdateWindowSurface(window); + } + cartrige.close(); + SDL_DestroyRenderer(renderer); + SDL_DestroyWindow(window); + SDL_Quit(); +}