Support significant parts of pico 8 graphics
This commit is contained in:
parent
95c03d25d5
commit
30e4d544fd
@ -3,5 +3,5 @@ cc_library(
|
||||
srcs = glob(["*.c"]),
|
||||
hdrs = glob(["*.h"]),
|
||||
visibility = ["//visibility:public"],
|
||||
deps = ["//device:device"]
|
||||
deps = ["//device:device", "//sys:sys"]
|
||||
)
|
29
game/game.c
29
game/game.c
@ -1,23 +1,36 @@
|
||||
#include "device/device.h"
|
||||
#include "game.h"
|
||||
#include "sys/sys.h"
|
||||
|
||||
uint32_t game_frame;
|
||||
|
||||
const char* game_title() {
|
||||
return "Croc Party!";
|
||||
}
|
||||
|
||||
void game_init() {
|
||||
sys_init();
|
||||
|
||||
game_frame = 0;
|
||||
|
||||
for (uint32_t x = 0; x < 8; x++) {
|
||||
for (uint32_t y = 0; y < 8; y++) {
|
||||
for (uint32_t z = 0; z < 4; z++) {
|
||||
device_palette[
|
||||
(x << 5)|(y << 2)|(z)
|
||||
] =
|
||||
sys_spal_set(
|
||||
(x << 5)|(y << 2)|(z),
|
||||
|
||||
((x * 255)/7) << 24 |
|
||||
((y * 255)/7) << 16 |
|
||||
((z * 255)/3) << 8;
|
||||
((z * 255)/3) << 8
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
sys_spal_set(0xfe, 0xffffffff);
|
||||
}
|
||||
|
||||
void game_destroy() {
|
||||
sys_destroy();
|
||||
}
|
||||
|
||||
void game_update() {
|
||||
@ -25,6 +38,8 @@ void game_update() {
|
||||
}
|
||||
|
||||
void game_draw() {
|
||||
sys_dpal_set(0xff, 0xfe); // map to a non-transparent color
|
||||
|
||||
for (int x = 0; x < DEVICE_W; x++) {
|
||||
for (int y = 0; y < DEVICE_H; y++) {
|
||||
uint32_t r = (x * 255)/(DEVICE_W - 1);
|
||||
@ -35,12 +50,12 @@ void game_draw() {
|
||||
g = 255 - g;
|
||||
b = 255 - b;
|
||||
}
|
||||
uint8_t color = (r >> 5) << 5 | (g >> 5) << 2 | (b >> 6);
|
||||
device_pixels[y][x] = color;
|
||||
sys_color color = (r >> 5) << 5 | (g >> 5) << 2 | (b >> 6);
|
||||
sys_pixel_set(x, y, color);
|
||||
}
|
||||
}
|
||||
|
||||
for (int i = 0; i < DEVICE_BUTTON_N; i++) {
|
||||
device_pixels[0][i] = device_buttons[i] ? 0x00 : 0xff;
|
||||
sys_pixel_set(i, 0, device_buttons[i] ? 0x00 : 0xff);
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,10 @@
|
||||
#ifndef CROCPARTY_GAME_H
|
||||
#define CROCPARTY_GAME_H
|
||||
|
||||
const char* game_title();
|
||||
void game_init();
|
||||
void game_destroy();
|
||||
|
||||
void game_update();
|
||||
void game_draw();
|
||||
|
||||
|
@ -28,7 +28,7 @@ int main(int argc, char** argv) {
|
||||
|
||||
// create window
|
||||
sdl_host_window = SDL_CreateWindow(
|
||||
"Croc Party!",
|
||||
game_title(),
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
SDL_WINDOWPOS_CENTERED,
|
||||
(int) window_w, (int) window_h,
|
||||
|
7
sys/BUILD
Normal file
7
sys/BUILD
Normal 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
25
sys/sys.c
Normal 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;
|
||||
}
|
15
sys/sys.h
15
sys/sys.h
@ -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
9
sys/sys_data.c
Normal 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;
|
||||
}
|
@ -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
|
@ -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;
|
||||
}
|
@ -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();
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user