Skip to content

Commit

Permalink
#238 keyboard control improvement (#241)
Browse files Browse the repository at this point in the history
* #238-key-improvements
* rework tests, cleanup, improve handling
* Improve doc generation
  • Loading branch information
vintagepc authored Sep 19, 2020
1 parent 1627a0a commit ab781c7
Show file tree
Hide file tree
Showing 55 changed files with 810 additions and 307 deletions.
54 changes: 42 additions & 12 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,8 @@ set(H_FILES
3rdParty/arcball/Vectors.hpp
3rdParty/arcball/ArcBall.hpp
3rdParty/arcball/Quaternion.hpp
parts/IKeyClient.h
parts/KeyController.h
)

set(MK404_SOURCES
Expand Down Expand Up @@ -167,6 +169,8 @@ set(MK404_SOURCES
utility/Color.cpp
utility/SerialPipe.cpp
3rdParty/arcball/Camera.cpp
parts/IKeyClient.cpp
parts/KeyController.cpp
)

if (ENABLE_TIDY)
Expand Down Expand Up @@ -390,22 +394,48 @@ add_custom_target(Einsy_atmega2560_SDcard.bin COMMAND mcopy -vsi FAT32.img ${PRO
COMMAND mv FAT32.img Einsy_atmega2560_SDcard.bin)
add_dependencies(Einsy_atmega2560_SDcard.bin FAT32.img)

SET(PRINTERS
Prusa_MK3
Prusa_MK3MMU2
Prusa_MK3S
Prusa_MK3SMMU2
)

add_custom_target(UpdateDocs
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 -g none --scripthelp --markdown | grep -A500 "Scripting options" > ${PROJECT_SOURCE_DIR}/ref/autogen/Scripting_MK3S.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 -g none --scripthelp --markdown Prusa_MK3SMMU2 | grep -A500 "Scripting options" > ${PROJECT_SOURCE_DIR}/ref/autogen/Scripting_MK3SMMU2.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 -g none --scripthelp --markdown Prusa_MK3MMU2 | grep -A500 "Scripting options" > ${PROJECT_SOURCE_DIR}/ref/autogen/Scripting_MK3MMU2.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 -g none --scripthelp --markdown Prusa_MK3 | grep -A500 "Scripting options" > ${PROJECT_SOURCE_DIR}/ref/autogen/Scripting_MK3.md
COMMAND echo '```' > ${PROJECT_SOURCE_DIR}/ref/autogen/CommandLine.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 --help >> ${PROJECT_SOURCE_DIR}/ref/autogen/CommandLine.md
COMMAND echo '```' >> ${PROJECT_SOURCE_DIR}/ref/autogen/CommandLine.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 -g none --markdown --trace ? | grep -A500 "telemetry" > ${PROJECT_SOURCE_DIR}/ref/autogen/TraceOptions_MK3S.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 -g none --markdown --trace ? Prusa_MK3SMMU2| grep -A500 "telemetry" > ${PROJECT_SOURCE_DIR}/ref/autogen/TraceOptions_MK3SMMU2.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 -g none --markdown --trace ? Prusa_MK3MMU2| grep -A500 "telemetry" > ${PROJECT_SOURCE_DIR}/ref/autogen/TraceOptions_MK3MMU2.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 -g none --markdown --trace ? Prusa_MK3| grep -A500 "telemetry" > ${PROJECT_SOURCE_DIR}/ref/autogen/TraceOptions_MK3.md
COMMAND echo '```' > ${PROJECT_SOURCE_DIR}/ref/autogen/Command-Line.md
COMMAND cd ${PROJECT_BINARY_DIR} && ./MK404 --help >> ${PROJECT_SOURCE_DIR}/ref/autogen/Command-Line.md
COMMAND echo '```' >> ${PROJECT_SOURCE_DIR}/ref/autogen/Command-Line.md
COMMAND cd ${PROJECT_SOURCE_DIR}/ref/autogen && sh ../../assets/updateTOC.sh
)
add_dependencies(UpdateDocs MK404)

foreach (PRINTER IN LISTS PRINTERS)
message(STATUS "Adding DocGen for ${PRINTER}")
add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/ref/autogen/Scripting-${PRINTER}.md
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMAND ./MK404 ${PRINTER} -g none --scripthelp --markdown | grep -A500 "Scripting options" > ${PROJECT_SOURCE_DIR}/ref/autogen/Scripting-${PRINTER}.md
DEPENDS MK404
)
add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/ref/autogen/Trace-Options-${PRINTER}.md
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMAND ./MK404 ${PRINTER} -g none --markdown --trace ? | grep -A500 "telemetry" > ${PROJECT_SOURCE_DIR}/ref/autogen/Trace-Options-${PRINTER}.md
DEPENDS MK404
)
add_custom_command(OUTPUT ${PROJECT_SOURCE_DIR}/ref/autogen/Key-Controls-${PRINTER}.md
WORKING_DIRECTORY ${PROJECT_BINARY_DIR}
COMMAND ./MK404 ${PRINTER} -g none --markdown -k | grep -A500 "Key Controls:" > ${PROJECT_SOURCE_DIR}/ref/autogen/Key-Controls-${PRINTER}.md
DEPENDS MK404
)
add_custom_target(DocGen_${PRINTER} DEPENDS
${PROJECT_SOURCE_DIR}/ref/autogen/Key-Controls-${PRINTER}.md
${PROJECT_SOURCE_DIR}/ref/autogen/Trace-Options-${PRINTER}.md
${PROJECT_SOURCE_DIR}/ref/autogen/Scripting-${PRINTER}.md
)
add_dependencies(UpdateDocs DocGen_${PRINTER})
endforeach()




