diff --git a/src/new_pins.c b/src/new_pins.c index 0cf8b2af9..c54f1559f 100644 --- a/src/new_pins.c +++ b/src/new_pins.c @@ -1303,6 +1303,9 @@ static commandResult_t CMD_setButtonHoldRepeat(const void *context, const char * CFG_DEFAULT_BTN_REPEAT); return CMD_RES_OK; } +// SetButtonTimes [ValLongPress] [ValShortPress] [ValRepeat] +// Each value is times 100ms, so: +// SetButtonTimes 2 1 1 static commandResult_t CMD_SetButtonTimes(const void *context, const char *cmd, const char *args, int cmdFlags){ diff --git a/src/sim/Controller_Bulb.cpp b/src/sim/Controller_Bulb.cpp index d6e510be1..02799a683 100644 --- a/src/sim/Controller_Bulb.cpp +++ b/src/sim/Controller_Bulb.cpp @@ -19,14 +19,30 @@ void CControllerBulb::onDrawn() { switch (mode) { case BM_BULB: { - setShapesFillColor(CColor(1.0f,1.0f,0.0f)); - if (a && b) { - if (a->shouldLightUpBulb(b)) { - setShapesActive(true); - } - else { - setShapesActive(false); - } + if (a->getVisitCount() == 0) + { + setShapesActive(false); + return; + } + if (b->getVisitCount() == 0) + { + setShapesActive(false); + return; + } + CColor col_yellow(255, 255, 0); + float frac_bulb; + if (a->isDutyPercent(100.0f)) { + frac_bulb = a->determineLEDLightFraction(b); + } + else { + frac_bulb = b->determineLEDLightFraction(a); + } + setShapesFillColor(frac_bulb * col_yellow); + if (a->shouldLightUpBulb(b)) { + setShapesActive(true); + } + else { + setShapesActive(false); } } break; @@ -37,30 +53,35 @@ void CControllerBulb::onDrawn() { setShapesActive(false); return; } - bool bInv = false; - if (gnd->getVoltage() > 1.5f) { - bInv = true; - } - float frac_c = 0; - float frac_w = 0; - if (cool->getVisitCount()) { - if (cool->getVoltage() > 1.5f) { - frac_c = cool->getDutyRange01(); - } - } - if (warm->getVisitCount()) { - if (warm->getVoltage() > 1.5f) { - frac_w = warm->getDutyRange01(); - } - } - CColor col_cool(254, 160, 3); - CColor col_warm(167, 209, 253); + float frac_c = gnd->determineLEDLightFraction(cool); + float frac_w = gnd->determineLEDLightFraction(warm); + CColor col_cool(167, 209, 253); + CColor col_warm(254, 160, 3); CColor fin = col_cool * frac_c + col_warm * frac_w; setShapesActive(true); setShapesFillColor(fin); } break; + case BM_RGB: + { + if (gnd->getVisitCount() == 0) + { + setShapesActive(false); + return; + } + float frac_red = gnd->determineLEDLightFraction(red); + float frac_green = gnd->determineLEDLightFraction(green); + float frac_blue = gnd->determineLEDLightFraction(blue); + CColor col_red(255, 0, 0); + CColor col_green(0, 255, 0); + CColor col_blue(0, 0, 255); + CColor fin = col_red * frac_red + col_green * frac_green + col_blue * frac_blue; + + setShapesActive(true); + setShapesFillColor(fin); + } + break; } } class CControllerBase *CControllerBulb::cloneController(class CShape *origOwner, class CShape *newOwner) { diff --git a/src/sim/Junction.cpp b/src/sim/Junction.cpp index d816a9dae..3d4451f19 100644 --- a/src/sim/Junction.cpp +++ b/src/sim/Junction.cpp @@ -38,6 +38,21 @@ bool CJunction::hasLinkedOnlyWires() const { } return true; } +float CJunction::determineLEDLightFraction(class CJunction *other) { + bool bInv = false; + if (this->getVoltage() > 1.5f) { + bInv = true; + } + float frac_c = 0; + if (other->getVisitCount()) { + if (other->getVoltage() > 1.5f) { + frac_c = other->getDutyRange01(); + if (bInv) + frac_c = 1.0f - frac_c; + } + } + return frac_c; +} bool CJunction::shouldLightUpBulb(class CJunction *other) { float v = other->getVoltage(); float v2 = this->getVoltage(); diff --git a/src/sim/Junction.h b/src/sim/Junction.h index 8de2db9aa..afd6672fa 100644 --- a/src/sim/Junction.h +++ b/src/sim/Junction.h @@ -65,6 +65,9 @@ public: float getDuty() const { return duty; } + bool isDutyPercent(float per) const { + return abs(duty - per) > 0.1f; + } float getDutyRange01() const { return duty*0.01f; } @@ -88,6 +91,7 @@ public: return "CJunction"; } bool shouldLightUpBulb(class CJunction *other); + float determineLEDLightFraction(class CJunction *other); void translateLinked(const Coord &o); void setPosLinked(const Coord &o); void rotateDegreesAround_internal(float f, const Coord &p); diff --git a/src/sim/PrefabManager.h b/src/sim/PrefabManager.h index f7993b673..6ce22d6b2 100644 --- a/src/sim/PrefabManager.h +++ b/src/sim/PrefabManager.h @@ -27,6 +27,12 @@ public: void addPrefab(CShape *o); CShape *findPrefab(const char *name); CShape *instantiatePrefab(const char *name); + unsigned int size() const { + return prefabs.size(); + } + CShape *get(int i) { + return prefabs[i]; + } }; #endif diff --git a/src/sim/Simulator.cpp b/src/sim/Simulator.cpp index 04fed0113..fd512e572 100644 --- a/src/sim/Simulator.cpp +++ b/src/sim/Simulator.cpp @@ -248,6 +248,15 @@ bool CSimulator::createSimulation(bool bDemo) { return false; } +bool CSimulator::beginAddingPrefab(const char *s) { + CShape *newShape = prefabs->instantiatePrefab(s); + if (newShape == 0) { + return true; + } + newShape->setPosition(80, 80); + sim->addObject(newShape); + return false; +} bool CSimulator::loadSimulation(const char *s) { CString fixed; if (FS_Exists(s) == false) { diff --git a/src/sim/Simulator.h b/src/sim/Simulator.h index 046d5fec0..8434c6e2b 100644 --- a/src/sim/Simulator.h +++ b/src/sim/Simulator.h @@ -51,6 +51,7 @@ public: bool isMouseButtonHold(int idx) const { return bMouseButtonStates[idx]; } + bool beginAddingPrefab(const char *s); bool createSimulation(bool bDemo); bool loadSimulation(const char *s); bool saveSimulationAs(const char *s); diff --git a/src/sim/WinMenuBar.cpp b/src/sim/WinMenuBar.cpp index a2b29b3c2..3cbefe88e 100644 --- a/src/sim/WinMenuBar.cpp +++ b/src/sim/WinMenuBar.cpp @@ -3,6 +3,8 @@ #include "WinMenuBar.h" #include "Simulator.h" #include "RecentList.h" +#include "Shape.h" +#include "PrefabManager.h" #include #pragma comment (lib, "nfd_d.lib") @@ -19,6 +21,8 @@ enum { ID_EXIT, ID_OPEN_RECENT_FIRST, ID_OPEN_RECENT_LAST = ID_OPEN_RECENT_FIRST + 100, + ID_CREATE_FIRST, + ID_CREATE_LAST = ID_CREATE_FIRST + 100, ID_OPTIONS, ID_ABOUT, }; @@ -29,6 +33,7 @@ void CWinMenuBar::createWindowsMenu(HWND windowRef) { hEdit = CreateMenu(); hHelp = CreateMenu(); HMENU hRecent = CreateMenu(); + HMENU hCreate = CreateMenu(); AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hFile, "File"); AppendMenu(hMenuBar, MF_POPUP, (UINT_PTR)hEdit, "Edit"); @@ -50,8 +55,17 @@ void CWinMenuBar::createWindowsMenu(HWND windowRef) { AppendMenu(hRecent, MF_STRING, ID_OPEN_RECENT_FIRST + i, tmp.c_str()); } AppendMenu(hFile, MF_STRING, ID_EXIT, "Exit"); - + prefabNames.clear(); AppendMenu(hEdit, MF_STRING, ID_OPTIONS, "Options"); + AppendMenu(hEdit, MF_POPUP, (UINT_PTR)hCreate, "Add.."); + PrefabManager *prefabs = sim->getPfbs(); + for (int i = 0; i < prefabs->size(); i++) { + CShape *sh = prefabs->get(i); + prefabNames.push_back(sh->getName()); + CString tmp = "Add "; + tmp.append(sh->getName()); + AppendMenu(hCreate, MF_STRING, ID_CREATE_FIRST + i, tmp.c_str()); + } AppendMenu(hHelp, MF_STRING, ID_ABOUT, "About"); @@ -126,6 +140,12 @@ void CWinMenuBar::processEvent(const SDL_Event &Event) { const char *recentStr = recents[recentID].c_str(); sim->loadSimulation(recentStr); } + else if (id >= ID_CREATE_FIRST && id <= ID_CREATE_LAST) + { + int createID = id - ID_CREATE_FIRST; + const char *createStr = prefabNames[createID].c_str(); + sim->beginAddingPrefab(createStr); + } } } } diff --git a/src/sim/WinMenuBar.h b/src/sim/WinMenuBar.h index 1d8aedf6d..5f66fa8b9 100644 --- a/src/sim/WinMenuBar.h +++ b/src/sim/WinMenuBar.h @@ -12,6 +12,7 @@ class CWinMenuBar { HMENU hEdit; HMENU hHelp; TArray recents; + TArray prefabNames; void createWindowsMenu(HWND windowRef); HWND getHWNDForSDLWindow(SDL_Window* win);