Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
fb2782c
Separated generic list stuff from GenericSelector into GenericList
kometbomb Dec 9, 2018
61ea56b
PatchManager WIP
kometbomb Dec 11, 2018
1a536ca
Add extension handling
kometbomb Dec 11, 2018
09988d8
Merge branch 'refactor-main-app' into extensions
kometbomb Dec 12, 2018
03a9e8a
Refactored default functionality into extension
kometbomb Dec 12, 2018
03d596d
Pass data to extension init
kometbomb Dec 14, 2018
b1cf922
Remove debug flag from compiler options
kometbomb Dec 14, 2018
e0cdd13
Renamed BaseExtension directory
kometbomb Jan 21, 2019
cb5ed95
Merge branch 'master' into extensions
kometbomb Jan 21, 2019
b1ed2ad
Added support for extension dependencies
kometbomb Jan 23, 2019
3e300f0
Merge branch 'extensions' into patch-manager
kometbomb Jan 23, 2019
89592c0
Moved manager to an extension
kometbomb Jan 23, 2019
fcb5da9
Unify makefiles
kometbomb Jan 23, 2019
2adbb5f
Merge branch 'extensions' into patch-manager
kometbomb Jan 23, 2019
196631f
Added readme on extensions
kometbomb Jan 23, 2019
4769873
Added getPatchManager method
kometbomb Jan 24, 2019
7218c9d
Updated documentation
kometbomb Jan 24, 2019
8ed29bb
Updated makefile to include the extension
kometbomb Jan 24, 2019
99d2d57
Updated extension doc
kometbomb Jan 25, 2019
f1e65f8
Updated error message if no synth registered
kometbomb Jan 25, 2019
ed29fae
Refactor editor state values definition
kometbomb Jan 26, 2019
ddb6d13
Patch editor updates
kometbomb Jan 26, 2019
4017658
Refactor editor state values definition
kometbomb Jan 26, 2019
122d1f7
Merge branch 'extensions' into patch-manager
kometbomb Jan 26, 2019
77e7224
Patch editors
kometbomb Jan 26, 2019
5324fb8
EDITOR_STATE_VAUES macro was not expanded
kometbomb Jan 26, 2019
57e0689
Merge branch 'extensions' into patch-manager
kometbomb Jan 26, 2019
3720ba9
Merge branch 'master' into patch-manager
kometbomb Jan 26, 2019
3b8bd3a
Fixed patch saving
kometbomb Jan 26, 2019
060669b
Fixed state saving
kometbomb Jan 26, 2019
f9d3db8
Merge branch 'extensions' into patch-manager
kometbomb Jan 26, 2019
08adc1c
Merge branch 'master' into patch-manager
kometbomb Dec 22, 2021
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 30 additions & 0 deletions EXTENSIONS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
# Extensions

Prototracker can be extended (compile-time) with modular extensions. The exensions can provide new UI components ("Editors") and the main synth engine. The idea is that any forked trackers can pick and choose interesting features while avoiding feature bloat.

The basic Prototracker functionality is in `src/BaseExtension`, you should replace this with your own if you choose to fork Prototracker and name it descriptively.

The main `Makefile` needs to be updated to enable extensions. I.e. locate the following line and add your extension to it:

...

EXTENSIONS=BaseExtension YourExtension

...

## Extension lifecycle

1. `Extension::Extension()` will be called when a new extension is loaded by `Prototracker::loadExtension<Extension>()` and if it was not already constructed by earlier loads.
2. `Extension::init()` will be called some time after `Prototracker::loadExtension<Extension>()` has been called. If you add a dependency in `Extension::init()`, it is ensured that it has been constructed but it is not ensured the init method for the extension has been called. You should only store the reference to the dependency here and use it later in the other lifecycle methods.
3. `Extension::registerSynth()` will be called if an extension hasn't registered a synth yet - not a problem as only one extension should provide a synth.
4. `Extension::registerUIComponents()` will be called.
5. `Extension::registerSectionListeners()` will be called.
6. `Extension::deinit()` (and `Extension::~Extension()`) will be called when Prototracker is shut down.

