Skip to content

Commit

Permalink
Added support for PumaTracker format.
Browse files Browse the repository at this point in the history
  • Loading branch information
neumatho committed Jan 18, 2025
1 parent 6aa8441 commit a116710
Show file tree
Hide file tree
Showing 26 changed files with 2,635 additions and 1 deletion.
2 changes: 1 addition & 1 deletion Documentation/features.html
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
<tr><td>
<span>
<ul>
<li>Supports 179 different types of modules (and increasing).</li>
<li>Supports 180 different types of modules (and increasing).</li>
<li>One of the most accurate players in the world: plays modules like nature intended.</li>
<li>Fast and optimized.</li>
<li>Edit and save your favorite lists of modules.</li>
Expand Down
3 changes: 3 additions & 0 deletions Documentation/images/editors/pumatracker.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 3 additions & 0 deletions Documentation/images/editors/pumatracker_t.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions Documentation/moduletypes.html
Original file line number Diff line number Diff line change
Expand Up @@ -1952,6 +1952,20 @@
</span>
</td>
</tr>
<tr name="P" style="display:none;">
<td>
<a href="images/editors/pumatracker.png" data-lightbox="image-pumatracker"><img src="images/editors/pumatracker_t.png"/></a>
</td>
<td>
<span>
<p><b><i>PumaTracker</i></b> - The original player was ripped from the game Toki and then optimized by Flyspy/Agile. Agile then created an editor based on the replay routine. This player can play those modules.</p>
<p class="first"><b>File extension</b></p>
<p>.puma</p>
<p><b>Player</b></p>
<p>PumaTracker</p>
</span>
</td>
</tr>
<tr name="P" style="display:none;">
<td>
<a href="images/editors/pygmypacker.png" data-lightbox="image-pygmypacker"><img src="images/editors/pygmypacker_t.png"/></a>
Expand Down
157 changes: 157 additions & 0 deletions Format_Descriptions/PumaTracker.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,157 @@
Module format:

0 C Module name
C 2 Number of positions - 1 (NOP)
E 2 Number of tracks (NOT)
10 2 Number of instruments (NOI)
12
14 A * 4 Sample start offsets
3C A * 2 Sample lengths in words
50 (NOP + 1) * E Position list
NOT * x Tracks
Extra "patt" mark
Instruments
Extra "inst" mark
Samples


Position list:

0 1 Track number for voice 1
1 2 Instrument transpose for voice 1
2 3 Note transpose for voice 1
3 1 Track number for voice 2
4 2 Instrument transpose for voice 2
5 3 Note transpose for voice 2
6 1 Track number for voice 3
7 2 Instrument transpose for voice 3
8 3 Note transpose for voice 3
9 1 Track number for voice 4
A 2 Instrument transpose for voice 4
B 3 Note transpose for voice 4
C 1 Speed
D 1 Not used


Tracks:

0 4 Mark (patt)
4 Track data

AAAAAAAA BBBCCCCC DDDDDDDD EEEEEEEE

A = Note
B = Effect:
0: None
1: Set volume
2: Portamento down
3: Portamento up
C = Instrument number
D = Effect argument
E = Number of rows until next note


Instruments

0 4 Mark (inst)
4 x Volume data commands (from documentation):
* C0-aa-bb-cc
aa is the number of the sample (or waveform) used.
Numbers between 00 and 09 included are samples.
Numbers between 0A and 33 are waveforms.
bb is the step to skip waveforms.
If bb=0 then there is no effect.
If you want to use a sample, you must set bb to 0.
cc is the number of waveforms to be played

* A0-aa-bb-cc: This instruction makes the volume vary.
aa is the volume at the beginning.
bb is the volume at the end.
cc is the length of time to achieve the volume variation.

* E0-00-00-00: This instruction stops the sound (It cuts the voice).

* B0-aa-00-00: This instruction is the GOTO or LOOP command.
It permits to restarts a sound at any step of the volume sequence
(It's used for echo, make a never-ending sound or restart a
sound).
The aa number is the number of the line to reach multiplied by 4.
4 Mark (insf)
x Frequency data commands (from documentation):
* D0-aa-bb-cc: This instruction keeps the frequency constant.
aa is the offset of the note multiplied by 2 (always even) and it's
added to the played note. A value of 18 means that the frequency
is transposed of 1 octave up.
bb is unused.
cc is the length of time while the frequency doesn't vary.

