Update to spice2x-25-04-25 (pre-apply)
> broken commit
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "modules/capture.h"
|
||||
#include "modules/coin.h"
|
||||
#include "modules/control.h"
|
||||
#include "modules/ddr.h"
|
||||
#include "modules/drs.h"
|
||||
#include "modules/iidx.h"
|
||||
#include "modules/info.h"
|
||||
@@ -26,6 +27,7 @@
|
||||
#include "modules/lights.h"
|
||||
#include "modules/memory.h"
|
||||
#include "modules/touch.h"
|
||||
#include "modules/resize.h"
|
||||
#include "request.h"
|
||||
#include "response.h"
|
||||
|
||||
@@ -393,6 +395,7 @@ void Controller::init_state(api::ClientState *state) {
|
||||
state->modules.push_back(new modules::Capture());
|
||||
state->modules.push_back(new modules::Coin());
|
||||
state->modules.push_back(new modules::Control());
|
||||
state->modules.push_back(new modules::DDR());
|
||||
state->modules.push_back(new modules::DRS());
|
||||
state->modules.push_back(new modules::IIDX());
|
||||
state->modules.push_back(new modules::Info());
|
||||
@@ -401,6 +404,7 @@ void Controller::init_state(api::ClientState *state) {
|
||||
state->modules.push_back(new modules::Lights());
|
||||
state->modules.push_back(new modules::Memory());
|
||||
state->modules.push_back(new modules::Touch());
|
||||
state->modules.push_back(new modules::Resize());
|
||||
}
|
||||
|
||||
void Controller::free_state(api::ClientState *state) {
|
||||
|
||||
+1
-29
@@ -27,34 +27,6 @@ namespace api::modules {
|
||||
{ SIGTERM, "SIGTERM" },
|
||||
};
|
||||
|
||||
static inline bool acquire_shutdown_privs() {
|
||||
|
||||
// check if already acquired
|
||||
static bool acquired = false;
|
||||
if (acquired)
|
||||
return true;
|
||||
|
||||
// get process token
|
||||
HANDLE hToken;
|
||||
if (!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken))
|
||||
return false;
|
||||
|
||||
// get the LUID for the shutdown privilege
|
||||
TOKEN_PRIVILEGES tkp;
|
||||
LookupPrivilegeValue(NULL, SE_SHUTDOWN_NAME, &tkp.Privileges[0].Luid);
|
||||
tkp.PrivilegeCount = 1;
|
||||
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
|
||||
|
||||
// get the shutdown privilege for this process
|
||||
AdjustTokenPrivileges(hToken, FALSE, &tkp, 0, (PTOKEN_PRIVILEGES) NULL, 0);
|
||||
|
||||
// check for error
|
||||
bool success = GetLastError() == ERROR_SUCCESS;
|
||||
if (success)
|
||||
acquired = true;
|
||||
return success;
|
||||
}
|
||||
|
||||
Control::Control() : Module("control", true) {
|
||||
functions["raise"] = std::bind(&Control::raise, this, _1, _2);
|
||||
functions["exit"] = std::bind(&Control::exit, this, _1, _2);
|
||||
@@ -150,7 +122,7 @@ namespace api::modules {
|
||||
return error(res, "Unable to acquire shutdown privileges");
|
||||
|
||||
// exit windows
|
||||
if (!ExitWindowsEx(EWX_POWEROFF | EWX_FORCE,
|
||||
if (!ExitWindowsEx(EWX_SHUTDOWN | EWX_HYBRID_SHUTDOWN | EWX_FORCE,
|
||||
SHTDN_REASON_MAJOR_APPLICATION |
|
||||
SHTDN_REASON_MINOR_MAINTENANCE))
|
||||
return error(res, "Unable to shutdown system");
|
||||
|
||||
@@ -0,0 +1,54 @@
|
||||
#include "ddr.h"
|
||||
#include <functional>
|
||||
#include "external/rapidjson/document.h"
|
||||
#include "games/ddr/ddr.h"
|
||||
|
||||
using namespace std::placeholders;
|
||||
using namespace rapidjson;
|
||||
|
||||
namespace api::modules {
|
||||
|
||||
DDR::DDR() : Module("ddr") {
|
||||
functions["tapeled_get"] = std::bind(&DDR::tapeled_get, this, _1, _2);
|
||||
}
|
||||
|
||||
/**
|
||||
* Allows fetching of the RGB LED strips that are gold cabinets, via SpiceAPI
|
||||
*/
|
||||
void DDR::tapeled_get(Request &req, Response &res) {
|
||||
static const char* device_names[11] = {
|
||||
"p1_foot_up",
|
||||
"p1_foot_right",
|
||||
"p1_foot_left",
|
||||
"p1_foot_down",
|
||||
"p2_foot_up",
|
||||
"p2_foot_right",
|
||||
"p2_foot_left",
|
||||
"p2_foot_down",
|
||||
"top_panel",
|
||||
"monitor_left",
|
||||
"monitor_right"
|
||||
};
|
||||
|
||||
Value response_object(kObjectType);
|
||||
|
||||
// Iterate through each device and dump its lights data into the response
|
||||
for (size_t device = 0; device < 11; device++) {
|
||||
size_t num_leds = 25;
|
||||
if (device > 7)
|
||||
num_leds = 50;
|
||||
|
||||
Value light_state(kArrayType);
|
||||
light_state.Reserve(num_leds * 3, res.doc()->GetAllocator());
|
||||
for (size_t led = 0; led < num_leds; led++) {
|
||||
light_state.PushBack(games::ddr::DDR_TAPELEDS[device][led][0], res.doc()->GetAllocator());
|
||||
light_state.PushBack(games::ddr::DDR_TAPELEDS[device][led][1], res.doc()->GetAllocator());
|
||||
light_state.PushBack(games::ddr::DDR_TAPELEDS[device][led][2], res.doc()->GetAllocator());
|
||||
}
|
||||
|
||||
response_object.AddMember(StringRef(device_names[device]), light_state, res.doc()->GetAllocator());
|
||||
}
|
||||
|
||||
res.add_data(response_object);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include "api/module.h"
|
||||
#include "api/request.h"
|
||||
|
||||
namespace api::modules {
|
||||
|
||||
class DDR : public Module {
|
||||
public:
|
||||
DDR();
|
||||
|
||||
private:
|
||||
// function definitions
|
||||
void tapeled_get(Request &req, Response &res);
|
||||
};
|
||||
}
|
||||
+84
-44
@@ -1,5 +1,7 @@
|
||||
#include "lights.h"
|
||||
#include <functional>
|
||||
#include <cfg/configurator.h>
|
||||
|
||||
#include "external/rapidjson/document.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "cfg/light.h"
|
||||
@@ -17,11 +19,16 @@ namespace api::modules {
|
||||
functions["read"] = std::bind(&Lights::read, this, _1, _2);
|
||||
functions["write"] = std::bind(&Lights::write, this, _1, _2);
|
||||
functions["write_reset"] = std::bind(&Lights::write_reset, this, _1, _2);
|
||||
lights = games::get_lights(eamuse_get_game());
|
||||
|
||||
this->lights = games::get_lights(eamuse_get_game());
|
||||
for (auto &light : *this->lights) {
|
||||
this->lights_by_names.emplace(light.getName(), light);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* read()
|
||||
* read(name: str, ...)
|
||||
*/
|
||||
void Lights::read(api::Request &req, Response &res) {
|
||||
|
||||
@@ -30,17 +37,39 @@ namespace api::modules {
|
||||
return;
|
||||
}
|
||||
|
||||
// add state for each light
|
||||
for (auto &light : *this->lights) {
|
||||
Value state(kArrayType);
|
||||
Value light_name(light.getName().c_str(), res.doc()->GetAllocator());
|
||||
Value light_state(GameAPI::Lights::readLight(RI_MGR, light));
|
||||
Value light_enabled(light.override_enabled);
|
||||
state.PushBack(light_name, res.doc()->GetAllocator());
|
||||
state.PushBack(light_state, res.doc()->GetAllocator());
|
||||
state.PushBack(light_enabled, res.doc()->GetAllocator());
|
||||
res.add_data(state);
|
||||
// all lights for this game
|
||||
if (req.params.Size() == 0) {
|
||||
// add state for each light
|
||||
for (auto &light : *this->lights) {
|
||||
get_light(light, res);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
// specified light names
|
||||
for (Value ¶m : req.params.GetArray()) {
|
||||
// check params
|
||||
if (!param.IsString()) {
|
||||
error_type(res, "name", "string");
|
||||
return;
|
||||
}
|
||||
const auto name = param.GetString();
|
||||
if (this->lights_by_names.contains(name)) {
|
||||
get_light(this->lights_by_names.at(name).get(), res);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Lights::get_light(Light &light, Response &res) {
|
||||
Value state(kArrayType);
|
||||
Value light_name(light.getName().c_str(), res.doc()->GetAllocator());
|
||||
Value light_state(GameAPI::Lights::readLight(RI_MGR, light));
|
||||
Value light_enabled(light.override_enabled);
|
||||
state.PushBack(light_name, res.doc()->GetAllocator());
|
||||
state.PushBack(light_state, res.doc()->GetAllocator());
|
||||
state.PushBack(light_enabled, res.doc()->GetAllocator());
|
||||
res.add_data(state);
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,6 +117,7 @@ namespace api::modules {
|
||||
|
||||
/**
|
||||
* write_reset()
|
||||
* write_reset(name: str, ...)
|
||||
* write_reset([name: str], ...)
|
||||
*/
|
||||
void Lights::write_reset(Request &req, Response &res) {
|
||||
@@ -104,7 +134,12 @@ namespace api::modules {
|
||||
if (params.Size() == 0) {
|
||||
if (lights != nullptr) {
|
||||
for (auto &light : *this->lights) {
|
||||
light.override_enabled = false;
|
||||
if (light.override_enabled) {
|
||||
if (cfg::CONFIGURATOR_STANDALONE) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, light, light.last_state);
|
||||
}
|
||||
light.override_enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return;
|
||||
@@ -112,26 +147,28 @@ namespace api::modules {
|
||||
|
||||
// loop parameters
|
||||
for (Value ¶m : req.params.GetArray()) {
|
||||
const char* light_name = nullptr;
|
||||
|
||||
// check params
|
||||
if (!param.IsArray()) {
|
||||
error(res, "parameters must be arrays");
|
||||
return;
|
||||
if (param.IsArray()) {
|
||||
if (param.Size() < 1) {
|
||||
error_params_insufficient(res);
|
||||
continue;
|
||||
}
|
||||
if (!param[0].IsString()) {
|
||||
error_type(res, "name", "string");
|
||||
continue;
|
||||
}
|
||||
// get params
|
||||
light_name = param[0].GetString();
|
||||
} else if (param.IsString()) {
|
||||
light_name = param.GetString();
|
||||
} else {
|
||||
error(res, "parameters must be arrays or strings");
|
||||
}
|
||||
if (param.Size() < 1) {
|
||||
error_params_insufficient(res);
|
||||
continue;
|
||||
}
|
||||
if (!param[0].IsString()) {
|
||||
error_type(res, "name", "string");
|
||||
continue;
|
||||
}
|
||||
|
||||
// get params
|
||||
auto light_name = param[0].GetString();
|
||||
|
||||
// write analog state
|
||||
if (!this->write_light_reset(light_name)) {
|
||||
if (light_name && !this->write_light_reset(light_name)) {
|
||||
error_unknown(res, "analog", light_name);
|
||||
continue;
|
||||
}
|
||||
@@ -146,16 +183,20 @@ namespace api::modules {
|
||||
}
|
||||
|
||||
// find light
|
||||
for (auto &light : *this->lights) {
|
||||
if (light.getName() == name) {
|
||||
light.override_state = CLAMP(state, 0.f, 1.f);
|
||||
light.override_enabled = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
if (this->lights_by_names.contains(name)) {
|
||||
auto &light = this->lights_by_names.at(name).get();
|
||||
light.override_state = CLAMP(state, 0.f, 1.f);
|
||||
light.override_enabled = true;
|
||||
|
||||
// unknown light
|
||||
return false;
|
||||
if (cfg::CONFIGURATOR_STANDALONE) {
|
||||
GameAPI::Lights::writeLight(RI_MGR, light, state);
|
||||
}
|
||||
|
||||
return true;
|
||||
} else {
|
||||
// unknown light
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
bool Lights::write_light_reset(std::string name) {
|
||||
@@ -166,14 +207,13 @@ namespace api::modules {
|
||||
}
|
||||
|
||||
// find light
|
||||
for (auto &light : *this->lights) {
|
||||
if (light.getName() == name) {
|
||||
light.override_enabled = false;
|
||||
return true;
|
||||
}
|
||||
if (this->lights_by_names.contains(name)) {
|
||||
auto &light = this->lights_by_names.at(name).get();
|
||||
light.override_enabled = false;
|
||||
return true;
|
||||
} else {
|
||||
// unknown light
|
||||
return false;
|
||||
}
|
||||
|
||||
// unknown light
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
#include <external/robin_hood.h>
|
||||
|
||||
#include "api/module.h"
|
||||
#include "api/request.h"
|
||||
#include "cfg/api.h"
|
||||
@@ -15,6 +17,7 @@ namespace api::modules {
|
||||
|
||||
// state
|
||||
std::vector<Light> *lights;
|
||||
robin_hood::unordered_map<std::string, std::reference_wrapper<Light>> lights_by_names;
|
||||
|
||||
// function definitions
|
||||
void read(Request &req, Response &res);
|
||||
@@ -22,6 +25,7 @@ namespace api::modules {
|
||||
void write_reset(Request &req, Response &res);
|
||||
|
||||
// helper
|
||||
void get_light(Light &light, Response &res);
|
||||
bool write_light(std::string name, float state);
|
||||
bool write_light_reset(std::string name);
|
||||
};
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
#include "resize.h"
|
||||
#include "external/rapidjson/document.h"
|
||||
#include "cfg/screen_resize.h"
|
||||
|
||||
using namespace std::placeholders;
|
||||
using namespace rapidjson;
|
||||
|
||||
namespace api::modules {
|
||||
|
||||
static thread_local std::vector<uint8_t> CAPTURE_BUFFER;
|
||||
|
||||
Resize::Resize() : Module("resize") {
|
||||
functions["image_resize_enable"] = std::bind(&Resize::image_resize_enable, this, _1, _2);
|
||||
functions["image_resize_set_scene"] = std::bind(&Resize::image_resize_set_scene, this, _1, _2);
|
||||
}
|
||||
|
||||
/**
|
||||
* image_resize_enable(enable: bool)
|
||||
*/
|
||||
void Resize::image_resize_enable(Request &req, Response &res) {
|
||||
if (req.params.Size() < 1) {
|
||||
return error_params_insufficient(res);
|
||||
}
|
||||
if (!req.params[0].IsBool()) {
|
||||
return error_type(res, "enable", "bool");
|
||||
}
|
||||
|
||||
cfg::SCREENRESIZE->enable_screen_resize = req.params[0].GetBool();
|
||||
}
|
||||
|
||||
/**
|
||||
* image_resize_set_scene(scene: int)
|
||||
*/
|
||||
void Resize::image_resize_set_scene(Request &req, Response &res) {
|
||||
if (req.params.Size() < 1) {
|
||||
return error_params_insufficient(res);
|
||||
}
|
||||
if (!req.params[0].IsInt()) {
|
||||
return error_type(res, "scene", "int");
|
||||
}
|
||||
|
||||
const auto scene = req.params[0].GetInt();
|
||||
if (scene < 0 || (int)std::size(cfg::SCREENRESIZE->scene_settings) < scene) {
|
||||
return error(res, "invalid scene number");
|
||||
}
|
||||
if (scene == 0) {
|
||||
cfg::SCREENRESIZE->enable_screen_resize = false;
|
||||
} else {
|
||||
cfg::SCREENRESIZE->enable_screen_resize = true;
|
||||
cfg::SCREENRESIZE->screen_resize_current_scene = scene - 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
#pragma once
|
||||
|
||||
#include "api/module.h"
|
||||
#include "api/request.h"
|
||||
|
||||
namespace api::modules {
|
||||
|
||||
class Resize : public Module {
|
||||
public:
|
||||
Resize();
|
||||
|
||||
private:
|
||||
|
||||
// function definitions
|
||||
void image_resize_enable(Request &req, Response &res);
|
||||
void image_resize_set_scene(Request &req, Response &res);
|
||||
};
|
||||
}
|
||||
@@ -4,6 +4,7 @@
|
||||
|
||||
#include "external/rapidjson/document.h"
|
||||
#include "avs/game.h"
|
||||
#include "hooks/graphics/graphics.h"
|
||||
#include "misc/eamuse.h"
|
||||
#include "launcher/launcher.h"
|
||||
#include "touch/touch.h"
|
||||
@@ -18,7 +19,12 @@ namespace api::modules {
|
||||
|
||||
Touch::Touch() : Module("touch") {
|
||||
is_sdvx = avs::game::is_model("KFC");
|
||||
|
||||
is_tdj_fhd = (avs::game::is_model("LDJ") && games::iidx::is_tdj_fhd());
|
||||
// special case: when windowed subscreen is in use, use the original coords
|
||||
if (GRAPHICS_IIDX_WSUB) {
|
||||
is_tdj_fhd = false;
|
||||
}
|
||||
|
||||
functions["read"] = std::bind(&Touch::read, this, _1, _2);
|
||||
functions["write"] = std::bind(&Touch::write, this, _1, _2);
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
# Lua Scripting
|
||||
Supported version: Lua 5.4.3
|
||||
No proper documentation yet. Check the example scripts if you need this!
|
||||
For undocumented functions you can find the definitions in the source code (script/api/*.cpp).
|
||||
They are very similar to what the network API provides.
|
||||
|
||||
# Automatic Execution
|
||||
Create a "scripts" folder next to spice and put your scripts in there (subfolders allowed).
|
||||
The prefix specifies when the script will be called:
|
||||
|
||||
- `boot_*`: executed on game boot
|
||||
- `shutdown_*`: executed on game end
|
||||
- `config_*`: executed when you start spicecfg (mostly for debugging/tests)
|
||||
|
||||
Example: "scripts/boot_patch.py" would be called on game boot.
|
||||
@@ -1,113 +0,0 @@
|
||||
-- example script for light effects on IIDX TT stab movement
|
||||
-- create a folder called "script" next to spice and put me in there
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- settings
|
||||
tt_duration = 0.25
|
||||
zero_duration = 0.3141592
|
||||
loop_delta = 1 / 240
|
||||
curve_pow = 1 / 4
|
||||
col_r = 1.0
|
||||
col_g = 0.0
|
||||
col_b = 0.0
|
||||
light_p1_r = "Side Panel Left Avg R"
|
||||
light_p1_g = "Side Panel Left Avg G"
|
||||
light_p1_b = "Side Panel Left Avg B"
|
||||
light_p2_r = "Side Panel Right Avg R"
|
||||
light_p2_g = "Side Panel Right Avg G"
|
||||
light_p2_b = "Side Panel Right Avg B"
|
||||
|
||||
-- wait for game
|
||||
while not analogs.read()["Turntable P1"] do yield() end
|
||||
|
||||
-- initial state
|
||||
tt1_last = tonumber(analogs.read()["Turntable P1"].state)
|
||||
tt2_last = tonumber(analogs.read()["Turntable P2"].state)
|
||||
tt1_diff_last = 0
|
||||
tt2_diff_last = 0
|
||||
tt1_trigger = 0
|
||||
tt2_trigger = 0
|
||||
tt1_zero_elapsed = 0
|
||||
tt2_zero_elapsed = 0
|
||||
|
||||
-- main loop
|
||||
while true do
|
||||
|
||||
-- read state
|
||||
tt1 = tonumber(analogs.read()["Turntable P1"].state)
|
||||
tt2 = tonumber(analogs.read()["Turntable P2"].state)
|
||||
time_cur = time()
|
||||
|
||||
-- calculate difference
|
||||
tt1_diff = tt1 - tt1_last
|
||||
tt2_diff = tt2 - tt2_last
|
||||
|
||||
-- fix wrap around
|
||||
if math.abs(tt1_diff) > 0.5 then tt1_diff = 0 end
|
||||
if math.abs(tt2_diff) > 0.5 then tt2_diff = 0 end
|
||||
|
||||
-- trigger on movement start and direction changes
|
||||
if (tt1_diff_last == 0 and tt1_diff ~= 0)
|
||||
or (tt1_diff_last > 0 and tt1_diff < 0)
|
||||
or (tt1_diff_last < 0 and tt1_diff > 0) then
|
||||
tt1_trigger = time_cur
|
||||
end
|
||||
if (tt2_diff_last == 0 and tt2_diff ~= 0)
|
||||
or (tt2_diff_last > 0 and tt2_diff < 0)
|
||||
or (tt2_diff_last < 0 and tt2_diff > 0) then
|
||||
tt2_trigger = time_cur
|
||||
end
|
||||
|
||||
-- light effects when last trigger is still active
|
||||
if time_cur - tt1_trigger < tt_duration then
|
||||
brightness = 1 - ((time_cur - tt1_trigger) / tt_duration) ^ curve_pow
|
||||
lights.write({[light_p1_r]={state=brightness*col_r}})
|
||||
lights.write({[light_p1_g]={state=brightness*col_g}})
|
||||
lights.write({[light_p1_b]={state=brightness*col_b}})
|
||||
else
|
||||
lights.write_reset(light_p1_r)
|
||||
lights.write_reset(light_p1_g)
|
||||
lights.write_reset(light_p1_b)
|
||||
end
|
||||
if time_cur - tt2_trigger < tt_duration then
|
||||
brightness = 1 - ((time_cur - tt2_trigger) / tt_duration) ^ curve_pow
|
||||
lights.write({[light_p2_r]={state=brightness*col_r}})
|
||||
lights.write({[light_p2_g]={state=brightness*col_g}})
|
||||
lights.write({[light_p2_b]={state=brightness*col_b}})
|
||||
else
|
||||
lights.write_reset(light_p2_r)
|
||||
lights.write_reset(light_p2_g)
|
||||
lights.write_reset(light_p2_b)
|
||||
end
|
||||
|
||||
-- flush HID light output
|
||||
lights.update()
|
||||
|
||||
-- turntable movement detection
|
||||
-- doesn't set the diff back to zero unless enough time has passed
|
||||
if tt1_diff == 0 then
|
||||
tt1_zero_elapsed = tt1_zero_elapsed + loop_delta
|
||||
if tt1_zero_elapsed >= zero_duration then
|
||||
tt1_diff_last = tt1_diff
|
||||
end
|
||||
else
|
||||
tt1_zero_elapsed = 0
|
||||
tt1_diff_last = tt1_diff
|
||||
end
|
||||
if tt2_diff == 0 then
|
||||
tt2_zero_elapsed = tt2_zero_elapsed + loop_delta
|
||||
if tt2_zero_elapsed >= zero_duration then
|
||||
tt2_diff_last = tt2_diff
|
||||
end
|
||||
else
|
||||
tt2_zero_elapsed = 0
|
||||
tt2_diff_last = tt2_diff
|
||||
end
|
||||
|
||||
-- remember state
|
||||
tt1_last = tt1
|
||||
tt2_last = tt2
|
||||
|
||||
-- loop end
|
||||
sleep(loop_delta)
|
||||
end
|
||||
@@ -1,57 +0,0 @@
|
||||
-- script examples
|
||||
-- no proper documentation yet
|
||||
-- create a folder called "script" next to spice and put me in there
|
||||
-- then open the config and if needed select IIDX for the demo
|
||||
--------------------------------------------------------------------------------
|
||||
|
||||
-- sleep for 0.2 seconds
|
||||
sleep(0.2)
|
||||
|
||||
-- log functions
|
||||
log_misc("example misc")
|
||||
log_info("example info")
|
||||
log_warning("example warning")
|
||||
--log_fatal("this would terminate")
|
||||
|
||||
-- print time
|
||||
log_info(time())
|
||||
|
||||
-- show message box
|
||||
msgbox("You are running the example script! Select IIDX if not already done.")
|
||||
|
||||
-- wait until analog is available
|
||||
while not analogs.read()["Turntable P1"] do yield() end
|
||||
|
||||
-- write button state
|
||||
buttons.write({["P1 Start"]={state=1}})
|
||||
|
||||
-- write analog state
|
||||
analogs.write({["Turntable P1"]={state=0.33}})
|
||||
|
||||
-- write light state
|
||||
lights.write({["P2 Start"]={state=0.8}})
|
||||
|
||||
-- import other libraries in "script" folder
|
||||
--local example = require('script.example')
|
||||
|
||||
-- demo
|
||||
while true do
|
||||
|
||||
-- analog animation
|
||||
analogs.write({["Turntable P2"]={state=math.abs(math.sin(time()))}})
|
||||
|
||||
-- button blink
|
||||
if math.cos(time() * 10) > 0 then
|
||||
buttons.write({["P1 1"]={state=1}})
|
||||
else
|
||||
buttons.write({["P1 1"]={state=0}})
|
||||
end
|
||||
|
||||
-- flush HID light output
|
||||
lights.update()
|
||||
|
||||
-- check for keyboard press
|
||||
if GetAsyncKeyState(0x20) > 0 then
|
||||
msgbox("You pressed space!")
|
||||
end
|
||||
end
|
||||
@@ -12,3 +12,4 @@ from .keypads import *
|
||||
from .lights import *
|
||||
from .memory import *
|
||||
from .touch import *
|
||||
from .resize import *
|
||||
@@ -2,8 +2,14 @@ from .connection import Connection
|
||||
from .request import Request
|
||||
|
||||
|
||||
def lights_read(con: Connection):
|
||||
res = con.request(Request("lights", "read"))
|
||||
def lights_read(con: Connection, light_names=None):
|
||||
req = Request("lights", "read")
|
||||
|
||||
if light_names:
|
||||
for light_name in light_names:
|
||||
req.add_param(light_name)
|
||||
|
||||
res = con.request(req)
|
||||
return res.get_data()
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
from .connection import Connection
|
||||
from .request import Request
|
||||
|
||||
def image_resize_enable(con: Connection, enable: bool):
|
||||
req = Request("resize", "image_resize_enable")
|
||||
req.add_param(enable)
|
||||
con.request(req)
|
||||
|
||||
def image_resize_set_scene(con: Connection, scene: int):
|
||||
req = Request("resize", "image_resize_set_scene")
|
||||
req.add_param(scene)
|
||||
con.request(req)
|
||||
@@ -179,7 +179,7 @@ class ControlTab(ttk.Frame):
|
||||
self.card_lbl = ttk.Label(self.card, text="Card")
|
||||
self.card_lbl.grid(row=0, columnspan=2)
|
||||
self.card_entry = ttk.Entry(self.card)
|
||||
self.card_entry.insert(tk.END, "E004000000000000")
|
||||
self.card_entry.insert(tk.END, "E004010000000000")
|
||||
self.card_entry.grid(row=1, columnspan=2, sticky=NSEW, padx=2, pady=2)
|
||||
self.card_insert_p1 = ttk.Button(self.card, text="Insert P1", command=self.action_insert_p1)
|
||||
self.card_insert_p1.grid(row=2, column=0, sticky=NSEW, padx=2, pady=2)
|
||||
@@ -397,6 +397,65 @@ class LightsTab(ttk.Frame):
|
||||
# set text
|
||||
self.txt_lights.set_text(txt)
|
||||
|
||||
class ResizeTab(ttk.Frame):
|
||||
"""Resize tab."""
|
||||
|
||||
def __init__(self, app, parent, **kwargs):
|
||||
|
||||
# init frame
|
||||
ttk.Frame.__init__(self, parent, **kwargs)
|
||||
self.app = app
|
||||
self.parent = parent
|
||||
|
||||
# scale grid
|
||||
self.columnconfigure(0, weight=1)
|
||||
|
||||
# image resize
|
||||
self.resize = ttk.Frame(self, padding=(8, 8, 8, 8))
|
||||
self.resize.grid(row=0, column=0, sticky=tk.E+tk.W)
|
||||
self.resize.columnconfigure(0, weight=1)
|
||||
self.resize.columnconfigure(1, weight=1)
|
||||
self.resize_lbl = ttk.Label(self.resize, text="Image Resize")
|
||||
self.resize_lbl.grid(row=0, columnspan=2)
|
||||
|
||||
self.resize_off = ttk.Button(self.resize, text="Disable", command=self.action_resize_false)
|
||||
self.resize_off.grid(row=2, column=0, sticky=NSEW, padx=2, pady=2)
|
||||
|
||||
self.resize_on = ttk.Button(self.resize, text="Enable", command=self.action_resize_on)
|
||||
self.resize_on.grid(row=2, column=1, sticky=NSEW, padx=2, pady=2)
|
||||
|
||||
self.resize_scene_1 = ttk.Button(self.resize, text="Scene 1", command=self.action_resize_scene_1)
|
||||
self.resize_scene_1.grid(row=3, column=0, sticky=NSEW, padx=2, pady=2)
|
||||
self.resize_scene_2 = ttk.Button(self.resize, text="Scene 2", command=self.action_resize_scene_2)
|
||||
self.resize_scene_2.grid(row=3, column=1, sticky=NSEW, padx=2, pady=2)
|
||||
self.resize_scene_3 = ttk.Button(self.resize, text="Scene 3", command=self.action_resize_scene_3)
|
||||
self.resize_scene_3.grid(row=4, column=0, sticky=NSEW, padx=2, pady=2)
|
||||
self.resize_scene_4 = ttk.Button(self.resize, text="Scene 4", command=self.action_resize_scene_4)
|
||||
self.resize_scene_4.grid(row=4, column=1, sticky=NSEW, padx=2, pady=2)
|
||||
|
||||
@api_action
|
||||
def action_resize_on(self):
|
||||
spiceapi.image_resize_enable(self.app.connection, True)
|
||||
|
||||
@api_action
|
||||
def action_resize_false(self):
|
||||
spiceapi.image_resize_enable(self.app.connection, False)
|
||||
|
||||
@api_action
|
||||
def action_resize_scene_1(self):
|
||||
spiceapi.image_resize_set_scene(self.app.connection, 1)
|
||||
|
||||
@api_action
|
||||
def action_resize_scene_2(self):
|
||||
spiceapi.image_resize_set_scene(self.app.connection, 2)
|
||||
|
||||
@api_action
|
||||
def action_resize_scene_3(self):
|
||||
spiceapi.image_resize_set_scene(self.app.connection, 3)
|
||||
|
||||
@api_action
|
||||
def action_resize_scene_4(self):
|
||||
spiceapi.image_resize_set_scene(self.app.connection, 4)
|
||||
|
||||
class MainApp(ttk.Frame):
|
||||
"""The main application frame."""
|
||||
@@ -419,6 +478,8 @@ class MainApp(ttk.Frame):
|
||||
self.tabs.add(self.tab_analogs, text="Analogs")
|
||||
self.tab_lights = LightsTab(self, self.tabs)
|
||||
self.tabs.add(self.tab_lights, text="Lights")
|
||||
self.tab_resize = ResizeTab(self, self.tabs)
|
||||
self.tabs.add(self.tab_resize, text="Resize")
|
||||
self.tab_manual = ManualTab(self, self.tabs)
|
||||
self.tabs.add(self.tab_manual, text="Manual")
|
||||
self.tabs.pack(expand=True, fill=tk.BOTH)
|
||||
|
||||
Reference in New Issue
Block a user