Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions Apps/Brainfuck/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.brainfuck
app.version.name=0.8.0
app.version.code=8
app.id=tactility.brainfuck
app.version.name=0.9.0
app.version.code=9
app.name=Brainfuck interpreter
app.description=Brainfuck esoteric language interpreter
6 changes: 3 additions & 3 deletions Apps/Breakout/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.breakout
app.version.name=0.9.0
app.version.code=9
app.id=tactility.breakout
app.version.name=0.10.0
app.version.code=10
app.name=Breakout
app.description=Classic brick-breaking arcade game
106 changes: 80 additions & 26 deletions Apps/Calculator/main/Source/Calculator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,63 +14,96 @@ constexpr auto* TAG = "Calculator";
static int precedence(char op) {
if (op == '+' || op == '-') return 1;
if (op == '*' || op == '/') return 2;
if (op == '~') return 3; // unary minus marker, binds tighter than * and /
return 0;
}

static std::deque<std::string> infixToRPN(const std::string& infix) {
static bool infixToRPN(const std::string& infix, std::deque<std::string>& output) {
std::stack<char> opStack;
std::deque<std::string> output;
output.clear();
std::string token;
size_t i = 0;
bool expectOperand = true; // true at start, after '(', or after a binary/unary operator

while (i < infix.length()) {
char ch = infix[i];

if (isdigit(ch)) {
if (isdigit((unsigned char)ch) || ch == '.') {
token.clear();
while (i < infix.length() && (isdigit(infix[i]) || infix[i] == '.')) { token += infix[i++]; }
bool hasDecimalPoint = false;
while (i < infix.length()) {
char current = infix[i];
if (isdigit((unsigned char)current)) {
token += current;
} else if (current == '.' && !hasDecimalPoint) {
hasDecimalPoint = true;
token += current;
} else {
break;
}
++i;
}
if (i < infix.length() && infix[i] == '.') return false;
if (token.find_first_of("0123456789") == std::string::npos) return false; // no digits, e.g. "."
output.push_back(token);
expectOperand = false;
continue;
}

if (ch == '(') { opStack.push(ch); } else if (ch == ')') {
if (ch == '(') {
opStack.push(ch);
expectOperand = true;
} else if (ch == ')') {
while (!opStack.empty() && opStack.top() != '(') {
output.push_back(std::string(1, opStack.top()));
opStack.pop();
}
opStack.pop();
if (opStack.empty()) return false; // unmatched ')'
opStack.pop(); // remove matching '('
expectOperand = false;
} else if (ch == '-' && expectOperand) {
// unary minus: push a marker that binds only to the next operand
opStack.push('~');
expectOperand = true;
} else if (strchr("+-*/", ch)) {
while (!opStack.empty() && precedence(opStack.top()) >= precedence(ch)) {
output.push_back(std::string(1, opStack.top()));
opStack.pop();
}
opStack.push(ch);
expectOperand = true;
}

i++;
}

while (!opStack.empty()) {
if (opStack.top() == '(') return false; // unmatched '('
output.push_back(std::string(1, opStack.top()));
opStack.pop();
}

return output;
return true;
}

static double evaluateRPN(std::deque<std::string> rpnQueue) {
static bool evaluateRPN(std::deque<std::string> rpnQueue, double& result) {
std::stack<double> values;

while (!rpnQueue.empty()) {
std::string token = rpnQueue.front();
rpnQueue.pop_front();

if (isdigit(token[0])) {
if (isdigit((unsigned char)token[0]) || token[0] == '.') {
double d;
sscanf(token.c_str(), "%lf", &d);
values.push(d);
} else if (token[0] == '~') {
if (values.empty()) return false;
double a = values.top();
values.pop();
values.push(-a);
} else if (strchr("+-*/", token[0])) {
if (values.size() < 2) return 0;
if (values.size() < 2) return false;

double b = values.top();
values.pop();
Expand All @@ -80,40 +113,50 @@ static double evaluateRPN(std::deque<std::string> rpnQueue) {
if (token[0] == '+') values.push(a + b);
else if (token[0] == '-') values.push(a - b);
else if (token[0] == '*') values.push(a * b);
else if (token[0] == '/' && b != 0) values.push(a / b);
else if (token[0] == '/') {
if (b == 0) return false;
values.push(a / b);
}
}
}

return values.empty() ? 0 : values.top();
if (values.size() != 1) return false;
result = values.top();
return true;
Comment thread
KenVanHoeylandt marked this conversation as resolved.
}

static double computeFormula(Context* ctx) {
return evaluateRPN(infixToRPN(std::string(ctx->formulaBuffer)));
static bool computeFormula(Context* ctx, double& result) {
std::deque<std::string> rpn;
if (!infixToRPN(std::string(ctx->formulaBuffer), rpn) || rpn.empty()) return false;
return evaluateRPN(std::move(rpn), result);
}

static void resetCalculator(Context* ctx) {
memset(ctx->formulaBuffer, 0, sizeof(ctx->formulaBuffer));
lv_label_set_text(ctx->displayLabel, "0");
lv_label_set_text(ctx->resultLabel, "");
ctx->newInput = true;
ctx->hasLastResult = false;
}

static void evaluateExpression(Context* ctx) {
double result = computeFormula(ctx);
double result;
if (!computeFormula(ctx, result)) {
lv_label_set_text(ctx->displayLabel, "Error");
lv_label_set_text(ctx->resultLabel, ctx->formulaBuffer);
ctx->newInput = true;
return;
}

size_t formulaLen = strlen(ctx->formulaBuffer);
size_t maxAvailable = sizeof(ctx->formulaBuffer) - formulaLen - 1;
char equationBuffer[192];
snprintf(equationBuffer, sizeof(equationBuffer), "%s = %.8g", ctx->formulaBuffer, result);

if (maxAvailable > 10) {
char resultBuffer[32];
snprintf(resultBuffer, sizeof(resultBuffer), " = %.8g", result);
strncat(ctx->formulaBuffer, resultBuffer, maxAvailable);
} else {
snprintf(ctx->formulaBuffer, sizeof(ctx->formulaBuffer), "%.8g", result);
}
snprintf(ctx->formulaBuffer, sizeof(ctx->formulaBuffer), "%.8g", result);
snprintf(ctx->lastResult, sizeof(ctx->lastResult), "%.8g", result);
ctx->hasLastResult = true;

lv_label_set_text(ctx->displayLabel, "0");
lv_label_set_text(ctx->resultLabel, ctx->formulaBuffer);
lv_label_set_text(ctx->resultLabel, equationBuffer);
ctx->newInput = true;
}

Expand All @@ -128,6 +171,17 @@ static void handleInput(Context* ctx, const char* txt) {
return;
}

char resToken[sizeof(ctx->lastResult) + 2];
if (strcmp(txt, "RES") == 0) {
if (!ctx->hasLastResult) return;
if (ctx->lastResult[0] == '-') {
snprintf(resToken, sizeof(resToken), "(%s)", ctx->lastResult);
} else {
snprintf(resToken, sizeof(resToken), "%s", ctx->lastResult);
}
txt = resToken;
}

if (strlen(ctx->formulaBuffer) + strlen(txt) < sizeof(ctx->formulaBuffer) - 1) {
if (ctx->newInput) {
memset(ctx->formulaBuffer, 0, sizeof(ctx->formulaBuffer));
Expand Down Expand Up @@ -188,7 +242,7 @@ void calculatorCreateWidgets(lv_obj_t* parent, void* userData) {
"7", "8", "9", "*", "\n",
"4", "5", "6", "-", "\n",
"1", "2", "3", "+", "\n",
"0", "=", "", "", ""
"0", ".", "RES", "=", ""
};

lv_obj_t* buttonmatrix = lv_buttonmatrix_create(parent);
Expand Down
2 changes: 2 additions & 0 deletions Apps/Calculator/main/Source/Calculator.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ struct Context {
lv_obj_t* resultLabel = nullptr;
char formulaBuffer[128] = {0}; // Stores the full input expression
bool newInput = true;
char lastResult[32] = {0}; // Last computed result, empty if none available
bool hasLastResult = false;
};

/** window_manager_create()'s WindowCreateWidgetsFn - @a userData is the Context* for this instance. */
Expand Down
6 changes: 3 additions & 3 deletions Apps/Calculator/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.calculator
app.version.name=0.9.0
app.version.code=9
app.id=tactility.calculator
app.version.name=0.10.0
app.version.code=10
app.name=Calculator
6 changes: 3 additions & 3 deletions Apps/Diceware/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.diceware
app.version.name=0.10.0
app.version.code=10
app.id=tactility.diceware
app.version.name=0.11.0
app.version.code=11
app.name=Diceware
6 changes: 3 additions & 3 deletions Apps/EpubReader/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32s3,esp32p4
app.id=one.tactility.epubreader
app.version.name=0.7.0
app.version.code=7
app.id=tactility.epubreader
app.version.name=0.8.0
app.version.code=8
app.name=Epub Reader
app.description=Epub and text file reader. Requires PSRAM!
6 changes: 3 additions & 3 deletions Apps/EspNowBridge/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32p4
app.id=one.tactility.espnowbridge
app.version.name=0.5.0
app.version.code=5
app.id=tactility.espnowbridge
app.version.name=0.6.0
app.version.code=6
app.name=ESP-NOW Bridge
app.description=Companion app for updating P4 device C6 co-processor firmware to enable ESP-NOW bridge support.
6 changes: 3 additions & 3 deletions Apps/GPIO/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.gpio
app.version.name=0.11.0
app.version.code=11
app.id=tactility.gpio
app.version.name=0.12.0
app.version.code=12
app.name=GPIO
6 changes: 3 additions & 3 deletions Apps/GraphicsDemo/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.graphicsdemo
app.version.name=0.9.0
app.version.code=9
app.id=tactility.graphicsdemo
app.version.name=0.10.0
app.version.code=10
app.name=Graphics Demo
6 changes: 3 additions & 3 deletions Apps/HelloWorld/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.helloworld
app.version.name=0.9.0
app.version.code=9
app.id=tactility.helloworld
app.version.name=0.10.0
app.version.code=10
app.name=Hello World
6 changes: 3 additions & 3 deletions Apps/M5UnitTest/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32s3,esp32p4
app.id=one.tactility.m5unittest
app.version.name=0.7.0
app.version.code=7
app.id=tactility.m5unittest
app.version.name=0.8.0
app.version.code=8
app.name=M5 Unit Test
6 changes: 3 additions & 3 deletions Apps/Magic8Ball/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.magic8ball
app.version.name=0.8.0
app.version.code=8
app.id=tactility.magic8ball
app.version.name=0.9.0
app.version.code=9
app.name=Magic 8-Ball
6 changes: 3 additions & 3 deletions Apps/MediaKeys/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32s3,esp32p4
app.id=one.tactility.mediakeys
app.version.name=0.8.0
app.version.code=8
app.id=tactility.mediakeys
app.version.name=0.9.0
app.version.code=9
app.name=Media Keys
app.description=Bluetooth media keys. Touch or Physical Keyboard control\nB - previous, P - play/pause, N - next, M - mute, D - volume down, U - volume up.\nQ or ESC to exit focus.
6 changes: 3 additions & 3 deletions Apps/MystifyDemo/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.mystifydemo
app.version.name=0.10.0
app.version.code=10
app.id=tactility.mystifydemo
app.version.name=0.11.0
app.version.code=11
app.name=Mystify Demo
8 changes: 4 additions & 4 deletions Apps/SerialConsole/main/Source/ConnectView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,9 @@
#include <lvgl_window_manager/window_manager.h>

#include <app/manager.h>
#include <app/paths.h>
#include <tactility/device.h>
#include <tactility/drivers/uart_controller.h>
#include <tactility/paths.h>
#include <tactility/preferences.h>

#include <cstdlib>
Expand All @@ -19,11 +19,11 @@ namespace {
constexpr TickType_t LVGL_DEFAULT_LOCK_TIME = 500; // 500 ticks = 500 ms

bool getPreferencesPath(std::string& outPath) {
char root[128];
if (paths_get_user_data_path(root, sizeof(root)) != ERROR_NONE) {
char path[128];
if (app_paths_get_user_data_path("tactility.serialconsole", "serial_console.properties", path, sizeof(path)) != ERROR_NONE) {
Comment thread
KenVanHoeylandt marked this conversation as resolved.
return false;
}
outPath = std::string(root) + "/serial_console.properties";
outPath = std::string(path);
return true;
}

Expand Down
6 changes: 3 additions & 3 deletions Apps/SerialConsole/manifest.properties
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
manifest.version=0.2
target.sdk=0.8.0-dev
target.platforms=esp32,esp32s3,esp32c6,esp32p4
app.id=one.tactility.serialconsole
app.version.name=0.11.0
app.version.code=11
app.id=tactility.serialconsole
app.version.name=0.12.0
app.version.code=12
app.name=Serial Console
Loading
Loading