* A0-aa-bb-cc: This instruction makes the frequency vary.
aa is a value added to the frequency of the note at the beginning.
bb is a value added to the frequency of the note at the end.
cc is the number of VBL

* E0-00-00-00: See above
* B0-aa-00-00:


Voice structure:

0 4 Hardware register
4 4 Pointer to sample data
8 2 Sample length in words
A 2 Period
C 2 Volume slide value
E 4 Pointer to track
12 1 Number of rows until next note
13
14 1 Flag
15 1 Volume
18 1 Instrument transpose
19 1 Note transpose
1A 4 Pointer to instrument volume data
1E 4 Pointer to instrument frequency data
22 1 Flag
23
24 1 Instrument volume data position
25 1 Instrument frequency data position
26 1 Volume slide tick counter
27 1 Volume slide remaining time
28 1 Volume slide delta
29 1 Frequency vary tick counter
2A 1 Volume slide direction
2B
2C 2 Frequency vary value
2E
30 4 Frequency vary add value
34 1 Waveform add value
35 1 Waveform number
36 1 Number of waveforms to change
37
38 2 Portamento effect add value
3A 1 Transposed note




6C0 M Modul data
6C4 Voice 1
700 Voice 2
73C Voice 3
778 Voice 4
7B4 130 Speed counter
7B5 131 Current row number
7B6 M2 132 Current position
7B7
260 134 Current speed
136 ??
138 ??
13A ???

7B8 M4 Period table
84A M5 Empty instrument
852 M6 Pointer til instruments: volume, frequency
95A M7 Pointer til tracks
B5A M8 Pointer til sample data
B82 Pointer til waveforms (0x20 bytes stykket, 0x2A ialt)
C2A M9 Sample lengths
C92 M10 Waveforms
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,7 @@ Modules in all supported formats can be found on my homepage at https://nostalgi
| ProRunner 2 | .pr2 / .pru2 | ProWizard | ModTracker |
| ProTracker | .mod | | ModTracker |
| ProTracker IFF | .ptm | | ModTracker |
| PumaTracker | .puma | | PumaTracker |
| Pygmy Packer | .pyg | ProWizard | ModTracker |
| Quadra Composer | .emod | | Quadra Composer |
| RIFF-WAVE (ADPCM) | .wav | | Sample |
Expand Down
30 changes: 30 additions & 0 deletions Source/Agents/Players/PumaTracker/Containers/GlobalPlayingInfo.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/******************************************************************************/
/* This source, or parts thereof, may be used in any software as long the */
/* license of NostalgicPlayer is keep. See the LICENSE file for more */
/* information. */
/******************************************************************************/
using Polycode.NostalgicPlayer.Kit.Interfaces;

