Merge pull request #2 from liux-pro/main

在电脑上粗略的模拟arduino环境,使WouoUI能在电脑上运行
This commit is contained in:
音游玩的人 2023-07-07 14:50:05 +08:00 committed by GitHub
commit e7fa910e61
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 800 additions and 0 deletions

4
.gitmodules vendored Normal file
View File

@ -0,0 +1,4 @@
[submodule "Third-party-design/Emulator/u8g2"]
path = Third-party-design/Emulator/u8g2
url = https://github.com/liux-pro/u8g2.git
branch = patch-1

View File

@ -0,0 +1 @@
cmake-*

View File

@ -0,0 +1,18 @@
#include "u8g2.h"
#include <stdio.h>
#include "SDL.h"
#include "Arduino.h"
void postLoop();
_Noreturn int main(int argc, char *argv[])
{
setup();
while (1){
loop();
postLoop();
}
}

View File

@ -0,0 +1,13 @@
#ifdef __cplusplus
#include "ArduinoCompatible.h"
extern "C"
{
#endif
void setup();
void loop();
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,19 @@
#include <cstdlib>
#include <unordered_map>
#include <SDL_keycode.h>
#include <SDL_events.h>
#include "ArduinoCompatible.h"
class Serial Serial;
long map(long value, long fromLow, long fromHigh, long toLow, long toHigh) {
return (value - fromLow) * (toHigh - toLow) / (fromHigh - fromLow) + toLow;
}
static float a = 0;
int analogRead(int pin) {
a = a + 1;
return sin(0.1f * a)*1023;
}

View File

@ -0,0 +1,67 @@
#pragma once
#include "U8g2lib.h"
#include <cstdint>
#include <SDL_timer.h>
#include "iostream"
#include <cstdlib>
#include "Pins.h"
#include "WouoFix.h"
#include "Print.h"
#define PROGMEM
// 使用SDL模拟 12864 oled
class U8G2_SDL_128X64 : public U8G2, public Print {
public:
U8G2_SDL_128X64(const u8g2_cb_t *pStruct, int i, int i1, int i2) : U8G2() {
u8g2_SetupBuffer_SDL_128x64(&u8g2, &u8g2_cb_r0);
}
size_t write(const uint8_t *buffer, size_t size) override {
return 1;
}
size_t write(uint8_t) override {
return 1;
}
};
// 兼容串口输出,直接输出到stdout
class Serial {
public:
void println(const char *message) {
std::cout << message << std::endl;
}
void println(int value) {
std::cout << value << std::endl;
}
void println(float value) {
std::cout << value << std::endl;
}
void begin(int rate) {
std::cout << "set fake Serial baud rate " << rate << std::endl;
}
};
extern Serial Serial;
#define delay(ms) SDL_Delay(ms)
long map(long value, long fromLow, long fromHigh, long toLow, long toHigh);
int analogRead(int pin);
#define LOW 0
#define HIGH 1

View File

@ -0,0 +1,11 @@
class EEPROM {
public:
void write(int address, int data) {
}
int read(int address) {
return 0;
}
} EEPROM;

View File

@ -0,0 +1,12 @@
void pinMode(int pin, int mode) {
}
int digitalPinToInterrupt(int pin) {
return 0;
}
void attachInterrupt(int ii, void (*param)(void), int i) {
}

View File

@ -0,0 +1,9 @@
#define INPUT 0
#define INPUT_PULLUP 0
#define CHANGE 0
void pinMode(int pin,int mode);
int digitalPinToInterrupt(int pin);
void attachInterrupt(int ii, void (*param)(void), int i);
int digitalRead(int pin);

View File

@ -0,0 +1,234 @@
/*
Print.cpp - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
Modified 23 November 2006 by David A. Mellis
Modified 03 August 2015 by Chuck Todd
*/
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
// Use Self-defined isnan isinf in Print.h
//#include <math.h>
#include "Print.h"
// Public Methods //////////////////////////////////////////////////////////////
/* default implementation: may be overridden */
size_t Print::write(const uint8_t *buffer, size_t size)
{
size_t n = 0;
while (size--) {
if (write(*buffer++)) n++;
else break;
}
return n;
}
size_t Print::print(const char str[])
{
return write(str);
}
size_t Print::print(char c)
{
return write(c);
}
size_t Print::print(unsigned char b, int base)
{
return print((unsigned long) b, base);
}
size_t Print::print(int n, int base)
{
return print((long) n, base);
}
size_t Print::print(unsigned int n, int base)
{
return print((unsigned long) n, base);
}
size_t Print::print(long n, int base)
{
if (base == 0) {
return write(n);
} else if (base == 10) {
if (n < 0) {
int t = print('-');
n = -n;
return printNumber(n, 10) + t;
}
return printNumber(n, 10);
} else {
return printNumber(n, base);
}
}
size_t Print::print(unsigned long n, int base)
{
if (base == 0) return write(n);
else return printNumber(n, base);
}
size_t Print::print(double n, int digits)
{
return printFloat(n, digits);
}
size_t Print::print(const Printable& x)
{
return x.printTo(*this);
}
size_t Print::println(void)
{
return write("\r\n");
}
size_t Print::println(const char c[])
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(char c)
{
size_t n = print(c);
n += println();
return n;
}
size_t Print::println(unsigned char b, int base)
{
size_t n = print(b, base);
n += println();
return n;
}
size_t Print::println(int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned int num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(unsigned long num, int base)
{
size_t n = print(num, base);
n += println();
return n;
}
size_t Print::println(double num, int digits)
{
size_t n = print(num, digits);
n += println();
return n;
}
size_t Print::println(const Printable& x)
{
size_t n = print(x);
n += println();
return n;
}
// Private Methods /////////////////////////////////////////////////////////////
size_t Print::printNumber(unsigned long n, uint8_t base)
{
char buf[8 * sizeof(long) + 1]; // Assumes 8-bit chars plus zero byte.
char *str = &buf[sizeof(buf) - 1];
*str = '\0';
// prevent crash if called with base == 1
if (base < 2) base = 10;
do {
char c = n % base;
n /= base;
*--str = c < 10 ? c + '0' : c + 'A' - 10;
} while(n);
return write(str);
}
size_t Print::printFloat(double number, uint8_t digits)
{
size_t n = 0;
if (isnan(number)) return print("nan");
if (isinf(number)) return print("inf");
if (number > 4294967040.0) return print ("ovf"); // constant determined empirically
if (number <-4294967040.0) return print ("ovf"); // constant determined empirically
// Handle negative numbers
if (number < 0.0)
{
n += print('-');
number = -number;
}
// Round correctly so that print(1.999, 2) prints as "2.00"
double rounding = 0.5;
for (uint8_t i=0; i<digits; ++i)
rounding /= 10.0;
number += rounding;
// Extract the integer part of the number and print it
unsigned long int_part = (unsigned long)number;
double remainder = number - (double)int_part;
n += print(int_part);
// Print the decimal point, but only if there are digits beyond
if (digits > 0) {
n += print('.');
}
// Extract digits from the remainder one at a time
while (digits-- > 0)
{
remainder *= 10.0;
unsigned int toPrint = (unsigned int)(remainder);
n += print(toPrint);
remainder -= toPrint;
}
return n;
}

View File

@ -0,0 +1,94 @@
/*
Print.h - Base class that provides print() and println()
Copyright (c) 2008 David A. Mellis. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Print_h
#define Print_h
#include <inttypes.h>
#include <stdio.h> // for size_t
#include <string.h>
#include "Printable.h"
#define DEC 10
#define HEX 16
#define OCT 8
#ifdef BIN // Prevent warnings if BIN is previously defined in "iotnx4.h" or similar
#undef BIN
#endif
#define BIN 2
class Print
{
private:
int write_error;
size_t printNumber(unsigned long, uint8_t);
size_t printFloat(double, uint8_t);
int isnan(double x) { return x != x; };
int isinf(double x) { return !isnan(x) && isnan(x - x); };
protected:
void setWriteError(int err = 1) { write_error = err; }
public:
Print() : write_error(0) {}
int getWriteError() { return write_error; }
void clearWriteError() { setWriteError(0); }
virtual size_t write(uint8_t) = 0;
size_t write(const char *str) {
if (str == NULL) return 0;
return write((const uint8_t *)str, strlen(str));
}
virtual size_t write(const uint8_t *buffer, size_t size);
size_t write(const char *buffer, size_t size) {
return write((const uint8_t *)buffer, size);
}
// default to zero, meaning "a single write may block"
// should be overriden by subclasses with buffering
virtual int availableForWrite() { return 0; }
// size_t print(const __FlashStringHelper *);
// size_t print(const String &);
size_t print(const char[]);
size_t print(char);
size_t print(unsigned char, int = DEC);
size_t print(int, int = DEC);
size_t print(unsigned int, int = DEC);
size_t print(long, int = DEC);
size_t print(unsigned long, int = DEC);
size_t print(double, int = 2);
size_t print(const Printable&);
// size_t println(const __FlashStringHelper *);
// size_t println(const String &s);
size_t println(const char[]);
size_t println(char);
size_t println(unsigned char, int = DEC);
size_t println(int, int = DEC);
size_t println(unsigned int, int = DEC);
size_t println(long, int = DEC);
size_t println(unsigned long, int = DEC);
size_t println(double, int = 2);
size_t println(const Printable&);
size_t println(void);
virtual void flush() { /* Empty implementation for backward compatibility */ }
};
#endif

