Skip to content

Commit 7d4f11b

Browse files
committed
Implement sound_play block
1 parent 40c1163 commit 7d4f11b

File tree

3 files changed

+391
-1
lines changed

3 files changed

+391
-1
lines changed

src/blocks/soundblocks.cpp

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
// SPDX-License-Identifier: Apache-2.0
22

3+
#include <scratchcpp/iengine.h>
4+
#include <scratchcpp/compiler.h>
5+
#include <scratchcpp/target.h>
6+
#include <algorithm>
7+
38
#include "soundblocks.h"
49

510
using namespace libscratchcpp;
@@ -21,4 +26,63 @@ Rgb SoundBlocks::color() const
2126

2227
void SoundBlocks::registerBlocks(IEngine *engine)
2328
{
29+
engine->addCompileFunction(this, "sound_play", &compilePlay);
30+
}
31+
32+
CompilerValue *SoundBlocks::compilePlay(Compiler *compiler)
33+
{
34+
auto sound = compiler->addInput("SOUND_MENU");
35+
compiler->addTargetFunctionCall("sound_play", Compiler::StaticType::Void, { Compiler::StaticType::Unknown }, { sound });
36+
return nullptr;
37+
}
38+
39+
int sound_wrap_clamp_index(Target *target, int index)
40+
{
41+
const long soundCount = target->sounds().size();
42+
43+
if (index < 0)
44+
return (soundCount + index % (-soundCount)) % soundCount;
45+
else if (index >= soundCount)
46+
return index % soundCount;
47+
else
48+
return index;
49+
}
50+
51+
int sound_get_index(Target *target, const ValueData *sound)
52+
{
53+
if (!value_isString(sound)) {
54+
// Numbers should be treated as sound indices
55+
if (value_isNaN(sound) || value_isInfinity(sound) || value_isNegativeInfinity(sound))
56+
return -1;
57+
else
58+
return sound_wrap_clamp_index(target, value_toLong(sound) - 1);
59+
} else {
60+
// Strings should be treated as sound names, where possible
61+
// TODO: Use UTF-16 in Target
62+
// StringPtr *nameStr = value_toStringPtr(sound);
63+
std::string nameStr;
64+
value_toString(sound, &nameStr);
65+
const int soundIndex = target->findSound(nameStr);
66+
67+
auto it = std::find_if(nameStr.begin(), nameStr.end(), [](char c) { return !std::isspace(c); });
68+
bool isWhiteSpace = (it == nameStr.end());
69+
70+
if (soundIndex != -1) {
71+
return soundIndex;
72+
// Try to cast the string to a number (and treat it as a costume index)
73+
// Pure whitespace should not be treated as a number
74+
} else if (value_isValidNumber(sound) && !isWhiteSpace)
75+
return sound_wrap_clamp_index(target, value_toLong(sound) - 1);
76+
}
77+
78+
return -1;
79+
}
80+
81+
extern "C" void sound_play(Target *target, const ValueData *soundName)
82+
{
83+
int index = sound_get_index(target, soundName);
84+
auto sound = target->soundAt(index);
85+
86+
if (sound)
87+
sound->start();
2488
}

src/blocks/soundblocks.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
namespace libscratchcpp
88
{
99

10+
class IAudioOutput;
11+
1012
class SoundBlocks : public IExtension
1113
{
1214
public:
@@ -15,6 +17,9 @@ class SoundBlocks : public IExtension
1517
Rgb color() const override;
1618

1719
void registerBlocks(IEngine *engine) override;
20+
21+
private:
22+
static CompilerValue *compilePlay(Compiler *compiler);
1823
};
1924

2025
} // namespace libscratchcpp

0 commit comments

Comments
 (0)