DV Display: Sprites in palette mode

dv_stick
Mike Bell 2023-07-12 21:52:01 +01:00 zatwierdzone przez Phil Howard
rodzic 3a5f069ec1
commit 103228a88d
6 zmienionych plików z 2366 dodań i 2152 usunięć

Wyświetl plik

@ -136,13 +136,12 @@ namespace pimoroni {
);
}
hw_set_bits(&dma_hw->ch[dma_channel].al1_ctrl, DMA_CH0_CTRL_TRIG_INCR_READ_BITS);
for (int len = len_in_bytes, page_len = std::min(PAGE_SIZE, len);
len > 0;
addr += page_len, data += page_len >> 2, len -= page_len, page_len = std::min(PAGE_SIZE, len))
{
wait_for_finish_blocking();
hw_set_bits(&dma_hw->ch[dma_channel].al1_ctrl, DMA_CH0_CTRL_TRIG_INCR_READ_BITS);
pio_sm_put_blocking(pio, pio_sm, (page_len << 1) - 1);
pio_sm_put_blocking(pio, pio_sm, 0x38000000u | addr);
@ -174,13 +173,12 @@ namespace pimoroni {
);
}
hw_clear_bits(&dma_hw->ch[dma_channel].al1_ctrl, DMA_CH0_CTRL_TRIG_INCR_READ_BITS);
for (int len = len_in_bytes, page_len = std::min(PAGE_SIZE, len);
len > 0;
addr += page_len, len -= page_len, page_len = std::min(PAGE_SIZE, len))
{
wait_for_finish_blocking();
hw_clear_bits(&dma_hw->ch[dma_channel].al1_ctrl, DMA_CH0_CTRL_TRIG_INCR_READ_BITS);
repeat_data = data;
pio_sm_put_blocking(pio, pio_sm, (page_len << 1) - 1);

Wyświetl plik

@ -1,6 +1,6 @@
#include "dv_display.hpp"
#include "swd_load.hpp"
#include "pico-stick-wide.h"
#include "pico-stick.h"
#include <cstdlib>
#include <math.h>
@ -410,7 +410,7 @@ namespace pimoroni {
uint32_t buf[buf_size];
uint addr = (display_height + 7) * 4 + PALETTE_SIZE * 3;
uint sprite_type = 0x10000000u;
uint sprite_type = (uint)mode << 28;
for (uint32_t i = 0; i < max_num_sprites; i += buf_size) {
for (uint32_t j = 0; j < buf_size; ++j) {
buf[j] = sprite_type + (i + j) * sprite_size + sprite_base_address;
@ -428,7 +428,7 @@ namespace pimoroni {
write_sprite_table();
}
void DVDisplay::define_sprite(uint16_t sprite_data_idx, uint16_t width, uint16_t height, uint16_t* data)
void DVDisplay::define_sprite_internal(uint16_t sprite_data_idx, uint16_t width, uint16_t height, uint32_t* data)
{
uint32_t buf[33];
uint16_t* buf_ptr = (uint16_t*)buf;
@ -449,6 +449,16 @@ namespace pimoroni {
ram.write(addr, (uint32_t*)data, width * height * 2);
}
void DVDisplay::define_sprite(uint16_t sprite_data_idx, uint16_t width, uint16_t height, uint16_t* data)
{
define_sprite_internal(sprite_data_idx, width, height, (uint32_t*)data);
}
void DVDisplay::define_palette_sprite(uint16_t sprite_data_idx, uint16_t width, uint16_t height, uint8_t* data)
{
define_sprite_internal(sprite_data_idx, width, height, (uint32_t*)data);
}
void DVDisplay::set_sprite(int sprite_num, uint16_t sprite_data_idx, const Point &p)
{
uint8_t buf[7];

Wyświetl plik

@ -141,10 +141,13 @@ namespace pimoroni {
// to set_sprite to use the sprite. Up to 1024 sprites can be defined.
// Each sprite can be up to 2KB big, with a maximum width or height of 64 pixels.
// So for ARGB1555 sprites 64x16, 32x32, 16x64 are examples of maximum sizes.
// Sprites are currently only supported when using ARGB1555 mode.
// You must define the sprite to each RAM bank.
void define_sprite(uint16_t sprite_data_idx, uint16_t width, uint16_t height, uint16_t* data);
// Palette mode sprites are defined with the colour number in bits 6-2 of each byte and alpha in bit 0.
// Because palette mode sprites only use 1 byte per pixel they can be bigger, up to 64x32, or 45x45, for example.
void define_palette_sprite(uint16_t sprite_data_idx, uint16_t width, uint16_t height, uint8_t* data);
// Display/move a sprite to a given position.
// Note sprite positions are always display relative (not scrolled)
// TODO: Blend mode
@ -217,6 +220,8 @@ namespace pimoroni {
void read(uint32_t address, size_t len, uint8_t *data);
void write(uint32_t address, size_t len, const RGB888 colour);
void define_sprite_internal(uint16_t sprite_data_idx, uint16_t width, uint16_t height, uint32_t* data);
uint32_t point_to_address(const Point& p) const;
int pixel_size() const;

Wyświetl plik

@ -9,8 +9,8 @@
using namespace pimoroni;
#define DISPLAY_WIDTH 360
#define DISPLAY_HEIGHT 240
#define DISPLAY_WIDTH 720
#define DISPLAY_HEIGHT 480
#define FRAME_WIDTH 720
#define FRAME_HEIGHT 480
@ -18,16 +18,31 @@ using namespace pimoroni;
#define SPRITE_WIDTH 8
#define SPRITE_HEIGHT 8
static uint16_t sprite_data[] = {
0x0001, 0x0001, 0x0001, 0xF000, 0xF000, 0x0001, 0x0001, 0x0001,
0x0001, 0x0001, 0xF000, 0xF000, 0xF000, 0xF000, 0x0001, 0x0001,
0x0001, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0x0001,
0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000,
0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000,
0x0001, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0x0001,
0x0001, 0x0001, 0xF000, 0xF000, 0xF000, 0xF000, 0x0001, 0x0001,
0x0001, 0x0001, 0x0001, 0xF000, 0xF000, 0x0001, 0x0001, 0x0001,
#define USE_PALETTE 1
#if USE_PALETTE
static uint8_t sprite_data_pal[] = {
0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00,
0x00, 0x00, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00,
0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05,
0x00, 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00,
0x00, 0x00, 0x05, 0x05, 0x05, 0x05, 0x00, 0x00,
0x00, 0x00, 0x00, 0x05, 0x05, 0x00, 0x00, 0x00,
};
#else
static uint16_t sprite_data[] = {
0x0000, 0x0000, 0x0000, 0xF000, 0xF000, 0x0000, 0x0000, 0x0000,
0x0000, 0x0000, 0xF000, 0xF000, 0xF000, 0xF000, 0x0000, 0x0000,
0x0000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0x0000,
0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000,
0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000,
0x0000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0xF000, 0x0000,
0x0000, 0x0000, 0xF000, 0xF000, 0xF000, 0xF000, 0x0000, 0x0000,
0x0000, 0x0000, 0x0000, 0xF000, 0xF000, 0x0000, 0x0000, 0x0000,
};
#endif
void on_uart_rx() {
while (uart_is_readable(uart1)) {
@ -57,11 +72,21 @@ int main() {
//sleep_ms(5000);
DVDisplay display;
#if USE_PALETTE
display.init(DISPLAY_WIDTH, DISPLAY_HEIGHT, DVDisplay::MODE_PALETTE, FRAME_WIDTH, FRAME_HEIGHT);
PicoGraphics_PenDV_P5 graphics(FRAME_WIDTH, FRAME_HEIGHT, display);
display.define_palette_sprite(0, SPRITE_WIDTH, SPRITE_HEIGHT, sprite_data_pal);
graphics.create_pen(0, 0, 0x20);
graphics.create_pen(0xF0, 0, 0);
graphics.set_pen(0);
#else
display.init(DISPLAY_WIDTH, DISPLAY_HEIGHT, DVDisplay::MODE_RGB555, FRAME_WIDTH, FRAME_HEIGHT);
PicoGraphics_PenDV_RGB555 graphics(FRAME_WIDTH, FRAME_HEIGHT, display);
display.define_sprite(0, SPRITE_WIDTH, SPRITE_HEIGHT, sprite_data);
graphics.set_pen(0x000F);
#endif
graphics.clear();
display.flip();