## Dependencies

`Extension::init()` is the place to load new dependency extensions with `Prototracker::loadExtension<T>()` (the Prototracker instance is passed as the first argument to `Extension::init()`). This makes sure the dependency is loaded and not duplicated (in case multiple extensions depend on the same extension) and returns a reference to the extension. Please take care of the fact the dependency has been loaded but is not necessarily initialized at this point.

## Problems

While many changes to the main Prototracker fork can be isolated to extensions, it may be necessary to edit e.g. the TrackState class (to add effects) and those changes will not be automatically included when reusing an extension in another fork. The extension mechanism will still be useful for many features.
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
PLAT=none
PLATS=mingw linux chip8 emscripten macos

EXTENSIONS=BaseExtension PatchExtension

export SRC=src/*.cpp $(foreach ext,$(EXTENSIONS),src/$(ext)/*.cpp)
export SRC_H=src/*.h $(foreach ext,$(EXTENSIONS),src/$(ext)/*.h)

all: $(PLAT)

$(PLATS) clean:
Expand Down
3 changes: 1 addition & 2 deletions Makefile.chip8
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@
# to other optimizations. Fullscreen mode is forced.

OUTPUT=prototracker
SRC=src/*.cpp

$(OUTPUT): $(SRC) src/*.h
$(OUTPUT): $(SRC) $(SRC_H)
g++ -Wformat -s -std=c++11 -o $@ $(SRC) -lSDL2_image -lSDL2main `sdl2-config --cflags --libs` -march=armv7-a -mtune=cortex-a7 -ffast-math -Ofast -DSCALE=1 -DOVERSAMPLE=0 -DFULLSCREEN=1 -DSAMPLERATE=22050

clean:
Expand Down
5 changes: 2 additions & 3 deletions Makefile.emscripten
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,13 @@
# command line.

OUTPUT=prototracker
SRC=src/*.cpp

$(OUTPUT).html: $(SRC) src/*.h
$(OUTPUT).html: $(SRC) $(SRC_H)
emcc -std=c++11 --preload-file assets -O3 -s NO_EXIT_RUNTIME=0 \
-s EXPORTED_FUNCTIONS='["_main"]' -s SDL2_IMAGE_FORMATS='["png"]' \
-s EXTRA_EXPORTED_RUNTIME_METHODS='["ccall", "FS"]' -DSCALE=2 -DSAMPLERATE=22050 \
-s ALLOW_MEMORY_GROWTH=1 -s USE_SDL=2 -s USE_SDL_IMAGE=2 -s BINARYEN_TRAP_MODE=clamp \
-s WASM=1 -s MODULARIZE=1 $(wildcard $(SRC)) -o $@ -s ASSERTIONS=1
-s WASM=1 -s MODULARIZE=0 $(wildcard $(SRC)) -o $@ -s ASSERTIONS=1

clean:
rm $(OUTPUT).html $(OUTPUT).js $(OUTPUT).data $(OUTPUT).wasm
1 change: 0 additions & 1 deletion Makefile.linux
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
CC=g++
OUTPUT=prototracker
SRC=src/*.cpp

$(OUTPUT): $(SRC) src/*.h
$(CC) -O3 -Wformat -std=c++11 -o $@ $(SRC) -lSDL2_image -lSDL2main `sdl2-config --cflags --libs` -s -DSCALE=2 -static-libstdc++ -static-libgcc
Expand Down
3 changes: 1 addition & 2 deletions Makefile.mingw
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
OUTPUT=prototracker.exe
SRC=src/*.cpp

$(OUTPUT): $(SRC) src/*.h
$(OUTPUT): $(SRC) $(SRC_H)
g++ -DSCALE=2 -O3 -Wformat -std=c++11 -o $@ $(SRC) -lmingw32 -lSDL2_image -lSDL2main -lSDL2 -Ic:/mingw/include/SDL2 -Ic:/tdm-gcc-32/include/SDL2 -s -DENABLE_AUDIO_QUEUE=1

clean:
Expand Down
27 changes: 27 additions & 0 deletions src/BaseExtension/BaseExtension.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#include "BaseExtension.h"
#include "../UIComponentFactory.h"
#include "WaveView.h"
#include "../Prototracker.h"

void BaseExtension::init(Prototracker& prototracker, IPlayer& player, const Song& song)
{
mSynth = new Synth();
}


void BaseExtension::deinit()
{
delete mSynth;
}


ISynth* BaseExtension::registerSynth()
{
return mSynth;
}


void BaseExtension::registerUIComponents(UIComponentFactory& factory, EditorState& editorState)
{
factory.registerComponent("WaveView", [&](const Theme::Element& element){ return new WaveView(editorState, mSynth->getWaveStore()); });
}
16 changes: 16 additions & 0 deletions src/BaseExtension/BaseExtension.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#pragma once

#include "../Extension.h"
#include "Synth.h"

struct IPlayer;

class BaseExtension: public Extension
{
Synth *mSynth;
public:
virtual void init(Prototracker& prototracker, IPlayer& player, const Song& song);
virtual void deinit();
virtual ISynth* registerSynth();
virtual void registerUIComponents(UIComponentFactory& factory, EditorState& editorState);
};
6 changes: 3 additions & 3 deletions src/Oscillator.cpp → src/BaseExtension/Oscillator.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@
#include <math.h>
#include <cstdio>
#include "SDL.h"
#include "Sample.h"
#include "../Sample.h"
#include "WaveStore.h"
#include "SequenceRow.h"
#include "../SequenceRow.h"
#include "Wave.h"
#include "TrackState.h"
#include "../TrackState.h"

Oscillator::Oscillator()
: IOscillator(), mWaveStore(NULL), mWave(0), mSpeed(0), mVolume(1.0), mPosition(0)
Expand Down
10 changes: 5 additions & 5 deletions src/Oscillator.h → src/BaseExtension/Oscillator.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "IOscillator.h"
#include "../IOscillator.h"

struct WaveStore;

Expand All @@ -11,27 +11,27 @@ struct WaveStore;
class Oscillator: public IOscillator
{
const WaveStore* mWaveStore;

int mWave, mQueuedWave;
int mSpeed;
int mPosition;
int mVolume;

public:
static const int volumeResolution = 8192;
static const int oscillatorLength = 256;
static const int oscillatorOversample = OVERSAMPLE;

Oscillator();
virtual ~Oscillator();

virtual void triggerNote();
virtual void handleTrackState(ITrackState& trackState);
void setWaveStore(const WaveStore& sampleStore);
void setPosition(int newPosition);
void setWave(int wave);
void queueWave(int wave);

virtual void setFrequency(float frequency);
virtual void setVolume(int volume);
virtual void update(int numSamples);
Expand Down
File renamed without changes.
File renamed without changes.
22 changes: 11 additions & 11 deletions src/Synth.cpp → src/BaseExtension/Synth.cpp
Original file line number Diff line number Diff line change
@@ -1,21 +1,21 @@
#include "Synth.h"
#include "Oscillator.h"
#include "SequenceRow.h"
#include "Sample.h"
#include "../SequenceRow.h"
#include "../Sample.h"
#include "WaveStore.h"
#include "SDL.h"

Synth::Synth()
: ISynth()
: SynthBase()
{
mWaveStore = new WaveStore();
/*

/*

Initialize the audio tracks.

*/