View File

@ -0,0 +1,39 @@
/*
Printable.h - Interface class that allows printing of complex types
Copyright (c) 2011 Adrian McEwen. All right reserved.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 2.1 of the License, or (at your option) any later version.
This library 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
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
#ifndef Printable_h
#define Printable_h
#include <stdlib.h>
class Print;
/** The Printable class provides a way for new classes to allow themselves to be printed.
By deriving from Printable and implementing the printTo method, it will then be possible
for users to print out instances of this class by passing them into the usual
Print::print and Print::println methods.
*/
class Printable
{
public:
virtual size_t printTo(Print& p) const = 0;
};
#endif

View File

@ -0,0 +1,37 @@
class USBHID {
public:
void begin(const uint8_t bar[], int foo) {
}
};
class HIDConsumer {
public:
HIDConsumer(USBHID usbhid) {}
void press(int foo) {
}
void release() {
}
const static int BRIGHTNESS_DOWN=0;
const static int VOLUME_DOWN=0;
const static int VOLUME_UP=0;
const static int BRIGHTNESS_UP=0;
};
class HIDKeyboard {
public:
HIDKeyboard(USBHID usbhid) {
}
void press(int foo) {
}
void release(int foo) {
}
};
const bool USBComposite = true;
#define HID_KEYBOARD_REPORT_DESCRIPTOR(...) 1
#define HID_CONSUMER_REPORT_DESCRIPTOR(...) 1

