#include "sldj.h" void initSldj(Sldj *sldj) { // Create window. InitWindow(WINDOW_WIDTH, WINDOW_HEIGHT, "Scanline DJ"); SetWindowState(FLAG_WINDOW_RESIZABLE); sldj->isPaused = false; SetTargetFPS(DEFAULT_FRAME_RATE); sldj->targetFps = DEFAULT_FRAME_RATE; sldj->viewport = LoadRenderTexture(DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT); sldj->frameCounter = 0; sldj->xCount = UINT16_MAX / DEFAULT_SCREEN_WIDTH; sldj->yCount = UINT16_MAX / DEFAULT_SCREEN_HEIGHT; resetViewportRect(sldj, DEFAULT_SCREEN_SCALE); // Scripting. initScripting(&sldj->scripting); sldj->scriptFilepath[0] = '\0'; // Gui. resizeGui(sldj); sldj->gui.fpsSliderValue = (float)DEFAULT_FRAME_RATE; sldj->gui.widthSliderValue = (float)DEFAULT_SCREEN_WIDTH; sldj->gui.heightSliderValue = (float)DEFAULT_SCREEN_HEIGHT; } void handleInput(Sldj* sldj) { if (IsKeyPressed(KEY_R)) { reloadScript(sldj); sldj->isPaused = false; } if (IsKeyPressed(KEY_SPACE)) { sldj->isPaused = !sldj->isPaused; } } void updateGui(Sldj* sldj) { // Fps. float oldFps = sldj->gui.fpsSliderValue; GuiSlider(sldj->gui.fpsSlider, "fps", oldFps > FRAME_RATE_MAX ? "Unlimited" : TextFormat("%d", (int)oldFps), &sldj->gui.fpsSliderValue, FRAME_RATE_MIN, FRAME_RATE_MAX + 1); // Fps has changed. if (sldj->gui.fpsSliderValue != oldFps) { sldj->targetFps = (uint32_t)sldj->gui.fpsSliderValue; sldj->targetFps = sldj->targetFps > FRAME_RATE_MAX ? 0 : sldj->targetFps; SetTargetFPS(sldj->targetFps); } // Width and height. GuiSlider(sldj->gui.widthSlider, "Width", TextFormat("%d", (int)sldj->gui.widthSliderValue), &sldj->gui.widthSliderValue, SCREEN_MIN, SCREEN_MAX); GuiSlider(sldj->gui.heightSlider, "Height", TextFormat("%d", (int)sldj->gui.heightSliderValue), &sldj->gui.heightSliderValue, SCREEN_MIN, SCREEN_MAX); if (GuiButton(sldj->gui.viewportButton, "Reset view")) { resetViewport(sldj, sldj->gui.widthSliderValue, sldj->gui.heightSliderValue); resizeGui(sldj); } } void updateSldj(Sldj* sldj) { BeginDrawing(); handleInput(sldj); // Scan image. BeginTextureMode(sldj->viewport); if (!sldj->isPaused && sldj->scripting.lineScanner != NULL) { uint16_t xScan = 0; uint16_t yScan = 0; for (int y = 0; y < sldj->viewport.texture.height; ++y) { xScan = 0; for (int x = 0; x < sldj->viewport.texture.width; ++x) { DrawPixel(x, y, sldj->scripting.lineScanner(xScan, yScan, sldj->frameCounter)); xScan += sldj->xCount; } yScan += sldj->yCount; } ++sldj->frameCounter; } EndTextureMode(); ClearBackground(DARKGRAY); // Draw scanned image. Texture viewport = sldj->viewport.texture; DrawTexturePro( viewport, (Rectangle){0.0, 0.0, viewport.width, viewport.height}, sldj->viewPortRect, (Vector2){0.0, 0.0}, 0.0, WHITE ); DrawFPS(0, viewport.height); updateGui(sldj); EndDrawing(); } void closeSldj(Sldj* sldj) { UnloadRenderTexture(sldj->viewport); closeScripting(&sldj->scripting); CloseWindow(); } void resizeGui(Sldj* sldj) { Rectangle view = sldj->viewPortRect; // Starting place for ui. float startX = view.x + view.width + 40.0; float startY = 5.0; // Standard sizes unit for gui elements. float guiWidth = 50.0; float guiHeight = 25.0; float sliderWidth = guiWidth * 3.0; sldj->gui.fpsSlider = (Rectangle){startX, startY, sliderWidth, guiHeight}; sldj->gui.widthSlider = (Rectangle){startX, startY + guiHeight, sliderWidth, guiHeight}; sldj->gui.heightSlider = (Rectangle){startX, startY + guiHeight * 2.0, sliderWidth, guiHeight}; sldj->gui.viewportButton = (Rectangle){startX, startY + guiHeight * 3.0, guiWidth * 2.0, guiHeight}; } void resetViewportRect(Sldj* sldj, float scale) { Texture texture = sldj->viewport.texture; sldj->viewPortRect = (Rectangle){0.0, 0.0, texture.width * scale, texture.height * scale}; } void resetViewport(Sldj* sldj, int width, int height) { UnloadRenderTexture(sldj->viewport); sldj->viewport = LoadRenderTexture(width, height); // Set up scan counters. sldj->xCount = UINT16_MAX / width; sldj->yCount = UINT16_MAX / height; resetViewportRect(sldj, 1.0); } void reloadScriptContext(Sldj* sldj) { if (sldj->scripting.loadContext != NULL) { sldj->scripting.loadContext((SldjContext){ .viewportWidth = sldj->viewport.texture.width, .viewportHeight = sldj->viewport.texture.height, .targetFps = sldj->targetFps, .xCount = sldj->xCount, .yCount = sldj->yCount }); } } void reloadScript(Sldj* sldj) { if (sldj->scriptFilepath[0] != '\0') { compileScript(&sldj->scripting, sldj->scriptFilepath); reloadScriptContext(sldj); } }