for (int i = 0 ; i < SequenceRow::maxTracks ; ++i)
{
Oscillator *oscillator = new Oscillator();
Expand All @@ -28,12 +28,12 @@ Synth::Synth()
Synth::~Synth()
{
delete mWaveStore;

/*

NOTE: ~ISynth() will delete the Oscillator objects we initialized
above! No need to cleanup yourself.

*/
}

Expand Down
8 changes: 4 additions & 4 deletions src/Synth.h → src/BaseExtension/Synth.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,16 @@
#pragma once

#include "ISynth.h"
#include "../SynthBase.h"

struct WaveStore;

class Synth: public ISynth
class Synth: public SynthBase
{
WaveStore* mWaveStore;

public:
Synth();
virtual ~Synth();

const WaveStore& getWaveStore() const;
};
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
4 changes: 2 additions & 2 deletions src/WaveView.cpp → src/BaseExtension/WaveView.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "WaveView.h"
#include "Renderer.h"
#include "Color.h"
#include "../Renderer.h"
#include "../Color.h"
#include "SDL.h"
#include "Wave.h"
#include "WaveStore.h"
Expand Down
4 changes: 1 addition & 3 deletions src/WaveView.h → src/BaseExtension/WaveView.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#pragma once

#include "Editor.h"
#include "../Editor.h"

struct WaveStore;

Expand All @@ -14,5 +14,3 @@ class WaveView: public Editor
virtual void onDraw(Renderer& renderer, const SDL_Rect& area);
virtual bool onEvent(SDL_Event& event);
};


