Skip to content

Commit

Permalink
Cosmic Unicorn version!
Browse files Browse the repository at this point in the history
This is just a bit of fun, so Not really planning to merge. Note the unicorn version (without rewriting all the drawing completely)
adds quite a bit of code, so this only builds with Clang

to build with Clang, you need >1.5.0/develop of pico-sdk (and pico_extras). -DPICO_COMPILER=pico_arm_clang, and PICO_TOOLCHAIN_PATH pointing at ARM embedded LLVM 14.0.0

You must also specify -DPICO_BOARD=pimoroni_cosmic_unicorn

Note also the unicorn uses 16K of RAM for the frame buffer, and so that is new RAM we didn't have space for, so i have decreased the size of the columns area. You may experience OOM on some levels, or visual distortion

Sleep: Enter / Fire (keyboard L-CTRL & Return)
Vol+: UP/Forward (keyboard Up)
Vol-: Down/Backward (keyboard Down)
Brightness+: Back one menu (keyboard Backspace)
Brightness-: Toggle menu (keyboard Escape)
A: Right (keyboard Right)
B: Left (keyboard Left)
C: Door open (keyboard Space)
D: Strafe (keyboard Alt)

You can start a game with Enter/Enter/Enter
  • Loading branch information
kilograham committed Mar 19, 2023
1 parent baf678b commit 6d1deb1
Show file tree
Hide file tree
Showing 12 changed files with 933 additions and 10 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ if (PICO_SDK_PATH)
#set(PICO_TINYUSB_PATH ${CMAKE_CURRENT_LIST_DIR}/3rdparty/tinyusb)
# this only affects device builds device, but we want to use zone for malloc in this case so we don't have two separate elastic spaces and can fit more in
set(SKIP_PICO_MALLOC 1)
list(PREPEND PICO_BOARD_HEADER_DIRS ${CMAKE_CURRENT_LIST_DIR}/src/pico) # for our custom (for now) unicorn header
pico_sdk_init()
if (PICO_ON_DEVICE AND NOT CMAKE_BUILD_TYPE STREQUAL "MinSizeRel")
message(WARNING "You should do a MinSizeRel build when targeting the RP2040
Expand Down
25 changes: 21 additions & 4 deletions src/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -497,6 +497,15 @@ function(add_doom_tiny SUFFIX RENDER_LIB)
target_compile_options(doom_tiny${SUFFIX} PRIVATE
-Wno-format-truncation)
endif()
# temp hack
if (NOT SUFFIX STREQUAL "_unicorn")
target_compile_definitions(doom_tiny${SUFFIX} PRIVATE
# for vgaboard
PICO_DEFAULT_I2C=1
PICO_DEFAULT_I2C_SDA_PIN=18
PICO_DEFAULT_I2C_SCL_PIN=19
)
endif()
target_compile_definitions(doom_tiny${SUFFIX} PRIVATE
DOOM_TINY=1
EMU8950_SLOT_RENDER=1
Expand All @@ -517,10 +526,6 @@ function(add_doom_tiny SUFFIX RENDER_LIB)

NO_USE_NET=1 # standard networking
USE_PICO_NET=1
# for vgaboard
PICO_DEFAULT_I2C=1
PICO_DEFAULT_I2C_SDA_PIN=18
PICO_DEFAULT_I2C_SCL_PIN=19

#NO_USE_LOAD=1
#NO_USE_SAVE=1
Expand Down Expand Up @@ -670,6 +675,18 @@ if (PICO_SDK)
TINY_WAD_ADDR=0x10048000
)
endif()

add_doom_tiny("_unicorn" render_newhope)
target_compile_definitions(doom_tiny_unicorn PRIVATE
TINY_WAD_ADDR=0x10040000
NO_USE_UART=1
RENDER_COL_MAX=3000 # just try to make a little more space (don't think any visual artifacts will be the end of the world)
)
target_link_libraries(doom_tiny_unicorn PRIVATE tiny_settings)
pico_enable_stdio_uart(doom_tiny_unicorn 0)
# did support this, nut no longer room
# pico_enable_stdio_usb(doom_tiny_unicorn 1)

endif()


2 changes: 2 additions & 0 deletions src/d_loop.c
Original file line number Diff line number Diff line change
Expand Up @@ -702,11 +702,13 @@ void TryRunTics(void) {
local_playeringame[j] = set->cmds[j].ingame;
lplayer_count += local_playeringame[j];
}
#if USE_PICO_NET
if (net_client_connected && lplayer_count < 2) {
net_client_connected = false;
piconet_stop();
}
#endif
#endif

//#define DUMP_TICS PICO_BUILD
#if DUMP_TICS
Expand Down
2 changes: 2 additions & 0 deletions src/doom/m_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -1204,10 +1204,12 @@ void M_DrawOptions(void)
W_CacheLumpName(DEH_String(detailNames[detailLevel]),
PU_CACHE));
#else
#if USE_PICO_NET
// "Game" for Network
V_DrawPatchDirect(OptionsDef.x + 105, OptionsDef.y + LINEHEIGHT * networkgame,
VPATCH_HANDLE(VPATCH_NAME(M_GAME)));

