88#include < scratchcpp/field.h>
99#include < scratchcpp/stage.h>
1010#include < scratchcpp/costume.h>
11+ #include < scratchcpp/block.h>
12+ #include < scratchcpp/itimer.h>
1113
1214#include " eventblocks.h"
15+ #include " audio/audioinput.h"
16+ #include " audio/iaudioloudness.h"
1317
1418using namespace libscratchcpp ;
1519
20+ IAudioInput *EventBlocks::audioInput = nullptr ;
21+
1622std::string EventBlocks::name () const
1723{
1824 return " Events" ;
@@ -28,15 +34,25 @@ void EventBlocks::registerBlocks(IEngine *engine)
2834 engine->addCompileFunction (this , " event_broadcastandwait" , &compileBroadcastAndWait);
2935 engine->addCompileFunction (this , " event_whenbroadcastreceived" , &compileWhenBroadcastReceived);
3036 engine->addCompileFunction (this , " event_whenbackdropswitchesto" , &compileWhenBackdropSwitchesTo);
37+ engine->addCompileFunction (this , " event_whengreaterthan" , &compileWhenGreaterThan);
3138 engine->addCompileFunction (this , " event_whenkeypressed" , &compileWhenKeyPressed);
3239
40+ // Hat predicates
41+ engine->addHatPredicateCompileFunction (this , " event_whengreaterthan" , &compileWhenGreaterThanPredicate);
42+
3343 // Inputs
3444 engine->addInput (this , " BROADCAST_INPUT" , BROADCAST_INPUT);
45+ engine->addInput (this , " VALUE" , VALUE);
3546
3647 // Fields
3748 engine->addField (this , " BROADCAST_OPTION" , BROADCAST_OPTION);
3849 engine->addField (this , " BACKDROP" , BACKDROP);
50+ engine->addField (this , " WHENGREATERTHANMENU" , WHENGREATERTHANMENU);
3951 engine->addField (this , " KEY_OPTION" , KEY_OPTION);
52+
53+ // Fields values
54+ engine->addFieldValue (this , " LOUDNESS" , Loudness);
55+ engine->addFieldValue (this , " TIMER" , Timer);
4056}
4157
4258void EventBlocks::compileWhenFlagClicked (Compiler *compiler)
@@ -97,6 +113,38 @@ void EventBlocks::compileWhenBackdropSwitchesTo(Compiler *compiler)
97113 compiler->engine ()->addBackdropChangeScript (compiler->block (), BACKDROP);
98114}
99115
116+ void EventBlocks::compileWhenGreaterThanPredicate (Compiler *compiler)
117+ {
118+ Field *field = compiler->field (WHENGREATERTHANMENU);
119+ BlockFunc predicate = nullptr ;
120+
121+ if (field) {
122+ switch (field->specialValueId ()) {
123+ case Loudness:
124+ predicate = &whenLoudnessGreaterThanPredicate;
125+ break ;
126+
127+ case Timer:
128+ predicate = &whenTimerGreaterThanPredicate;
129+ break ;
130+
131+ default :
132+ compiler->addInstruction (vm::OP_NULL);
133+ return ;
134+ }
135+ }
136+
137+ if (predicate) {
138+ compiler->addInput (VALUE);
139+ compiler->addFunctionCall (predicate);
140+ }
141+ }
142+
143+ void EventBlocks::compileWhenGreaterThan (Compiler *compiler)
144+ {
145+ compiler->engine ()->addWhenGreaterThanScript (compiler->block ());
146+ }
147+
100148void EventBlocks::compileWhenKeyPressed (Compiler *compiler)
101149{
102150 // NOTE: Field values don't have to be registered because keys are referenced by their names
@@ -140,3 +188,21 @@ unsigned int EventBlocks::checkBroadcastByIndex(VirtualMachine *vm)
140188 vm->stop (true , true , true );
141189 return 1 ;
142190}
191+
192+ unsigned int EventBlocks::whenLoudnessGreaterThanPredicate (VirtualMachine *vm)
193+ {
194+ if (!audioInput)
195+ audioInput = AudioInput::instance ().get ();
196+
197+ auto audioLoudness = audioInput->audioLoudness ();
198+ const Value &operand = *vm->getInput (0 , 1 );
199+ vm->replaceReturnValue (Value (audioLoudness->getLoudness ()) > operand, 1 );
200+ return 0 ;
201+ }
202+
203+ unsigned int EventBlocks::whenTimerGreaterThanPredicate (VirtualMachine *vm)
204+ {
205+ const Value &operand = *vm->getInput (0 , 1 );
206+ vm->replaceReturnValue (Value (vm->engine ()->timer ()->value ()) > operand, 1 );
207+ return 0 ;
208+ }
0 commit comments