44 changes: 21 additions & 23 deletions src/EditorState.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,12 @@ FileSection * EditorState::pack()
{
FileSection * state = FileSection::createSection("STAT");
state->writeByte(0);
state->writeDword(macro);
state->writeDword(octave);
state->writeDword(editMode);

#define EDITOR_STATE_VALUE(name) \
state->writeDword(name);
EDITOR_STATE_VALUES
#undef EDITOR_STATE_VALUE

state->writeDword(followPlayPosition);

/*state->writeDword(copyBuffer.getLength());
Expand Down Expand Up @@ -59,20 +62,12 @@ bool EditorState::unpack(const FileSection& section)
if (version == FileSection::invalidRead)
return false;

unsigned int macroNr = section.readDword(offset);

if (macroNr == FileSection::invalidRead)
return false;

unsigned int octaveNr = section.readDword(offset);

if (octaveNr == FileSection::invalidRead)
return false;

unsigned int editModeNr = section.readDword(offset);

if (editModeNr == FileSection::invalidRead)
return false;
#define EDITOR_STATE_VALUE(name) \
name = section.readDword(offset); \
if (name == FileSection::invalidRead) \
return false;
EDITOR_STATE_VALUES
#undef EDITOR_STATE_VALUE

unsigned int followNr = section.readDword(offset);

Expand Down Expand Up @@ -133,9 +128,6 @@ bool EditorState::unpack(const FileSection& section)
if (!tempAudioDevice)
return false;

macro = macroNr;
octave = octaveNr;
editMode = editModeNr;
followPlayPosition = followNr;
audioDevice = tempAudioDevice;

Expand Down Expand Up @@ -200,7 +192,7 @@ bool TrackEditorState::unpack(const FileSection& section)
if (blockEndNr == FileSection::invalidRead)
return false;

currentRow = currentRowNr;
currentRow = currentRowNr;
currentTrack = currentTrackNr;
currentColumn = currentColumnNr;

Expand All @@ -222,8 +214,14 @@ void EditorState::reset()

followPlayPosition = true;

macro = 0;
// Default all editor state values to zero, override below if needed

#define EDITOR_STATE_VALUE(name) \
name = 0;
EDITOR_STATE_VALUES
#undef EDITOR_STATE_VALUE

// Override octave default
octave = 4;
editMode = 0;
audioDevice = "";
}
12 changes: 9 additions & 3 deletions src/EditorState.h
Original file line number Diff line number Diff line change
Expand Up @@ -21,11 +21,17 @@ struct TrackEditorState
bool unpack(const FileSection& section);
};

#define EDITOR_STATE_VALUES \
EDITOR_STATE_VALUE(macro) \
EDITOR_STATE_VALUE(octave) \
EDITOR_STATE_VALUE(editMode) \
EDITOR_STATE_VALUE(patch)

struct EditorState
{
Value macro;
Value octave;
Value editMode;
#define EDITOR_STATE_VALUE(name) Value name;
EDITOR_STATE_VALUES
#undef EDITOR_STATE_VALUE

TrackEditorState sequenceEditor;
TrackEditorState patternEditor;
Expand Down
Loading