View File

@ -0,0 +1,27 @@
cmake_minimum_required(VERSION 3.24)
project(WouoUI)
set(CMAKE_C_COMPILER "cc")
set(CMAKE_CXX_COMPILER "c++")
set(CMAKE_NO_SYSTEM_FROM_IMPORTED YES)
find_package(SDL2 REQUIRED)
include_directories(${SDL2_INCLUDE_DIRS})
file(GLOB SRCS_EMULATOR
u8g2/csrc/*.c u8g2/sys/sdl/common/*.c u8g2/cppsrc/*.cpp
Arduino/*.c Arduino/*.cpp
*.c *.cpp)
include_directories(u8g2/csrc/)
include_directories(u8g2/cppsrc/)
include_directories(Arduino/)
include_directories(.)
include_directories(.)
add_executable(WouoUI ${SRCS_EMULATOR})
target_link_libraries(WouoUI ${SDL2_LIBRARIES})

View File

@ -0,0 +1,18 @@
# 作者
[Legend](https://github.com/liux-pro)
# 说明
基于SDL2,移植u8g2,添加Arduino兼容层,模拟必要的Arduino API,模拟编码、按键长短按时序,使WouoUI在能在PC平台编译运。
键盘QWER分别代表编码器左、右旋转,短按,长按。(注意把电脑输入法关了)
EEPROM,ADC,HID无实际功能。
# Windows编译
1. 装好 [msys2](https://www.msys2.org/) 环境
2. (可选)使用 msys2-mingw64 执行`sed -i "s#mirror.msys2.org/#mirrors.ustc.edu.cn/msys2/#g" /etc/pacman.d/mirrorlist*`切换国内源
3. 使用 msys2-mingw64 执行`pacman -S mingw-w64-x86_64-SDL2`安装SDL2
4. 使用 msys2-mingw64 执行`pacman -S mingw-w64-x86_64-toolchain cmake make ninja git`,安装编译器等
5. `git clone --recurse-submodules https://github.com/RQNG/WouoUI.git`
6. `cd WouoUI/Third-party-design/Emulator && cmake -G Ninja -B build`
7. `cd build && ninja`
8. `./WouoUI.exe`

View File

@ -0,0 +1,130 @@
#include <unordered_map>
#include <SDL_events.h>
#include "Arduino.h"
#include "WouoFix.h"
//每次循环加上10毫秒延迟
extern "C" void postLoop(){
delay(10);
}
bool takeOver = false;
long longPress = -1;
std::unordered_map<int32_t, bool> keyStatus;
void knob_inter();
void btn_scan();
int digitalRead(int pin) {
if (takeOver) {
if (longPress == 0) {
keyStatus[pin] = !keyStatus[pin];
longPress--;
}
if (longPress > 0) {
longPress--;
}
return keyStatus[pin];
}
SDL_Event event;
/* https://wiki.libsdl.org/SDL_PollEvent */
if (SDL_PollEvent(&event) != 0) {
switch (event.type) {
case SDL_QUIT:
exit(0);
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym) {
case 'q': {
// 模拟编码器
takeOver = true;
keyStatus[PB12] = 1;
keyStatus[PB13] = 0;
knob_inter();
keyStatus[PB12] = 0;
keyStatus[PB13] = 1;
knob_inter();
keyStatus[PB12] = 1;
keyStatus[PB13] = 0;
knob_inter();
keyStatus[PB12] = 0;
keyStatus[PB13] = 1;
knob_inter();
takeOver = false;
}
break;
case 'w': {
// 模拟编码器
takeOver = true;
keyStatus[PB12] = 1;
keyStatus[PB13] = 1;
knob_inter();
keyStatus[PB12] = 0;
keyStatus[PB13] = 0;
knob_inter();
keyStatus[PB12] = 1;
keyStatus[PB13] = 1;
knob_inter();
keyStatus[PB12] = 0;
keyStatus[PB13] = 0;
knob_inter();
takeOver = false;
}
break;
case 'e': {
// 模拟短按
takeOver = true;
keyStatus[PB14] = 1;
btn_scan();
keyStatus[PB14] = 1;
btn_scan();
keyStatus[PB14] = 0;
longPress = 3;
btn_scan();
takeOver = false;
}
break;
case 'r': {
// 模拟长按
takeOver = true;
keyStatus[PB14] = 1;
btn_scan();
keyStatus[PB14] = 1;
btn_scan();
keyStatus[PB14] = 0;
longPress = 400;
btn_scan();
takeOver = false;
}
break;
default: {
}
}
break;
case SDLK_UP:
switch (event.key.keysym.sym) {
case 'e':
// keyStatus[PB14] = 0;
break;
case 'r':
break;
}
}
}
return keyStatus[pin];
}

