From 1c1e91bd8bf4e9d08cd4d8ee41568e3d25ee8256 Mon Sep 17 00:00:00 2001 From: "Juan J. Martinez" Date: Tue, 6 Jun 2023 22:58:48 +0100 Subject: First stab at the sw blitter --- data/sprites.png | Bin 345 -> 9174 bytes src/main.c | 45 +++++++++++++++++++++++++++++++++++---------- src/vga.c | 42 +++++++++++++++++++++++++++++++++++++++--- src/vga.h | 9 ++++++++- 4 files changed, 82 insertions(+), 14 deletions(-) diff --git a/data/sprites.png b/data/sprites.png index bfe73d4..6ca0043 100644 Binary files a/data/sprites.png and b/data/sprites.png differ diff --git a/src/main.c b/src/main.c index 9876404..89ae860 100644 --- a/src/main.c +++ b/src/main.c @@ -1,7 +1,7 @@ #include -#include #include #include +#include #include #include "keyb.h" @@ -29,25 +29,50 @@ int main(int argc, char *argv[]) set_palette(binary_palette_start); - uint8_t *screen = open_framebuffer(); - if (!screen) + if (!open_framebuffer()) { set_mode(3); fprintf(stderr, "ERROR: failed to open the framebuffer\n"); return 1; } - int i = 0; + blit_erase(0); + + uint8_t bg[24 * 24] = { 0 }; + uint16_t x = 10, y = 10; + int8_t ix = 1, iy = 1; + uint8_t c = 0; + while (!keys[KEY_ESC]) { - wait_vsync(); + // erase + blit(bg, x, y, 24, 24); - memset(screen, i, 320 * 200); - i++; - if (i > 15) - i = 0; + x += ix; + y += iy; + + if (x >= 320 - 24 || x == 0) + { + ix *= -1; + c = (c + 1) % 15; + blit_erase(c); + memset(bg, c, 24 * 24); + } + if (y >= 200 - 24 || y == 0) + { + iy *= -1; + c = (c + 1) % 15; + blit_erase(c); + memset(bg, c, 24 * 24); + } + + // draw + blit(binary_sprites_start, x, y, 24, 24); + + wait_vsync(); + blit_update(); - timer_wait(1); + //timer_wait(1); } set_mode(3); diff --git a/src/vga.c b/src/vga.c index 981ad6f..e2fb7f9 100644 --- a/src/vga.c +++ b/src/vga.c @@ -1,15 +1,22 @@ #include +#include #include #include #include #include -uint8_t *open_framebuffer() +#include "vga.h" + +static uint8_t buffer[320 * 200]; +static uint8_t *screen = NULL; + +uint8_t open_framebuffer() { if (__djgpp_nearptr_enable() == 0) - return NULL; + return 0; - return (uint8_t *)(0xa0000 + __djgpp_conventional_base); + screen = (uint8_t *)(0xa0000 + __djgpp_conventional_base); + return 1; } void close_framebuffer() @@ -36,3 +43,32 @@ void set_palette(const uint8_t *palette) for (int i = 0; i < 768; i++) outportb(0x3c9, palette[i] >> 2); } + +void blit(const uint8_t *src, uint16_t x, uint16_t y, uint16_t w, uint16_t h) +{ + for (int32_t j = y; j < y + h; j++) + for (int32_t i = x; i < x + w; i++) + { + uint8_t b = *src++; + + /* transparent */ + if (b == TRANSPARENT) + continue; + + /* clipping */ + if (i < 0 || i >= 320 || j < 0 || j >= 200) + continue; + + buffer[i + j * 320] = b; + } +} + +void blit_erase(uint8_t c) +{ + memset(buffer, c, 320 * 200); +} + +void blit_update() +{ + memcpy(screen, buffer, 320 * 200); +} diff --git a/src/vga.h b/src/vga.h index be90b29..ef183ca 100644 --- a/src/vga.h +++ b/src/vga.h @@ -1,7 +1,10 @@ #ifndef _VGA_H #define _VGA_H -uint8_t *open_framebuffer(); +/* palette index to be used as transparent color */ +#define TRANSPARENT 16 + +uint8_t open_framebuffer(); void close_framebuffer(); void set_mode(uint8_t mode); @@ -10,4 +13,8 @@ void wait_vsync(); /* the palette is expected to be 8 bit per color, and will be converted to VGA's 6 bit per color */ void set_palette(const uint8_t *palette); +void blit(const uint8_t *src, uint16_t x, uint16_t y, uint16_t w, uint16_t h); +void blit_erase(uint8_t c); +void blit_update(); + #endif /* _VGA_H */ -- cgit v1.2.3