namespace Polycode.NostalgicPlayer.Agent.Player.PumaTracker.Containers
{
/// <summary>
/// Holds global information about the playing state
/// </summary>
internal class GlobalPlayingInfo : IDeepCloneable<GlobalPlayingInfo>
{
public byte CurrentSpeed;
public byte SpeedCounter;
public sbyte CurrentPosition;
public byte CurrentRowNumber;

/********************************************************************/
/// <summary>
/// Make a deep copy of the current object
/// </summary>
/********************************************************************/
public GlobalPlayingInfo MakeDeepClone()
{
return (GlobalPlayingInfo)MemberwiseClone();
}
}
}
16 changes: 16 additions & 0 deletions Source/Agents/Players/PumaTracker/Containers/Instrument.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/******************************************************************************/
/* This source, or parts thereof, may be used in any software as long the */
/* license of NostalgicPlayer is keep. See the LICENSE file for more */
/* information. */
/******************************************************************************/
namespace Polycode.NostalgicPlayer.Agent.Player.PumaTracker.Containers
{
/// <summary>
/// Holds information about a single instrument
/// </summary>
internal class Instrument
{
public InstrumentCommand[] VolumeCommands;
public InstrumentCommand[] FrequencyCommands;
}
}
18 changes: 18 additions & 0 deletions Source/Agents/Players/PumaTracker/Containers/InstrumentCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
/******************************************************************************/
/* This source, or parts thereof, may be used in any software as long the */
/* license of NostalgicPlayer is keep. See the LICENSE file for more */
/* information. */
/******************************************************************************/
namespace Polycode.NostalgicPlayer.Agent.Player.PumaTracker.Containers
{
/// <summary>
/// Holds information about a single command (both volume and frequency)
/// </summary>
internal class InstrumentCommand
{
public byte Command;
public byte Argument1;
public byte Argument2;
public byte Argument3;
}
}
16 changes: 16 additions & 0 deletions Source/Agents/Players/PumaTracker/Containers/Position.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/******************************************************************************/
/* This source, or parts thereof, may be used in any software as long the */
/* license of NostalgicPlayer is keep. See the LICENSE file for more */
/* information. */
/******************************************************************************/
namespace Polycode.NostalgicPlayer.Agent.Player.PumaTracker.Containers
{
/// <summary>
/// Holds information about a single position
/// </summary>
internal class Position
{
public readonly VoicePosition[] VoicePosition = new VoicePosition[4];
public byte Speed;
}
}
30 changes: 30 additions & 0 deletions Source/Agents/Players/PumaTracker/Containers/Snapshot.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/******************************************************************************/
/* This source, or parts thereof, may be used in any software as long the */
/* license of NostalgicPlayer is keep. See the LICENSE file for more */
/* information. */
/******************************************************************************/
using Polycode.NostalgicPlayer.Kit.Interfaces;
using Polycode.NostalgicPlayer.Kit.Utility;

namespace Polycode.NostalgicPlayer.Agent.Player.PumaTracker.Containers
{
/// <summary>
/// Holds all the information about the player state at a specific time
/// </summary>
internal class Snapshot : ISnapshot
{
public GlobalPlayingInfo PlayingInfo;
public VoiceInfo[] Voices;

/********************************************************************/
/// <summary>
/// Constructor
/// </summary>
/********************************************************************/
public Snapshot(GlobalPlayingInfo playingInfo, VoiceInfo[] voices)
{
PlayingInfo = playingInfo.MakeDeepClone();
Voices = ArrayHelper.CloneObjectArray(voices);
}
}
}
16 changes: 16 additions & 0 deletions Source/Agents/Players/PumaTracker/Containers/Track.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/******************************************************************************/
/* This source, or parts thereof, may be used in any software as long the */
/* license of NostalgicPlayer is keep. See the LICENSE file for more */
/* information. */
/******************************************************************************/
namespace Polycode.NostalgicPlayer.Agent.Player.PumaTracker.Containers
{
internal class Track
{
public byte Note;
public byte Instrument;
public TrackEffect Effect;
public byte EffectArgument;
public byte RowsToWait;
}
}
15 changes: 15 additions & 0 deletions Source/Agents/Players/PumaTracker/Containers/TrackEffect.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/******************************************************************************/
/* This source, or parts thereof, may be used in any software as long the */
/* license of NostalgicPlayer is keep. See the LICENSE file for more */
/* information. */
/******************************************************************************/
namespace Polycode.NostalgicPlayer.Agent.Player.PumaTracker.Containers
{
internal enum TrackEffect
{
None = 0,
SetVolume,
PortamentoDown,
PortamentoUp
}
}
22 changes: 22 additions & 0 deletions Source/Agents/Players/PumaTracker/Containers/VoiceFlag.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/******************************************************************************/
/* This source, or parts thereof, may be used in any software as long the */
/* license of NostalgicPlayer is keep. See the LICENSE file for more */
/* information. */
/******************************************************************************/
using System;

namespace Polycode.NostalgicPlayer.Agent.Player.PumaTracker.Containers
{
/// <summary>
///
/// </summary>
[Flags]
internal enum VoiceFlag
{
None = 0,
SetVolumeSlide = 0x01,
SetFrequency = 0x02,
VoiceRunning = 0x04,
NoLoop = 0x08,
}
}
Loading

0 comments on commit a116710

Please sign in to comment.