add_custom_target(Release_Package

Expand All @@ -428,7 +458,7 @@ add_custom_target(Tests
COMMAND ${CMAKE_COMMAND} -E make_directory "${PROJECT_BINARY_DIR}/tests/snaps"
COMMAND lcov -b ${PROJECT_BINARY_DIR} -d ${PROJECT_BINARY_DIR} --zerocounters
COMMAND cp ${PROJECT_SOURCE_DIR}/scripts/tests/Test.img.bz2 ${PROJECT_BINARY_DIR}
COMMAND bunzip2 ${PROJECT_BINARY_DIR}/Test.img.bz2
COMMAND bunzip2 -f ${PROJECT_BINARY_DIR}/Test.img.bz2
COMMAND cd ${PROJECT_BINARY_DIR} && env CTEST_OUTPUT_ON_FAILURE=1 ctest --timeout 180
)
message(STATUS "Environment path is $ENV{LD_LIBRARY_PATH}")
Expand Down
39 changes: 13 additions & 26 deletions MK404.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
*/

#include "FatImage.h" // for FatImage
#include "KeyController.h"
#include "Macros.h"
#include "Printer.h" // for Printer, Printer::VisualType
#include "PrinterFactory.h" // for PrinterFactory
Expand Down Expand Up @@ -71,14 +72,7 @@ void OnSigINT(int) {
{
std::cout << "Caught SIGINT... stopping..." << '\n';
m_bStopping = true;
if (m_bTestMode)
{
pBoard->SetQuitFlag();
}
else if (printer)
{
printer->OnKeyPress('q',0,0);
}
pBoard->SetQuitFlag();
}
else
{
Expand Down Expand Up @@ -153,22 +147,7 @@ void displayCB() /* function called whenever redisplay needed */
glutSwapBuffers();
}

void keyCB(unsigned char key, int x, int y) /* called on key press */
{
switch(key)
{
case '+':
TelemetryHost::GetHost().StartTrace();
std::cout << "Enabled VCD trace." << '\n';
break;
case '-':
TelemetryHost::GetHost().StopTrace();
std::cout << "Stopped VCD trace" << '\n';
break;
default:
printer->OnKeyPress(key,x,y);
}
}

// pragma: LCOV_EXCL_START
void MouseCB(int button, int action, int x, int y) /* called on key press */
{
Expand Down Expand Up @@ -225,7 +204,7 @@ int initGL()
{
// Set up projection matrix
glutDisplayFunc(displayCB); /* set window's display callback */
glutKeyboardFunc(keyCB); /* set window's key callback */
glutKeyboardFunc(KeyController::GLKeyReceiver); /* set window's key callback */
glutMouseFunc(MouseCB);
glutMotionFunc(MotionCB);
glutTimerFunc(1000, timerCB, 0);
Expand Down Expand Up @@ -284,6 +263,7 @@ int main(int argc, char *argv[])
cmd.add(argMute);
SwitchArg argLoad("l","loadfw","Directs the printer to load the default firmware file. (-f implies -l) If neither -l or -f are provided, the printer executes solely from its persisted flash.");
cmd.add(argLoad);
SwitchArg argKeyHelp("k","keys","Prints the list of available keyboard controls",cmd,false);
std::vector<string> vstrSizes = FatImage::GetSizes();
ValuesConstraint<string> vcSizes(vstrSizes);
ValueArg<string> argImgSize("","image-size","Specify a size for a new SD image. You must specify an image with --sdimage",false,"256M",&vcSizes);
Expand Down Expand Up @@ -407,6 +387,13 @@ int main(int argc, char *argv[])


}

if (argKeyHelp.isSet())
{
KeyController::GetController().PrintKeys(argMD.isSet());
exit(0);
}

if (argVCD.isSet() && argVCD.getValue().at(0)=="?")
{
TelemetryHost::GetHost().PrintTelemetry(argMD.isSet());
Expand Down Expand Up @@ -439,7 +426,7 @@ int main(int argc, char *argv[])
// This is a little lazy, I know. Figure it out once we have non-einsy printers.
if (argMute.isSet())
{
printer->OnKeyPress('m',0,0);
KeyController::GetController().OnKeyPressed('m');
}

// Useful for getting serial pipes/taps setup, the node exists so you can
Expand Down
6 changes: 3 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,12 +66,12 @@ You can make an SD card image and copy files to it using `mcopy`, or by placing
### Controls:

* [Mouse](https://github.com/vintagepc/MK404/wiki/Mouse-Functions)
* [Keyboard](https://github.com/vintagepc/MK404/wiki/Key-Functions)
* [Keyboard](https://github.com/vintagepc/MK404/wiki/Key-Controls)

### Reference documentation:
Advanced documentation has moved to the [Wiki](https://github.com/vintagepc/MK404/wiki):
* [Argument reference](https://github.com/vintagepc/MK404/wiki/CommandLine)
* [Argument reference](https://github.com/vintagepc/MK404/wiki/Command-Line)
* [General scripting info (not in wiki)](scripts/Scripting.md)

* [Script command reference](https://github.com/vintagepc/MK404/wiki/Scripting)
* [Trace option reference](https://github.com/vintagepc/MK404/wiki/TraceOptions)
* [Trace option reference](https://github.com/vintagepc/MK404/wiki/Trace-Options)
15 changes: 11 additions & 4 deletions assets/updateTOC.sh
Original file line number Diff line number Diff line change
@@ -1,14 +1,21 @@
#!/bin/sh
# Update scripting:
echo "# Select a printer to view scripting options:" > Scripting.md
for i in Scripting_*.md; do
for i in Scripting-*.md; do
TMP=`basename $i .md`;
echo "- [${TMP}](${TMP})" >> Scripting.md
done

# Update trace:
echo "# Select a printer to view trace options:" > TraceOptions.md
for i in TraceOptions_*.md; do
echo "# Select a printer to view trace options:" > Trace-Options.md
for i in Trace-Options-*.md; do
TMP=`basename $i .md`;
echo "- [${TMP}](${TMP})" >> TraceOptions.md
echo "- [${TMP}](${TMP})" >> Trace-Options.md
done

# Update trace:
echo "# Select a printer to view keyboard controls:" > Key-Controls.md
for i in Key-Controls-*.md; do
TMP=`basename $i .md`;
echo "- [${TMP}](${TMP})" >> Key-Controls.md
done
19 changes: 19 additions & 0 deletions parts/Board.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -181,6 +181,25 @@ namespace Boards {
OnAVRDeinit();
}

void Board::OnKeyPress(const Key& key)
{
switch (key)
{
case 'z':
m_bPaused ^= true;
std::cout << "Pause: " << m_bPaused << '\n';
break;
case 'q':
SetQuitFlag();
break;
case 'r':
std::cout << "RESET/KILL\n";
// RESET BUTTON
SetResetFlag();
break;
}
}

avr_flashaddr_t Board::LoadFirmware(const string &strFW)
{
uint32_t uiFWSize = 0, uiFWStart = 0;
Expand Down
17 changes: 14 additions & 3 deletions parts/Board.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,9 @@
#pragma once

#include "EEPROM.h" // for EEPROM
#include "IKeyClient.h"
#include "IScriptable.h" // for ArgType, IScriptable::LineStatus, IScript...
#include "KeyController.h"
#include "PinNames.h" // for Pin
#include "ScriptHost.h" // for ScriptHost
#include "Scriptable.h" // for Scriptable
Expand All @@ -35,6 +37,7 @@
#include "sim_regbit.h" // for avr_regbit_get, avr_regbit_set
#include <atomic>
#include <cstdint> // for uint32_t, uint8_t, int8_t
#include <iomanip>
#include <iostream> // for printf, fprintf, NULL, stderr
#include <pthread.h> // for pthread_join, pthread_t
#include <string> // for string, basic_string, stoi
Expand All @@ -47,7 +50,7 @@ using namespace PinNames; //NOLINT - because proper using declarations don't sup

namespace Boards
{
class Board : public Scriptable
class Board : public Scriptable, virtual private IKeyClient
{
public:
// Making a type so that this is easy to update
Expand All @@ -62,6 +65,11 @@ namespace Boards
RegisterActionAndMenu("Pause","Pauses the simulated AVR execution.", ScriptAction::Pause);
RegisterActionAndMenu("Resume","Resumes simulated AVR execution.", ScriptAction::Unpause);
RegisterAction("WaitMs","Waits the specified number of milliseconds (in AVR-clock time)", ScriptAction::Wait,{ArgType::Int});

RegisterKeyHandler('r', "Resets the AVR/board");
RegisterKeyHandler('z', "Pauses/resumes AVR execution");
RegisterKeyHandler('q', "Shuts down the board and exits");

};

~Board() override { if (m_thread) std::cerr << "PROGRAMMING ERROR: " << m_strBoard << " THREAD NOT STOPPED BEFORE DESTRUCTION.\n"; }
Expand Down Expand Up @@ -123,7 +131,7 @@ namespace Boards
inline std::string GetSDCardFile(){return m_strSDFile.empty()?GetStorageFileName("SDcard"):m_strSDFile;}

inline void SetResetFlag(){m_bReset = true;}
inline void SetQuitFlag(){m_bQuit = true;}
inline void SetQuitFlag(){m_bQuit = true; m_bPaused = false;}
inline bool GetQuitFlag(){return m_bQuit;}

inline bool IsStopped(){ return m_pAVR->state == cpu_Stopped;}
Expand All @@ -149,6 +157,8 @@ namespace Boards
// within the context of the AVR run thread.
virtual void OnAVRCycle(){};

void OnKeyPress(const Key& key) override;

LineStatus ProcessAction(unsigned int ID, const std::vector<std::string> &vArgs) override
{
switch (ID)
Expand Down Expand Up @@ -200,6 +210,7 @@ namespace Boards
if (m_bIsPrimary) // Only one board should be scripting.
{
ScriptHost::DispatchMenuCB();
KeyController::GetController().OnAVRCycle(); // Handle/dispatch any pressed keys.
}
if (m_bIsPrimary && ScriptHost::IsInitialized())
{
Expand All @@ -213,7 +224,7 @@ namespace Boards
int8_t uiMCUSR = avr_regbit_get(m_pAVR,MCUSR);
if (uiMCUSR != m_uiLastMCUSR)
{
std::cout << "MCUSR: " << std::hex << (m_uiLastMCUSR = uiMCUSR) << '\n';
std::cout << "MCUSR: " << std::setw(2) << std::hex << (m_uiLastMCUSR = uiMCUSR) << '\n';
if (uiMCUSR) // only run on change and not changed to 0
{
OnAVRReset();
Expand Down
33 changes: 33 additions & 0 deletions parts/IKeyClient.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
/*
IKeyClient.cpp - Mixin interface class for components/objects that have
key actions. To use, mix in this class and call AddKeyControl()
for each key you wish to get notified of. Multiple handlers can
act on the same key by design.
Copyright 2020 VintagePC <https://github.com/vintagepc/>
This file is part of MK404.
MK404 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MK404 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with MK404. If not, see <http://www.gnu.org/licenses/>.
*/

#include "IKeyClient.h"
#include "KeyController.h"
#include <string>


void IKeyClient::RegisterKeyHandler(const Key uiKey, const std::string &strDesc)
{
KeyController::GetController().AddKeyClient(this, uiKey, strDesc);
};
42 changes: 42 additions & 0 deletions parts/IKeyClient.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
IKeyClient.h - Mixin interface class for components/objects that have
key actions. To use, mix in this class and call AddKeyControl()
for each key you wish to get notified of. Multiple handlers can
act on the same key by design.
Copyright 2020 VintagePC <https://github.com/vintagepc/>
This file is part of MK404.
MK404 is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
MK404 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 General Public License for more details.
You should have received a copy of the GNU General Public License
along with MK404. If not, see <http://www.gnu.org/licenses/>.
*/

#pragma once

#include <string>

class KeyController;

using Key = unsigned char;


class IKeyClient
{
friend KeyController;

protected:
virtual void OnKeyPress(const Key &uiKey) = 0;

void RegisterKeyHandler(const Key uiKey, const std::string &strDesc);
};
Loading

0 comments on commit ab781c7

Please sign in to comment.