Created
August 26, 2023 06:05
-
-
Save 0b5vr/8af3d6df8c62779e29261ba5a7a6c413 to your computer and use it in GitHub Desktop.
rough prototype of protracker module pattern for imhex
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <std/io.pat> | |
#include <std/math.pat> | |
fn charString(str value) { | |
return value; | |
}; | |
fn u16LengthInWords(u16 value) { | |
return 2 * value; | |
}; | |
fn u8Finetune(u8 value) { | |
if (value & 0xf0 != 0x0) { | |
return "invalid"; | |
} | |
if (value >= 8) { | |
return s8(value) - 16; | |
} else { | |
return s8(value); | |
} | |
}; | |
fn u8Volume(u8 value) { | |
if (value > 0x40) { | |
return "invalid"; | |
} | |
return value; | |
}; | |
fn u16PeriodToNote(u16 period) { | |
match (period) { | |
(0): return "---"; | |
(57): return "B-4"; | |
(60): return "A#4"; | |
(64): return "A-4"; | |
(67): return "G#4"; | |
(71): return "G-4"; | |
(76): return "F#4"; | |
(80): return "F-4"; | |
(85): return "E-4"; | |
(90): return "D#4"; | |
(95): return "D-4"; | |
(101): return "C#4"; | |
(107): return "C-4"; | |
(113): return "B-3"; | |
(120): return "A#3"; | |
(127): return "A-3"; | |
(135): return "G#3"; | |
(143): return "G-3"; | |
(151): return "F#3"; | |
(160): return "F-3"; | |
(170): return "E-3"; | |
(180): return "D#3"; | |
(190): return "D-3"; | |
(202): return "C#3"; | |
(214): return "C-3"; | |
(226): return "B-2"; | |
(240): return "A#2"; | |
(254): return "A-2"; | |
(269): return "G#2"; | |
(285): return "G-2"; | |
(302): return "F#2"; | |
(320): return "F-2"; | |
(339): return "E-2"; | |
(360): return "D#2"; | |
(381): return "D-2"; | |
(404): return "C#2"; | |
(428): return "C-2"; | |
(453): return "B-1"; | |
(480): return "A#1"; | |
(508): return "A-1"; | |
(538): return "G#1"; | |
(570): return "G-1"; | |
(604): return "F#1"; | |
(640): return "F-1"; | |
(678): return "E-1"; | |
(720): return "D#1"; | |
(762): return "D-1"; | |
(808): return "C#1"; | |
(856): return "C-1"; | |
(907): return "B-0"; | |
(961): return "A#0"; | |
(1017): return "A-0"; | |
(1077): return "G#0"; | |
(1141): return "G-0"; | |
(1209): return "F#0"; | |
(1281): return "F-0"; | |
(1357): return "E-0"; | |
(1440): return "D#0"; | |
(1525): return "D-0"; | |
(1616): return "C#0"; | |
(1712): return "C-0"; | |
} | |
return "???"; | |
}; | |
fn u32Cell(u32 cell) { | |
u16 period = (cell & 0x0fff0000) >> 16; | |
u8 sample = ((cell & 0xf0000000) >> 24) | ((cell & 0x0000f000) >> 12); | |
u16 effect = cell & 0x00000fff; | |
str note = u16PeriodToNote(period); | |
return std::format("{} {:02X} {:03X}", note, sample, effect); | |
}; | |
fn findMax(auto orders, u32 length) { | |
u8 max; | |
for (u8 i = 0, i < length, i = i + 1) { | |
max = std::math::max(max, orders[i]); | |
} | |
return max; | |
}; | |
struct SampleInfo { | |
char name[22] [[format("charString"), color("888800")]]; | |
be u16 length [[format("u16LengthInWords")]]; | |
u8 finetune [[format("u8Finetune")]]; | |
u8 volume [[format("u8Volume")]]; | |
be u16 loopStart [[format("u16LengthInWords")]]; | |
be u16 loopLength [[format("u16LengthInWords")]]; | |
}; | |
struct PatternCell { | |
be u32 cell [[format("u32Cell")]]; | |
}; | |
struct PatternRow { | |
be PatternCell cells[4]; | |
}; | |
struct Pattern { | |
PatternRow rows[64]; | |
}; | |
struct ModuleFile { | |
char name[20] [[format("charString")]]; | |
SampleInfo sampleInfos[31] [[color("ffff00")]]; | |
u8 songLength; | |
u8 magic; | |
u8 songOrder[128]; | |
char sampleTag[4]; | |
u8 nPatterns = findMax(songOrder, 128) + 1; | |
Pattern patterns[nPatterns] [[color("0000ff")]]; | |
}; | |
ModuleFile mod @ 0x00; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment