kopia lustrzana https://github.com/pimoroni/pimoroni-pico
DV Display: Begin exposing sprites
rodzic
3c2c7ccc94
commit
765b8a6226
|
@ -398,16 +398,75 @@ namespace pimoroni {
|
|||
buf[2] = full_width << 16;
|
||||
buf[3] = (uint32_t)display_height << 16;
|
||||
buf[4] = 0x00000001;
|
||||
buf[5] = 0x00010000 + display_height + (bank << 24);
|
||||
buf[6] = 0x00000001;
|
||||
buf[5] = 0x00010000 + display_height + ((uint32_t)bank << 24);
|
||||
buf[6] = 0x04000001;
|
||||
ram.write(0, buf, 7 * 4);
|
||||
ram.wait_for_finish_blocking();
|
||||
}
|
||||
|
||||
void DVDisplay::write_sprite_table()
|
||||
{
|
||||
constexpr uint32_t buf_size = 32;
|
||||
uint32_t buf[buf_size];
|
||||
|
||||
uint addr = (display_height + 7) * 4 + PALETTE_SIZE * 3;
|
||||
uint sprite_type = 0x10000000u;
|
||||
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;
|
||||
}
|
||||
ram.write(addr, buf, buf_size * 4);
|
||||
ram.wait_for_finish_blocking();
|
||||
addr += buf_size * 4;
|
||||
}
|
||||
}
|
||||
|
||||
void DVDisplay::write_header()
|
||||
{
|
||||
write_header_preamble();
|
||||
set_scroll_idx_for_lines(1, 0, display_height);
|
||||
write_sprite_table();
|
||||
}
|
||||
|
||||
void DVDisplay::define_sprite(uint16_t sprite_data_idx, uint16_t width, uint16_t height, uint16_t* data)
|
||||
{
|
||||
uint32_t buf[33];
|
||||
uint16_t* buf_ptr = (uint16_t*)buf;
|
||||
uint addr = sprite_base_address + sprite_data_idx * sprite_size;
|
||||
|
||||
*buf_ptr++ = (height << 8) + width;
|
||||
|
||||
for (uint16_t i = 0; i < height; ++i)
|
||||
{
|
||||
*buf_ptr++ = width << 8;
|
||||
}
|
||||
uint len = (uint8_t*)buf_ptr - (uint8_t*)buf;
|
||||
ram.write(addr, buf, len);
|
||||
|
||||
addr += len;
|
||||
if (len & 2) addr += 2;
|
||||
|
||||
ram.write(addr, (uint32_t*)data, width * height * 2);
|
||||
}
|
||||
|
||||
void DVDisplay::set_sprite(int sprite_num, uint16_t sprite_data_idx, const Point &p)
|
||||
{
|
||||
uint8_t buf[7];
|
||||
buf[0] = 1; // BLEND_DEPTH
|
||||
buf[1] = sprite_data_idx & 0xff;
|
||||
buf[2] = sprite_data_idx >> 8;
|
||||
buf[3] = p.x & 0xff;
|
||||
buf[4] = p.x >> 8;
|
||||
buf[5] = p.y & 0xff;
|
||||
buf[6] = p.y >> 8;
|
||||
|
||||
i2c->write_bytes(I2C_ADDR, sprite_num, buf, 7);
|
||||
}
|
||||
|
||||
void DVDisplay::clear_sprite(int sprite_num)
|
||||
{
|
||||
uint16_t off = 0xFFFF;
|
||||
i2c->write_bytes(I2C_ADDR, sprite_num, (uint8_t*)&off, 2);
|
||||
}
|
||||
|
||||
uint32_t DVDisplay::point_to_address(const Point& p) const {
|
||||
|
|
|
@ -60,6 +60,9 @@ namespace pimoroni {
|
|||
static constexpr uint RAM_SEL = 8;
|
||||
|
||||
static constexpr uint32_t base_address = 0x10000;
|
||||
static constexpr uint32_t max_num_sprites = 1024;
|
||||
static constexpr uint32_t sprite_size = 0x900;
|
||||
static constexpr uint32_t sprite_base_address = 0x800000 - (max_num_sprites * sprite_size);
|
||||
uint16_t display_width = 0;
|
||||
uint16_t display_height = 0;
|
||||
uint16_t frame_width = 0;
|
||||
|
@ -134,6 +137,20 @@ namespace pimoroni {
|
|||
void flip();
|
||||
void reset();
|
||||
|
||||
// Define the data for a sprite, the specified data index can then be supplied
|
||||
// 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);
|
||||
|
||||
// Display/move a sprite to a given position.
|
||||
// Note sprite positions are always display relative (not scrolled)
|
||||
// TODO: Blend mode
|
||||
void set_sprite(int sprite_num, uint16_t sprite_data_idx, const Point &p);
|
||||
void clear_sprite(int sprite_num);
|
||||
|
||||
// 32 colour palette mode. Note that palette entries range from 0-31,
|
||||
// but when writing colour values the palette entry is in bits 6-2, so the
|
||||
// entry value is effectively multiplied by 4.
|
||||
|
@ -183,8 +200,9 @@ namespace pimoroni {
|
|||
|
||||
virtual void write_palette();
|
||||
virtual void write_header();
|
||||
virtual void write_sprite_table();
|
||||
virtual void write_header_preamble();
|
||||
|
||||
void write_header_preamble();
|
||||
void i2c_modify_bit(uint8_t reg, uint bit, bool enable);
|
||||
|
||||
private:
|
||||
|
|
|
@ -0,0 +1,15 @@
|
|||
set(OUTPUT_NAME dv_sprite_test)
|
||||
|
||||
add_executable(
|
||||
${OUTPUT_NAME}
|
||||
dv_sprite_test.cpp
|
||||
edid-decode.c
|
||||
)
|
||||
|
||||
# Pull in pico libraries that we need
|
||||
target_link_libraries(${OUTPUT_NAME} pico_stdlib dv_display hardware_i2c hardware_uart pico_graphics)
|
||||
|
||||
pico_enable_stdio_usb(${OUTPUT_NAME} 1)
|
||||
|
||||
# create map/bin/hex file etc.
|
||||
pico_add_extra_outputs(${OUTPUT_NAME})
|
|
@ -0,0 +1,97 @@
|
|||
#include <cstdio>
|
||||
#include <math.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include "hardware/gpio.h"
|
||||
#include "hardware/uart.h"
|
||||
#include "drivers/dv_display/dv_display.hpp"
|
||||
#include "libraries/pico_graphics/pico_graphics.hpp"
|
||||
|
||||
using namespace pimoroni;
|
||||
|
||||
#define DISPLAY_WIDTH 360
|
||||
#define DISPLAY_HEIGHT 240
|
||||
|
||||
#define FRAME_WIDTH 720
|
||||
#define FRAME_HEIGHT 480
|
||||
|
||||
#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,
|
||||
};
|
||||
|
||||
void on_uart_rx() {
|
||||
while (uart_is_readable(uart1)) {
|
||||
uint8_t ch = uart_getc(uart1);
|
||||
putc(ch, stdout);
|
||||
}
|
||||
}
|
||||
|
||||
int main() {
|
||||
stdio_init_all();
|
||||
|
||||
// Relay UART RX from the display driver
|
||||
gpio_set_function(5, GPIO_FUNC_UART);
|
||||
uart_init(uart1, 115200);
|
||||
uart_set_hw_flow(uart1, false, false);
|
||||
uart_set_format(uart1, 8, 1, UART_PARITY_NONE);
|
||||
uart_set_fifo_enabled(uart1, false);
|
||||
irq_set_exclusive_handler(UART1_IRQ, on_uart_rx);
|
||||
irq_set_enabled(UART1_IRQ, true);
|
||||
uart_set_irq_enables(uart1, true, false);
|
||||
|
||||
constexpr uint BUTTON_A = 9;
|
||||
gpio_init(BUTTON_A);
|
||||
gpio_set_dir(BUTTON_A, GPIO_IN);
|
||||
gpio_pull_up(BUTTON_A);
|
||||
|
||||
//sleep_ms(5000);
|
||||
|
||||
DVDisplay display;
|
||||
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);
|
||||
graphics.clear();
|
||||
display.flip();
|
||||
|
||||
constexpr int NUM_SPRITES = 32;
|
||||
Point sprite_pos[NUM_SPRITES];
|
||||
Point sprite_dir[NUM_SPRITES];
|
||||
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
sprite_pos[i].x = rand() % DISPLAY_WIDTH;
|
||||
sprite_pos[i].y = rand() % DISPLAY_HEIGHT;
|
||||
sprite_dir[i].x = (rand() & 1) ? 1 : -1;
|
||||
sprite_dir[i].y = (rand() & 1) ? 1 : -1;
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
for (int i = 0; i < 32; ++i) {
|
||||
display.set_sprite(i, 0, sprite_pos[i]);
|
||||
|
||||
sprite_pos[i] += sprite_dir[i];
|
||||
if (sprite_pos[i].x >= DISPLAY_WIDTH || sprite_pos[i].x <= 0) {
|
||||
sprite_dir[i].x = -sprite_dir[i].x;
|
||||
sprite_pos[i].x += sprite_dir[i].x;
|
||||
}
|
||||
if (sprite_pos[i].y >= DISPLAY_HEIGHT || sprite_pos[i].y <= 0) {
|
||||
sprite_dir[i].y = -sprite_dir[i].y;
|
||||
sprite_pos[i].y += sprite_dir[i].y;
|
||||
}
|
||||
}
|
||||
|
||||
sleep_ms(16);
|
||||
}
|
||||
}
|
|
@ -49,7 +49,7 @@ int main() {
|
|||
gpio_set_dir(BUTTON_A, GPIO_IN);
|
||||
gpio_pull_up(BUTTON_A);
|
||||
|
||||
sleep_ms(5000);
|
||||
//sleep_ms(5000);
|
||||
|
||||
DVDisplay display;
|
||||
display.init(DISPLAY_WIDTH, DISPLAY_HEIGHT, DVDisplay::MODE_RGB888, FRAME_WIDTH, FRAME_HEIGHT);
|
||||
|
|
Ładowanie…
Reference in New Issue