#endif
#endif

V_DrawPatchDirect(OptionsDef.x + 120, OptionsDef.y + LINEHEIGHT * messages,
Expand Down
12 changes: 12 additions & 0 deletions src/pd_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,7 +317,9 @@ const char *type_name(pd_column column) {
#endif
}

#ifndef RENDER_COL_MAX
#define RENDER_COL_MAX 3600
#endif
static uint8_t __aligned(4) list_buffer[RENDER_COL_MAX * sizeof(pd_column) + 64*64]; // extra 64*64 is for one flat
static uint8_t *last_list_buffer_limit = list_buffer + sizeof(list_buffer);
//static_assert(text_font_cpy > list_buffer, "");
Expand Down Expand Up @@ -2714,6 +2716,16 @@ void pd_end_frame(int wipe_start) {
}
}
}
#ifdef PIMORONI_COSMIC_UNICORN
if (wipestate != WIPESTATE_NONE) {
// little hack to stop wipe happening too fast
static absolute_time_t frame_time;
while (!time_reached(frame_time)) {
SafeUpdateSound();
}
frame_time = make_timeout_time_ms(20);
}
#endif
I_VideoBuffer = render_frame_buffer;
if (wipestate) list_buffer_limit -= 4096;
// we need to use the lower limit of this frame and the last since the final wipe frame may still be using the data
Expand Down
4 changes: 3 additions & 1 deletion src/pico/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -57,4 +57,6 @@ target_link_libraries(common_pico INTERFACE pico_stdlib pico_multicore pico_scan
add_library(pico_cd INTERFACE)
if (TARGET tinyusb_host)
target_link_libraries(pico_cd INTERFACE tinyusb_host)
endif()
endif()

pico_generate_pio_header(common_pico ${CMAKE_CURRENT_LIST_DIR}/cosmic_unicorn.pio)
80 changes: 80 additions & 0 deletions src/pico/cosmic_unicorn.pio
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
.program cosmic_unicorn
.side_set 1 opt

; out pins:
;
; - 3: row select bit 0
; - 4: row select bit 1
; - 5: row select bit 2
; - 6: row select bit 3

; set pins:
;
; - 0: column data (base)
; - 1: column latch
; - 2: column blank

; sideset pin:
;
; - 0: column clock

; for each row:
; for each bcd frame:
; 0: 00111111 // row pixel count (minus one)
; 1 - 64: xxxxxbgr, xxxxxbgr, xxxxxbgr, ... // pixel data
; 65 - 67: xxxxxxxx, xxxxxxxx, xxxxxxxx // dummy bytes to dword align
; 68: xxxxrrrr // row select bits
; 69 - 71: tttttttt, tttttttt, tttttttt // bcd tick count (0-65536)
;
; .. and back to the start


.wrap_target

; loop over row pixels
out y, 8 ; get row pixel count (minus 1 because test is pre decrement)
pixels:

; red bit
out x, 1 side 0 [1] ; pull in blue bit from OSR into register x, clear clock
set pins, 0b100 ; clear data bit, blank high
jmp !x endb ; if bit was zero jump
set pins, 0b101 ; set data bit, blank high
endb:
nop side 1 [2] ; clock in bit

; green bit
out x, 1 side 0 [1] ; pull in green bit from OSR into register X, clear clock
set pins, 0b100 ; clear data bit, blank high
jmp !x endg ; if bit was zero jump
set pins, 0b101 ; set data bit, blank high
endg:
nop side 1 [2] ; clock in bit

; blue bit
out x, 1 side 0 [1] ; pull in red bit from OSR into register X, clear clock
set pins, 0b100 ; clear data bit, blank high
jmp !x endr ; if bit was zero jump
set pins, 0b101 ; set data bit, blank high
endr:
out null, 5 side 1 [2] ; clock in bit

;out null, 5 side 0 ; discard the five dummy bits for this pixel

jmp y-- pixels

out null, 24 ; discard dummy bytes

out pins, 8 ; output row select

set pins, 0b110 [5] ; latch high, blank high
set pins, 0b000 ; blank low (enable output)

; loop over bcd delay period
out y, 24 ; get bcd delay counter value
bcd_delay:
jmp y-- bcd_delay

set pins 0b100 ; blank high (disable output)

.wrap
37 changes: 36 additions & 1 deletion src/pico/i_input.c
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@
#include "m_config.h"
#include "hardware/uart.h"
#include <stdlib.h>

#ifdef PIMORONI_COSMIC_UNICORN
#include "hardware/gpio.h"
#endif
#if USB_SUPPORT
#include "pico/binary_info.h"
#include "tusb.h"
Expand Down Expand Up @@ -528,8 +532,39 @@ void I_GetEvent() {
#endif
return I_GetEventTimeout(50);
}

#ifdef PIMORONI_COSMIC_UNICORN
static void do_key(uint diff, uint now, uint bit, int scancode) {
bit = 1u << bit;
if (diff & bit) {
if (now & bit) {
pico_key_up(scancode, 0, 0);
} else {
pico_key_down(scancode, 0, 0);
}
}
}
#endif
void I_GetEventTimeout(int key_timeout) {
#ifdef PIMORONI_COSMIC_UNICORN
#define COSMIC_SWITCHES ((1u<<SWITCH_A) | (1u<<SWITCH_B) | (1u<<SWITCH_C) | (1u<<SWITCH_D) | (1u<<SWITCH_SLEEP) | (1u<<SWITCH_VOLUME_UP) | (1u<<SWITCH_VOLUME_DOWN) | (1u<<SWITCH_BRIGHTNESS_UP) | (1u<<SWITCH_BRIGHTNESS_DOWN))
static uint last_gpio_state = COSMIC_SWITCHES;
uint gpio_state = gpio_get_all() & COSMIC_SWITCHES;
uint diff = last_gpio_state ^ gpio_state;
if (diff) {
do_key(diff, gpio_state, SWITCH_SLEEP, SDL_SCANCODE_LCTRL);
do_key(diff, gpio_state, SWITCH_SLEEP, 40); // ENTER (do enter as well for menus)
do_key(diff, gpio_state, SWITCH_VOLUME_UP, 82); // UP
do_key(diff, gpio_state, SWITCH_VOLUME_DOWN, 81); // DOWN
do_key(diff, gpio_state, SWITCH_BRIGHTNESS_UP, 42); // BACKSPACE
do_key(diff, gpio_state, SWITCH_BRIGHTNESS_DOWN, 41); // ESC
do_key(diff, gpio_state, SWITCH_B, 80); // LEFT
do_key(diff, gpio_state, SWITCH_A, 79); // RIGHT
do_key(diff, gpio_state, SWITCH_C, 44); // SPACE
do_key(diff, gpio_state, SWITCH_D, SDL_SCANCODE_LALT); // ALT for strage
// do_key(diff, gpio_state, SWITCH_D, 43); // tab for map
}
last_gpio_state = gpio_state;
#endif
#if PICO_ON_DEVICE && !NO_USE_UART
if (uart_is_readable(uart_default)) {
char c = uart_getc(uart_default);
Expand Down
3 changes: 3 additions & 0 deletions src/pico/i_picosound.c
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,9 @@ static boolean I_Pico_InitSound(boolean _use_sfx_prefix)
// todo this will likely need adjustment - maybe with IRQs/double buffer & pull from audio we can make it quite small
producer_pool = audio_new_producer_pool(&producer_format, 2, 1024); // todo correct size

#ifdef PIMORONI_COSMIC_UNICORN
gpio_init(MUTE); gpio_set_dir(MUTE, GPIO_OUT); gpio_put(MUTE, true); // why oh why was there no sound before?
#endif
struct audio_i2s_config config = {
.data_pin = PICO_AUDIO_I2S_DATA_PIN,
.clock_pin_base = PICO_AUDIO_I2S_CLOCK_PIN_BASE,
Expand Down
Loading

0 comments on commit 6d1deb1

Please sign in to comment.