mirror of
https://github.com/UpsilonNumworks/Upsilon.git
synced 2026-03-18 21:30:38 +01:00
Remove unused code
Change-Id: I2641bb3ef9427d955c4f8124c4b00930def91097
This commit is contained in:
@@ -1,7 +0,0 @@
|
||||
app_objs += $(addprefix app/,\
|
||||
escher_demo.o\
|
||||
plot.o\
|
||||
utils.o)
|
||||
products += $(app_objs) app.elf app.hex app.bin
|
||||
|
||||
app.elf: $(app_objs)
|
||||
179
app/app.cpp
179
app/app.cpp
@@ -1,179 +0,0 @@
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <kandinsky.h>
|
||||
#include <stdlib.h>
|
||||
#include <ion.h>
|
||||
}
|
||||
|
||||
#include <poincare.h>
|
||||
#include "../poincare/src/layout/string_layout.h"
|
||||
|
||||
#include "plot.h"
|
||||
#include "utils.h"
|
||||
|
||||
static const char* kParsingErrorMessage = "PARSING ERROR";
|
||||
|
||||
//////////////////////////////////////////////////////
|
||||
|
||||
static constexpr uint8_t kInputMemory = 15;
|
||||
|
||||
typedef struct user_expression_t {
|
||||
char* text_input;
|
||||
Expression* expression;
|
||||
Expression* simplified;
|
||||
ExpressionLayout* expression_layout;
|
||||
ExpressionLayout* simplified_layout;
|
||||
} user_expression_t;
|
||||
|
||||
class UserExpressions {
|
||||
public:
|
||||
UserExpressions() {
|
||||
m_numberOfExpressions = 0;
|
||||
m_position = kInputMemory;
|
||||
for (int i=0; i<kInputMemory; i++) {
|
||||
m_expressions[i] = {nullptr, nullptr, nullptr, nullptr, nullptr};
|
||||
}
|
||||
}
|
||||
|
||||
// Adds a user expression as the most recent one.
|
||||
void append_expression(user_expression_t user_expression) {
|
||||
if (m_numberOfExpressions < kInputMemory) {
|
||||
m_numberOfExpressions++;
|
||||
}
|
||||
m_position = (m_position + 1) % kInputMemory;
|
||||
if (m_position < 0) {
|
||||
m_numberOfExpressions += kInputMemory;
|
||||
}
|
||||
|
||||
// The circular buffer is full, now we have to erase stuff.
|
||||
if (m_numberOfExpressions == kInputMemory) {
|
||||
user_expression_t tmp = m_expressions[m_position];
|
||||
if (tmp.text_input) {
|
||||
free(tmp.text_input);
|
||||
if (tmp.expression) {
|
||||
free(tmp.expression);
|
||||
if (tmp.expression_layout) {
|
||||
free(tmp.expression_layout);
|
||||
}
|
||||
if (tmp.simplified && tmp.simplified != tmp.expression) {
|
||||
free(tmp.simplified);
|
||||
if (tmp.simplified_layout) {
|
||||
free(tmp.simplified_layout);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
m_expressions[m_position] = user_expression;
|
||||
}
|
||||
|
||||
// Gets the i th latest expression.
|
||||
user_expression_t get_expression(uint8_t index) const {
|
||||
//assert(index < m_numberOfExpressions);
|
||||
int pos = (m_position - index) % kInputMemory;
|
||||
if (pos < 0) {
|
||||
pos += kInputMemory;
|
||||
}
|
||||
return m_expressions[pos];
|
||||
}
|
||||
|
||||
uint8_t numberOfExpressions() const {
|
||||
return m_numberOfExpressions;
|
||||
}
|
||||
|
||||
private:
|
||||
uint8_t m_numberOfExpressions;
|
||||
uint8_t m_position;
|
||||
user_expression_t m_expressions[kInputMemory];
|
||||
};
|
||||
|
||||
/////////////////////////////////////////////////
|
||||
|
||||
static user_expression_t create_user_input(char* text) {
|
||||
user_expression_t user_expression = {text, nullptr, nullptr, nullptr, nullptr};
|
||||
user_expression.expression = Expression::parse(user_expression.text_input);
|
||||
if (user_expression.expression) {
|
||||
user_expression.expression_layout = user_expression.expression->createLayout();
|
||||
user_expression.simplified = user_expression.expression->simplify();
|
||||
user_expression.simplified_layout = user_expression.simplified->createLayout();
|
||||
} else {
|
||||
user_expression.expression_layout =
|
||||
new StringLayout(kParsingErrorMessage, strlen(kParsingErrorMessage));
|
||||
}
|
||||
return user_expression;
|
||||
}
|
||||
|
||||
static int16_t print_user_input(user_expression_t user_expression, int16_t yOffset) {
|
||||
if (user_expression.expression_layout) {
|
||||
int16_t height = user_expression.expression_layout->size().height;
|
||||
if (yOffset + height < ION_SCREEN_HEIGHT) {
|
||||
user_expression.expression_layout->draw(KDPointMake(0, yOffset));
|
||||
}
|
||||
yOffset += height;
|
||||
}
|
||||
if (user_expression.simplified_layout) {
|
||||
int16_t height = user_expression.simplified_layout->size().height;
|
||||
if (yOffset + height < ION_SCREEN_HEIGHT) {
|
||||
int16_t xOffset = ION_SCREEN_WIDTH - user_expression.simplified_layout->size().width;
|
||||
user_expression.simplified_layout->draw(KDPointMake(xOffset, yOffset));
|
||||
}
|
||||
yOffset += height;
|
||||
}
|
||||
return yOffset;
|
||||
}
|
||||
|
||||
static void print_user_inputs(const UserExpressions& user_inputs, uint8_t startingAt) {
|
||||
int16_t yOffset = 0;
|
||||
for (uint8_t i=startingAt; i<user_inputs.numberOfExpressions(); i++) {
|
||||
yOffset = print_user_input(user_inputs.get_expression(i), yOffset);
|
||||
if (yOffset>ION_SCREEN_HEIGHT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void interactive_expression_parsing() {
|
||||
UserExpressions user_inputs = UserExpressions();
|
||||
int index = 0;
|
||||
while (1) {
|
||||
text_event_t text_event;
|
||||
if (index == 0) {
|
||||
text_event = get_text(nullptr);
|
||||
} else {
|
||||
text_event = get_text(user_inputs.get_expression(index - 1).text_input);
|
||||
}
|
||||
if (text_event.event == EQUAL) {
|
||||
user_inputs.append_expression(create_user_input(text_event.text));
|
||||
} else if (text_event.event == UP_ARROW) {
|
||||
index--;
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
} else if (text_event.event == DOWN_ARROW) {
|
||||
if (user_inputs.numberOfExpressions() != 0) {
|
||||
index++;
|
||||
if (index >= user_inputs.numberOfExpressions()) {
|
||||
index = user_inputs.numberOfExpressions() - 1;
|
||||
}
|
||||
}
|
||||
} else if (text_event.event == PLOT) {
|
||||
user_inputs.append_expression(create_user_input(text_event.text));
|
||||
// We check that the expression is correct.
|
||||
if (user_inputs.get_expression(0).expression) {
|
||||
clear_screen();
|
||||
plot(user_inputs.get_expression(0).expression, -3, 3);
|
||||
}
|
||||
} else {
|
||||
assert(false); // unreachable.
|
||||
}
|
||||
clear_screen();
|
||||
print_user_inputs(user_inputs, index ? index - 1 : 0);
|
||||
}
|
||||
}
|
||||
|
||||
void ion_app() {
|
||||
interactive_expression_parsing();
|
||||
while (1) {
|
||||
ion_sleep();
|
||||
}
|
||||
}
|
||||
44
app/blinky.c
44
app/blinky.c
@@ -1,44 +0,0 @@
|
||||
#include <registers.h>
|
||||
|
||||
void sleep(long delay);
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
|
||||
// We want to blink LEDs connected to GPIO pin G13 and G14
|
||||
// (this is documented in our board's PDF)
|
||||
//
|
||||
// GPIO are grouped by letter, and GPIO "G" live on the "AHB1" bus
|
||||
// (this is documented in the STM32F4 reference mnual, page 65)
|
||||
|
||||
// Step 1 : Enable clock in RCC_AHBxENR
|
||||
RCC_AHB1ENR->GPIOGEN = 1;
|
||||
|
||||
|
||||
// Step 2 : Configure the GPIO pin to "general purpose output
|
||||
GPIO_MODER(GPIOG)->MODER13 = GPIO_MODE_OUTPUT;
|
||||
GPIO_MODER(GPIOG)->MODER14 = GPIO_MODE_OUTPUT;
|
||||
|
||||
// Per doc, the output is push-pull by default (yay)
|
||||
// And we should also set the output speed, but really
|
||||
// we don't care (we're doing something super slow)
|
||||
|
||||
long delay = 50000;
|
||||
|
||||
while (1) {
|
||||
GPIO_ODR(GPIOG)->ODR13 = 0;
|
||||
GPIO_ODR(GPIOG)->ODR14 = 1;
|
||||
|
||||
sleep(delay);
|
||||
|
||||
GPIO_ODR(GPIOG)->ODR13 = 1;
|
||||
GPIO_ODR(GPIOG)->ODR14 = 0;
|
||||
|
||||
sleep(delay);
|
||||
}
|
||||
}
|
||||
|
||||
void sleep(long delay) {
|
||||
for (long i=0; i<delay; i++) {
|
||||
// Do nothing!
|
||||
}
|
||||
}
|
||||
@@ -1,57 +0,0 @@
|
||||
#include <registers.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <timers.h>
|
||||
#include <semphr.h>
|
||||
|
||||
void BlinkGreenLed(void * pvParameters) {
|
||||
while(1) {
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
GPIO_ODR(GPIOG)->ODR13 = 0;
|
||||
vTaskDelay(1000/portTICK_PERIOD_MS);
|
||||
GPIO_ODR(GPIOG)->ODR13 = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void BlinkRedLed(void * pvParameters) {
|
||||
int delay = 10;
|
||||
while (1) {
|
||||
vTaskDelay(delay);
|
||||
GPIO_ODR(GPIOG)->ODR14 = 1;
|
||||
vTaskDelay(delay);
|
||||
GPIO_ODR(GPIOG)->ODR14 = 0;
|
||||
delay++;
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
// We want to blink LEDs connected to GPIO pin G13 and G14
|
||||
// (this is documented in our board's PDF)
|
||||
//
|
||||
// GPIO are grouped by letter, and GPIO "G" live on the "AHB1" bus
|
||||
// (this is documented in the STM32F4 reference mnual, page 65)
|
||||
|
||||
// Step 1 : Enable clock in RCC_AHBxENR
|
||||
RCC_AHB1ENR->GPIOGEN = 1;
|
||||
|
||||
|
||||
// Step 2 : Configure the GPIO pin to "general purpose output
|
||||
GPIO_MODER(GPIOG)->MODER13 = GPIO_MODE_OUTPUT;
|
||||
GPIO_MODER(GPIOG)->MODER14 = GPIO_MODE_OUTPUT;
|
||||
|
||||
|
||||
BaseType_t success = xTaskCreate(BlinkGreenLed,
|
||||
"BlkGrn",
|
||||
100, // Stack size
|
||||
NULL, // Parameters
|
||||
2,
|
||||
NULL);
|
||||
|
||||
xTaskCreate(BlinkRedLed, "BlkRed", 100, NULL, 2, NULL);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
while (1) {
|
||||
// We should never get here
|
||||
}
|
||||
}
|
||||
85
app/plot.cpp
85
app/plot.cpp
@@ -1,85 +0,0 @@
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <kandinsky.h>
|
||||
#include <stdlib.h>
|
||||
#include <ion.h>
|
||||
}
|
||||
|
||||
#include <poincare.h>
|
||||
|
||||
#include "utils.h"
|
||||
#include "plot.h"
|
||||
|
||||
constexpr KDCoordinate kScreenWidth = ION_SCREEN_WIDTH;
|
||||
const KDCoordinate kScreenHeight = ION_SCREEN_HEIGHT;
|
||||
|
||||
static float plotValues[kScreenWidth];
|
||||
static float yMin, yMax;
|
||||
|
||||
// For now we only plot the axes at the origin.
|
||||
// TODO: print axes not at the origin with some values too.
|
||||
// TODO: label the axes.
|
||||
// TODO: put the values on the axes.
|
||||
static void plot_axes(float xMin, float xMax, float yMin, float yMax) {
|
||||
if (xMin < 0 && xMax > 0) {
|
||||
float total = xMax - xMin;
|
||||
float ratio = xMax / total;
|
||||
KDCoordinate width = ratio * kScreenWidth;
|
||||
KDDrawLine(KDPointMake(width, 0), KDPointMake(width, kScreenHeight-1), 0xff);
|
||||
}
|
||||
if (yMin < 0 && yMax > 0) {
|
||||
float total = yMax - yMin;
|
||||
float ratio = yMax / total;
|
||||
KDCoordinate height = ratio * kScreenHeight;
|
||||
KDDrawLine(KDPointMake(0, height), KDPointMake(kScreenWidth-1, height), 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
static void fill_values(Expression * e, float xMin, float xMax) {
|
||||
assert(e);
|
||||
Context plotContext;
|
||||
|
||||
// Initialize min and max.
|
||||
Float xExp = Float(xMin);
|
||||
plotContext.setExpressionForSymbolName(&xExp, "x");
|
||||
plotValues[0] = e->approximate(plotContext);
|
||||
yMin = plotValues[0];
|
||||
yMax = plotValues[0];
|
||||
|
||||
for (KDCoordinate i = 1; i < kScreenWidth; i++) {
|
||||
float x = xMin + (xMax-xMin)/kScreenWidth*i;
|
||||
Float xExp = Float(x);
|
||||
plotContext.setExpressionForSymbolName(&xExp, "x");
|
||||
plotValues[i] = e->approximate(plotContext);
|
||||
if (plotValues[i] > yMax) {
|
||||
yMax = plotValues[i];
|
||||
}
|
||||
if (plotValues[i] < yMin) {
|
||||
yMin = plotValues[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Add a cursor.
|
||||
// TODO: print the expression.
|
||||
void plot(Expression * e, float xMin, float xMax) {
|
||||
assert(e);
|
||||
|
||||
fill_values(e, xMin, xMax);
|
||||
|
||||
// Plot the original axes.
|
||||
plot_axes(xMin, xMax, yMin, yMax);
|
||||
|
||||
// We need to initialize the first point.
|
||||
KDCoordinate j = ((plotValues[0]-yMin) / (yMax-yMin) * (kScreenHeight - 1));
|
||||
KDPoint previousPoint = KDPointMake(0, kScreenHeight - 1 - j);
|
||||
|
||||
for (KDCoordinate i = 1; i < kScreenWidth; i++) {
|
||||
// TODO: check for yMin == yMax
|
||||
KDCoordinate j = ((plotValues[i]-yMin) / (yMax-yMin) * (kScreenHeight - 1));
|
||||
KDPoint currentPoint = KDPointMake(i, kScreenHeight - 1 - j);
|
||||
KDDrawLine(previousPoint, currentPoint, 0xFF);
|
||||
previousPoint = currentPoint;
|
||||
}
|
||||
ion_get_event(); // We wait for a text input.
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
#ifndef APP_PLOT_H
|
||||
#define APP_PLOT_H
|
||||
|
||||
// Note that currently the only variable is 'x'
|
||||
void plot(Expression * e, float xMin, float xMax);
|
||||
|
||||
#endif
|
||||
79
app/spi.c
79
app/spi.c
@@ -1,79 +0,0 @@
|
||||
#include <registers.h>
|
||||
#include <FreeRTOS.h>
|
||||
#include <task.h>
|
||||
#include <timers.h>
|
||||
#include <semphr.h>
|
||||
|
||||
/* This code sends data over SPI
|
||||
* We're using SPI4, in this pinout
|
||||
*
|
||||
* PE11 - SPI4_NSS - Yellow
|
||||
* PE12 - SPI4_SCK - Green
|
||||
* PE13 - SPI4_MISO - Red
|
||||
* PE14 - SPI4_MOSI - Blue
|
||||
*/
|
||||
|
||||
void SpiSend(void * pvParameters) {
|
||||
uint16_t value = 0;
|
||||
while(1) {
|
||||
SPI_SR_t * spi_status = SPI_SR(SPI4);
|
||||
if (spi_status->BSY == 0) {
|
||||
uint16_t * SPI4_DR = (uint16_t *)(0x4001340C);
|
||||
*SPI4_DR = value++;
|
||||
}
|
||||
vTaskDelay(100/portTICK_PERIOD_MS);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char * argv[]) {
|
||||
// We'll use GPIO pins E11-E14 to emit SPI data
|
||||
// GPIO are grouped by letter, and GPIO "G" live on the "AHB1" bus (as all GPIOs BTW)
|
||||
// (this is documented in the STM32F4 reference mnual, page 65)
|
||||
|
||||
// Step 1 : Enable clock in RCC_AHBxENR
|
||||
RCC_AHB1ENR->GPIOEEN = 1;
|
||||
|
||||
// Step 2 : Configure the GPIO pin to "Alternate function number 5"
|
||||
// This means "SPI4 on pins E11-14", cf STM32F249 p78
|
||||
GPIO_MODER(GPIOE)->MODER11 = GPIO_MODE_ALTERNATE_FUNCTION;
|
||||
GPIO_MODER(GPIOE)->MODER12 = GPIO_MODE_ALTERNATE_FUNCTION;
|
||||
GPIO_MODER(GPIOE)->MODER13 = GPIO_MODE_ALTERNATE_FUNCTION;
|
||||
GPIO_MODER(GPIOE)->MODER14 = GPIO_MODE_ALTERNATE_FUNCTION;
|
||||
|
||||
// We're interested in pins 11-14, which are in the 8-16 range, so we
|
||||
// have to deal with the "high" version of the AF register
|
||||
GPIO_AFRH(GPIOE)->AFRH11 = GPIO_AF_AF5;
|
||||
GPIO_AFRH(GPIOE)->AFRH12 = GPIO_AF_AF5;
|
||||
GPIO_AFRH(GPIOE)->AFRH13 = GPIO_AF_AF5;
|
||||
GPIO_AFRH(GPIOE)->AFRH14 = GPIO_AF_AF5;
|
||||
|
||||
// Enable the SPI4 clock
|
||||
RCC_APB2ENR->SPI4EN = 1;
|
||||
|
||||
// Configure the SPI port
|
||||
// Using a C99 compound litteral
|
||||
*SPI_CR1(SPI4) = (SPI_CR1_t){
|
||||
.BIDIMODE = 1,
|
||||
.BIDIOE = 1,
|
||||
.MSTR = 1,
|
||||
.DFF = SPI_DFF_16_BITS,
|
||||
.CPOL = 0,
|
||||
.BR = SPI_BR_DIV_256,
|
||||
.SSM = 1,
|
||||
.SSI = 1,
|
||||
.SPE = 1
|
||||
};
|
||||
|
||||
BaseType_t success = xTaskCreate(SpiSend,
|
||||
"SpiSnd",
|
||||
100, // Stack size
|
||||
NULL, // Parameters
|
||||
2,
|
||||
NULL);
|
||||
|
||||
vTaskStartScheduler();
|
||||
|
||||
while (1) {
|
||||
// We should never get here
|
||||
}
|
||||
}
|
||||
195
app/utils.cpp
195
app/utils.cpp
@@ -1,195 +0,0 @@
|
||||
extern "C" {
|
||||
#include <assert.h>
|
||||
#include <kandinsky.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
}
|
||||
|
||||
#include "utils.h"
|
||||
|
||||
static constexpr int16_t kPromptHeight = 25;
|
||||
static constexpr uint8_t kBufferSize = 255;
|
||||
|
||||
void clear_screen() {
|
||||
KDRect r;
|
||||
r.x = 0;
|
||||
r.y = 0;
|
||||
r.width = ION_SCREEN_WIDTH;
|
||||
r.height = ION_SCREEN_HEIGHT;
|
||||
KDFillRect(r, 0x00);
|
||||
}
|
||||
|
||||
static void clear_prompt() {
|
||||
KDRect r;
|
||||
r.x = 0;
|
||||
r.y = ION_SCREEN_HEIGHT - kPromptHeight;
|
||||
r.width = ION_SCREEN_WIDTH;
|
||||
r.height = kPromptHeight;
|
||||
KDFillRect(r, 0x00);
|
||||
}
|
||||
|
||||
static void print_prompt(char* text, int index) {
|
||||
char* tmp = (char*) " ";
|
||||
KDSize font_size = KDStringSize(tmp);
|
||||
KDDrawLine(KDPointMake(0, ION_SCREEN_HEIGHT - kPromptHeight),
|
||||
KDPointMake(ION_SCREEN_WIDTH, ION_SCREEN_HEIGHT - kPromptHeight), 0xff);
|
||||
KDDrawString(text, KDPointMake(0, ION_SCREEN_HEIGHT - (kPromptHeight / 2)), 0);
|
||||
KDDrawChar(text[index], KDPointMake(index * font_size.width, ION_SCREEN_HEIGHT - (kPromptHeight / 2)), true);
|
||||
}
|
||||
|
||||
static void clear_trig_menu() {
|
||||
{
|
||||
KDRect r;
|
||||
r.x = ION_SCREEN_WIDTH / 4 - 1;
|
||||
r.y = ION_SCREEN_HEIGHT / 4 - 1;
|
||||
r.width = ION_SCREEN_WIDTH / 2 + 2;
|
||||
r.height = ION_SCREEN_HEIGHT / 2 + 2;
|
||||
KDFillRect(r, 0x00);
|
||||
}
|
||||
}
|
||||
|
||||
static void print_trig_menu() {
|
||||
{
|
||||
KDRect r;
|
||||
r.x = ION_SCREEN_WIDTH / 4;
|
||||
r.y = ION_SCREEN_HEIGHT / 4;
|
||||
r.width = ION_SCREEN_WIDTH / 2;
|
||||
r.height = ION_SCREEN_HEIGHT / 2;
|
||||
KDDrawRect(r, 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
static int get_trig_input(char* input) {
|
||||
int pos = 0;
|
||||
const char* kTexts[] = {
|
||||
"sine",
|
||||
"cosine",
|
||||
"tangent",
|
||||
"cancel"
|
||||
};
|
||||
const char* kOutputs[] = {
|
||||
"sin( )",
|
||||
"cos( )",
|
||||
"tan( )",
|
||||
};
|
||||
const KDPoint orig = KDPointMake(ION_SCREEN_WIDTH / 4, ION_SCREEN_HEIGHT / 4);
|
||||
while (true) {
|
||||
print_trig_menu();
|
||||
|
||||
uint16_t vert_acc = 0;
|
||||
for (int i(0); i<4; i++) {
|
||||
KDSize text_size = KDStringSize(kTexts[i]);
|
||||
KDDrawString(kTexts[i],
|
||||
KDPointMake(orig.x, orig.y + vert_acc + text_size.height / 2),
|
||||
i==pos);
|
||||
vert_acc += text_size.height;
|
||||
}
|
||||
|
||||
ion_event_t event = ion_get_event();
|
||||
if (event == UP_ARROW) {
|
||||
pos--;
|
||||
if (pos < 0) {
|
||||
pos = 0;
|
||||
}
|
||||
} else if (event == DOWN_ARROW) {
|
||||
pos++;
|
||||
if (pos >= 4) {
|
||||
pos = 3;
|
||||
}
|
||||
} else if (event == '=') {
|
||||
clear_trig_menu();
|
||||
if (pos == 3) {
|
||||
return 0;
|
||||
} else {
|
||||
memcpy(input, kOutputs[pos], (size_t) strlen(kOutputs[pos]));
|
||||
return strlen(kOutputs[pos]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
text_event_t get_text(char* txt) {
|
||||
char input[kBufferSize];
|
||||
int index = 0;
|
||||
int max = 0;
|
||||
text_event_t text_event = {nullptr, ERROR};
|
||||
|
||||
for (int i = 0; i < kBufferSize; i++) {
|
||||
input[i] = 0;
|
||||
}
|
||||
|
||||
if (txt != nullptr) {
|
||||
index = strlen(txt);
|
||||
max = index;
|
||||
memcpy(input, txt, (size_t) index);
|
||||
}
|
||||
|
||||
input[max] = ' ';
|
||||
input[max+1] = '\0';
|
||||
|
||||
while (1) {
|
||||
clear_prompt();
|
||||
print_prompt(input, index);
|
||||
ion_event_t event = ion_get_event();
|
||||
if (event == EQUAL) {
|
||||
input[max] = '\0';
|
||||
text_event.event = EQUAL;
|
||||
text_event.text = (char*) malloc(sizeof(char) * (index + 1));
|
||||
memcpy(text_event.text, input, (size_t) (index + 1));
|
||||
break;
|
||||
} else if (event == LEFT_ARROW) {
|
||||
index--;
|
||||
if (index < 0) {
|
||||
index = 0;
|
||||
}
|
||||
} else if (event == RIGHT_ARROW) {
|
||||
if (index < max) {
|
||||
index++;
|
||||
}
|
||||
} else if (event <= 0x7f) {
|
||||
input[index++] = (char) event;
|
||||
// We are at the end of the line.
|
||||
if (index > max) {
|
||||
max=index;
|
||||
input[max] = ' ';
|
||||
input[max+1] = '\0';
|
||||
}
|
||||
} else if (event == TRIG_MENU) {
|
||||
int tmp = get_trig_input(&input[index]);
|
||||
index+=tmp;
|
||||
if (index > max) {
|
||||
max=index;
|
||||
input[max] = ' ';
|
||||
input[max+1] = '\0';
|
||||
}
|
||||
// we want to be inside the parenthese if there are some.
|
||||
index -= (tmp > 2) ? 2 : 0;
|
||||
} else if (event == DELETE) {
|
||||
// Nothing to delete.
|
||||
if (index == max) {
|
||||
continue;
|
||||
}
|
||||
for (int i=index; i<max+1; i++) {
|
||||
input[i] = input[i+1];
|
||||
}
|
||||
max--;
|
||||
} else if (event == UP_ARROW) {
|
||||
text_event.event = UP_ARROW;
|
||||
break;
|
||||
} else if (event == DOWN_ARROW) {
|
||||
text_event.event = DOWN_ARROW;
|
||||
break;
|
||||
} else if (event == PLOT) {
|
||||
text_event.event = PLOT;
|
||||
input[max] = '\0';
|
||||
text_event.text = (char*) malloc(sizeof(char) * (index + 1));
|
||||
memcpy(text_event.text, input, (size_t) (index + 1));
|
||||
break;
|
||||
} else {
|
||||
assert(false); // unreachable.
|
||||
}
|
||||
}
|
||||
|
||||
clear_prompt();
|
||||
return text_event;
|
||||
}
|
||||
22
app/utils.h
22
app/utils.h
@@ -1,22 +0,0 @@
|
||||
#ifndef APP_UTILS_H
|
||||
#define APP_UTILS_H
|
||||
|
||||
extern "C" {
|
||||
#include <ion.h>
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
char* text;
|
||||
ion_event_t event;
|
||||
} text_event_t;
|
||||
|
||||
/* Returns a pointer to an input text allocated by the functions.
|
||||
* Also returns an event, which is its return reason.
|
||||
*
|
||||
* This function can get a text to work on instead of starting from an empty
|
||||
* string. */
|
||||
text_event_t get_text(char* txt);
|
||||
|
||||
void clear_screen();
|
||||
|
||||
#endif // APP_UTILS_H
|
||||
Reference in New Issue
Block a user