Groundwork for sys, palette

This commit is contained in:
Pyrex 2024-02-25 17:54:57 -08:00
parent 56eaee9d08
commit 95c03d25d5
8 changed files with 201 additions and 8 deletions

View File

@ -1,5 +1,7 @@
#include <stdbool.h> #include <stdbool.h>
#include "device.h" #include "device.h"
uint32_t device_pixels[DEVICE_H][DEVICE_W]; uint8_t device_pixels[DEVICE_H][DEVICE_W];
uint32_t device_palette[256];
bool device_buttons[DEVICE_BUTTON_N]; bool device_buttons[DEVICE_BUTTON_N];

View File

@ -22,7 +22,9 @@ typedef enum {
DEVICE_BUTTON_N=8, DEVICE_BUTTON_N=8,
} DeviceButton; } DeviceButton;
extern uint32_t device_pixels[DEVICE_H][DEVICE_W]; extern uint8_t device_pixels[DEVICE_H][DEVICE_W];
extern uint32_t device_palette[256];
extern bool device_buttons[DEVICE_BUTTON_N]; extern bool device_buttons[DEVICE_BUTTON_N];
#endif //CROCPARTY_DEVICE_H #endif //CROCPARTY_DEVICE_H

View File

@ -5,29 +5,42 @@ uint32_t game_frame;
void game_init() { void game_init() {
game_frame = 0; 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)
] =
((x * 255)/7) << 24 |
((y * 255)/7) << 16 |
((z * 255)/3) << 8;
}
}
}
} }
void game_update() { void game_update() {
game_frame += 1; game_frame += 4;
} }
void game_draw() { void game_draw() {
for (int x = 0; x < DEVICE_W; x++) { for (int x = 0; x < DEVICE_W; x++) {
for (int y = 0; y < DEVICE_H; y++) { for (int y = 0; y < DEVICE_H; y++) {
uint32_t r = (x * 255)/DEVICE_W; uint32_t r = (x * 255)/(DEVICE_W - 1);
uint32_t g = (y * 255)/DEVICE_H; uint32_t g = (y * 255)/(DEVICE_H - 1);
uint32_t b = game_frame & 0x100 ? 0xff - game_frame & 0xff : game_frame & 0xff; uint32_t b = game_frame & 0x100 ? 0xff - game_frame & 0xff : game_frame & 0xff;
if (x % 4 == 2 && y % 4 == 2) { if (x % 4 == 2 && y % 4 == 2) {
r = 255 - r; r = 255 - r;
g = 255 - g; g = 255 - g;
b = 255 - b; b = 255 - b;
} }
uint32_t color = r << 24 | g << 16 | b << 8; uint8_t color = (r >> 5) << 5 | (g >> 5) << 2 | (b >> 6);
device_pixels[y][x] = color; device_pixels[y][x] = color;
} }
} }
for (int i = 0; i < DEVICE_BUTTON_N; i++) { for (int i = 0; i < DEVICE_BUTTON_N; i++) {
device_pixels[0][i] = device_buttons[i] ? 0x000000ff : 0xffffffff; device_pixels[0][i] = device_buttons[i] ? 0x00 : 0xff;
} }
} }

View File

