Adding modding folder with a hacked build.

This commit is contained in:
ml
2026-09-26 08:53:08 +02:00
parent cdb960dc71
commit c91080aba7
755 changed files with 50424 additions and 0 deletions
@@ -0,0 +1,32 @@
package wav
import (
"io"
"github.com/inkyblackness/hacked/ss1"
"github.com/inkyblackness/hacked/ss1/content/audio"
)
const (
errSourceIsNil ss1.StringError = "source is nil"
errNotASupportedWave ss1.StringError = "not a supported WAV"
)
// Load reads from the provided source and returns the data.
func Load(source io.Reader) (data audio.L8, err error) {
if source == nil {
return data, errSourceIsNil
}
var loader waveLoader
loader.load(source)
if loader.err != nil {
return data, loader.err
}
data.SampleRate = loader.sampleRate
data.Samples = loader.samples
return
}
@@ -0,0 +1,65 @@
package wav_test
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/inkyblackness/hacked/ss1/content/audio/wav"
)
func TestLoadReturnsErrorOnNil(t *testing.T) {
_, err := wav.Load(nil)
assert.NotNil(t, err)
}
func TestLoadExtractsDataOfL8(t *testing.T) {
input := []byte{
0x52, 0x49, 0x46, 0x46, // "RIFF"
0x29, 0x00, 0x00, 0x00, // len(RIFF)
0x57, 0x41, 0x56, 0x45, // "WAVE"
0x66, 0x6d, 0x74, 0x20, // "fmt "
0x10, 0x00, 0x00, 0x00, // len(fmt)
0x01, 0x00, // fmt:type
0x01, 0x00, // fmt:channels
0x22, 0x56, 0x00, 0x00, // fmt:samples/sec
0x22, 0x56, 0x00, 0x00, // fmt:avgBytes/sec
0x01, 0x00, // fmt:blockAlign
0x08, 0x00, // fmt:bits/sample
0x64, 0x61, 0x74, 0x61, // "data"
0x05, 0x00, 0x00, 0x00, // len(data)
0x00, 0x40, 0x80, 0xC0, 0xFF} // data
data, err := wav.Load(bytes.NewReader(input))
require.Nil(t, err)
assert.Equal(t, float32(22050), data.SampleRate)
assert.Equal(t, []byte{0x00, 0x40, 0x80, 0xC0, 0xFF}, data.Samples)
}
func TestLoadExtractsDataOfL16(t *testing.T) {
input := []byte{
0x52, 0x49, 0x46, 0x46, // "RIFF"
0x2E, 0x00, 0x00, 0x00, // len(RIFF)
0x57, 0x41, 0x56, 0x45, // "WAVE"
0x66, 0x6d, 0x74, 0x20, // "fmt "
0x10, 0x00, 0x00, 0x00, // len(fmt)
0x01, 0x00, // fmt:type
0x01, 0x00, // fmt:channels
0x22, 0x56, 0x00, 0x00, // fmt:samples/sec
0x44, 0xAC, 0x00, 0x00, // fmt:avgBytes/sec
0x02, 0x00, // fmt:blockAlign
0x10, 0x00, // fmt:bits/sample
0x64, 0x61, 0x74, 0x61, // "data"
0x0A, 0x00, 0x00, 0x00, // len(data)
0xAA, 0x00, 0xAA, 0x40, 0xAA, 0x7F, 0xAA, 0xC0, 0xAA, 0xFF} // data
data, err := wav.Load(bytes.NewReader(input))
require.Nil(t, err)
assert.Equal(t, float32(22050), data.SampleRate)
assert.Equal(t, []byte{0x80, 0xC0, 0xFF, 0x40, 0x7F}, data.Samples)
}
@@ -0,0 +1,35 @@
package wav
import (
"encoding/binary"
"io"
)
// Save encodes the provided samples into the given writer.
func Save(writer io.Writer, sampleRate float32, samples []byte) error {
dataSize := uint32(len(samples))
var fmt formatHeader
fmtSize := fmt.size()
contentType := riffContentTypeWave
contentTypeSize := uint32(4)
tagSize := uint32(8)
tagSizes := tagSize * 2
fmt.base.FormatType = waveFormatTypePcm
fmt.base.Channels = 1
fmt.base.SamplesPerSec = uint32(sampleRate)
fmt.base.AvgBytesPerSec = fmt.base.SamplesPerSec
fmt.base.BlockAlign = 1
fmt.extension.BitsPerSample = 8
riffTag := riffChunkTag{ChunkType: riffChunkTypeRiff, Size: tagSizes + contentTypeSize + fmtSize + dataSize}
_ = binary.Write(writer, binary.LittleEndian, &riffTag)
_ = binary.Write(writer, binary.LittleEndian, &contentType)
_ = binary.Write(writer, binary.LittleEndian, &riffChunkTag{ChunkType: riffChunkTypeFmt, Size: fmtSize})
_ = binary.Write(writer, binary.LittleEndian, &fmt.base)
_ = binary.Write(writer, binary.LittleEndian, &fmt.extension)
_ = binary.Write(writer, binary.LittleEndian, &riffChunkTag{ChunkType: riffChunkTypeData, Size: dataSize})
_, err := writer.Write(samples)
return err
}
@@ -0,0 +1,37 @@
package wav_test
import (
"bytes"
"testing"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"github.com/inkyblackness/hacked/ss1/content/audio/wav"
)
func TestSaveStoresBytes(t *testing.T) {
sampleRate := float32(22050.0)
samples := []byte{0x00, 0x40, 0x80, 0xC0, 0xFF}
buf := bytes.NewBuffer(nil)
err := wav.Save(buf, sampleRate, samples)
require.Nil(t, err)
assert.Equal(t, []byte{
0x52, 0x49, 0x46, 0x46, // "RIFF"
0x2B, 0x00, 0x00, 0x00, // len(RIFF)
0x57, 0x41, 0x56, 0x45, // "WAVE"
0x66, 0x6d, 0x74, 0x20, // "fmt "
0x12, 0x00, 0x00, 0x00, // len(fmt)
0x01, 0x00, // fmt:type
0x01, 0x00, // fmt:channels
0x22, 0x56, 0x00, 0x00, // fmt:samples/sec
0x22, 0x56, 0x00, 0x00, // fmt:avgBytes/sec
0x01, 0x00, // fmt:blockAlign
0x08, 0x00, // fmt:bits/sample
0x00, 0x00, // fmt:extensionSize
0x64, 0x61, 0x74, 0x61, // "data"
0x05, 0x00, 0x00, 0x00, // len(data)
0x00, 0x40, 0x80, 0xC0, 0xFF}, buf.Bytes())
}
@@ -0,0 +1,133 @@
package wav
import (
"bytes"
"encoding/binary"
"io"
"github.com/inkyblackness/hacked/ss1"
)
const (
errUnsupportedFormat ss1.StringError = "unsupported WAVE format"
)
func l8FromL8(input []byte) []byte {
return input
}
func l8FromL16(input []byte) []byte {
samples := len(input) / 2
output := make([]byte, samples)
for i := 0; i < samples; i++ {
output[i] = byte(int(input[i*2+1]) + 0x80)
}
return output
}
type waveLoader struct {
dataRead bool
formatRead bool
samples []byte
sampleRate float32
reader io.Reader
err error
dataConverter func([]byte) []byte
}
func (loader *waveLoader) load(reader io.Reader) {
loader.reader = reader
loader.dataConverter = l8FromL8
loader.loadRiff()
}
func (loader *waveLoader) read(data interface{}) bool {
if loader.err == nil {
loader.err = binary.Read(loader.reader, binary.LittleEndian, data)
}
return loader.err == nil
}
func (loader *waveLoader) readBytes(size uint32) (data []byte) {
data = make([]byte, int(size))
_, loader.err = loader.reader.Read(data)
return
}
func (loader *waveLoader) loadChunk(handler func(riffChunkType, uint32)) {
var tag riffChunkTag
if loader.read(&tag) {
handler(tag.ChunkType, tag.Size)
}
}
func (loader *waveLoader) loadRiff() {
loader.loadChunk(loader.handleRiff)
}
func (loader *waveLoader) handleRiff(chunkType riffChunkType, size uint32) {
if chunkType == riffChunkTypeRiff {
var contentType riffContentType
if loader.read(&contentType) && (contentType == riffContentTypeWave) {
loader.loadWave()
} else if loader.err == nil {
loader.err = errNotASupportedWave
}
} else {
loader.err = errNotASupportedWave
}
}
func (loader *waveLoader) loadWave() {
for !loader.isDone() {
loader.loadFormatOrData()
}
loader.samples = loader.dataConverter(loader.samples)
}
func (loader *waveLoader) loadFormatOrData() {
loader.loadChunk(loader.handleFormatOrData)
}
func (loader *waveLoader) handleFormatOrData(chunkType riffChunkType, size uint32) {
if chunkType == riffChunkTypeFmt {
loader.loadFormat(size)
} else if chunkType == riffChunkTypeData {
loader.loadData(size)
}
}
func (loader *waveLoader) loadFormat(size uint32) {
headerData := loader.readBytes(size)
headerReader := bytes.NewReader(headerData)
var header formatHeader
loader.formatRead = true
loader.err = binary.Read(headerReader, binary.LittleEndian, &header.base)
loader.err = binary.Read(headerReader, binary.LittleEndian, &header.extension.BitsPerSample)
loader.sampleRate = float32(header.base.SamplesPerSec)
if header.extension.BitsPerSample == 16 {
loader.dataConverter = l8FromL16
}
if (header.base.FormatType != waveFormatTypePcm) ||
(header.base.Channels != 1) ||
((header.extension.BitsPerSample != 8) && (header.extension.BitsPerSample != 16)) {
loader.err = errUnsupportedFormat
}
}
func (loader *waveLoader) loadData(size uint32) {
loader.dataRead = true
loader.samples = loader.readBytes(size)
}
func (loader *waveLoader) isDone() bool {
return (loader.err != nil) || (loader.dataRead && loader.formatRead)
}
@@ -0,0 +1,33 @@
package wav
import (
"encoding/binary"
)
type waveFormatType uint16
const (
waveFormatTypePcm = 1
)
type waveFormat struct {
FormatType waveFormatType
Channels uint16
SamplesPerSec uint32
AvgBytesPerSec uint32
BlockAlign uint16
}
type waveFormatExtension struct {
BitsPerSample uint16
ExtensionSize uint16
}
type formatHeader struct {
base waveFormat
extension waveFormatExtension
}
func (header formatHeader) size() uint32 {
return uint32(binary.Size(&header.base) + binary.Size(&header.extension))
}
@@ -0,0 +1,19 @@
package wav
type riffChunkType uint32
type riffContentType uint32
const (
riffChunkTypeRiff = riffChunkType(0x46464952)
riffChunkTypeFmt = riffChunkType(0x20746d66)
riffChunkTypeData = riffChunkType(0x61746164)
)
const (
riffContentTypeWave = riffContentType(0x45564157)
)
type riffChunkTag struct {
ChunkType riffChunkType
Size uint32
}