View File

@ -0,0 +1,63 @@
#define KEY_ESC 0
#define KEY_F1 0
#define KEY_F2 0
#define KEY_F3 0
#define KEY_F4 0
#define KEY_F5 0
#define KEY_F6 0
#define KEY_F7 0
#define KEY_F8 0
#define KEY_F9 0
#define KEY_F10 0
#define KEY_F11 0
#define KEY_F12 0
#define KEY_LEFT_CTRL 0
#define KEY_LEFT_SHIFT 0
#define KEY_LEFT_ALT 0
#define KEY_LEFT_GUI 0
#define KEY_RIGHT_CTRL 0
#define KEY_RIGHT_SHIFT 0
#define KEY_RIGHT_ALT 0
#define KEY_RIGHT_GUI 0
#define KEY_CAPS_LOCK 0
#define KEY_BACKSPACE 0
#define KEY_RETURN 0
#define KEY_INSERT 0
#define KEY_DELETE 0
#define KEY_TAB 0
#define KEY_HOME 0
#define KEY_END 0
#define KEY_PAGE_UP 0
#define KEY_PAGE_DOWN 0
#define KEY_UP_ARROW 0
#define KEY_DOWN_ARROW 0
#define KEY_LEFT_ARROW 0
#define KEY_RIGHT_ARROW 0
#define PA0 0
#define PA1 0
#define PA2 0
#define PA3 0
#define PA4 0
#define PA5 0
#define PA6 0
#define PA7 0
#define PB0 0
#define PB1 0
#include <SDL_keycode.h>
#define PB12 SDLK_q
#define PB13 SDLK_w
#define PB14 SDLK_e
#define PB6 0
#define PB7 0
#define U8X8_PIN_NONE (-1)
#define U8G2_SSD1306_128X64_NONAME_F_HW_I2C U8G2_SDL_128X64
void ui_param_init();

View File

@ -0,0 +1,2 @@
#include "Arduino.h"
#include "../../WouoUI-128_64/WouoUI-128_64.ino"

@ -0,0 +1 @@
Subproject commit 20692fb90d1b40ed61b26795a769ad0c1165d8ec

View File

@ -3,3 +3,4 @@
# 目录 # 目录
* Template第三方项目模板作者RQNG * Template第三方项目模板作者RQNG
* Emulator在电脑上运行WonoUI作者Legend