Add support for reading QR image
This commit is contained in:
parent
2739bc5c8c
commit
9e8375a21b
2
.gitignore
vendored
2
.gitignore
vendored
@ -9,5 +9,7 @@ subprojects/tomlc99
|
||||
subprojects/SDL2-2.26.5
|
||||
subprojects/xxHash-0.8.2
|
||||
subprojects/safetyhook
|
||||
subprojects/zxing-cpp-2.2.1
|
||||
subprojects/stb
|
||||
dist.7z
|
||||
.vscode
|
1
dist/config.toml
vendored
1
dist/config.toml
vendored
@ -22,6 +22,7 @@ unlock_songs = true
|
||||
|
||||
[qr]
|
||||
data = { serial = "", type = 0, song_no = [] }
|
||||
image_path = ""
|
||||
|
||||
[drum]
|
||||
wait_period = 4
|
||||
|
1
dist/keyconfig.toml
vendored
1
dist/keyconfig.toml
vendored
@ -10,6 +10,7 @@ COIN_ADD = ["ENTER", "SDL_START"]
|
||||
CARD_INSERT_1 = ["P"]
|
||||
CARD_INSERT_2 = []
|
||||
QR_DATA_READ = ["Q"]
|
||||
QR_IMAGE_READ = ["W"]
|
||||
|
||||
P1_LEFT_BLUE = ["D", "SDL_LTRIGGER"]
|
||||
P1_LEFT_RED = ["F", "SDL_LSTICK_PRESS"]
|
||||
|
@ -31,6 +31,8 @@ tomlc99 = subproject('tomlc99')
|
||||
sdl2 = subproject('sdl2', default_options: ['default_library=static', 'test=false', 'use_render=disabled'])
|
||||
xxhash = subproject('xxhash', default_options: ['default_library=static', 'cli=false'])
|
||||
safetyhook = subproject('safetyhook')
|
||||
stb = subproject('stb')
|
||||
zxing_dep = dependency('ZXing')
|
||||
|
||||
library(
|
||||
'bnusio',
|
||||
@ -49,6 +51,9 @@ library(
|
||||
xxhash.get_variable('inc'),
|
||||
safetyhook.get_variable('safetyhook_inc'),
|
||||
],
|
||||
dependencies: [stb.get_variable('stb_dep'),
|
||||
zxing_dep,
|
||||
],
|
||||
sources : [
|
||||
'src/dllmain.cpp',
|
||||
'src/helpers.cpp',
|
||||
|
@ -30,6 +30,7 @@ Keybindings COIN_ADD = {.keycodes = {VK_RETURN}, .buttons = {SDL_CONTROLLER
|
||||
Keybindings CARD_INSERT_1 = {.keycodes = {'P'}};
|
||||
Keybindings CARD_INSERT_2 = {};
|
||||
Keybindings QR_DATA_READ = {.keycodes = {'Q'}};
|
||||
Keybindings QR_IMAGE_READ = {.keycodes = {'W'}};
|
||||
Keybindings P1_LEFT_BLUE = {.keycodes = {'D'}, .axis = {SDL_AXIS_LEFT_DOWN}};
|
||||
Keybindings P1_LEFT_RED = {.keycodes = {'F'}, .axis = {SDL_AXIS_LEFT_RIGHT}};
|
||||
Keybindings P1_RIGHT_RED = {.keycodes = {'J'}, .axis = {SDL_AXIS_RIGHT_RIGHT}};
|
||||
@ -348,6 +349,7 @@ Init () {
|
||||
SetConfigValue (keyconfig, "CARD_INSERT_1", &CARD_INSERT_1);
|
||||
SetConfigValue (keyconfig, "CARD_INSERT_2", &CARD_INSERT_2);
|
||||
SetConfigValue (keyconfig, "QR_DATA_READ", &QR_DATA_READ);
|
||||
SetConfigValue (keyconfig, "QR_IMAGE_READ", &QR_IMAGE_READ);
|
||||
|
||||
SetConfigValue (keyconfig, "P1_LEFT_BLUE", &P1_LEFT_BLUE);
|
||||
SetConfigValue (keyconfig, "P1_LEFT_RED", &P1_LEFT_RED);
|
||||
|
@ -1,23 +1,27 @@
|
||||
#include "constants.h"
|
||||
#include "helpers.h"
|
||||
#include "poll.h"
|
||||
#include <ReadBarcode.h>
|
||||
#include <cstdint>
|
||||
#include <filesystem>
|
||||
#include <fstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#define STB_IMAGE_IMPLEMENTATION
|
||||
#include "stb_image.h"
|
||||
|
||||
extern GameVersion gameVersion;
|
||||
extern Keybindings CARD_INSERT_1;
|
||||
extern Keybindings CARD_INSERT_2;
|
||||
extern Keybindings QR_DATA_READ;
|
||||
extern Keybindings QR_IMAGE_READ;
|
||||
extern char accessCode1[21];
|
||||
extern char accessCode2[21];
|
||||
|
||||
namespace patches::Qr {
|
||||
|
||||
enum class State { Ready, CopyWait };
|
||||
enum class Mode { Card, Data };
|
||||
enum class Mode { Card, Data, Image };
|
||||
State gState = State::Ready;
|
||||
Mode gMode = Mode::Card;
|
||||
std::string accessCode;
|
||||
@ -48,16 +52,15 @@ HOOK_DYNAMIC (i64, __fastcall, copy_data, i64, void *dest, int length) {
|
||||
if (gState == State::CopyWait) {
|
||||
std::cout << "Copy data, length: " << length << std::endl;
|
||||
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
toml_table_t *config = openConfig (configPath);
|
||||
auto configPath = std::filesystem::current_path () / "config.toml";
|
||||
std::unique_ptr<toml_table_t, void (*) (toml_table_t *)> config_ptr (openConfig (configPath), toml_free);
|
||||
toml_table_t *config = config_ptr.get ();
|
||||
|
||||
if (gMode == Mode::Card) {
|
||||
if (config) toml_free (config);
|
||||
|
||||
memcpy (dest, accessCode.c_str (), accessCode.size () + 1);
|
||||
gState = State::Ready;
|
||||
return accessCode.size () + 1;
|
||||
} else {
|
||||
} else if (gMode == Mode::Data) {
|
||||
std::string serial = "";
|
||||
u16 type = 0;
|
||||
std::vector<i64> songNoes;
|
||||
@ -72,7 +75,6 @@ HOOK_DYNAMIC (i64, __fastcall, copy_data, i64, void *dest, int length) {
|
||||
songNoes = readConfigIntArray (data, "song_no", songNoes);
|
||||
}
|
||||
}
|
||||
toml_free (config);
|
||||
}
|
||||
|
||||
BYTE serial_length = (BYTE)serial.size ();
|
||||
@ -104,6 +106,47 @@ HOOK_DYNAMIC (i64, __fastcall, copy_data, i64, void *dest, int length) {
|
||||
memcpy (dest, byteBuffer.data (), byteBuffer.size ());
|
||||
gState = State::Ready;
|
||||
return byteBuffer.size ();
|
||||
} else {
|
||||
const char *imagePath = "";
|
||||
|
||||
if (config) {
|
||||
auto qr = openConfigSection (config, "qr");
|
||||
if (qr) imagePath = readConfigString (qr, "image_path", imagePath);
|
||||
}
|
||||
|
||||
if (!std::filesystem::is_regular_file (imagePath)) {
|
||||
std::cerr << "Failed to open image: " << imagePath << " (file not found)"
|
||||
<< "\n";
|
||||
gState = State::Ready;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int width, height, channels;
|
||||
std::unique_ptr<stbi_uc, void (*) (void *)> buffer (stbi_load (imagePath, &width, &height, &channels, 3), stbi_image_free);
|
||||
if (!buffer) {
|
||||
std::cerr << "Failed to read image: " << imagePath << " (" << stbi_failure_reason () << ")"
|
||||
<< "\n";
|
||||
gState = State::Ready;
|
||||
return 0;
|
||||
}
|
||||
|
||||
ZXing::ImageView image{buffer.get (), width, height, ZXing::ImageFormat::RGB};
|
||||
auto result = ReadBarcode (image);
|
||||
if (!result.isValid ()) {
|
||||
std::cerr << "Failed to read qr: " << imagePath << " (" << ToString (result.error ()) << ")"
|
||||
<< "\n";
|
||||
gState = State::Ready;
|
||||
return 0;
|
||||
}
|
||||
|
||||
std::cout << "Valid" << std::endl;
|
||||
auto byteData = result.bytes ();
|
||||
std::cout << ZXing::ToHex (byteData) << std::endl;
|
||||
auto dataSize = byteData.size ();
|
||||
|
||||
memcpy (dest, byteData.data (), dataSize);
|
||||
gState = State::Ready;
|
||||
return dataSize;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
@ -132,6 +175,10 @@ Update () {
|
||||
std::cout << "Insert" << std::endl;
|
||||
gState = State::CopyWait;
|
||||
gMode = Mode::Data;
|
||||
} else if (IsButtonTapped (QR_IMAGE_READ)) {
|
||||
std::cout << "Insert" << std::endl;
|
||||
gState = State::CopyWait;
|
||||
gMode = Mode::Image;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
6
subprojects/packagefiles/stb/meson.build
Normal file
6
subprojects/packagefiles/stb/meson.build
Normal file
@ -0,0 +1,6 @@
|
||||
project('stb', 'cpp')
|
||||
|
||||
depinc = include_directories('.')
|
||||
stb_dep = declare_dependency(
|
||||
include_directories: depinc,
|
||||
)
|
8
subprojects/stb.wrap
Normal file
8
subprojects/stb.wrap
Normal file
@ -0,0 +1,8 @@
|
||||
[wrap-git]
|
||||
directory=stb
|
||||
url=https://github.com/nothings/stb.git
|
||||
revision=head
|
||||
patch_directory = stb
|
||||
|
||||
[provide]
|
||||
stb = stb_dep
|
11
subprojects/zxing.wrap
Normal file
11
subprojects/zxing.wrap
Normal file
@ -0,0 +1,11 @@
|
||||
[wrap-file]
|
||||
directory=zxing-cpp-2.2.1
|
||||
|
||||
source_url=https://github.com/zxing-cpp/zxing-cpp/archive/refs/tags/v2.2.1.zip
|
||||
source_filename=zxing-cpp-2.2.1.zip
|
||||
source_hash=71d9288f0637d321ee6823d8c27e684e9a00d4ffb92f18aff95fb5342cb6521d
|
||||
method = cmake
|
||||
|
||||
[provide]
|
||||
ZXing=ZXing_dep
|
||||
|
Loading…
Reference in New Issue
Block a user