BG implemented
This commit is contained in:
209
src/duskraylib/display/renderimpl.c
Normal file
209
src/duskraylib/display/renderimpl.c
Normal file
@ -0,0 +1,209 @@
|
||||
/**
|
||||
* Copyright (c) 2025 Dominic Masters
|
||||
*
|
||||
* This software is released under the MIT License.
|
||||
* https://opensource.org/licenses/MIT
|
||||
*/
|
||||
|
||||
#include "display/render.h"
|
||||
#include "assert/assert.h"
|
||||
#include "util/memory.h"
|
||||
|
||||
uint8_t RENDER_BACKGROUND_X = 0;
|
||||
uint8_t RENDER_BACKGROUND_Y = 0;
|
||||
uint8_t RENDER_STATUS = 0;
|
||||
|
||||
uint8_t RENDER_TILES[RENDER_TILE_COUNT] = { 0 };
|
||||
uint8_t RENDER_BACKGROUND_TILEMAP[RENDER_BACKGROUND_TILE_COUNT] = { 0 };
|
||||
|
||||
Color RENDER_PALETTE[RENDER_PALETTE_COLOR_COUNT] = {
|
||||
{ 102, 191, 47, 255 },
|
||||
{ 78, 146, 35, 255 },
|
||||
{ 48, 89, 22, 255 },
|
||||
{ 18, 33, 8, 255 }
|
||||
};
|
||||
bool_t RENDER_DISPLAY_ON = false;
|
||||
|
||||
RenderTexture2D RENDER_BACKBUFFER;
|
||||
RenderTexture2D RENDER_TILES_TEXTURE;
|
||||
|
||||
void renderInit(void) {
|
||||
InitWindow(RENDER_WIDTH_PIXELS * 4, RENDER_HEIGHT_PIXELS * 4, "Dusk");
|
||||
SetTargetFPS(60);
|
||||
SetWindowState(
|
||||
FLAG_WINDOW_RESIZABLE |
|
||||
FLAG_WINDOW_HIGHDPI |
|
||||
FLAG_VSYNC_HINT
|
||||
);
|
||||
|
||||
// Create back buffer for rendering.
|
||||
RENDER_BACKBUFFER = LoadRenderTexture(
|
||||
RENDER_WIDTH_PIXELS,
|
||||
RENDER_HEIGHT_PIXELS
|
||||
);
|
||||
|
||||
// Create texture to hold the tile data.
|
||||
RENDER_TILES_TEXTURE = LoadRenderTexture(
|
||||
RENDER_TILE_COUNT * RENDER_TILE_WIDTH,
|
||||
RENDER_TILE_HEIGHT
|
||||
);
|
||||
}
|
||||
|
||||
void renderVsync() {
|
||||
int32_t x, y, i;
|
||||
BeginDrawing();
|
||||
|
||||
if(RENDER_DISPLAY_ON) {
|
||||
// Update the texture with the new tile data
|
||||
BeginTextureMode(RENDER_TILES_TEXTURE);
|
||||
i = 0;
|
||||
for(i = 0; i < RENDER_TILE_COUNT; i++) {
|
||||
uint8_t *tile = RENDER_TILES + (i * RENDER_TILE_BYTES_PER_TILE);
|
||||
|
||||
// For each pixel in the tile...
|
||||
for(y = 0; y < RENDER_TILE_HEIGHT; y++) {
|
||||
uint8_t low = tile[y * RENDER_TILE_BYTES_PER_ROW];
|
||||
uint8_t high = tile[y * RENDER_TILE_BYTES_PER_ROW + 1];
|
||||
|
||||
for(x = 0; x < RENDER_TILE_WIDTH; x++) {
|
||||
uint8_t loBit = (low >> (7 - x)) & 1;
|
||||
uint8_t hiBit = (high >> (7 - x)) & 1;
|
||||
uint8_t paletteIndex = (hiBit << 1) | loBit;
|
||||
|
||||
// Draw the pixel to the texture
|
||||
DrawPixel(
|
||||
(i * RENDER_TILE_WIDTH) + x,
|
||||
y,
|
||||
RENDER_PALETTE[paletteIndex]
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
EndTextureMode();
|
||||
|
||||
// Clear the back buffer
|
||||
BeginTextureMode(RENDER_BACKBUFFER);
|
||||
ClearBackground(RENDER_PALETTE[0]);
|
||||
|
||||
// Render background tiles
|
||||
i = 0;
|
||||
for(y = 0; y < RENDER_BACKGROUND_ROWS; y++) {
|
||||
for(x = 0; x < RENDER_BACKGROUND_COLUMNS; x++) {
|
||||
// Get the tile index from the tilemap
|
||||
uint8_t tileIndex = RENDER_BACKGROUND_TILEMAP[i++];
|
||||
|
||||
DrawTexturePro(
|
||||
RENDER_TILES_TEXTURE.texture,
|
||||
(Rectangle){
|
||||
.x = ((int32_t)tileIndex) * RENDER_TILE_WIDTH,
|
||||
.y = 0,
|
||||
.width = RENDER_TILE_WIDTH,
|
||||
.height = -RENDER_TILE_HEIGHT
|
||||
},
|
||||
(Rectangle){
|
||||
((int32_t)x * RENDER_TILE_WIDTH) - RENDER_BACKGROUND_X,
|
||||
((int32_t)y * RENDER_TILE_HEIGHT) - RENDER_BACKGROUND_Y,
|
||||
RENDER_TILE_WIDTH,
|
||||
RENDER_TILE_HEIGHT
|
||||
},
|
||||
(Vector2){ 0, 0 },
|
||||
0.0f,
|
||||
WHITE
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Render the back buffer to the screen
|
||||
EndTextureMode();
|
||||
ClearBackground(WHITE);
|
||||
|
||||
// Keep aspect and center the render
|
||||
int32_t renderWidth, renderHeight, renderX, renderY;
|
||||
const int32_t width = GetScreenWidth();
|
||||
const int32_t height = GetScreenHeight();
|
||||
if (RENDER_WIDTH_PIXELS * height > RENDER_HEIGHT_PIXELS * width) {
|
||||
renderWidth = width;
|
||||
renderHeight = (RENDER_HEIGHT_PIXELS * width) / RENDER_WIDTH_PIXELS;
|
||||
renderX = 0;
|
||||
renderY = (height - renderHeight) / 2;
|
||||
} else {
|
||||
renderWidth = (RENDER_WIDTH_PIXELS * height) / RENDER_HEIGHT_PIXELS;
|
||||
renderHeight = height;
|
||||
renderX = (width - renderWidth) / 2;
|
||||
renderY = 0;
|
||||
}
|
||||
DrawTexturePro(
|
||||
RENDER_BACKBUFFER.texture,
|
||||
(Rectangle) { 0, 0, RENDER_WIDTH_PIXELS, -RENDER_HEIGHT_PIXELS },
|
||||
(Rectangle) { renderX, renderY, renderWidth, renderHeight },
|
||||
(Vector2) { 0, 0 },
|
||||
0.0f,
|
||||
WHITE
|
||||
);
|
||||
}
|
||||
|
||||
EndDrawing();
|
||||
if(WindowShouldClose()) RENDER_STATUS |= RENDER_SHOULD_EXIT;
|
||||
}
|
||||
|
||||
void renderDispose() {
|
||||
UnloadRenderTexture(RENDER_TILES_TEXTURE);
|
||||
CloseWindow();
|
||||
}
|
||||
|
||||
void renderDisplayOn(void) {
|
||||
RENDER_DISPLAY_ON = true;
|
||||
}
|
||||
|
||||
void renderDisplayOff(void) {
|
||||
RENDER_DISPLAY_ON = false;
|
||||
}
|
||||
|
||||
void set_bkg_data(
|
||||
const uint8_t index,
|
||||
const uint8_t count,
|
||||
const uint8_t *tiles
|
||||
) {
|
||||
assertTrue(count > 0, "Count must be greater than zero");
|
||||
assertNotNull(tiles, "Tiles pointer must not be null");
|
||||
|
||||
// Copy data to fake vram
|
||||
memoryCopy(
|
||||
&RENDER_TILES[index * RENDER_TILE_BYTES_PER_TILE],
|
||||
tiles,
|
||||
count * RENDER_TILE_BYTES_PER_TILE
|
||||
);
|
||||
}
|
||||
|
||||
void set_bkg_tiles(
|
||||
const uint8_t xPos,
|
||||
const uint8_t yPos,
|
||||
const uint8_t width,
|
||||
const uint8_t height,
|
||||
const uint8_t *tiles
|
||||
) {
|
||||
uint8_t w = width, h = height, x = xPos, y = yPos;
|
||||
assertNotNull(tiles, "Tiles pointer must not be null");
|
||||
|
||||
// Clamp x and y to tilemap bounds
|
||||
if (x >= RENDER_BACKGROUND_COLUMNS) x = RENDER_BACKGROUND_COLUMNS - 1;
|
||||
if (y >= RENDER_BACKGROUND_ROWS) y = RENDER_BACKGROUND_ROWS - 1;
|
||||
|
||||
// Clamp width and height so we don't overflow past edges
|
||||
if (x + w > RENDER_BACKGROUND_COLUMNS) {
|
||||
w = RENDER_BACKGROUND_COLUMNS - x;
|
||||
}
|
||||
if (y + h > RENDER_BACKGROUND_ROWS) {
|
||||
h = RENDER_BACKGROUND_ROWS - y;
|
||||
}
|
||||
|
||||
if (w == 0 || h == 0) return;
|
||||
|
||||
for (uint8_t row = 0; row < h; row++) {
|
||||
memoryCopy(
|
||||
&RENDER_BACKGROUND_TILEMAP[(y + row) * RENDER_BACKGROUND_COLUMNS + x],
|
||||
&tiles[row * width],
|
||||
w
|
||||
);
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user