mirror of
https://github.com/portapack-mayhem/mayhem-firmware.git
synced 2026-08-19 14:14:04 +00:00
Merge 'upstream/master' - At least it builds...
This commit is contained in:
+31
-34
@@ -52,84 +52,81 @@ struct Config {
|
||||
uint32_t cr;
|
||||
};
|
||||
|
||||
template<uint32_t BaseAddress>
|
||||
class ADC {
|
||||
public:
|
||||
constexpr ADC(
|
||||
LPC_ADCx_Type* adcp
|
||||
) : adcp(adcp)
|
||||
{
|
||||
static void power_up(const Config config) {
|
||||
adcp().CR = config.cr;
|
||||
}
|
||||
|
||||
void power_up(const Config config) const {
|
||||
adcp->CR = config.cr;
|
||||
}
|
||||
|
||||
void clock_enable() const {
|
||||
if( adcp == LPC_ADC0 ) {
|
||||
static void clock_enable() {
|
||||
if( &adcp() == LPC_ADC0 ) {
|
||||
LPC_CCU1->CLK_APB3_ADC0_CFG.AUTO = 1;
|
||||
LPC_CCU1->CLK_APB3_ADC0_CFG.RUN = 1;
|
||||
}
|
||||
if( adcp == LPC_ADC1 ) {
|
||||
if( &adcp() == LPC_ADC1 ) {
|
||||
LPC_CCU1->CLK_APB3_ADC1_CFG.AUTO = 1;
|
||||
LPC_CCU1->CLK_APB3_ADC1_CFG.RUN = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void clock_disable() const {
|
||||
if( adcp == LPC_ADC0 ) {
|
||||
static void clock_disable() {
|
||||
if( &adcp() == LPC_ADC0 ) {
|
||||
LPC_CCU1->CLK_APB3_ADC0_CFG.RUN = 0;
|
||||
}
|
||||
if( adcp == LPC_ADC1 ) {
|
||||
if( &adcp() == LPC_ADC1 ) {
|
||||
LPC_CCU1->CLK_APB3_ADC1_CFG.RUN = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void disable() const {
|
||||
adcp->INTEN = 0;
|
||||
adcp->CR = 0;
|
||||
static void disable() {
|
||||
adcp().INTEN = 0;
|
||||
adcp().CR = 0;
|
||||
|
||||
clock_disable();
|
||||
}
|
||||
|
||||
void interrupts_disable() const {
|
||||
adcp->INTEN = 0;
|
||||
static void interrupts_disable() {
|
||||
adcp().INTEN = 0;
|
||||
}
|
||||
|
||||
void interrupts_enable(const uint32_t mask) const {
|
||||
adcp->INTEN = mask;
|
||||
static void interrupts_enable(const uint32_t mask) {
|
||||
adcp().INTEN = mask;
|
||||
}
|
||||
|
||||
void start_burst() const {
|
||||
adcp->CR |= (1U << 16);
|
||||
static void start_burst() {
|
||||
adcp().CR |= (1U << 16);
|
||||
}
|
||||
|
||||
void start_once() const {
|
||||
adcp->CR |= (1U << 24);
|
||||
static void start_once() {
|
||||
adcp().CR |= (1U << 24);
|
||||
}
|
||||
|
||||
void start_once(size_t n) const {
|
||||
uint32_t cr = adcp->CR;
|
||||
static void start_once(size_t n) {
|
||||
uint32_t cr = adcp().CR;
|
||||
cr &= ~(0xffU);
|
||||
cr |= (1 << 24) | (1 << n);
|
||||
adcp->CR = cr;
|
||||
adcp().CR = cr;
|
||||
}
|
||||
|
||||
void stop_burst() const {
|
||||
adcp->CR &= ~(1U << 16);
|
||||
static void stop_burst() {
|
||||
adcp().CR &= ~(1U << 16);
|
||||
}
|
||||
|
||||
uint32_t convert(size_t n) const {
|
||||
static uint32_t convert(size_t n) {
|
||||
start_once(n);
|
||||
while(true) {
|
||||
const uint32_t data = adcp->DR[n];
|
||||
const uint32_t data = adcp().DR[n];
|
||||
if( (data >> 31) & 1 ) {
|
||||
return (data >> 6) & 0x3ff;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
LPC_ADCx_Type* const adcp;
|
||||
static LPC_ADCx_Type& adcp() {
|
||||
return *reinterpret_cast<LPC_ADCx_Type*>(BaseAddress);
|
||||
}
|
||||
};
|
||||
|
||||
} /* namespace adc */
|
||||
|
||||
@@ -32,21 +32,13 @@
|
||||
namespace baseband {
|
||||
namespace ais {
|
||||
|
||||
// RRC length should be about 4 x the symbol length (4T) to do a good job of
|
||||
// cleaning up ISI.
|
||||
|
||||
// Translate+RRC filter
|
||||
// sample=38.4k, deviation=2400, b=0.5, symbol=9600
|
||||
// Length: 16 taps, 4 symbols, 1 cycles of sinusoid
|
||||
constexpr std::array<std::complex<float>, 16> rrc_taps_38k4_4t_p { {
|
||||
{ 1.0619794019e-02f, 0.0000000000e+00f }, { 3.5758705854e-03f, 1.4811740938e-03f },
|
||||
{ -1.3274742629e-02f, -1.3274742629e-02f }, { -1.5018657262e-02f, -3.6258246051e-02f },
|
||||
{ 0.0000000000e+00f, -2.6549484581e-02f }, { -1.5018657262e-02f, 3.6258246051e-02f },
|
||||
{ -1.0237997393e-01f, 1.0237997393e-01f }, { -2.2527985355e-01f, 9.3313970669e-02f },
|
||||
{ -2.8440842032e-01f, 0.0000000000e+00f }, { -2.2527985355e-01f, -9.3313970669e-02f },
|
||||
{ -1.0237997393e-01f, -1.0237997393e-01f }, { -1.5018657262e-02f, -3.6258246051e-02f },
|
||||
{ 0.0000000000e+00f, 2.6549484581e-02f }, { -1.5018657262e-02f, 3.6258246051e-02f },
|
||||
{ -1.3274742629e-02f, 1.3274742629e-02f }, { 3.5758705854e-03f, -1.4811740938e-03f },
|
||||
// Translate+Rectangular window filter
|
||||
// sample=38.4k, deviation=2400, symbol=9600
|
||||
// Length: 4 taps, 1 symbol, 1/4 cycle of sinusoid
|
||||
// Gain: 1.0 (sinusoid / len(taps))
|
||||
constexpr std::array<std::complex<float>, 4> square_taps_38k4_1t_p { {
|
||||
{ 0.25000000f, 0.00000000f }, { 0.23096988f, 0.09567086f },
|
||||
{ 0.17677670f, 0.17677670f }, { 0.09567086f, 0.23096988f },
|
||||
} };
|
||||
|
||||
} /* namespace ais */
|
||||
|
||||
@@ -62,7 +62,7 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
std::bitset<1408> data;
|
||||
std::bitset<1408> data { };
|
||||
Timestamp timestamp_ { };
|
||||
size_t count { 0 };
|
||||
};
|
||||
|
||||
@@ -184,13 +184,13 @@ constexpr Slice slice_order[] {
|
||||
};
|
||||
|
||||
constexpr uint32_t gpio_outreg(const Direction direction) {
|
||||
return ((direction == Direction::Transmit) ? (1U << 11) : 0U) | (1U << 10);
|
||||
return ((direction == Direction::Transmit) ? (1U << PIN_DIRECTION) : 0U) | (1U << PIN_DISABLE);
|
||||
}
|
||||
|
||||
constexpr uint32_t gpio_oenreg(const Direction direction) {
|
||||
return
|
||||
(0U << PIN_DECIM2)
|
||||
| (1U << PIN_DECIM1)
|
||||
| (0U << PIN_DECIM1)
|
||||
| (0U << PIN_DECIM0)
|
||||
| (0U << PIN_INVERT)
|
||||
| (1U << PIN_DIRECTION)
|
||||
@@ -282,7 +282,7 @@ constexpr CLK_CAPTURE_MODE data_clk_capture_mode(
|
||||
) {
|
||||
return (direction == Direction::Transmit)
|
||||
? CLK_CAPTURE_MODE::RISING_CLOCK_EDGE
|
||||
: CLK_CAPTURE_MODE::FALLING_CLOCK_EDGE
|
||||
: CLK_CAPTURE_MODE::RISING_CLOCK_EDGE
|
||||
;
|
||||
}
|
||||
|
||||
@@ -298,8 +298,12 @@ constexpr P_OUT_CFG data_p_out_cfg(
|
||||
void SGPIO::configure(const Direction direction) {
|
||||
disable_all_slice_counters();
|
||||
|
||||
// Set data pins as input, temporarily.
|
||||
LPC_SGPIO->GPIO_OENREG = gpio_oenreg(Direction::Receive);
|
||||
|
||||
// Now that data pins are inputs, safe to change CPLD direction.
|
||||
LPC_SGPIO->GPIO_OUTREG = gpio_outreg(direction);
|
||||
LPC_SGPIO->GPIO_OENREG = gpio_oenreg(direction);
|
||||
|
||||
LPC_SGPIO->OUT_MUX_CFG[ 8] = out_mux_cfg(P_OUT_CFG::DOUT_DOUTM1, P_OE_CFG::GPIO_OE);
|
||||
LPC_SGPIO->OUT_MUX_CFG[ 9] = out_mux_cfg(P_OUT_CFG::DOUT_DOUTM1, P_OE_CFG::GPIO_OE);
|
||||
LPC_SGPIO->OUT_MUX_CFG[10] = out_mux_cfg(P_OUT_CFG::GPIO_OUT, P_OE_CFG::GPIO_OE);
|
||||
@@ -314,6 +318,9 @@ void SGPIO::configure(const Direction direction) {
|
||||
LPC_SGPIO->OUT_MUX_CFG[i] = data_out_mux_cfg;
|
||||
}
|
||||
|
||||
// Now that output enable sources are set, enable data bus in correct direction.
|
||||
LPC_SGPIO->GPIO_OENREG = gpio_oenreg(direction);
|
||||
|
||||
const auto slice_gpdma = Slice::H;
|
||||
|
||||
const size_t slice_count = slice_mode_multislice ? 8 : 1;
|
||||
|
||||
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (C) 2014 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "buffer.hpp"
|
||||
|
||||
#if defined(LPC43XX_M4)
|
||||
#include "lpc43xx_m4.h"
|
||||
|
||||
Timestamp Timestamp::now() {
|
||||
// Code stolen from LPC43xx rtc_lld.c
|
||||
Timestamp timestamp;
|
||||
do {
|
||||
timestamp.tv_time = LPC_RTC->CTIME0;
|
||||
timestamp.tv_date = LPC_RTC->CTIME1;
|
||||
} while( (timestamp.tv_time != LPC_RTC->CTIME0) || (timestamp.tv_date != LPC_RTC->CTIME1) );
|
||||
return timestamp;
|
||||
}
|
||||
#endif
|
||||
@@ -33,21 +33,11 @@
|
||||
* a knot to tackle at the moment, though...
|
||||
*/
|
||||
#if defined(LPC43XX_M4)
|
||||
#include "lpc43xx_m4.h"
|
||||
|
||||
struct Timestamp {
|
||||
uint32_t tv_date { 0 };
|
||||
uint32_t tv_time { 0 };
|
||||
|
||||
static Timestamp now() {
|
||||
// Code stolen from LPC43xx rtc_lld.c
|
||||
Timestamp timestamp;
|
||||
do {
|
||||
timestamp.tv_time = LPC_RTC->CTIME0;
|
||||
timestamp.tv_date = LPC_RTC->CTIME1;
|
||||
} while( (timestamp.tv_time != LPC_RTC->CTIME0) || (timestamp.tv_date != LPC_RTC->CTIME1) );
|
||||
return timestamp;
|
||||
}
|
||||
static Timestamp now();
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "buffer_exchange.hpp"
|
||||
|
||||
BufferExchange* BufferExchange::obj { nullptr };
|
||||
|
||||
BufferExchange::BufferExchange(
|
||||
CaptureConfig* const config
|
||||
) : config { config }
|
||||
{
|
||||
obj = this;
|
||||
fifo_buffers_for_baseband = config->fifo_buffers_empty;
|
||||
fifo_buffers_for_application = config->fifo_buffers_full;
|
||||
}
|
||||
|
||||
BufferExchange::~BufferExchange() {
|
||||
obj = nullptr;
|
||||
fifo_buffers_for_baseband = nullptr;
|
||||
fifo_buffers_for_application = nullptr;
|
||||
}
|
||||
|
||||
StreamBuffer* BufferExchange::get(FIFO<StreamBuffer*>* fifo) {
|
||||
while(true) {
|
||||
StreamBuffer* p { nullptr };
|
||||
fifo->out(p);
|
||||
if( p ) {
|
||||
return p;
|
||||
}
|
||||
|
||||
chSysLock();
|
||||
thread = chThdSelf();
|
||||
chSchGoSleepS(THD_STATE_SUSPENDED);
|
||||
chSysUnlock();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (C) 2016 Jared Boone, ShareBrained Technology, Inc.
|
||||
*
|
||||
* This file is part of PortaPack.
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2, or (at your option)
|
||||
* any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; see the file COPYING. If not, write to
|
||||
* the Free Software Foundation, Inc., 51 Franklin Street,
|
||||
* Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "ch.h"
|
||||
|
||||
#include "message.hpp"
|
||||
#include "fifo.hpp"
|
||||
#include "io.hpp"
|
||||
|
||||
class BufferExchange {
|
||||
public:
|
||||
BufferExchange(CaptureConfig* const config);
|
||||
~BufferExchange();
|
||||
|
||||
BufferExchange(const BufferExchange&) = delete;
|
||||
BufferExchange(BufferExchange&&) = delete;
|
||||
BufferExchange& operator=(const BufferExchange&) = delete;
|
||||
BufferExchange& operator=(BufferExchange&&) = delete;
|
||||
|
||||
#if defined(LPC43XX_M0)
|
||||
bool empty() const {
|
||||
return fifo_buffers_for_application->is_empty();
|
||||
}
|
||||
|
||||
StreamBuffer* get() {
|
||||
return get(fifo_buffers_for_application);
|
||||
}
|
||||
|
||||
bool put(StreamBuffer* const p) {
|
||||
return fifo_buffers_for_baseband->in(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(LPC43XX_M4)
|
||||
bool empty() const {
|
||||
return fifo_buffers_for_baseband->is_empty();
|
||||
}
|
||||
|
||||
StreamBuffer* get() {
|
||||
return get(fifo_buffers_for_baseband);
|
||||
}
|
||||
|
||||
bool put(StreamBuffer* const p) {
|
||||
return fifo_buffers_for_application->in(p);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void handle_isr() {
|
||||
if( obj ) {
|
||||
obj->check_fifo_isr();
|
||||
}
|
||||
}
|
||||
|
||||
private:
|
||||
CaptureConfig* const config;
|
||||
FIFO<StreamBuffer*>* fifo_buffers_for_baseband { nullptr };
|
||||
FIFO<StreamBuffer*>* fifo_buffers_for_application { nullptr };
|
||||
Thread* thread { nullptr };
|
||||
static BufferExchange* obj;
|
||||
|
||||
void check_fifo_isr() {
|
||||
if( !empty() ) {
|
||||
wakeup_isr();
|
||||
}
|
||||
}
|
||||
|
||||
void wakeup_isr() {
|
||||
auto thread_tmp = thread;
|
||||
if( thread_tmp ) {
|
||||
thread = nullptr;
|
||||
chSchReadyI(thread_tmp);
|
||||
}
|
||||
}
|
||||
|
||||
StreamBuffer* get(FIFO<StreamBuffer*>* fifo);
|
||||
};
|
||||
@@ -41,6 +41,14 @@ void operator delete[](void* p) noexcept {
|
||||
chHeapFree(p);
|
||||
}
|
||||
|
||||
void operator delete(void* ptr, std::size_t) noexcept {
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
void operator delete[](void* ptr, std::size_t) noexcept {
|
||||
::operator delete(ptr);
|
||||
}
|
||||
|
||||
extern uint8_t __heap_base__[];
|
||||
extern uint8_t __heap_end__[];
|
||||
|
||||
|
||||
@@ -30,6 +30,8 @@ void* operator new(size_t size);
|
||||
void* operator new[](size_t size);
|
||||
void operator delete(void* p);
|
||||
void operator delete[](void* p);
|
||||
void operator delete(void* ptr, std::size_t);
|
||||
void operator delete[](void* ptr, std::size_t);
|
||||
|
||||
namespace chibios {
|
||||
|
||||
|
||||
@@ -35,14 +35,14 @@ struct PinConfig {
|
||||
const uint32_t input;
|
||||
const uint32_t ifilt;
|
||||
|
||||
constexpr operator uint16_t() {
|
||||
constexpr operator uint16_t() const {
|
||||
return
|
||||
((~ifilt) << 7)
|
||||
| (input << 6)
|
||||
| (fast << 5)
|
||||
| ((~pu) << 4)
|
||||
| (pd << 3)
|
||||
| (mode << 0);
|
||||
(((~ifilt) & 1) << 7)
|
||||
| ((input & 1) << 6)
|
||||
| ((fast & 1) << 5)
|
||||
| (((~pu) & 1) << 4)
|
||||
| ((pd & 1) << 3)
|
||||
| ((mode & 7) << 0);
|
||||
}
|
||||
/*
|
||||
constexpr operator uint32_t() {
|
||||
|
||||
@@ -71,12 +71,7 @@ constexpr GPIO gpio_max2837_txenable = gpio[GPIO2_4];
|
||||
|
||||
constexpr GPIO gpio_max5864_select = gpio[GPIO2_7];
|
||||
|
||||
constexpr std::array<GPIO, 3> gpios_baseband_decimation {
|
||||
gpio[GPIO5_12],
|
||||
gpio[GPIO5_13],
|
||||
gpio[GPIO5_14]
|
||||
};
|
||||
constexpr GPIO gpio_baseband_q_invert = gpio[GPIO0_13];
|
||||
constexpr GPIO gpio_baseband_invert = gpio[GPIO0_13];
|
||||
|
||||
constexpr GPIO gpio_cpld_tdo = gpio[GPIO5_18];
|
||||
constexpr GPIO gpio_cpld_tck = gpio[GPIO3_0];
|
||||
|
||||
@@ -67,11 +67,11 @@ constexpr size_t clock_generator_output_mcu_clkin = 7;
|
||||
|
||||
/* ADC0 */
|
||||
|
||||
constexpr adc::ADC adc0 { LPC_ADC0 };
|
||||
using adc0 = adc::ADC<LPC_ADC0_BASE>;
|
||||
|
||||
/* ADC1 */
|
||||
|
||||
constexpr adc::ADC adc1 { LPC_ADC1 };
|
||||
using adc1 = adc::ADC<LPC_ADC1_BASE>;
|
||||
|
||||
void reset();
|
||||
|
||||
|
||||
@@ -46,15 +46,15 @@ struct I2CClockConfig {
|
||||
return 1e9 / f;
|
||||
}
|
||||
|
||||
constexpr uint32_t i2c_period_count() {
|
||||
constexpr uint32_t i2c_period_count() const {
|
||||
return period_ns(bus_f) / period_ns(clock_source_f) + 0.5f;
|
||||
}
|
||||
|
||||
constexpr uint32_t i2c_high_count() {
|
||||
constexpr uint32_t i2c_high_count() const {
|
||||
return high_period_ns / period_ns(clock_source_f) + 0.5f;
|
||||
}
|
||||
|
||||
constexpr uint32_t i2c_low_count() {
|
||||
constexpr uint32_t i2c_low_count() const {
|
||||
return i2c_period_count() - i2c_high_count();
|
||||
}
|
||||
};
|
||||
|
||||
+24
-22
@@ -155,8 +155,6 @@ struct ConfigDMA {
|
||||
template<uint32_t BaseAddress>
|
||||
class I2S {
|
||||
public:
|
||||
static constexpr LPC_I2S_Type* Peripheral = reinterpret_cast<LPC_I2S_Type*>(BaseAddress);
|
||||
|
||||
static void configure(
|
||||
const ConfigTX& config_tx,
|
||||
const ConfigRX& config_rx
|
||||
@@ -167,28 +165,28 @@ public:
|
||||
/* NOTE: Documentation of CREG6 is quite confusing. Refer to "I2S clocking and
|
||||
* pin connections" and other I2S diagrams for more clarity.
|
||||
*/
|
||||
if( Peripheral == LPC_I2S0 ) {
|
||||
if( &p() == LPC_I2S0 ) {
|
||||
LPC_CREG->CREG6 |=
|
||||
(1U << 12)
|
||||
| (1U << 13)
|
||||
;
|
||||
}
|
||||
if( Peripheral == LPC_I2S1 ) {
|
||||
if( &p() == LPC_I2S1 ) {
|
||||
LPC_CREG->CREG6 |=
|
||||
(1U << 14)
|
||||
| (1U << 15)
|
||||
;
|
||||
}
|
||||
|
||||
Peripheral->DAO = config_tx.dao;
|
||||
Peripheral->TXRATE = config_tx.txrate;
|
||||
Peripheral->TXBITRATE = config_tx.txbitrate;
|
||||
Peripheral->TXMODE = config_tx.txmode;
|
||||
p().DAO = config_tx.dao;
|
||||
p().TXRATE = config_tx.txrate;
|
||||
p().TXBITRATE = config_tx.txbitrate;
|
||||
p().TXMODE = config_tx.txmode;
|
||||
|
||||
Peripheral->DAI = config_rx.dai;
|
||||
Peripheral->RXRATE = config_rx.rxrate;
|
||||
Peripheral->RXBITRATE = config_rx.rxbitrate;
|
||||
Peripheral->RXMODE = config_rx.rxmode;
|
||||
p().DAI = config_rx.dai;
|
||||
p().RXRATE = config_rx.rxrate;
|
||||
p().RXBITRATE = config_rx.rxbitrate;
|
||||
p().RXMODE = config_rx.rxmode;
|
||||
}
|
||||
|
||||
static void configure(
|
||||
@@ -198,38 +196,42 @@ public:
|
||||
) {
|
||||
configure(config_tx, config_rx);
|
||||
|
||||
Peripheral->DMA1 = config_dma.dma1;
|
||||
Peripheral->DMA2 = config_dma.dma2;
|
||||
p().DMA1 = config_dma.dma1;
|
||||
p().DMA2 = config_dma.dma2;
|
||||
}
|
||||
|
||||
static void rx_start() {
|
||||
Peripheral->DAI &= ~(1U << 3);
|
||||
p().DAI &= ~(1U << 3);
|
||||
}
|
||||
|
||||
static void rx_stop() {
|
||||
Peripheral->DAI |= (1U << 3);
|
||||
p().DAI |= (1U << 3);
|
||||
}
|
||||
|
||||
static void tx_start() {
|
||||
Peripheral->DAO &= ~(1U << 3);
|
||||
p().DAO &= ~(1U << 3);
|
||||
}
|
||||
|
||||
static void tx_stop() {
|
||||
Peripheral->DAO |= (1U << 3);
|
||||
p().DAO |= (1U << 3);
|
||||
}
|
||||
|
||||
static void tx_mute() {
|
||||
Peripheral->DAO |= (1U << 15);
|
||||
p().DAO |= (1U << 15);
|
||||
}
|
||||
|
||||
static void tx_unmute() {
|
||||
Peripheral->DAO &= ~(1U << 15);
|
||||
p().DAO &= ~(1U << 15);
|
||||
}
|
||||
|
||||
private:
|
||||
static void reset() {
|
||||
Peripheral->DAO |= (1U << 4);
|
||||
Peripheral->DAI |= (1U << 4);
|
||||
p().DAO |= (1U << 4);
|
||||
p().DAI |= (1U << 4);
|
||||
}
|
||||
|
||||
static LPC_I2S_Type& p() {
|
||||
return *reinterpret_cast<LPC_I2S_Type*>(BaseAddress);
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -198,8 +198,8 @@ void lcd_start_ram_write(
|
||||
const ui::Point p,
|
||||
const ui::Size s
|
||||
) {
|
||||
lcd_caset(p.x, p.x + s.w - 1);
|
||||
lcd_paset(p.y, p.y + s.h - 1);
|
||||
lcd_caset(p.x(), p.x() + s.width() - 1);
|
||||
lcd_paset(p.y(), p.y() + s.height() - 1);
|
||||
lcd_ramwr_start();
|
||||
}
|
||||
|
||||
@@ -207,21 +207,21 @@ void lcd_start_ram_read(
|
||||
const ui::Point p,
|
||||
const ui::Size s
|
||||
) {
|
||||
lcd_caset(p.x, p.x + s.w - 1);
|
||||
lcd_paset(p.y, p.y + s.h - 1);
|
||||
lcd_caset(p.x(), p.x() + s.width() - 1);
|
||||
lcd_paset(p.y(), p.y() + s.height() - 1);
|
||||
lcd_ramrd_start();
|
||||
}
|
||||
|
||||
void lcd_start_ram_write(
|
||||
const ui::Rect& r
|
||||
) {
|
||||
lcd_start_ram_write(r.pos, r.size);
|
||||
lcd_start_ram_write(r.location(), r.size());
|
||||
}
|
||||
|
||||
void lcd_start_ram_read(
|
||||
const ui::Rect& r
|
||||
) {
|
||||
lcd_start_ram_read(r.pos, r.size);
|
||||
lcd_start_ram_read(r.location(), r.size());
|
||||
}
|
||||
|
||||
void lcd_vertical_scrolling_definition(
|
||||
@@ -274,7 +274,7 @@ void ILI9341::fill_rectangle(ui::Rect r, const ui::Color c) {
|
||||
const auto r_clipped = r.intersect(screen_rect());
|
||||
if( !r_clipped.is_empty() ) {
|
||||
lcd_start_ram_write(r_clipped);
|
||||
size_t count = r_clipped.size.w * r_clipped.size.h;
|
||||
size_t count = r_clipped.width() * r_clipped.height();
|
||||
io.lcd_write_pixels(c, count);
|
||||
}
|
||||
}
|
||||
@@ -286,7 +286,7 @@ void ILI9341::render_line(const ui::Point p, const uint8_t count, const ui::Colo
|
||||
|
||||
void ILI9341::render_box(const ui::Point p, const ui::Size s, const ui::Color* line_buffer) {
|
||||
lcd_start_ram_write(p, s);
|
||||
io.lcd_write_pixels(line_buffer, s.w * s.h);
|
||||
io.lcd_write_pixels(line_buffer, s.width() * s.height());
|
||||
}
|
||||
|
||||
// RLE_4 BMP loader (delta not implemented)
|
||||
@@ -328,7 +328,7 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
|
||||
} else {
|
||||
by = bitmap[data_idx++];
|
||||
if (by == 0) {
|
||||
render_line({p.x, p.y + py}, bmp_header->width, line_buffer);
|
||||
render_line({p.x(), p.y() + py}, bmp_header->width, line_buffer);
|
||||
py--;
|
||||
px = 0;
|
||||
} else if (by == 1) {
|
||||
@@ -354,10 +354,10 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
|
||||
count = by >> 1;
|
||||
by = bitmap[data_idx++];
|
||||
for (c = 0; c < count; c++) {
|
||||
if ((by >> 4) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x + px), static_cast<ui::Coord>(p.y + py)}, palette[by >> 4]);
|
||||
if ((by >> 4) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x() + px), static_cast<ui::Coord>(p.y() + py)}, palette[by >> 4]);
|
||||
px++;
|
||||
if (px < bmp_header->width) {
|
||||
if ((by & 15) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x + px), static_cast<ui::Coord>(p.y + py)}, palette[by & 15]);
|
||||
if ((by & 15) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x() + px), static_cast<ui::Coord>(p.y() + py)}, palette[by & 15]);
|
||||
}
|
||||
px++;
|
||||
}
|
||||
@@ -375,10 +375,10 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
|
||||
count = by >> 1;
|
||||
for (c = 0; c < count; c++) {
|
||||
by = bitmap[data_idx++];
|
||||
if ((by >> 4) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x + px), static_cast<ui::Coord>(p.y + py)}, palette[by >> 4]);
|
||||
if ((by >> 4) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x() + px), static_cast<ui::Coord>(p.y() + py)}, palette[by >> 4]);
|
||||
px++;
|
||||
if (px < bmp_header->width) {
|
||||
if ((by & 15) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x + px), static_cast<ui::Coord>(p.y + py)}, palette[by & 15]);
|
||||
if ((by & 15) != transp_idx) draw_pixel({static_cast<ui::Coord>(p.x() + px), static_cast<ui::Coord>(p.y() + py)}, palette[by & 15]);
|
||||
}
|
||||
px++;
|
||||
}
|
||||
@@ -390,10 +390,10 @@ void ILI9341::drawBMP(const ui::Point p, const uint8_t * bitmap, const bool tran
|
||||
}
|
||||
|
||||
void ILI9341::draw_line(const ui::Point start, const ui::Point end, const ui::Color color) {
|
||||
int x0 = start.x;
|
||||
int y0 = start.y;
|
||||
int x1 = end.x;
|
||||
int y1 = end.y;
|
||||
int x0 = start.x();
|
||||
int y0 = start.y();
|
||||
int x1 = end.x();
|
||||
int y1 = end.y();
|
||||
|
||||
int dx = std::abs(x1-x0), sx = x0<x1 ? 1 : -1;
|
||||
int dy = std::abs(y1-y0), sy = y0<y1 ? 1 : -1;
|
||||
@@ -422,10 +422,7 @@ void ILI9341::fill_circle(
|
||||
const uint32_t d2 = x2 + y2;
|
||||
const bool inside = d2 < radius2;
|
||||
const auto color = inside ? foreground : background;
|
||||
draw_pixel({
|
||||
static_cast<ui::Coord>(x + center.x),
|
||||
static_cast<ui::Coord>(y + center.y)
|
||||
}, color);
|
||||
draw_pixel({ x + center.x(), y + center.y() }, color);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -446,7 +443,7 @@ void ILI9341::draw_pixels(
|
||||
const size_t count
|
||||
) {
|
||||
/* TODO: Assert that rectangle width x height < count */
|
||||
lcd_start_ram_write(r.pos, r.size);
|
||||
lcd_start_ram_write(r);
|
||||
io.lcd_write_pixels(colors, count);
|
||||
}
|
||||
|
||||
@@ -472,7 +469,7 @@ void ILI9341::draw_bitmap(
|
||||
) {
|
||||
lcd_start_ram_write(p, size);
|
||||
|
||||
const size_t count = size.w * size.h;
|
||||
const size_t count = size.width() * size.height();
|
||||
for(size_t i=0; i<count; i++) {
|
||||
const auto pixel = pixels[i >> 3] & (1U << (i & 0x7));
|
||||
io.lcd_write_pixel(pixel ? foreground : background);
|
||||
|
||||
@@ -43,15 +43,15 @@ public:
|
||||
|
||||
}
|
||||
|
||||
constexpr uint32_t base() {
|
||||
constexpr uint32_t base() const {
|
||||
return base_;
|
||||
}
|
||||
|
||||
constexpr uint32_t end() {
|
||||
constexpr uint32_t end() const {
|
||||
return base_ + size_;
|
||||
}
|
||||
|
||||
constexpr size_t size() {
|
||||
constexpr size_t size() const {
|
||||
return size_;
|
||||
}
|
||||
|
||||
|
||||
@@ -439,7 +439,7 @@ public:
|
||||
return used_ >= capacity_;
|
||||
}
|
||||
|
||||
const void* data() const {
|
||||
void* data() const {
|
||||
return data_;
|
||||
}
|
||||
|
||||
@@ -447,6 +447,10 @@ public:
|
||||
return used_;
|
||||
}
|
||||
|
||||
void set_size(const size_t value) {
|
||||
used_ = value;
|
||||
}
|
||||
|
||||
void empty() {
|
||||
used_ = 0;
|
||||
}
|
||||
|
||||
@@ -80,7 +80,7 @@ public:
|
||||
|
||||
private:
|
||||
FIFO<uint8_t> fifo;
|
||||
Mutex mutex_write;
|
||||
Mutex mutex_write { };
|
||||
|
||||
Message* peek(std::array<uint8_t, Message::MAX_SIZE>& buf) {
|
||||
Message* const p = reinterpret_cast<Message*>(buf.data());
|
||||
|
||||
@@ -61,7 +61,7 @@ constexpr Pin pins[] = {
|
||||
[P1_15] = { 1, 15, PinConfig::sgpio_inout_fast(2) }, /* SGPIO2/BANK2F3M9: CPLD.74/HOST_DATA2(IO) */
|
||||
[P1_16] = { 1, 16, PinConfig::sgpio_inout_fast(2) }, /* SGPIO3/BANK2F3M10: CPLD.72/HOST_DATA3(IO) */
|
||||
[P1_17] = { 1, 17, PinConfig::sgpio_out_fast_with_pullup(6) }, /* SGPIO11/P79/BANK2F3M11: CPLD.71/HOST_DIRECTION(I) */
|
||||
[P1_18] = { 1, 18, PinConfig::gpio_out_with_pulldown(0) }, /* SGPIO12/BANK2F3M12: CPLD.70/HOST_Q_INVERT(I) */
|
||||
[P1_18] = { 1, 18, PinConfig::gpio_out_with_pulldown(0) }, /* SGPIO12/BANK2F3M12: CPLD.70/HOST_INVERT(I) */
|
||||
[P1_19] = { 1, 19, { .mode=1, .pd=1, .pu=0, .fast=0, .input=0, .ifilt=1 } }, /* SSP1_SCK/P39: MAX2837.SCLK(I), MAX5864.SCLK(I) */
|
||||
[P1_20] = { 1, 20, { .mode=0, .pd=0, .pu=1, .fast=0, .input=0, .ifilt=1 } }, /* CS_XCVR/P53: MAX2837.CS(I) */
|
||||
[P2_0] = { 2, 0, { .mode=4, .pd=0, .pu=1, .fast=0, .input=1, .ifilt=1 } }, /* U0_TXD: PortaPack P2_0/IO_STBX */
|
||||
|
||||
@@ -50,7 +50,7 @@ static constexpr std::array<uint8_t, 12> png_iend { {
|
||||
} };
|
||||
|
||||
Optional<File::Error> PNGWriter::create(
|
||||
const std::string& filename
|
||||
const std::filesystem::path& filename
|
||||
) {
|
||||
const auto create_error = file.create(filename);
|
||||
if( create_error.is_valid() ) {
|
||||
|
||||
@@ -35,7 +35,7 @@ class PNGWriter {
|
||||
public:
|
||||
~PNGWriter();
|
||||
|
||||
Optional<File::Error> create(const std::string& filename);
|
||||
Optional<File::Error> create(const std::filesystem::path& filename);
|
||||
|
||||
void write_scanline(const std::array<ui::ColorRGB888, 240>& scanline);
|
||||
|
||||
@@ -44,10 +44,10 @@ private:
|
||||
static constexpr int width { 240 };
|
||||
static constexpr int height { 320 };
|
||||
|
||||
File file;
|
||||
File file { };
|
||||
int scanline_count { 0 };
|
||||
CRC<32, true, true> crc { 0x04c11db7, 0xffffffff, 0xffffffff };
|
||||
Adler32 adler_32;
|
||||
Adler32 adler_32 { };
|
||||
|
||||
void write_chunk_header(const size_t length, const std::array<uint8_t, 4>& type);
|
||||
void write_chunk_content(const void* const p, const size_t count);
|
||||
|
||||
@@ -64,7 +64,7 @@ struct SharedMemory {
|
||||
ToneData tones_data;
|
||||
JammerRange jammer_ranges[9];
|
||||
uint8_t data[512];
|
||||
} bb_data;
|
||||
} bb_data { { { { 0, 0 } }, 0, { 0 } } };
|
||||
};
|
||||
|
||||
extern SharedMemory& shared_memory;
|
||||
|
||||
@@ -28,6 +28,30 @@
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
template<typename T>
|
||||
struct simd32_t {
|
||||
union {
|
||||
uint32_t raw;
|
||||
T vec;
|
||||
};
|
||||
|
||||
operator uint32_t() const {
|
||||
return raw;
|
||||
}
|
||||
|
||||
simd32_t& operator=(uint32_t v) {
|
||||
raw = v;
|
||||
return *this;
|
||||
}
|
||||
|
||||
static_assert(sizeof(raw) == sizeof(vec), "simd32_t types are not the same size.");
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
simd32_t<T>* simd32_ptr(T* const p) {
|
||||
return reinterpret_cast<simd32_t<T>*>(p);
|
||||
}
|
||||
|
||||
struct vec4_s8 {
|
||||
union {
|
||||
int8_t v[4];
|
||||
@@ -41,6 +65,12 @@ struct vec2_s16 {
|
||||
{
|
||||
}
|
||||
|
||||
constexpr vec2_s16(
|
||||
const int16_t v
|
||||
) : v { v, v }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr vec2_s16(
|
||||
const int16_t v0,
|
||||
const int16_t v1
|
||||
|
||||
@@ -100,7 +100,7 @@ struct region_t {
|
||||
const size_t offset;
|
||||
const size_t size;
|
||||
|
||||
constexpr const void* base() {
|
||||
constexpr const void* base() const {
|
||||
return reinterpret_cast<void*>(portapack::memory::map::spifi_cached.base() + offset);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -88,7 +88,7 @@ Optional<Reading> Packet::reading_ook_8k192_schrader() const {
|
||||
reader_.read(3, 24),
|
||||
Pressure { static_cast<int>(reader_.read(27, 8)) * 4 / 3 },
|
||||
{ },
|
||||
Flags { (flags << 4) | checksum }
|
||||
Flags { static_cast<Flags>((flags << 4) | checksum) }
|
||||
};
|
||||
} else {
|
||||
return { };
|
||||
|
||||
+16
-4
@@ -26,8 +26,8 @@
|
||||
namespace ui {
|
||||
|
||||
bool Rect::contains(const Point p) const {
|
||||
return (p.x >= left()) && (p.y >= top()) &&
|
||||
(p.x < right()) && (p.y < bottom());
|
||||
return (p.x() >= left()) && (p.y() >= top()) &&
|
||||
(p.x() < right()) && (p.y() < bottom());
|
||||
}
|
||||
|
||||
Rect Rect::intersect(const Rect& o) const {
|
||||
@@ -42,6 +42,8 @@ Rect Rect::intersect(const Rect& o) const {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: This violates the principle of least surprise!
|
||||
// This does a union, but that might not be obvious from "+=" syntax.
|
||||
Rect& Rect::operator+=(const Rect& p) {
|
||||
if( is_empty() ) {
|
||||
*this = p;
|
||||
@@ -49,12 +51,22 @@ Rect& Rect::operator+=(const Rect& p) {
|
||||
if( !p.is_empty() ) {
|
||||
const auto x1 = std::min(left(), p.left());
|
||||
const auto y1 = std::min(top(), p.top());
|
||||
pos = { x1, y1 };
|
||||
_pos = { x1, y1 };
|
||||
const auto x2 = std::max(right(), p.right());
|
||||
const auto y2 = std::max(bottom(), p.bottom());
|
||||
size = { x2 - x1, y2 - y1 };
|
||||
_size = { x2 - x1, y2 - y1 };
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rect& Rect::operator+=(const Point& p) {
|
||||
_pos += p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Rect& Rect::operator-=(const Point& p) {
|
||||
_pos -= p;
|
||||
return *this;
|
||||
}
|
||||
|
||||
} /* namespace ui */
|
||||
|
||||
+77
-39
@@ -116,121 +116,157 @@ struct ColorRGB888 {
|
||||
};
|
||||
|
||||
struct Point {
|
||||
Coord x;
|
||||
Coord y;
|
||||
private:
|
||||
Coord _x;
|
||||
Coord _y;
|
||||
|
||||
public:
|
||||
constexpr Point(
|
||||
) : x { 0 },
|
||||
y { 0 }
|
||||
) : _x { 0 },
|
||||
_y { 0 }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr Point(
|
||||
int x,
|
||||
int y
|
||||
) : x { static_cast<Coord>(x) },
|
||||
y { static_cast<Coord>(y) }
|
||||
) : _x { static_cast<Coord>(x) },
|
||||
_y { static_cast<Coord>(y) }
|
||||
{
|
||||
}
|
||||
|
||||
Point operator-() const {
|
||||
return { -x, -y };
|
||||
constexpr int x() const {
|
||||
return _x;
|
||||
}
|
||||
|
||||
Point operator+(const Point& p) const {
|
||||
return { x + p.x, y + p.y };
|
||||
constexpr int y() const {
|
||||
return _y;
|
||||
}
|
||||
|
||||
Point operator-(const Point& p) const {
|
||||
return { x - p.x, y - p.y };
|
||||
constexpr Point operator-() const {
|
||||
return { -_x, -_y };
|
||||
}
|
||||
|
||||
constexpr Point operator+(const Point& p) const {
|
||||
return { _x + p._x, _y + p._y };
|
||||
}
|
||||
|
||||
constexpr Point operator-(const Point& p) const {
|
||||
return { _x - p._x, _y - p._y };
|
||||
}
|
||||
|
||||
Point& operator+=(const Point& p) {
|
||||
x += p.x;
|
||||
y += p.y;
|
||||
_x += p._x;
|
||||
_y += p._y;
|
||||
return *this;
|
||||
}
|
||||
|
||||
Point& operator-=(const Point& p) {
|
||||
_x -= p._x;
|
||||
_y -= p._y;
|
||||
return *this;
|
||||
}
|
||||
};
|
||||
|
||||
struct Size {
|
||||
Dim w;
|
||||
Dim h;
|
||||
private:
|
||||
Dim _w;
|
||||
Dim _h;
|
||||
|
||||
public:
|
||||
constexpr Size(
|
||||
) : w { 0 },
|
||||
h { 0 }
|
||||
) : _w { 0 },
|
||||
_h { 0 }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr Size(
|
||||
int w,
|
||||
int h
|
||||
) : w { static_cast<Dim>(w) },
|
||||
h { static_cast<Dim>(h) }
|
||||
) : _w { static_cast<Dim>(w) },
|
||||
_h { static_cast<Dim>(h) }
|
||||
{
|
||||
}
|
||||
|
||||
int width() const {
|
||||
return _w;
|
||||
}
|
||||
|
||||
int height() const {
|
||||
return _h;
|
||||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return (w < 1) || (h < 1);
|
||||
return (_w < 1) || (_h < 1);
|
||||
}
|
||||
};
|
||||
|
||||
struct Rect {
|
||||
Point pos;
|
||||
Size size;
|
||||
private:
|
||||
Point _pos;
|
||||
Size _size;
|
||||
|
||||
public:
|
||||
constexpr Rect(
|
||||
) : pos { },
|
||||
size { }
|
||||
) : _pos { },
|
||||
_size { }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr Rect(
|
||||
int x, int y,
|
||||
int w, int h
|
||||
) : pos { x, y },
|
||||
size { w, h }
|
||||
) : _pos { x, y },
|
||||
_size { w, h }
|
||||
{
|
||||
}
|
||||
|
||||
constexpr Rect(
|
||||
Point pos,
|
||||
Size size
|
||||
) : pos(pos),
|
||||
size(size)
|
||||
) : _pos(pos),
|
||||
_size(size)
|
||||
{
|
||||
}
|
||||
|
||||
Point location() const {
|
||||
return _pos;
|
||||
}
|
||||
|
||||
Size size() const {
|
||||
return _size;
|
||||
}
|
||||
|
||||
int top() const {
|
||||
return pos.y;
|
||||
return _pos.y();
|
||||
}
|
||||
|
||||
int bottom() const {
|
||||
return pos.y + size.h;
|
||||
return _pos.y() + _size.height();
|
||||
}
|
||||
|
||||
int left() const {
|
||||
return pos.x;
|
||||
return _pos.x();
|
||||
}
|
||||
|
||||
int right() const {
|
||||
return pos.x + size.w;
|
||||
return _pos.x() + _size.width();
|
||||
}
|
||||
|
||||
int width() const {
|
||||
return size.w;
|
||||
return _size.width();
|
||||
}
|
||||
|
||||
int height() const {
|
||||
return size.h;
|
||||
return _size.height();
|
||||
}
|
||||
|
||||
Point center() const {
|
||||
return { pos.x + size.w / 2, pos.y + size.h / 2 };
|
||||
return { _pos.x() + _size.width() / 2, _pos.y() + _size.height() / 2 };
|
||||
}
|
||||
|
||||
bool is_empty() const {
|
||||
return size.is_empty();
|
||||
return _size.is_empty();
|
||||
}
|
||||
|
||||
bool contains(const Point p) const;
|
||||
@@ -238,13 +274,15 @@ struct Rect {
|
||||
Rect intersect(const Rect& o) const;
|
||||
|
||||
Rect operator+(const Point& p) const {
|
||||
return { pos + p, size };
|
||||
return { _pos + p, _size };
|
||||
}
|
||||
|
||||
Rect& operator+=(const Rect& p);
|
||||
Rect& operator+=(const Point& p);
|
||||
Rect& operator-=(const Point& p);
|
||||
|
||||
operator bool() const {
|
||||
return !size.is_empty();
|
||||
return !_size.is_empty();
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -127,14 +127,14 @@ static int32_t rect_distances(
|
||||
switch(direction) {
|
||||
case KeyEvent::Right:
|
||||
case KeyEvent::Left:
|
||||
perpendicular_axis_start = rect_start.center().y;
|
||||
perpendicular_axis_end = rect_end.center().y;
|
||||
perpendicular_axis_start = rect_start.center().y();
|
||||
perpendicular_axis_end = rect_end.center().y();
|
||||
break;
|
||||
|
||||
case KeyEvent::Up:
|
||||
case KeyEvent::Down:
|
||||
perpendicular_axis_start = rect_start.center().x;
|
||||
perpendicular_axis_end = rect_end.center().x;
|
||||
perpendicular_axis_start = rect_start.center().x();
|
||||
perpendicular_axis_end = rect_end.center().x();
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
@@ -39,7 +39,7 @@ Style Style::invert() const {
|
||||
int Painter::draw_char(const Point p, const Style& style, const char c) {
|
||||
const auto glyph = style.font.glyph(c);
|
||||
display.draw_glyph(p, glyph, style.foreground, style.background);
|
||||
return glyph.advance().x;
|
||||
return glyph.advance().x();
|
||||
}
|
||||
|
||||
int Painter::draw_string(Point p, const Style& style, const std::string text) {
|
||||
@@ -49,7 +49,7 @@ int Painter::draw_string(Point p, const Style& style, const std::string text) {
|
||||
display.draw_glyph(p, glyph, style.foreground, style.background);
|
||||
const auto advance = glyph.advance();
|
||||
p += advance;
|
||||
width += advance.x;
|
||||
width += advance.x();
|
||||
}
|
||||
return width;
|
||||
}
|
||||
@@ -67,10 +67,10 @@ void Painter::draw_vline(Point p, int height, const Color c) {
|
||||
}
|
||||
|
||||
void Painter::draw_rectangle(const Rect r, const Color c) {
|
||||
draw_hline(r.pos, r.size.w, c);
|
||||
draw_vline({ r.pos.x, r.pos.y + 1 }, r.size.h - 2, c);
|
||||
draw_vline({ r.pos.x + r.size.w - 1, r.pos.y + 1 }, r.size.h - 2, c);
|
||||
draw_hline({ r.pos.x, r.pos.y + r.size.h - 1 }, r.size.w, c);
|
||||
draw_hline(r.location(), r.width(), c);
|
||||
draw_vline({ r.left(), r.top() + 1 }, r.height() - 2, c);
|
||||
draw_vline({ r.left() + r.width() - 1, r.top() + 1 }, r.height() - 2, c);
|
||||
draw_hline({ r.left(), r.top() + r.height() - 1 }, r.width(), c);
|
||||
}
|
||||
|
||||
void Painter::fill_rectangle(const Rect r, const Color c) {
|
||||
|
||||
@@ -44,8 +44,10 @@ Size Font::size_of(const std::string s) const {
|
||||
|
||||
for(const auto c : s) {
|
||||
const auto glyph_data = glyph(c);
|
||||
size.w += glyph_data.w();
|
||||
size.h = std::max(size.h, glyph_data.h());
|
||||
size = {
|
||||
size.width() + glyph_data.w(),
|
||||
std::max(size.height(), glyph_data.h())
|
||||
};
|
||||
}
|
||||
|
||||
return size;
|
||||
|
||||
@@ -42,11 +42,11 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
Dim w() const {
|
||||
int w() const {
|
||||
return w_;
|
||||
}
|
||||
|
||||
Dim h() const {
|
||||
int h() const {
|
||||
return h_;
|
||||
}
|
||||
|
||||
|
||||
@@ -53,19 +53,23 @@ bool is_dirty() {
|
||||
const std::vector<Widget*> Widget::no_children { };
|
||||
|
||||
Point Widget::screen_pos() {
|
||||
return screen_rect().pos;
|
||||
return screen_rect().location();
|
||||
}
|
||||
|
||||
Size Widget::size() const {
|
||||
return parent_rect.size;
|
||||
return _parent_rect.size();
|
||||
}
|
||||
|
||||
Rect Widget::screen_rect() const {
|
||||
return parent() ? (parent_rect + parent()->screen_pos()) : parent_rect;
|
||||
return parent() ? (parent_rect() + parent()->screen_pos()) : parent_rect();
|
||||
}
|
||||
|
||||
Rect Widget::parent_rect() const {
|
||||
return _parent_rect;
|
||||
}
|
||||
|
||||
void Widget::set_parent_rect(const Rect new_parent_rect) {
|
||||
parent_rect = new_parent_rect;
|
||||
_parent_rect = new_parent_rect;
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
@@ -74,12 +78,19 @@ Widget* Widget::parent() const {
|
||||
}
|
||||
|
||||
void Widget::set_parent(Widget* const widget) {
|
||||
if( widget == parent_ ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if( parent_ && !widget ) {
|
||||
// We have a parent, but are losing it. Update visible status.
|
||||
dirty_overlapping_children_in_rect(screen_rect());
|
||||
visible(false);
|
||||
}
|
||||
|
||||
parent_ = widget;
|
||||
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
void Widget::set_dirty() {
|
||||
@@ -103,7 +114,7 @@ void Widget::hidden(bool hide) {
|
||||
if( hide ) {
|
||||
// TODO: Instead of dirtying parent entirely, dirty only children
|
||||
// that overlap with this widget.
|
||||
dirty_overlapping_children_in_rect(parent_rect);
|
||||
parent()->dirty_overlapping_children_in_rect(parent_rect());
|
||||
/* TODO: Notify self and all non-hidden children that they're
|
||||
* now effectively hidden?
|
||||
*/
|
||||
@@ -211,7 +222,7 @@ void Widget::set_highlighted(const bool value) {
|
||||
|
||||
void Widget::dirty_overlapping_children_in_rect(const Rect& child_rect) {
|
||||
for(auto child : children()) {
|
||||
if( !child_rect.intersect(child->parent_rect).is_empty() ) {
|
||||
if( !child_rect.intersect(child->parent_rect()).is_empty() ) {
|
||||
child->set_dirty();
|
||||
}
|
||||
}
|
||||
@@ -231,21 +242,20 @@ void View::add_child(Widget* const widget) {
|
||||
if( widget->parent() == nullptr ) {
|
||||
widget->set_parent(this);
|
||||
children_.push_back(widget);
|
||||
widget->set_dirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void View::add_children(const std::vector<Widget*>& children) {
|
||||
void View::add_children(const std::initializer_list<Widget*> children) {
|
||||
children_.insert(std::end(children_), children);
|
||||
for(auto child : children) {
|
||||
add_child(child);
|
||||
child->set_parent(this);
|
||||
}
|
||||
}
|
||||
|
||||
void View::remove_child(Widget* const widget) {
|
||||
if( widget ) {
|
||||
children_.erase(std::remove(children_.begin(), children_.end(), widget), children_.end());
|
||||
dirty_overlapping_children_in_rect(widget->screen_rect());
|
||||
widget->set_parent(nullptr);
|
||||
}
|
||||
}
|
||||
@@ -281,11 +291,6 @@ Rectangle::Rectangle(
|
||||
{
|
||||
}
|
||||
|
||||
Rectangle::Rectangle(
|
||||
) : Widget { }
|
||||
{
|
||||
}
|
||||
|
||||
void Rectangle::set_color(const Color c) {
|
||||
color = c;
|
||||
set_dirty();
|
||||
@@ -316,7 +321,7 @@ Text::Text(
|
||||
Rect parent_rect,
|
||||
std::string text
|
||||
) : Widget { parent_rect },
|
||||
text_ { text }
|
||||
text { text }
|
||||
{
|
||||
}
|
||||
|
||||
@@ -327,14 +332,10 @@ Text::Text(
|
||||
}
|
||||
|
||||
void Text::set(const std::string value) {
|
||||
text_ = value;
|
||||
text = value;
|
||||
set_dirty();
|
||||
}
|
||||
|
||||
std::string Text::text() const {
|
||||
return text_;
|
||||
}
|
||||
|
||||
void Text::paint(Painter& painter) {
|
||||
const auto rect = screen_rect();
|
||||
const auto s = style();
|
||||
@@ -342,9 +343,9 @@ void Text::paint(Painter& painter) {
|
||||
painter.fill_rectangle(rect, s.background);
|
||||
|
||||
painter.draw_string(
|
||||
rect.pos,
|
||||
rect.location(),
|
||||
s,
|
||||
text_
|
||||
text
|
||||
);
|
||||
}
|
||||
|
||||
@@ -387,7 +388,7 @@ void BigFrequency::paint(Painter& painter) {
|
||||
const auto rect = screen_rect();
|
||||
|
||||
// Erase
|
||||
painter.fill_rectangle({{0, rect.pos.y}, {240, 52}}, ui::Color::black());
|
||||
painter.fill_rectangle({{0, rect.location().y()}, {240, 52}}, ui::Color::black());
|
||||
|
||||
if (!_frequency) {
|
||||
for (i = 0; i < 7; i++) // ----.------
|
||||
@@ -412,10 +413,10 @@ void BigFrequency::paint(Painter& painter) {
|
||||
segment_color = style().foreground;
|
||||
|
||||
// Draw
|
||||
digit_x = rect.pos.x; // 7 * 32 + 8 = 232 (4 px margins)
|
||||
digit_x = rect.location().x(); // 7 * 32 + 8 = 232 (4 px margins)
|
||||
for (i = 0; i < 7; i++) {
|
||||
digit = digits[i];
|
||||
digit_y = rect.pos.y;
|
||||
digit_y = rect.location().y();
|
||||
if (digit < 16) {
|
||||
digit_def = big_segment_font[(uint8_t)digit];
|
||||
if (digit_def & 0x01) painter.fill_rectangle({{digit_x + 4, digit_y}, {20, 4}}, segment_color);
|
||||
@@ -464,10 +465,10 @@ void ProgressBar::paint(Painter& painter) {
|
||||
const auto rect = screen_rect();
|
||||
const auto s = style();
|
||||
|
||||
v_sized = (rect.size.w * _value) / _max;
|
||||
v_sized = (rect.size().width() * _value) / _max;
|
||||
|
||||
painter.fill_rectangle({rect.pos, {v_sized, rect.size.h}}, style().foreground);
|
||||
painter.fill_rectangle({{rect.pos.x + v_sized, rect.pos.y}, {rect.size.w - v_sized, rect.size.h}}, s.background);
|
||||
painter.fill_rectangle({rect.location(), {v_sized, rect.size().height()}}, style().foreground);
|
||||
painter.fill_rectangle({{rect.location().x() + v_sized, rect.location().y()}, {rect.size().width() - v_sized, rect.size().height()}}, s.background);
|
||||
|
||||
painter.draw_rectangle(rect, s.foreground);
|
||||
}
|
||||
@@ -500,15 +501,15 @@ void Console::write(std::string message) {
|
||||
} else {
|
||||
const auto glyph = font.glyph(c);
|
||||
const auto advance = glyph.advance();
|
||||
if( (pos.x + advance.x) > rect.width() ) {
|
||||
if( (pos.x() + advance.x()) > rect.width() ) {
|
||||
crlf();
|
||||
}
|
||||
const Point pos_glyph {
|
||||
rect.pos.x + pos.x,
|
||||
display.scroll_area_y(pos.y)
|
||||
rect.left() + pos.x(),
|
||||
display.scroll_area_y(pos.y())
|
||||
};
|
||||
display.draw_glyph(pos_glyph, glyph, s.foreground, s.background);
|
||||
pos.x += advance.x;
|
||||
pos += { advance.x(), 0 };
|
||||
}
|
||||
}
|
||||
buffer = message;
|
||||
@@ -545,14 +546,13 @@ void Console::crlf() {
|
||||
const Style& s = style();
|
||||
const auto sr = screen_rect();
|
||||
const auto line_height = s.font.line_height();
|
||||
pos.x = 0;
|
||||
pos.y += line_height;
|
||||
const int32_t y_excess = pos.y + line_height - sr.height();
|
||||
pos = { 0, pos.y() + line_height };
|
||||
const int32_t y_excess = pos.y() + line_height - sr.height();
|
||||
if( y_excess > 0 ) {
|
||||
display.scroll(-y_excess);
|
||||
pos.y -= y_excess;
|
||||
pos = { pos.x(), pos.y() - y_excess };
|
||||
|
||||
const Rect dirty { sr.left(), display.scroll_area_y(pos.y), sr.width(), line_height };
|
||||
const Rect dirty { sr.left(), display.scroll_area_y(pos.y()), sr.width(), line_height };
|
||||
display.fill_rectangle(dirty, s.background);
|
||||
}
|
||||
}
|
||||
@@ -596,33 +596,33 @@ void Checkbox::paint(Painter& painter) {
|
||||
|
||||
const auto paint_style = (has_focus() || highlighted()) ? style().invert() : style();
|
||||
|
||||
painter.draw_rectangle({ r.pos.x, r.pos.y, 24, 24 }, style().foreground);
|
||||
painter.draw_rectangle({ r.location().x(), r.location().y(), 24, 24 }, style().foreground);
|
||||
|
||||
painter.fill_rectangle(
|
||||
{
|
||||
static_cast<Coord>(r.pos.x + 1), static_cast<Coord>(r.pos.y + 1),
|
||||
static_cast<Coord>(r.location().x() + 1), static_cast<Coord>(r.location().y() + 1),
|
||||
static_cast<Dim>(24 - 2), static_cast<Dim>(24 - 2)
|
||||
},
|
||||
style().background
|
||||
);
|
||||
|
||||
painter.draw_rectangle({ r.pos.x+2, r.pos.y+2, 24-4, 24-4 }, paint_style.background);
|
||||
painter.draw_rectangle({ r.location().x() + 2, r.location().y() + 2, 24-4, 24-4 }, paint_style.background);
|
||||
|
||||
if (value_ == true) {
|
||||
// Check
|
||||
portapack::display.draw_line( {r.pos.x+2, r.pos.y+14}, {r.pos.x+6, r.pos.y+18}, ui::Color::green());
|
||||
portapack::display.draw_line( {r.pos.x+6, r.pos.y+18}, {r.pos.x+20, r.pos.y+4}, ui::Color::green());
|
||||
portapack::display.draw_line( {r.location().x()+2, r.location().y()+14}, {r.location().x()+6, r.location().y()+18}, ui::Color::green());
|
||||
portapack::display.draw_line( {r.location().x()+6, r.location().y()+18}, {r.location().x()+20, r.location().y()+4}, ui::Color::green());
|
||||
} else {
|
||||
// Cross
|
||||
portapack::display.draw_line( {r.pos.x+1, r.pos.y+1}, {r.pos.x+24-2, r.pos.y+24-2}, ui::Color::red());
|
||||
portapack::display.draw_line( {r.pos.x+24-2, r.pos.y+1}, {r.pos.x+1, r.pos.y+24-2}, ui::Color::red());
|
||||
portapack::display.draw_line( {r.location().x()+1, r.location().y()+1}, {r.location().x()+24-2, r.location().y()+24-2}, ui::Color::red());
|
||||
portapack::display.draw_line( {r.location().x()+24-2, r.location().y()+1}, {r.location().x()+1, r.location().y()+24-2}, ui::Color::red());
|
||||
}
|
||||
|
||||
const auto label_r = paint_style.font.size_of(text_);
|
||||
painter.draw_string(
|
||||
{
|
||||
static_cast<Coord>(r.pos.x + 24 + 4),
|
||||
static_cast<Coord>(r.pos.y + (24 - label_r.h) / 2)
|
||||
static_cast<Coord>(r.location().x() + 24 + 4),
|
||||
static_cast<Coord>(r.location().y() + (24 - label_r.height()) / 2)
|
||||
},
|
||||
paint_style,
|
||||
text_
|
||||
@@ -691,18 +691,18 @@ void Button::paint(Painter& painter) {
|
||||
|
||||
const Style paint_style = { style().font, bg, fg };
|
||||
|
||||
painter.draw_rectangle({r.pos, {r.size.w, 1}}, Color::light_grey());
|
||||
painter.draw_rectangle({r.pos.x, r.pos.y + r.size.h - 1, r.size.w, 1}, Color::dark_grey());
|
||||
painter.draw_rectangle({r.pos.x + r.size.w - 1, r.pos.y, 1, r.size.h}, Color::dark_grey());
|
||||
painter.draw_rectangle({r.location(), {r.size().width(), 1}}, Color::light_grey());
|
||||
painter.draw_rectangle({r.location().x(), r.location().y() + r.size().height() - 1, r.size().width(), 1}, Color::dark_grey());
|
||||
painter.draw_rectangle({r.location().x() + r.size().width() - 1, r.location().y(), 1, r.size().height()}, Color::dark_grey());
|
||||
|
||||
painter.fill_rectangle(
|
||||
{ r.pos.x, r.pos.y + 1, r.size.w - 1, r.size.h - 2 },
|
||||
{ r.location().x(), r.location().y() + 1, r.size().width() - 1, r.size().height() - 2 },
|
||||
paint_style.background
|
||||
);
|
||||
|
||||
const auto label_r = paint_style.font.size_of(text_);
|
||||
painter.draw_string(
|
||||
{ r.pos.x + (r.size.w - label_r.w) / 2, r.pos.y + (r.size.h - label_r.h) / 2 },
|
||||
{ r.location().x() + (r.size().width() - label_r.width()) / 2, r.location().y() + (r.size().height() - label_r.height()) / 2 },
|
||||
paint_style,
|
||||
text_
|
||||
);
|
||||
@@ -753,6 +753,7 @@ bool Button::on_touch(const TouchEvent event) {
|
||||
flags.highlighted = true;
|
||||
set_dirty();
|
||||
return true;
|
||||
|
||||
case TouchEvent::Type::Move:
|
||||
{
|
||||
const bool new_highlighted = screen_rect().contains(event.point);
|
||||
@@ -762,6 +763,7 @@ bool Button::on_touch(const TouchEvent event) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
case TouchEvent::Type::End:
|
||||
if( flags.highlighted ) {
|
||||
flags.highlighted = false;
|
||||
@@ -771,6 +773,7 @@ bool Button::on_touch(const TouchEvent event) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
@@ -865,6 +868,7 @@ bool ImageButton::on_touch(const TouchEvent event) {
|
||||
set_dirty();
|
||||
return true;
|
||||
|
||||
|
||||
case TouchEvent::Type::End:
|
||||
set_highlighted(false);
|
||||
set_dirty();
|
||||
@@ -931,9 +935,9 @@ void ImageOptionsField::paint(Painter& painter) {
|
||||
|
||||
if( selected_index() < options.size() ) {
|
||||
const auto bmp_ptr = options[selected_index()].first;
|
||||
painter.fill_rectangle({screen_rect().pos, {screen_rect().size.w + 4, screen_rect().size.h + 4}}, ui::Color::black());
|
||||
painter.draw_rectangle({screen_rect().pos, {screen_rect().size.w + 4, screen_rect().size.h + 4}}, paint_style.background);
|
||||
portapack::display.drawBMP({screen_pos().x + 2, screen_pos().y + 1}, bmp_ptr, true);
|
||||
painter.fill_rectangle({screen_rect().location(), {screen_rect().size().width() + 4, screen_rect().size().height() + 4}}, ui::Color::black());
|
||||
painter.draw_rectangle({screen_rect().location(), {screen_rect().size().width() + 4, screen_rect().size().height() + 4}}, paint_style.background);
|
||||
portapack::display.drawBMP({screen_pos().x() + 2, screen_pos().y() + 1}, bmp_ptr, true);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -959,9 +963,9 @@ bool ImageOptionsField::on_touch(const TouchEvent event) {
|
||||
|
||||
OptionsField::OptionsField(
|
||||
Point parent_pos,
|
||||
size_t length,
|
||||
int length,
|
||||
options_t options
|
||||
) : Widget { { parent_pos, { static_cast<ui::Dim>(8 * length), 16 } } },
|
||||
) : Widget { { parent_pos, { 8 * length, 16 } } },
|
||||
length_ { length },
|
||||
options { options }
|
||||
{
|
||||
@@ -1008,7 +1012,7 @@ void OptionsField::set_options(options_t new_options) {
|
||||
void OptionsField::paint(Painter& painter) {
|
||||
const auto paint_style = has_focus() ? style().invert() : style();
|
||||
|
||||
painter.fill_rectangle({screen_rect().pos, {(int)length_ * 8, 16}}, ui::Color::black());
|
||||
painter.fill_rectangle({screen_rect().location(), {(int)length_ * 8, 16}}, ui::Color::black());
|
||||
|
||||
if( selected_index() < options.size() ) {
|
||||
const auto text = options[selected_index()].first;
|
||||
@@ -1042,11 +1046,11 @@ bool OptionsField::on_touch(const TouchEvent event) {
|
||||
|
||||
NumberField::NumberField(
|
||||
Point parent_pos,
|
||||
size_t length,
|
||||
int length,
|
||||
range_t range,
|
||||
int32_t step,
|
||||
char fill_char
|
||||
) : Widget { { parent_pos, { static_cast<ui::Dim>(8 * length), 16 } } },
|
||||
) : Widget { { parent_pos, { 8 * length, 16 } } },
|
||||
range { range },
|
||||
step { step },
|
||||
length_ { length },
|
||||
@@ -1224,7 +1228,7 @@ void SymField::paint(Painter& painter) {
|
||||
text
|
||||
);
|
||||
|
||||
pt_draw.x += 8;
|
||||
pt_draw += { 8, 0 };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1319,15 +1323,15 @@ void Waveform::set_length(const uint32_t new_length) {
|
||||
|
||||
void Waveform::paint(Painter& painter) {
|
||||
uint32_t n, point_count;
|
||||
Coord y, y_offset = screen_rect().pos.y;
|
||||
Coord prev_x = screen_rect().pos.x, prev_y;
|
||||
Coord y, y_offset = screen_rect().location().y();
|
||||
Coord prev_x = screen_rect().location().x(), prev_y;
|
||||
float x, x_inc;
|
||||
Dim h = screen_rect().size.h;
|
||||
Dim h = screen_rect().size().height();
|
||||
|
||||
// Clear
|
||||
painter.fill_rectangle(screen_rect(), Color::black());
|
||||
|
||||
x_inc = (float)screen_rect().size.w / length_;
|
||||
x_inc = (float)screen_rect().size().width() / length_;
|
||||
point_count = length_;
|
||||
const float y_scale = (float)(h - 1) / 256; // TODO: Make variable
|
||||
|
||||
|
||||
@@ -49,30 +49,33 @@ public:
|
||||
}
|
||||
|
||||
private:
|
||||
FocusManager focus_manager_;
|
||||
FocusManager focus_manager_ { };
|
||||
};
|
||||
|
||||
class Widget {
|
||||
public:
|
||||
Widget(
|
||||
) : parent_rect { }
|
||||
) : _parent_rect { }
|
||||
{
|
||||
}
|
||||
|
||||
Widget(
|
||||
Rect parent_rect
|
||||
) : parent_rect { parent_rect }
|
||||
) : _parent_rect { parent_rect }
|
||||
{
|
||||
}
|
||||
|
||||
Widget(const Widget&) = delete;
|
||||
Widget(Widget&&) = delete;
|
||||
Widget& operator=(const Widget&) = delete;
|
||||
Widget& operator=(Widget&&) = delete;
|
||||
|
||||
virtual ~Widget() = default;
|
||||
|
||||
Point screen_pos();
|
||||
Size size() const;
|
||||
Rect screen_rect() const;
|
||||
Rect parent_rect() const;
|
||||
virtual void set_parent_rect(const Rect new_parent_rect);
|
||||
|
||||
Widget* parent() const;
|
||||
@@ -122,7 +125,7 @@ protected:
|
||||
|
||||
private:
|
||||
/* Widget rectangle relative to parent pos(). */
|
||||
Rect parent_rect;
|
||||
Rect _parent_rect;
|
||||
const Style* style_ { nullptr };
|
||||
Widget* parent_ { nullptr };
|
||||
|
||||
@@ -159,7 +162,7 @@ public:
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
void add_child(Widget* const widget);
|
||||
void add_children(const std::vector<Widget*>& children);
|
||||
void add_children(const std::initializer_list<Widget*> children);
|
||||
void remove_child(Widget* const widget);
|
||||
void remove_children(const std::vector<Widget*>& children);
|
||||
const std::vector<Widget*>& children() const override;
|
||||
@@ -167,7 +170,7 @@ public:
|
||||
virtual std::string title() const;
|
||||
|
||||
protected:
|
||||
std::vector<Widget*> children_;
|
||||
std::vector<Widget*> children_ { };
|
||||
|
||||
void invalidate_child(Widget* const widget);
|
||||
};
|
||||
@@ -176,7 +179,10 @@ class Rectangle : public Widget {
|
||||
public:
|
||||
Rectangle(Color c);
|
||||
Rectangle(Rect parent_rect, Color c);
|
||||
Rectangle();
|
||||
Rectangle(
|
||||
) : Rectangle { { }, { } }
|
||||
{
|
||||
}
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
@@ -191,19 +197,18 @@ private:
|
||||
class Text : public Widget {
|
||||
public:
|
||||
Text(
|
||||
) : text_ { "" } {
|
||||
) : text { "" } {
|
||||
}
|
||||
|
||||
Text(Rect parent_rect, std::string text);
|
||||
Text(Rect parent_rect);
|
||||
|
||||
void set(const std::string value);
|
||||
std::string text() const;
|
||||
|
||||
void paint(Painter& painter) override;
|
||||
|
||||
private:
|
||||
std::string text_;
|
||||
std::string text;
|
||||
};
|
||||
|
||||
class BigFrequency : public Widget {
|
||||
@@ -248,14 +253,14 @@ public:
|
||||
private:
|
||||
bool visible = false;
|
||||
Point pos { 0, 0 };
|
||||
std::string buffer;
|
||||
std::string buffer { };
|
||||
|
||||
void crlf();
|
||||
};
|
||||
|
||||
class Checkbox : public Widget {
|
||||
public:
|
||||
std::function<void(Checkbox&)> on_select;
|
||||
std::function<void(Checkbox&)> on_select { };
|
||||
|
||||
Checkbox(Point parent_pos, size_t length, std::string text);
|
||||
|
||||
@@ -264,6 +269,11 @@ public:
|
||||
{
|
||||
}
|
||||
|
||||
Checkbox(const Checkbox&) = delete;
|
||||
Checkbox(Checkbox&&) = delete;
|
||||
Checkbox& operator=(const Checkbox&) = delete;
|
||||
Checkbox& operator=(Checkbox&&) = delete;
|
||||
|
||||
void set_text(const std::string value);
|
||||
bool set_value(const bool value);
|
||||
bool value() const;
|
||||
@@ -281,9 +291,9 @@ private:
|
||||
|
||||
class Button : public Widget {
|
||||
public:
|
||||
std::function<void(Button&)> on_select;
|
||||
std::function<bool(Button&,KeyEvent)> on_dir;
|
||||
std::function<void(Button&)> on_highlight;
|
||||
std::function<void(Button&)> on_select { };
|
||||
std::function<bool(Button&, KeyEvent)> on_dir { };
|
||||
std::function<void(Button&)> on_highlight { };
|
||||
|
||||
Button(Rect parent_rect, std::string text);
|
||||
|
||||
@@ -315,6 +325,11 @@ public:
|
||||
const Color background
|
||||
);
|
||||
|
||||
Image(const Image&) = delete;
|
||||
Image(Image&&) = delete;
|
||||
Image& operator=(const Image&) = delete;
|
||||
Image& operator=(Image&&) = delete;
|
||||
|
||||
void set_bitmap(const Bitmap* bitmap);
|
||||
void set_foreground(const Color color);
|
||||
void set_background(const Color color);
|
||||
@@ -330,7 +345,7 @@ private:
|
||||
|
||||
class ImageButton : public Image {
|
||||
public:
|
||||
std::function<void(ImageButton&)> on_select;
|
||||
std::function<void(ImageButton&)> on_select { };
|
||||
|
||||
ImageButton(
|
||||
const Rect parent_rect,
|
||||
@@ -350,8 +365,8 @@ public:
|
||||
using option_t = std::pair<image_t, value_t>;
|
||||
using options_t = std::vector<option_t>;
|
||||
|
||||
std::function<void(size_t, value_t)> on_change;
|
||||
std::function<void(void)> on_show_options;
|
||||
std::function<void(size_t, value_t)> on_change { };
|
||||
std::function<void(void)> on_show_options { };
|
||||
|
||||
ImageOptionsField(Rect parent_rect, options_t options);
|
||||
|
||||
@@ -386,10 +401,10 @@ public:
|
||||
using option_t = std::pair<name_t, value_t>;
|
||||
using options_t = std::vector<option_t>;
|
||||
|
||||
std::function<void(size_t, value_t)> on_change;
|
||||
std::function<void(void)> on_show_options;
|
||||
std::function<void(size_t, value_t)> on_change { };
|
||||
std::function<void(void)> on_show_options { };
|
||||
|
||||
OptionsField(Point parent_pos, size_t length, options_t options);
|
||||
OptionsField(Point parent_pos, int length, options_t options);
|
||||
|
||||
void set_options(options_t new_options);
|
||||
|
||||
@@ -406,19 +421,19 @@ public:
|
||||
bool on_touch(const TouchEvent event) override;
|
||||
|
||||
private:
|
||||
const size_t length_;
|
||||
const int length_;
|
||||
options_t options;
|
||||
size_t selected_index_ { 0 };
|
||||
};
|
||||
|
||||
class NumberField : public Widget {
|
||||
public:
|
||||
std::function<void(NumberField&)> on_select;
|
||||
std::function<void(int32_t)> on_change;
|
||||
std::function<void(NumberField&)> on_select { };
|
||||
std::function<void(int32_t)> on_change { };
|
||||
|
||||
using range_t = std::pair<int32_t, int32_t>;
|
||||
|
||||
NumberField(Point parent_pos, size_t length, range_t range, int32_t step, char fill_char);
|
||||
NumberField(Point parent_pos, int length, range_t range, int32_t step, char fill_char);
|
||||
NumberField(
|
||||
) : NumberField { { 0, 0 }, 1, { 0, 1 }, 1, ' ' }
|
||||
{
|
||||
@@ -440,17 +455,17 @@ public:
|
||||
private:
|
||||
range_t range;
|
||||
const int32_t step;
|
||||
const size_t length_;
|
||||
const int length_;
|
||||
const char fill_char;
|
||||
int32_t value_;
|
||||
int32_t value_ { 0 };
|
||||
|
||||
int32_t clip_value(int32_t value);
|
||||
};
|
||||
|
||||
class SymField : public Widget {
|
||||
public:
|
||||
std::function<void(SymField&)> on_select;
|
||||
std::function<void()> on_change;
|
||||
std::function<void(SymField&)> on_select { };
|
||||
std::function<void()> on_change { };
|
||||
|
||||
SymField(Point parent_pos, size_t length);
|
||||
SymField(Point parent_pos, size_t length, bool hex);
|
||||
@@ -474,7 +489,7 @@ private:
|
||||
std::string symbol_list_[32] = { "01" }; // Failsafe init
|
||||
uint32_t values_[32] = { 0 };
|
||||
uint32_t selected_ = 0;
|
||||
size_t length_, prev_length_;
|
||||
size_t length_, prev_length_ = 0;
|
||||
bool erase_prev_ = false;
|
||||
bool hex_ = false;
|
||||
|
||||
@@ -488,6 +503,8 @@ public:
|
||||
|
||||
Waveform(const Waveform&) = delete;
|
||||
Waveform(Waveform&&) = delete;
|
||||
Waveform& operator=(const Waveform&) = delete;
|
||||
Waveform& operator=(Waveform&&) = delete;
|
||||
|
||||
void set_offset(const uint32_t new_offset);
|
||||
void set_length(const uint32_t new_length);
|
||||
|
||||
@@ -121,46 +121,4 @@ struct range_t {
|
||||
}
|
||||
};
|
||||
|
||||
namespace std {
|
||||
|
||||
/*! Stephan T Lavavej (STL!) implementation of make_unique, which has been accepted into the C++14 standard.
|
||||
* It includes handling for arrays.
|
||||
* Paper here: http://isocpp.org/files/papers/N3656.txt
|
||||
*/
|
||||
template<class T> struct _Unique_if {
|
||||
typedef unique_ptr<T> _Single_object;
|
||||
};
|
||||
|
||||
//! Specialization for unbound array
|
||||
template<class T> struct _Unique_if<T[]> {
|
||||
typedef unique_ptr<T[]> _Unknown_bound;
|
||||
};
|
||||
|
||||
//! Specialization for array of known size
|
||||
template<class T, size_t N> struct _Unique_if<T[N]> {
|
||||
typedef void _Known_bound;
|
||||
};
|
||||
|
||||
//! Specialization for normal object type
|
||||
template<class T, class... Args>
|
||||
typename _Unique_if<T>::_Single_object
|
||||
make_unique(Args&& ... args) {
|
||||
return unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
//! Specialization for unknown bound
|
||||
template<class T>
|
||||
typename _Unique_if<T>::_Unknown_bound
|
||||
make_unique(size_t n) {
|
||||
typedef typename remove_extent<T>::type U;
|
||||
return unique_ptr<T>(new U[n]());
|
||||
}
|
||||
|
||||
//! Deleted specialization
|
||||
template<class T, class... Args>
|
||||
typename _Unique_if<T>::_Known_bound
|
||||
make_unique(Args&& ...) = delete;
|
||||
|
||||
} /* namespace std */
|
||||
|
||||
#endif/*__UTILITY_H__*/
|
||||
|
||||
Reference in New Issue
Block a user