@ -121,6 +121,7 @@ void sdl_host_suggest_dimensions(uint32_t* window_w, uint32_t* window_h) {
void sdl_host_loop() { void sdl_host_loop() {
uint32_t ticks_per_frame = 1000/60; uint32_t ticks_per_frame = 1000/60;
uint32_t real_pixels[DEVICE_H][DEVICE_W];
game_init(); game_init();
while (true) { while (true) {
@ -139,7 +140,13 @@ void sdl_host_loop() {
game_update(); game_update();
game_draw(); game_draw();
SDL_UpdateTexture(sdl_host_target, NULL, &device_pixels, sizeof(device_pixels[0])); for (int x = 0; x < DEVICE_W; x++) {
for (int y = 0; y < DEVICE_H; y++) {
real_pixels[y][x] = device_palette[device_pixels[y][x]];
}
}
SDL_UpdateTexture(sdl_host_target, NULL, &real_pixels, sizeof(real_pixels[0]));
SDL_RenderClear(sdl_host_renderer); SDL_RenderClear(sdl_host_renderer);
SDL_RenderCopy(sdl_host_renderer, sdl_host_target, NULL, NULL); SDL_RenderCopy(sdl_host_renderer, sdl_host_target, NULL, NULL);
SDL_RenderPresent(sdl_host_renderer); SDL_RenderPresent(sdl_host_renderer);

7
sys/sys.h Normal file
View File

@ -0,0 +1,7 @@
#ifndef CROCPARTY_SYS_H
#define CROCPARTY_SYS_H
#include "sys_data.h"
#include "sys_graphics.h"
#endif // CROCPARTY_SYS_H

13
sys/sys_data.h Normal file
View File

@ -0,0 +1,13 @@
#ifndef CROCPARTY_SYS_DATA_H
#define CROCPARTY_SYS_DATA_H
#include <stdint.h>
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);
#endif // CROCPARTY_SYS_DATA_H

0
sys/sys_graphics.c Normal file
View File

149
sys/sys_graphics.h Normal file
View File

@ -0,0 +1,149 @@
// Corresponds roughly to section 6.2 of the Pico 8 manual
//
// However, all ranges are now half-open.
//
// https://www.lexaloffle.com/dl/docs/pico-8_manual.html
//
#ifndef CROCPARTY_SYS_GRAPHICS_H
#define CROCPARTY_SYS_GRAPHICS_H
#include <stdbool.h>
#include <stdint.h>
#include "sys_data.h"
/**
* Set the clipping rectangle in pixels.
*
* All drawing operations will be clipped to this rectangle.
*/
void sys_clip_set(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1);
/**
* Set the clipping rectangle in pixels.
*
* This is the same as `sys_clip_set`, but you can pass clip_previous in order
* to clip to the previous region.
*/
void sys_clip_set_ext(
sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1,
bool clip_previous
);
/**
* Set the color of the pixel `(x, y)`.
*/
void sys_pixel_set(
sys_i32 x, sys_i32 y,
sys_color c
);
/**
* Get the color of the pixel `(x, y)`.
*
* Returns 0 if the pixel is out of bounds.
*/
sys_color sys_pixel_get(
sys_i32 x, sys_i32 y
);
// TODO: SSET/SGET
// TODO: FGET/FSET
// TODO: PRINT
// TODO: CURSOR? COLOR?
/**
* Fill the entire screen with color `c`.
*/
void sys_cls(sys_color c);
/**
* Create a screen offset of `(-x, -y)` for all drawing operations.
*/
void sys_camera_set(sys_i32 x, sys_i32 y);
/**
* Reset the camera's offset to `(0, 0)`.
*/
void sys_camera_reset();
/**
* Draw or fill a circle at `(x, y)` with radius `r`.
*
* The circle consists of a "stroke" region and a "fill" region which the user
* can decide individually on whether or not to fill.
*
* If r is negative, the circle is not drawn.
*
* This is a special case of sys_circ_oval_draw_ext.
*/
void sys_circ_draw_ext(sys_i32 x, sys_i32 y, sys_i32 r, sys_color c, bool stroke, bool fill);
void sys_circ_draw(sys_i32 x, sys_i32 y, sys_i32 r, sys_color c);
void sys_circ_fill(sys_i32 x, sys_i32 y, sys_i32 r);
/**
* Draw or fill an oval in the rectangle from `(x0, y0)` to `(x1, y1)`
*
* The oval consists of a "stroke" region and a "fill" region which the user
* can decide individually on whether or not to fill.
*/
void sys_oval_draw_ext(
sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c,
bool stroke, bool fill
);
void sys_oval_draw(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
void sys_oval_fill(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
/**
* Draw a line from x0 to y0.
*/
void sys_line_draw(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
/**
* Draw or fill a rectangle `(x, y, w, h)`
*/
void sys_rect_draw_ext(
sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c,
bool stroke, bool fill
);
void sys_rect_draw(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
void sys_rect_fill(sys_i32 x0, sys_i32 y0, sys_i32 x1, sys_i32 y1, sys_color c);
/**
* Set screen palette.
*
* After calling this function, virtual color `c0` will be rendered as
* real color `rc1`.
*/
void sys_spal_set(uint8_t c0, uint32_t rc1);
/**
* Reset screen palette.
*
* After calling this function, all screen colors are (0, 0, 0).
*/
void sys_spal_reset();
/**
* Set draw palette.
*
* 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.
*/
void sys_dpal_set(uint8_t c0, uint8_t c1);
/**
* Reset draw palette.
*
* All colors are mapped to themselves. Color 255 is transparent.
*/
void sys_dpal_reset();
// TODO: SPR
// TODO: SSPR
// TODO: FILLP?
#endif // CROCPARTY_SYS_GRAPHICS_H