Support significant parts of pico 8 graphics

This commit is contained in:
2024-02-25 18:38:53 -08:00
parent 95c03d25d5
commit 30e4d544fd
11 changed files with 225 additions and 15 deletions

7
sys/BUILD Normal file
View File

@ -0,0 +1,7 @@
cc_library(
name = "sys",
srcs = glob(["*.c"]),
hdrs = glob(["*.h"]),
visibility = ["//visibility:public"],
deps = ["//device:device"]
)

25
sys/sys.c Normal file
View File

@ -0,0 +1,25 @@
#include <assert.h>
#include <stdbool.h>
#include "sys.h"
bool sys_initialized = false;
void sys_init() {
assert(!sys_get_initialized());
sys_initialized = true;
// reset graphics
sys_clip_reset();
sys_camera_reset();
sys_spal_reset();
sys_dpal_reset();
}
bool sys_get_initialized() {
return sys_initialized;
}
void sys_destroy() {
assert(sys_get_initialized());
sys_initialized = false;
}

View File

@ -4,4 +4,19 @@
#include "sys_data.h"
#include "sys_graphics.h"
/**
* Initialize sys.
*/
void sys_init();
/**
* Return whether sys was initialized.
*/
bool sys_get_initialized();
/**
* Destroy sys.
*/
void sys_destroy();
#endif // CROCPARTY_SYS_H

9
sys/sys_data.c Normal file
View File

@ -0,0 +1,9 @@
#include "sys_data.h"
sys_i32 sys_max_i32(sys_i32 x, sys_i32 y) {
return x > y ? x : y;
}
sys_i32 sys_min_i32(sys_i32 x, sys_i32 y) {
return x < y ? x : y;
}

View File

@ -7,7 +7,12 @@ typedef int32_t sys_i32;
typedef uint8_t sys_color;
typedef uint32_t sys_screen_color;
sys_screen_color sys_make_screen_color(uint8_t r, uint8_t g, uint8_t b);
sys_i32 sys_max_i32(sys_i32 x, sys_i32 y);
sys_i32 sys_min_i32(sys_i32 x, sys_i32 y);
#define SYS_COLOR_TRANSPARENT 255
#define SYS_COLOR_N 256
#endif // CROCPARTY_SYS_DATA_H

View File

@ -0,0 +1,126 @@
#include <assert.h>
#include "sys.h"
#include "device/device.h"
sys_i32 sys_cam_dx, sys_cam_dy;
sys_i32 sys_clip_x0, sys_clip_y0, sys_clip_x1, sys_clip_y1;
sys_color sys_dpal[256];
// primitives (forward declare)
void sys_pixel_internal_set(sys_i32 x, sys_i32 y, sys_color c);
// == public ==
void sys_clip_set(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1) {
assert(sys_get_initialized());
sys_clip_set_ext(x0, y0, x1, y1, false);
}
void sys_clip_reset() {
assert(sys_get_initialized());
sys_clip_set(0, 0, DEVICE_W, DEVICE_H);
}
void sys_clip_set_ext(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, bool clip_previous) {
assert(sys_get_initialized());
sys_clip_x0 = sys_max_i32(x0, clip_previous ? sys_clip_x0 : 0);
sys_clip_y0 = sys_max_i32(y0, clip_previous ? sys_clip_y0 : 0);
sys_clip_x1 = sys_min_i32(x1, clip_previous ? sys_clip_x1 : DEVICE_W);
sys_clip_y1 = sys_min_i32(y1, clip_previous ? sys_clip_y1 : DEVICE_H);
}
void sys_pixel_set(sys_i32 x, sys_i32 y, sys_color c) {
assert(sys_get_initialized());
x += sys_cam_dx;
y += sys_cam_dy;
sys_pixel_internal_set(x, y, c);
}
sys_color sys_pixel_get(sys_i32 x, sys_i32 y) {
assert(sys_get_initialized());
x += sys_cam_dx;
y += sys_cam_dy;
if (x < 0 || y < 0 || x >= DEVICE_W || y >= DEVICE_H) {
return SYS_COLOR_TRANSPARENT;
}
return device_pixels[y][x];
}
void sys_cls(sys_color c) {
assert(sys_get_initialized());
for (int x = 0; x < DEVICE_W; x++) {
for (int y = 0; y < DEVICE_W; y++) {
sys_pixel_internal_set(x, y, c);
}
}
}
void sys_camera_set(sys_i32 x, sys_i32 y) {
assert(sys_get_initialized());
sys_cam_dx = -x;
sys_cam_dy = -y;
}
void sys_camera_reset() {
assert(sys_get_initialized());
sys_camera_set(0, 0);
}
// TODO: Continue from sys_circ_draw_ext
void sys_spal_set(sys_color c0, sys_screen_color rc1) {
assert(sys_get_initialized());
device_palette[c0] = rc1;
}
void sys_spal_reset() {
assert(sys_get_initialized());
for (int i = 0; i < SYS_COLOR_N; i++) {
sys_spal_set(i, 0x000000ff);
}
}
void sys_dpal_set(sys_color c0, sys_color c1) {
assert(sys_get_initialized());
sys_dpal[c0] = c1;
}
void sys_dpal_reset() {
assert(sys_get_initialized());
for (int i = 0; i < SYS_COLOR_N; i++) {
sys_dpal_set(i, i);
}
}
// == internal primitives ==
void sys_pixel_internal_set(sys_i32 x, sys_i32 y, sys_color c) {
sys_color realc = sys_dpal[c];
if (realc == SYS_COLOR_TRANSPARENT) { return; }
if (
x < sys_clip_x0 || y < sys_clip_y0 ||
x >= sys_clip_x1 || y >= sys_clip_y1
) {
return;
}
assert(x >= 0);
assert(y >= 0);
assert(x < DEVICE_W);
assert(y < DEVICE_H);
device_pixels[y][x] = realc;
}

View File

@ -19,6 +19,11 @@
*/
void sys_clip_set(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1);
/**
* Reset the clipping rectangle.
*/
void sys_clip_reset();
/**
* Set the clipping rectangle in pixels.
*
@ -41,7 +46,7 @@ void sys_pixel_set(
/**
* Get the color of the pixel `(x, y)`.
*
* Returns 0 if the pixel is out of bounds.
* Returns SYS_COLOR_TRANSPARENT if the pixel is out of bounds.
*/
sys_color sys_pixel_get(
sys_i32 x, sys_i32 y
@ -115,7 +120,7 @@ void sys_rect_fill(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
* After calling this function, virtual color `c0` will be rendered as
* real color `rc1`.
*/
void sys_spal_set(uint8_t c0, uint32_t rc1);
void sys_spal_set(sys_color c0, sys_screen_color rc1);
/**
* Reset screen palette.
@ -130,14 +135,14 @@ void sys_spal_reset();
* After calling this function, draws using color `c0` will be performed
* using color `c1` instead.
*
* Any color mapped to `255` will not actually be drawn.
* Any color mapped to `SYS_COLOR_TRANSPARENT` will not actually be drawn.
*/
void sys_dpal_set(uint8_t c0, uint8_t c1);
void sys_dpal_set(sys_color c0, sys_color c1);
/**
* Reset draw palette.
*
* All colors are mapped to themselves. Color 255 is transparent.
* All colors are mapped to themselves. SYS_COLOR_TRANSPARENT is transparent.
*/
void sys_dpal_reset();