From e0a83e3d72bb8157a412318734ac026850ca12d3 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Thu, 6 Sep 2018 03:45:50 -0500 Subject: Update scaninc and preproc with multi-file incbins --- tools/preproc/c_file.cpp | 92 ++++++++++++++++++++++++++---------------------- tools/scaninc/c_file.cpp | 17 ++++++--- 2 files changed, 63 insertions(+), 46 deletions(-) (limited to 'tools') diff --git a/tools/preproc/c_file.cpp b/tools/preproc/c_file.cpp index 2f4bfea7c..229f568fa 100644 --- a/tools/preproc/c_file.cpp +++ b/tools/preproc/c_file.cpp @@ -325,66 +325,74 @@ void CFile::TryConvertIncbin() m_pos++; - SkipWhitespace(); + std::printf("{"); - if (m_buffer[m_pos] != '"') - RaiseError("expected double quote"); + while (true) + { + SkipWhitespace(); - m_pos++; + if (m_buffer[m_pos] != '"') + RaiseError("expected double quote"); - int startPos = m_pos; + m_pos++; - while (m_buffer[m_pos] != '"') - { - if (m_buffer[m_pos] == 0) - { - if (m_pos >= m_size) - RaiseError("unexpected EOF in path string"); - else - RaiseError("unexpected null character in path string"); - } + int startPos = m_pos; - if (m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n') - RaiseError("unexpected end of line character in path string"); + while (m_buffer[m_pos] != '"') + { + if (m_buffer[m_pos] == 0) + { + if (m_pos >= m_size) + RaiseError("unexpected EOF in path string"); + else + RaiseError("unexpected null character in path string"); + } - if (m_buffer[m_pos] == '\\') - RaiseError("unexpected escape in path string"); - - m_pos++; - } + if (m_buffer[m_pos] == '\r' || m_buffer[m_pos] == '\n') + RaiseError("unexpected end of line character in path string"); - std::string path(&m_buffer[startPos], m_pos - startPos); + if (m_buffer[m_pos] == '\\') + RaiseError("unexpected escape in path string"); + + m_pos++; + } - m_pos++; + std::string path(&m_buffer[startPos], m_pos - startPos); - SkipWhitespace(); + m_pos++; - if (m_buffer[m_pos] != ')') - RaiseError("expected ')'"); + int fileSize; + std::unique_ptr buffer = ReadWholeFile(path, fileSize); - m_pos++; + if ((fileSize % size) != 0) + RaiseError("Size %d doesn't evenly divide file size %d.\n", size, fileSize); - std::printf("{"); + int count = fileSize / size; + int offset = 0; - int fileSize; - std::unique_ptr buffer = ReadWholeFile(path, fileSize); + for (int i = 0; i < count; i++) + { + int data = ExtractData(buffer, offset, size); + offset += size; - if ((fileSize % size) != 0) - RaiseError("Size %d doesn't evenly divide file size %d.\n", size, fileSize); + if (isSigned) + std::printf("%d,", data); + else + std::printf("%uu,", data); + } - int count = fileSize / size; - int offset = 0; + SkipWhitespace(); - for (int i = 0; i < count; i++) - { - int data = ExtractData(buffer, offset, size); - offset += size; + if (m_buffer[m_pos] != ',') + break; - if (isSigned) - std::printf("%d,", data); - else - std::printf("%uu,", data); + m_pos++; } + + if (m_buffer[m_pos] != ')') + RaiseError("expected ')'"); + + m_pos++; std::printf("}"); } diff --git a/tools/scaninc/c_file.cpp b/tools/scaninc/c_file.cpp index f7acc833f..d470f959d 100644 --- a/tools/scaninc/c_file.cpp +++ b/tools/scaninc/c_file.cpp @@ -244,18 +244,27 @@ void CFile::CheckIncbin() m_pos++; - SkipWhitespace(); + while (true) + { + SkipWhitespace(); - std::string path = ReadPath(); + std::string path = ReadPath(); - SkipWhitespace(); + SkipWhitespace(); + + m_incbins.emplace(path); + + if (m_buffer[m_pos] != ',') + break; + + m_pos++; + } if (m_buffer[m_pos] != ')') FATAL_INPUT_ERROR("expected ')'"); m_pos++; - m_incbins.emplace(path); } std::string CFile::ReadPath() -- cgit v1.2.3 From 78cdd97c8b958fa60ab0d70201360835aac985c6 Mon Sep 17 00:00:00 2001 From: Marcus Huderle Date: Thu, 6 Sep 2018 11:44:50 -0500 Subject: Add ability to specify metatile dimensions to gbagfx --- tools/gbagfx/Makefile | 7 +- tools/gbagfx/gfx.c | 175 +++++++++++++++++++++++++++---------------------- tools/gbagfx/gfx.h | 4 +- tools/gbagfx/main.c | 105 +++++++++++++++++++++++------ tools/gbagfx/options.h | 24 +++++++ 5 files changed, 210 insertions(+), 105 deletions(-) create mode 100755 tools/gbagfx/options.h (limited to 'tools') diff --git a/tools/gbagfx/Makefile b/tools/gbagfx/Makefile index 6f11b1b3f..c10b258de 100644 --- a/tools/gbagfx/Makefile +++ b/tools/gbagfx/Makefile @@ -1,12 +1,15 @@ CC = gcc -CFLAGS = -Wall -Wextra -Werror -std=c11 -O2 -DPNG_SKIP_SETJMP_CHECK +CFLAGS = -Wall -Wextra -Werror -std=c11 -O2 -s -DPNG_SKIP_SETJMP_CHECK LIBS = -lpng -lz SRCS = main.c convert_png.c gfx.c jasc_pal.c lz.c rl.c util.c font.c -.PHONY: clean +.PHONY: all clean + +all: gbagfx + @: gbagfx: $(SRCS) convert_png.h gfx.h global.h jasc_pal.h lz.h rl.h util.h font.h $(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS) $(LIBS) diff --git a/tools/gbagfx/gfx.c b/tools/gbagfx/gfx.c index c0f7f492c..f927deed9 100644 --- a/tools/gbagfx/gfx.c +++ b/tools/gbagfx/gfx.c @@ -18,16 +18,35 @@ #define DOWNCONVERT_BIT_DEPTH(x) ((x) / 8) -static void ConvertFromTiles1Bpp(unsigned char *src, unsigned char *dest, int numTiles, int tilesWidth, bool invertColors) +static void AdvanceMetatilePosition(int *subTileX, int *subTileY, int *metatileX, int *metatileY, int metatilesWide, int metatileWidth, int metatileHeight) { - int tilesX = 0; - int tilesY = 0; - int pitch = tilesWidth; + (*subTileX)++; + if (*subTileX == metatileWidth) { + *subTileX = 0; + (*subTileY)++; + if (*subTileY == metatileHeight) { + *subTileY = 0; + (*metatileX)++; + if (*metatileX == metatilesWide) { + *metatileX = 0; + (*metatileY)++; + } + } + } +} + +static void ConvertFromTiles1Bpp(unsigned char *src, unsigned char *dest, int numTiles, int metatilesWide, int metatileWidth, int metatileHeight, bool invertColors) +{ + int subTileX = 0; + int subTileY = 0; + int metatileX = 0; + int metatileY = 0; + int pitch = metatilesWide * metatileWidth; for (int i = 0; i < numTiles; i++) { for (int j = 0; j < 8; j++) { - int destY = tilesY * 8 + j; - int destX = tilesX; + int destY = (metatileY * metatileHeight + subTileY) * 8 + j; + int destX = metatileX * metatileWidth + subTileX; unsigned char srcPixelOctet = *src++; unsigned char *destPixelOctet = &dest[destY * pitch + destX]; @@ -38,27 +57,24 @@ static void ConvertFromTiles1Bpp(unsigned char *src, unsigned char *dest, int nu } } - tilesX++; - - if (tilesX == tilesWidth) { - tilesX = 0; - tilesY++; - } + AdvanceMetatilePosition(&subTileX, &subTileY, &metatileX, &metatileY, metatilesWide, metatileWidth, metatileHeight); } } -static void ConvertFromTiles4Bpp(unsigned char *src, unsigned char *dest, int numTiles, int tilesWidth, bool invertColors) +static void ConvertFromTiles4Bpp(unsigned char *src, unsigned char *dest, int numTiles, int metatilesWide, int metatileWidth, int metatileHeight, bool invertColors) { - int tilesX = 0; - int tilesY = 0; - int pitch = tilesWidth * 4; + int subTileX = 0; + int subTileY = 0; + int metatileX = 0; + int metatileY = 0; + int pitch = (metatilesWide * metatileWidth) * 4; for (int i = 0; i < numTiles; i++) { for (int j = 0; j < 8; j++) { - int destY = tilesY * 8 + j; + int destY = (metatileY * metatileHeight + subTileY) * 8 + j; for (int k = 0; k < 4; k++) { - int destX = tilesX * 4 + k; + int destX = (metatileX * metatileWidth + subTileX) * 4 + k; unsigned char srcPixelPair = *src++; unsigned char leftPixel = srcPixelPair & 0xF; unsigned char rightPixel = srcPixelPair >> 4; @@ -72,27 +88,24 @@ static void ConvertFromTiles4Bpp(unsigned char *src, unsigned char *dest, int nu } } - tilesX++; - - if (tilesX == tilesWidth) { - tilesX = 0; - tilesY++; - } + AdvanceMetatilePosition(&subTileX, &subTileY, &metatileX, &metatileY, metatilesWide, metatileWidth, metatileHeight); } } -static void ConvertFromTiles8Bpp(unsigned char *src, unsigned char *dest, int numTiles, int tilesWidth, bool invertColors) +static void ConvertFromTiles8Bpp(unsigned char *src, unsigned char *dest, int numTiles, int metatilesWide, int metatileWidth, int metatileHeight, bool invertColors) { - int tilesX = 0; - int tilesY = 0; - int pitch = tilesWidth * 8; + int subTileX = 0; + int subTileY = 0; + int metatileX = 0; + int metatileY = 0; + int pitch = (metatilesWide * metatileWidth) * 8; for (int i = 0; i < numTiles; i++) { for (int j = 0; j < 8; j++) { - int destY = tilesY * 8 + j; + int destY = (metatileY * metatileHeight + subTileY) * 8 + j; for (int k = 0; k < 8; k++) { - int destX = tilesX * 8 + k; + int destX = (metatileX * metatileWidth + subTileX) * 8 + k; unsigned char srcPixel = *src++; if (invertColors) @@ -102,25 +115,22 @@ static void ConvertFromTiles8Bpp(unsigned char *src, unsigned char *dest, int nu } } - tilesX++; - - if (tilesX == tilesWidth) { - tilesX = 0; - tilesY++; - } + AdvanceMetatilePosition(&subTileX, &subTileY, &metatileX, &metatileY, metatilesWide, metatileWidth, metatileHeight); } } -static void ConvertToTiles1Bpp(unsigned char *src, unsigned char *dest, int numTiles, int tilesWidth, bool invertColors) +static void ConvertToTiles1Bpp(unsigned char *src, unsigned char *dest, int numTiles, int metatilesWide, int metatileWidth, int metatileHeight, bool invertColors) { - int tilesX = 0; - int tilesY = 0; - int pitch = tilesWidth; + int subTileX = 0; + int subTileY = 0; + int metatileX = 0; + int metatileY = 0; + int pitch = metatilesWide * metatileWidth; for (int i = 0; i < numTiles; i++) { for (int j = 0; j < 8; j++) { - int srcY = tilesY * 8 + j; - int srcX = tilesX; + int srcY = (metatileY * metatileHeight + subTileY) * 8 + j; + int srcX = metatileX * metatileWidth + subTileX; unsigned char srcPixelOctet = src[srcY * pitch + srcX]; unsigned char *destPixelOctet = dest++; @@ -131,27 +141,24 @@ static void ConvertToTiles1Bpp(unsigned char *src, unsigned char *dest, int numT } } - tilesX++; - - if (tilesX == tilesWidth) { - tilesX = 0; - tilesY++; - } + AdvanceMetatilePosition(&subTileX, &subTileY, &metatileX, &metatileY, metatilesWide, metatileWidth, metatileHeight); } } -static void ConvertToTiles4Bpp(unsigned char *src, unsigned char *dest, int numTiles, int tilesWidth, bool invertColors) +static void ConvertToTiles4Bpp(unsigned char *src, unsigned char *dest, int numTiles, int metatilesWide, int metatileWidth, int metatileHeight, bool invertColors) { - int tilesX = 0; - int tilesY = 0; - int pitch = tilesWidth * 4; + int subTileX = 0; + int subTileY = 0; + int metatileX = 0; + int metatileY = 0; + int pitch = (metatilesWide * metatileWidth) * 4; for (int i = 0; i < numTiles; i++) { for (int j = 0; j < 8; j++) { - int srcY = tilesY * 8 + j; + int srcY = (metatileY * metatileHeight + subTileY) * 8 + j; for (int k = 0; k < 4; k++) { - int srcX = tilesX * 4 + k; + int srcX = (metatileX * metatileWidth + subTileX) * 4 + k; unsigned char srcPixelPair = src[srcY * pitch + srcX]; unsigned char leftPixel = srcPixelPair >> 4; unsigned char rightPixel = srcPixelPair & 0xF; @@ -165,27 +172,24 @@ static void ConvertToTiles4Bpp(unsigned char *src, unsigned char *dest, int numT } } - tilesX++; - - if (tilesX == tilesWidth) { - tilesX = 0; - tilesY++; - } + AdvanceMetatilePosition(&subTileX, &subTileY, &metatileX, &metatileY, metatilesWide, metatileWidth, metatileHeight); } } -static void ConvertToTiles8Bpp(unsigned char *src, unsigned char *dest, int numTiles, int tilesWidth, bool invertColors) +static void ConvertToTiles8Bpp(unsigned char *src, unsigned char *dest, int numTiles, int metatilesWide, int metatileWidth, int metatileHeight, bool invertColors) { - int tilesX = 0; - int tilesY = 0; - int pitch = tilesWidth * 8; + int subTileX = 0; + int subTileY = 0; + int metatileX = 0; + int metatileY = 0; + int pitch = (metatilesWide * metatileWidth) * 8; for (int i = 0; i < numTiles; i++) { for (int j = 0; j < 8; j++) { - int srcY = tilesY * 8 + j; + int srcY = (metatileY * metatileHeight + subTileY) * 8 + j; for (int k = 0; k < 8; k++) { - int srcX = tilesX * 8 + k; + int srcX = (metatileX * metatileWidth + subTileX) * 8 + k; unsigned char srcPixel = src[srcY * pitch + srcX]; if (invertColors) @@ -195,16 +199,11 @@ static void ConvertToTiles8Bpp(unsigned char *src, unsigned char *dest, int numT } } - tilesX++; - - if (tilesX == tilesWidth) { - tilesX = 0; - tilesY++; - } + AdvanceMetatilePosition(&subTileX, &subTileY, &metatileX, &metatileY, metatilesWide, metatileWidth, metatileHeight); } } -void ReadImage(char *path, int tilesWidth, int bitDepth, struct Image *image, bool invertColors) +void ReadImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors) { int tileSize = bitDepth * 8; @@ -215,6 +214,12 @@ void ReadImage(char *path, int tilesWidth, int bitDepth, struct Image *image, bo int tilesHeight = (numTiles + tilesWidth - 1) / tilesWidth; + if (tilesWidth % metatileWidth != 0) + FATAL_ERROR("The width in tiles (%d) isn't a multiple of the specified metatile width (%d)", tilesWidth, metatileWidth); + + if (tilesHeight % metatileHeight != 0) + FATAL_ERROR("The height in tiles (%d) isn't a multiple of the specified metatile height (%d)", tilesHeight, metatileHeight); + image->width = tilesWidth * 8; image->height = tilesHeight * 8; image->bitDepth = bitDepth; @@ -223,22 +228,24 @@ void ReadImage(char *path, int tilesWidth, int bitDepth, struct Image *image, bo if (image->pixels == NULL) FATAL_ERROR("Failed to allocate memory for pixels.\n"); + int metatilesWide = tilesWidth / metatileWidth; + switch (bitDepth) { case 1: - ConvertFromTiles1Bpp(buffer, image->pixels, numTiles, tilesWidth, invertColors); + ConvertFromTiles1Bpp(buffer, image->pixels, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; case 4: - ConvertFromTiles4Bpp(buffer, image->pixels, numTiles, tilesWidth, invertColors); + ConvertFromTiles4Bpp(buffer, image->pixels, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; case 8: - ConvertFromTiles8Bpp(buffer, image->pixels, numTiles, tilesWidth, invertColors); + ConvertFromTiles8Bpp(buffer, image->pixels, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; } free(buffer); } -void WriteImage(char *path, int numTiles, int bitDepth, struct Image *image, bool invertColors) +void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors) { int tileSize = bitDepth * 8; @@ -251,6 +258,12 @@ void WriteImage(char *path, int numTiles, int bitDepth, struct Image *image, boo int tilesWidth = image->width / 8; int tilesHeight = image->height / 8; + if (tilesWidth % metatileWidth != 0) + FATAL_ERROR("The width in tiles (%d) isn't a multiple of the specified metatile width (%d)", tilesWidth, metatileWidth); + + if (tilesHeight % metatileHeight != 0) + FATAL_ERROR("The height in tiles (%d) isn't a multiple of the specified metatile height (%d)", tilesHeight, metatileHeight); + int maxNumTiles = tilesWidth * tilesHeight; if (numTiles == 0) @@ -264,15 +277,17 @@ void WriteImage(char *path, int numTiles, int bitDepth, struct Image *image, boo if (buffer == NULL) FATAL_ERROR("Failed to allocate memory for pixels.\n"); + int metatilesWide = tilesWidth / metatileWidth; + switch (bitDepth) { case 1: - ConvertToTiles1Bpp(image->pixels, buffer, numTiles, tilesWidth, invertColors); + ConvertToTiles1Bpp(image->pixels, buffer, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; case 4: - ConvertToTiles4Bpp(image->pixels, buffer, numTiles, tilesWidth, invertColors); + ConvertToTiles4Bpp(image->pixels, buffer, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; case 8: - ConvertToTiles8Bpp(image->pixels, buffer, numTiles, tilesWidth, invertColors); + ConvertToTiles8Bpp(image->pixels, buffer, numTiles, metatilesWide, metatileWidth, metatileHeight, invertColors); break; } diff --git a/tools/gbagfx/gfx.h b/tools/gbagfx/gfx.h index ecd436652..5355ced85 100644 --- a/tools/gbagfx/gfx.h +++ b/tools/gbagfx/gfx.h @@ -27,8 +27,8 @@ struct Image { bool hasTransparency; }; -void ReadImage(char *path, int tilesWidth, int bitDepth, struct Image *image, bool invertColors); -void WriteImage(char *path, int numTiles, int bitDepth, struct Image *image, bool invertColors); +void ReadImage(char *path, int tilesWidth, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors); +void WriteImage(char *path, int numTiles, int bitDepth, int metatileWidth, int metatileHeight, struct Image *image, bool invertColors); void FreeImage(struct Image *image); void ReadGbaPalette(char *path, struct Palette *palette); void WriteGbaPalette(char *path, struct Palette *palette); diff --git a/tools/gbagfx/main.c b/tools/gbagfx/main.c index 97db60e84..86b0afa53 100644 --- a/tools/gbagfx/main.c +++ b/tools/gbagfx/main.c @@ -5,6 +5,7 @@ #include #include "global.h" #include "util.h" +#include "options.h" #include "gfx.h" #include "convert_png.h" #include "jasc_pal.h" @@ -19,13 +20,13 @@ struct CommandHandler void(*function)(char *inputPath, char *outputPath, int argc, char **argv); }; -void ConvertGbaToPng(char *inputPath, char *outputPath, int width, int bitDepth, char *paletteFilePath, bool hasTransparency) +void ConvertGbaToPng(char *inputPath, char *outputPath, struct GbaToPngOptions *options) { struct Image image; - if (paletteFilePath != NULL) + if (options->paletteFilePath != NULL) { - ReadGbaPalette(paletteFilePath, &image.palette); + ReadGbaPalette(options->paletteFilePath, &image.palette); image.hasPalette = true; } else @@ -33,24 +34,24 @@ void ConvertGbaToPng(char *inputPath, char *outputPath, int width, int bitDepth, image.hasPalette = false; } - ReadImage(inputPath, width, bitDepth, &image, !image.hasPalette); + ReadImage(inputPath, options->width, options->bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette); - image.hasTransparency = hasTransparency; + image.hasTransparency = options->hasTransparency; WritePng(outputPath, &image); FreeImage(&image); } -void ConvertPngToGba(char *inputPath, char *outputPath, int numTiles, int bitDepth) +void ConvertPngToGba(char *inputPath, char *outputPath, struct PngToGbaOptions *options) { struct Image image; - image.bitDepth = bitDepth; + image.bitDepth = options->bitDepth; ReadPng(inputPath, &image); - WriteImage(outputPath, numTiles, bitDepth, &image, !image.hasPalette); + WriteImage(outputPath, options->numTiles, options->bitDepth, options->metatileWidth, options->metatileHeight, &image, !image.hasPalette); FreeImage(&image); } @@ -58,10 +59,13 @@ void ConvertPngToGba(char *inputPath, char *outputPath, int numTiles, int bitDep void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **argv) { char *inputFileExtension = GetFileExtension(inputPath); - int bitDepth = inputFileExtension[0] - '0'; - char *paletteFilePath = NULL; - bool hasTransparency = false; - int width = 1; + struct GbaToPngOptions options; + options.paletteFilePath = NULL; + options.bitDepth = inputFileExtension[0] - '0'; + options.hasTransparency = false; + options.width = 1; + options.metatileWidth = 1; + options.metatileHeight = 1; for (int i = 3; i < argc; i++) { @@ -74,11 +78,11 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a i++; - paletteFilePath = argv[i]; + options.paletteFilePath = argv[i]; } else if (strcmp(option, "-object") == 0) { - hasTransparency = true; + options.hasTransparency = true; } else if (strcmp(option, "-width") == 0) { @@ -87,26 +91,59 @@ void HandleGbaToPngCommand(char *inputPath, char *outputPath, int argc, char **a i++; - if (!ParseNumber(argv[i], NULL, 10, &width)) + if (!ParseNumber(argv[i], NULL, 10, &options.width)) FATAL_ERROR("Failed to parse width.\n"); - if (width < 1) + if (options.width < 1) FATAL_ERROR("Width must be positive.\n"); } + else if (strcmp(option, "-mwidth") == 0) + { + if (i + 1 >= argc) + FATAL_ERROR("No metatile width value following \"-mwidth\".\n"); + + i++; + + if (!ParseNumber(argv[i], NULL, 10, &options.metatileWidth)) + FATAL_ERROR("Failed to parse metatile width.\n"); + + if (options.metatileWidth < 1) + FATAL_ERROR("metatile width must be positive.\n"); + } + else if (strcmp(option, "-mheight") == 0) + { + if (i + 1 >= argc) + FATAL_ERROR("No metatile height value following \"-mheight\".\n"); + + i++; + + if (!ParseNumber(argv[i], NULL, 10, &options.metatileHeight)) + FATAL_ERROR("Failed to parse metatile height.\n"); + + if (options.metatileHeight < 1) + FATAL_ERROR("metatile height must be positive.\n"); + } else { FATAL_ERROR("Unrecognized option \"%s\".\n", option); } } - ConvertGbaToPng(inputPath, outputPath, width, bitDepth, paletteFilePath, hasTransparency); + if (options.metatileWidth > options.width) + options.width = options.metatileWidth; + + ConvertGbaToPng(inputPath, outputPath, &options); } void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **argv) { char *outputFileExtension = GetFileExtension(outputPath); int bitDepth = outputFileExtension[0] - '0'; - int numTiles = 0; + struct PngToGbaOptions options; + options.numTiles = 0; + options.bitDepth = bitDepth; + options.metatileWidth = 1; + options.metatileHeight = 1; for (int i = 3; i < argc; i++) { @@ -119,19 +156,45 @@ void HandlePngToGbaCommand(char *inputPath, char *outputPath, int argc, char **a i++; - if (!ParseNumber(argv[i], NULL, 10, &numTiles)) + if (!ParseNumber(argv[i], NULL, 10, &options.numTiles)) FATAL_ERROR("Failed to parse number of tiles.\n"); - if (numTiles < 1) + if (options.numTiles < 1) FATAL_ERROR("Number of tiles must be positive.\n"); } + else if (strcmp(option, "-mwidth") == 0) + { + if (i + 1 >= argc) + FATAL_ERROR("No metatile width value following \"-mwidth\".\n"); + + i++; + + if (!ParseNumber(argv[i], NULL, 10, &options.metatileWidth)) + FATAL_ERROR("Failed to parse metatile width.\n"); + + if (options.metatileWidth < 1) + FATAL_ERROR("metatile width must be positive.\n"); + } + else if (strcmp(option, "-mheight") == 0) + { + if (i + 1 >= argc) + FATAL_ERROR("No metatile height value following \"-mheight\".\n"); + + i++; + + if (!ParseNumber(argv[i], NULL, 10, &options.metatileHeight)) + FATAL_ERROR("Failed to parse metatile height.\n"); + + if (options.metatileHeight < 1) + FATAL_ERROR("metatile height must be positive.\n"); + } else { FATAL_ERROR("Unrecognized option \"%s\".\n", option); } } - ConvertPngToGba(inputPath, outputPath, numTiles, bitDepth); + ConvertPngToGba(inputPath, outputPath, &options); } void HandlePngToGbaPaletteCommand(char *inputPath, char *outputPath, int argc UNUSED, char **argv UNUSED) diff --git a/tools/gbagfx/options.h b/tools/gbagfx/options.h new file mode 100755 index 000000000..2ff3967a4 --- /dev/null +++ b/tools/gbagfx/options.h @@ -0,0 +1,24 @@ +// Copyright (c) 2018 huderlem + +#ifndef OPTIONS_H +#define OPTIONS_H + +#include + +struct GbaToPngOptions { + char *paletteFilePath; + int bitDepth; + bool hasTransparency; + int width; + int metatileWidth; + int metatileHeight; +}; + +struct PngToGbaOptions { + int numTiles; + int bitDepth; + int metatileWidth; + int metatileHeight; +}; + +#endif // OPTIONS_H -- cgit v1.2.3 From f73807ea607ce195f0351213c24869d2f5286e5a Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Fri, 7 Sep 2018 23:52:11 -0500 Subject: Add palette tags for event objects --- tools/gbafix/.gitignore | 1 + 1 file changed, 1 insertion(+) (limited to 'tools') diff --git a/tools/gbafix/.gitignore b/tools/gbafix/.gitignore index 23abdd29c..3cebf8ae8 100644 --- a/tools/gbafix/.gitignore +++ b/tools/gbafix/.gitignore @@ -1 +1,2 @@ gbafix +README -- cgit v1.2.3 From aa0782c40bc5ace54447c8234a8ca8a08ee6d788 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Mon, 10 Sep 2018 12:03:24 -0500 Subject: Make gbafix silent --- tools/gbafix/gbafix.c | 25 +++++++++++++++---------- 1 file changed, 15 insertions(+), 10 deletions(-) (limited to 'tools') diff --git a/tools/gbafix/gbafix.c b/tools/gbafix/gbafix.c index 60e4ccb4f..071568d45 100644 --- a/tools/gbafix/gbafix.c +++ b/tools/gbafix/gbafix.c @@ -135,6 +135,7 @@ int main(int argc, char *argv[]) int arg; char *argfile = 0; FILE *infile; + int silent = 0; int size,bit; @@ -142,7 +143,7 @@ int main(int argc, char *argv[]) if (argc <= 1) { printf("GBA ROM fixer v"VER" by Dark Fader / BlackThunder / WinterMute / Diegoisawesome \n"); - printf("Syntax: gbafix [-p] [-t[title]] [-c] [-m] [-r] [-d]\n"); + printf("Syntax: gbafix [-p] [-t[title]] [-c] [-m] [-r] [-d] [-silent]\n"); printf("\n"); printf("parameters:\n"); printf(" -p Pad to next exact power of 2. No minimum size!\n"); @@ -151,25 +152,27 @@ int main(int argc, char *argv[]) printf(" -m Patch maker code (two characters)\n"); printf(" -r Patch game version (number)\n"); printf(" -d Enable debugging handler and set debug entry point (0 or 1)\n"); + printf(" -silent Silence non-error output\n"); return -1; } // get filename for (arg=1; arg Date: Mon, 10 Sep 2018 13:15:53 -0500 Subject: Make long param use two dashes --- tools/gbafix/gbafix.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/gbafix/gbafix.c b/tools/gbafix/gbafix.c index 071568d45..d5e2f62ab 100644 --- a/tools/gbafix/gbafix.c +++ b/tools/gbafix/gbafix.c @@ -33,6 +33,7 @@ History ------- + v1.06 - added output silencing, (Diegoisawesome) v1.05 - added debug offset argument, (Diegoisawesome) v1.04 - converted to plain C, (WinterMute) v1.03 - header.fixed, header.device_type @@ -48,7 +49,7 @@ #include #include -#define VER "1.05" +#define VER "1.06" #define ARGV argv[arg] #define VALUE (ARGV+2) #define NUMBER strtoul(VALUE, NULL, 0) @@ -143,7 +144,7 @@ int main(int argc, char *argv[]) if (argc <= 1) { printf("GBA ROM fixer v"VER" by Dark Fader / BlackThunder / WinterMute / Diegoisawesome \n"); - printf("Syntax: gbafix [-p] [-t[title]] [-c] [-m] [-r] [-d] [-silent]\n"); + printf("Syntax: gbafix [-p] [-t[title]] [-c] [-m] [-r] [-d] [--silent]\n"); printf("\n"); printf("parameters:\n"); printf(" -p Pad to next exact power of 2. No minimum size!\n"); @@ -152,7 +153,7 @@ int main(int argc, char *argv[]) printf(" -m Patch maker code (two characters)\n"); printf(" -r Patch game version (number)\n"); printf(" -d Enable debugging handler and set debug entry point (0 or 1)\n"); - printf(" -silent Silence non-error output\n"); + printf(" --silent Silence non-error output\n"); return -1; } @@ -160,7 +161,7 @@ int main(int argc, char *argv[]) for (arg=1; arg Date: Fri, 14 Sep 2018 22:35:04 -0500 Subject: Add running status to mid2agb --- tools/mid2agb/main.cpp | 14 +++++++++++++- tools/mid2agb/midi.cpp | 13 +++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/mid2agb/main.cpp b/tools/mid2agb/main.cpp index 9b883fba5..5659e49b1 100644 --- a/tools/mid2agb/main.cpp +++ b/tools/mid2agb/main.cpp @@ -73,6 +73,18 @@ static std::string StripExtension(std::string s) return s; } +static std::string StripPathAndExtension(std::string s) +{ + std::size_t pos = s.find_last_of("/\\"); + + if (pos > 0 && pos != std::string::npos) + { + s = s.substr(pos + 1, pos); + } + + return StripExtension(s); +} + static std::string GetExtension(std::string s) { std::size_t pos = s.find_last_of('.'); @@ -206,7 +218,7 @@ int main(int argc, char** argv) RaiseError("output filename extension is not \"s\""); if (g_asmLabel.empty()) - g_asmLabel = StripExtension(outputFilename); + g_asmLabel = StripPathAndExtension(outputFilename); g_inputFile = std::fopen(inputFilename.c_str(), "rb"); diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index ba5dd654a..7c05c5237 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -52,6 +52,7 @@ static std::int32_t s_absoluteTime; static int s_blockCount = 0; static int s_minNote; static int s_maxNote; +static int s_runningStatus = 0; void Seek(long offset) { @@ -181,19 +182,31 @@ void DetermineEventCategory(MidiEventCategory& category, int& typeChan, int& siz { typeChan = ReadInt8(); + if (typeChan < 0x80 && s_runningStatus != 0) + { + typeChan = s_runningStatus; + Skip(-1); + } + if (typeChan == 0xFF) { category = MidiEventCategory::Meta; size = 0; } + else if (typeChan >= 0xF8) + { + category = MidiEventCategory::Invalid; + } else if (typeChan >= 0xF0) { category = MidiEventCategory::SysEx; size = 0; + s_runningStatus = 0; } else if (typeChan >= 0x80) { category = MidiEventCategory::Control; + s_runningStatus = typeChan; switch (typeChan >> 4) { -- cgit v1.2.3 From 3028fdc353447be5b36a5bee526ffe3ee696a62a Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Sat, 15 Sep 2018 15:49:31 -0500 Subject: Update mid2agb source Credit to @camthesaxman --- tools/mid2agb/Makefile | 7 ++- tools/mid2agb/main.cpp | 124 ++++++++++++++++++++++--------------------------- tools/mid2agb/midi.cpp | 21 +++++---- 3 files changed, 72 insertions(+), 80 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/Makefile b/tools/mid2agb/Makefile index 7fd5d5fc8..4dc2f123f 100644 --- a/tools/mid2agb/Makefile +++ b/tools/mid2agb/Makefile @@ -1,12 +1,15 @@ CXX := g++ -CXXFLAGS := -std=c++11 -O2 -Wall -Wno-switch -Werror +CXXFLAGS := -std=c++11 -O2 -s -Wall -Wno-switch -Werror SRCS := agb.cpp error.cpp main.cpp midi.cpp tables.cpp HEADERS := agb.h error.h main.h midi.h tables.h -.PHONY: clean +.PHONY: all clean + +all: mid2agb + @: mid2agb: $(SRCS) $(HEADERS) $(CXX) $(CXXFLAGS) $(SRCS) -o $@ $(LDFLAGS) diff --git a/tools/mid2agb/main.cpp b/tools/mid2agb/main.cpp index 5659e49b1..03feabdd8 100644 --- a/tools/mid2agb/main.cpp +++ b/tools/mid2agb/main.cpp @@ -50,7 +50,8 @@ bool g_compressionEnabled = true; " input_file filename(.mid) of MIDI file\n" " output_file filename(.s) for AGB file (default:input_file)\n" "\n" - "options -V??? master volume (default:127)\n" + "options -L??? label for assembler (default:output_file)\n" + " -V??? master volume (default:127)\n" " -G??? voice group number (default:0)\n" " -P??? priority (default:0)\n" " -R??? reverb (default:off)\n" @@ -73,18 +74,6 @@ static std::string StripExtension(std::string s) return s; } -static std::string StripPathAndExtension(std::string s) -{ - std::size_t pos = s.find_last_of("/\\"); - - if (pos > 0 && pos != std::string::npos) - { - s = s.substr(pos + 1, pos); - } - - return StripExtension(s); -} - static std::string GetExtension(std::string s) { std::size_t pos = s.find_last_of('.'); @@ -97,57 +86,45 @@ static std::string GetExtension(std::string s) return ""; } -struct Option -{ - char letter = 0; - const char *arg = NULL; -}; - -static Option ParseOption(int& index, const int argc, char** argv) +static std::string BaseName(std::string s) { - static std::set optionsWithArg = { 'L', 'V', 'G', 'P', 'R' }; - static std::set optionsWithoutArg = { 'X', 'E', 'N' }; - - assert(index >= 0 && index < argc); + std::size_t posAfterSlash = s.find_last_of("/\\"); - const char *opt = argv[index]; + if (posAfterSlash == std::string::npos) + posAfterSlash = 0; + else + posAfterSlash++; - assert(opt[0] == '-'); - assert(std::strlen(opt) == 2); + std::size_t dotPos = s.find_first_of('.', posAfterSlash); + if (dotPos > posAfterSlash && dotPos != std::string::npos) + s = s.substr(posAfterSlash, dotPos - posAfterSlash); - char letter = std::toupper(opt[1]); - - bool isOption = false; - bool hasArg = false; + return s; +} - if (optionsWithArg.count(letter) != 0) - { - isOption = true; - hasArg = true; - } - else if (optionsWithoutArg.count(letter) != 0) - { - isOption = true; - } +static const char *GetArgument(int argc, char **argv, int& index) +{ + assert(index >= 0 && index < argc); - if (!isOption) - PrintUsage(); + const char *option = argv[index]; - Option retVal; + assert(option != nullptr); + assert(option[0] == '-'); - retVal.letter = letter; + // If there is text following the letter, return that. + if (std::strlen(option) >= 3) + return option + 2; - if (hasArg) + // Otherwise, try to get the next arg. + if (index + 1 < argc) { index++; - - if (index >= argc) - RaiseError("missing argument for \"-%c\"", letter); - - retVal.arg = argv[index]; + return argv[index]; + } + else + { + return nullptr; } - - return retVal; } int main(int argc, char** argv) @@ -157,51 +134,60 @@ int main(int argc, char** argv) for (int i = 1; i < argc; i++) { - if (argv[i][0] == '-' && std::strlen(argv[i]) == 2) + const char *option = argv[i]; + + if (option[0] == '-' && option[1] != '\0') { - Option option = ParseOption(i, argc, argv); + const char *arg = GetArgument(argc, argv, i); - switch (option.letter) + switch (std::toupper(option[1])) { case 'E': g_exactGateTime = true; break; case 'G': - g_voiceGroup = std::stoi(option.arg); + if (arg == nullptr) + PrintUsage(); + g_voiceGroup = std::stoi(arg); break; case 'L': - g_asmLabel = option.arg; + if (arg == nullptr) + PrintUsage(); + g_asmLabel = std::stoi(arg); break; case 'N': g_compressionEnabled = false; break; case 'P': - g_priority = std::stoi(option.arg); + if (arg == nullptr) + PrintUsage(); + g_priority = std::stoi(arg); break; case 'R': - g_reverb = std::stoi(option.arg); + if (arg == nullptr) + PrintUsage(); + g_reverb = std::stoi(arg); break; case 'V': - g_masterVolume = std::stoi(option.arg); + if (arg == nullptr) + PrintUsage(); + g_masterVolume = std::stoi(arg); break; case 'X': g_clocksPerBeat = 2; break; + default: + PrintUsage(); } } else { - switch (i) - { - case 1: + if (inputFilename.empty()) inputFilename = argv[i]; - break; - case 2: + else if (outputFilename.empty()) outputFilename = argv[i]; - break; - default: + else PrintUsage(); - } } } @@ -218,7 +204,7 @@ int main(int argc, char** argv) RaiseError("output filename extension is not \"s\""); if (g_asmLabel.empty()) - g_asmLabel = StripPathAndExtension(outputFilename); + g_asmLabel = BaseName(outputFilename); g_inputFile = std::fopen(inputFilename.c_str(), "rb"); diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index 7c05c5237..09480e139 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -52,7 +52,7 @@ static std::int32_t s_absoluteTime; static int s_blockCount = 0; static int s_minNote; static int s_maxNote; -static int s_runningStatus = 0; +static int s_runningStatus; void Seek(long offset) { @@ -171,6 +171,7 @@ void StartTrack() { Seek(s_trackDataStart); s_absoluteTime = 0; + s_runningStatus = 0; } void SkipEventData() @@ -182,20 +183,18 @@ void DetermineEventCategory(MidiEventCategory& category, int& typeChan, int& siz { typeChan = ReadInt8(); - if (typeChan < 0x80 && s_runningStatus != 0) + if (typeChan < 0x80) { + // If data byte was found, use the running status. + ungetc(typeChan, g_inputFile); typeChan = s_runningStatus; - Skip(-1); } - + if (typeChan == 0xFF) { category = MidiEventCategory::Meta; size = 0; - } - else if (typeChan >= 0xF8) - { - category = MidiEventCategory::Invalid; + s_runningStatus = 0; } else if (typeChan >= 0xF0) { @@ -206,7 +205,6 @@ void DetermineEventCategory(MidiEventCategory& category, int& typeChan, int& siz else if (typeChan >= 0x80) { category = MidiEventCategory::Control; - s_runningStatus = typeChan; switch (typeChan >> 4) { @@ -218,6 +216,7 @@ void DetermineEventCategory(MidiEventCategory& category, int& typeChan, int& siz size = 2; break; } + s_runningStatus = typeChan; } else { @@ -434,7 +433,10 @@ bool CheckNoteEnd(Event& event) void FindNoteEnd(Event& event) { + // Save the current file position and running status + // which get modified by CheckNoteEnd. long startPos = ftell(g_inputFile); + int savedRunningStatus = s_runningStatus; event.param2 = 0; @@ -442,6 +444,7 @@ void FindNoteEnd(Event& event) ; Seek(startPos); + s_runningStatus = savedRunningStatus; } bool ReadTrackEvent(Event& event) -- cgit v1.2.3 From f6131763085175cfbe027089e96afa840e774ea1 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Sat, 22 Sep 2018 13:54:00 -0500 Subject: Fix order of initial vol command --- tools/mid2agb/agb.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/agb.cpp b/tools/mid2agb/agb.cpp index 9ff1efa86..5023455ca 100644 --- a/tools/mid2agb/agb.cpp +++ b/tools/mid2agb/agb.cpp @@ -334,8 +334,6 @@ void PrintAgbTrack(std::vector& events) { std::fprintf(g_outputFile, "\n@**************** Track %u (Midi-Chn.%u) ****************@\n\n", g_agbTrack, g_midiChan + 1); std::fprintf(g_outputFile, "%s_%u:\n", g_asmLabel.c_str(), g_agbTrack); - PrintWait(g_initialWait); - PrintByte("KEYSH , %s_key%+d", g_asmLabel.c_str(), 0); int wholeNoteCount = 0; int loopEndBlockNum = 0; @@ -359,6 +357,9 @@ void PrintAgbTrack(std::vector& events) if (!foundVolBeforeNote) PrintByte("\tVOL , 127*%s_mvl/mxv", g_asmLabel.c_str()); + PrintWait(g_initialWait); + PrintByte("KEYSH , %s_key%+d", g_asmLabel.c_str(), 0); + for (unsigned i = 0; events[i].type != EventType::EndOfTrack; i++) { const Event& event = events[i]; -- cgit v1.2.3 From e0acb92a3f71b196644d2c8a3b6e2b5729f92a9a Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Sun, 23 Sep 2018 00:27:40 -0500 Subject: mid2agb: allow -L param to take string --- tools/mid2agb/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/mid2agb/main.cpp b/tools/mid2agb/main.cpp index 03feabdd8..ece8e2556 100644 --- a/tools/mid2agb/main.cpp +++ b/tools/mid2agb/main.cpp @@ -153,7 +153,7 @@ int main(int argc, char** argv) case 'L': if (arg == nullptr) PrintUsage(); - g_asmLabel = std::stoi(arg); + g_asmLabel = arg; break; case 'N': g_compressionEnabled = false; -- cgit v1.2.3 From ef95a132885280dc15848ef6bc6081e0cce35c7e Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Sun, 23 Sep 2018 23:37:47 -0500 Subject: Fix compression score lower limit --- tools/mid2agb/midi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index 09480e139..c7a4389b9 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -900,7 +900,7 @@ void Compress(std::vector& events) return; } - if (CalculateCompressionScore(events, i) >= 6) + if (CalculateCompressionScore(events, i) > 6) { CompressWholeNote(events, i); } -- cgit v1.2.3 From 98e1c1994b8bd75113ffe971eebbfb0acf0d2e81 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Mon, 24 Sep 2018 02:00:09 -0500 Subject: Completely blind guess to fix compression score --- tools/mid2agb/midi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index c7a4389b9..744ef42e8 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -836,7 +836,7 @@ int CalculateCompressionScore(std::vector& events, int index) } else { - score += 2; + score++; } } @@ -900,7 +900,7 @@ void Compress(std::vector& events) return; } - if (CalculateCompressionScore(events, i) > 6) + if (CalculateCompressionScore(events, i) >= 6) { CompressWholeNote(events, i); } -- cgit v1.2.3 From 48b65eecee4675415605b2734fe32f3048382a9c Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 25 Sep 2018 01:26:09 -0500 Subject: Match compression behavior, for real --- tools/mid2agb/midi.cpp | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index 744ef42e8..1458a32b3 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -773,14 +773,16 @@ void CalculateWaits(std::vector& events) } } +// This code is (purposely) buggy as shit, to mimic how the real mid2agb worked int CalculateCompressionScore(std::vector& events, int index) { int score = 0; - std::uint8_t lastParam1 = events[index].param1; + std::uint8_t lastParam1 = (std::uint8_t)events[index].type; std::uint8_t lastVelocity = 0x80u; EventType lastType = events[index].type; std::int32_t lastDuration = 0x80000000; std::uint8_t lastNote = 0x80u; + std::int32_t lastParam2; if (events[index].time > 0) score++; @@ -791,10 +793,11 @@ int CalculateCompressionScore(std::vector& events, int index) { int val = 0; - if (events[i].note != lastNote) + // BUG: uses type instead of note + if ((std::uint8_t)events[i].type != lastNote) { val++; - lastNote = events[i].note; + lastNote = (std::uint8_t)events[i].type; } if (events[i].param1 != lastVelocity) @@ -840,7 +843,10 @@ int CalculateCompressionScore(std::vector& events, int index) } } - lastParam1 = events[i].param1; + // BUG: uses type instead of param1 + lastParam1 = (std::uint8_t)events[i].type; + // unused + lastParam2 = events[i].param2; lastType = events[i].type; if (events[i].time) -- cgit v1.2.3 From af4ff89e550455bbd503a44ac26ba6b1bc2857f7 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 25 Sep 2018 01:32:13 -0500 Subject: Comment out unused variable so GCC doesn't complain --- tools/mid2agb/midi.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index 1458a32b3..8a84a0945 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -782,7 +782,7 @@ int CalculateCompressionScore(std::vector& events, int index) EventType lastType = events[index].type; std::int32_t lastDuration = 0x80000000; std::uint8_t lastNote = 0x80u; - std::int32_t lastParam2; + //std::int32_t lastParam2; if (events[index].time > 0) score++; @@ -846,7 +846,7 @@ int CalculateCompressionScore(std::vector& events, int index) // BUG: uses type instead of param1 lastParam1 = (std::uint8_t)events[i].type; // unused - lastParam2 = events[i].param2; + //lastParam2 = events[i].param2; lastType = events[i].type; if (events[i].time) -- cgit v1.2.3 From 7f38a03093cf20e1db57ec739029fff316e69686 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 25 Sep 2018 11:41:18 -0500 Subject: mid2agb compression algorithm less buggy than originally thought --- tools/mid2agb/midi.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index 8a84a0945..be5454d4e 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -773,7 +773,6 @@ void CalculateWaits(std::vector& events) } } -// This code is (purposely) buggy as shit, to mimic how the real mid2agb worked int CalculateCompressionScore(std::vector& events, int index) { int score = 0; @@ -782,7 +781,12 @@ int CalculateCompressionScore(std::vector& events, int index) EventType lastType = events[index].type; std::int32_t lastDuration = 0x80000000; std::uint8_t lastNote = 0x80u; - //std::int32_t lastParam2; + + if (events[index].type == EventType::Note) + { + // Bug reintroduction + lastParam1 |= events[index].note + 0x40; + } if (events[index].time > 0) score++; @@ -793,11 +797,10 @@ int CalculateCompressionScore(std::vector& events, int index) { int val = 0; - // BUG: uses type instead of note - if ((std::uint8_t)events[i].type != lastNote) + if (events[i].note != lastNote) { val++; - lastNote = (std::uint8_t)events[i].type; + lastNote = events[i].note; } if (events[i].param1 != lastVelocity) @@ -845,8 +848,12 @@ int CalculateCompressionScore(std::vector& events, int index) // BUG: uses type instead of param1 lastParam1 = (std::uint8_t)events[i].type; - // unused - //lastParam2 = events[i].param2; + if (events[i].type == EventType::Note) + { + // Bug reintroduction + lastParam1 |= events[i].note + 0x40; + } + lastType = events[i].type; if (events[i].time) -- cgit v1.2.3 From d86b290419169579ecbca29aafcc46bb5a53f34f Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 25 Sep 2018 11:43:46 -0500 Subject: Change initial state of lastNote --- tools/mid2agb/midi.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index be5454d4e..b49970282 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -780,7 +780,7 @@ int CalculateCompressionScore(std::vector& events, int index) std::uint8_t lastVelocity = 0x80u; EventType lastType = events[index].type; std::int32_t lastDuration = 0x80000000; - std::uint8_t lastNote = 0x80u; + std::uint8_t lastNote = 0x40u; if (events[index].type == EventType::Note) { -- cgit v1.2.3 From 7522d2e16a22de58e60e829c8cae93b35dd5a431 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 25 Sep 2018 15:07:14 -0500 Subject: Partial implementation of MEMACC command --- tools/mid2agb/agb.cpp | 92 ++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 88 insertions(+), 4 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/agb.cpp b/tools/mid2agb/agb.cpp index 5023455ca..d4d79f133 100644 --- a/tools/mid2agb/agb.cpp +++ b/tools/mid2agb/agb.cpp @@ -38,6 +38,9 @@ static bool s_noteChanged; static bool s_velocityChanged; static bool s_inPattern; static int s_extendedCommand; +static int s_memaccOp; +static int s_memaccParam1; +static int s_memaccParam2; void PrintAgbHeader() { @@ -247,6 +250,84 @@ void PrintSeqLoopLabel(const Event& event) ResetTrackVars(); } +void PrintMemAcc(const Event& event) +{ + switch (s_memaccOp) + { + case 0x00: + PrintByte("MEMACC, mem_set, 0x%02X, %u", s_memaccParam1, event.param2); + break; + case 0x01: + PrintByte("MEMACC, mem_add, 0x%02X, %u", s_memaccParam1, event.param2); + break; + case 0x02: + PrintByte("MEMACC, mem_sub, 0x%02X, %u", s_memaccParam1, event.param2); + break; + case 0x03: + PrintByte("MEMACC, mem_mem_set, 0x%02X, 0x%02X", s_memaccParam1, event.param2); + break; + case 0x04: + PrintByte("MEMACC, mem_mem_add, 0x%02X, 0x%02X", s_memaccParam1, event.param2); + break; + case 0x05: + PrintByte("MEMACC, mem_mem_sub, 0x%02X, 0x%02X", s_memaccParam1, event.param2); + break; + // TODO: everything else + case 0x06: + break; + case 0x07: + break; + case 0x08: + break; + case 0x09: + break; + case 0x0A: + break; + case 0x0B: + break; + case 0x0C: + break; + case 0x0D: + break; + case 0x0E: + break; + case 0x0F: + break; + case 0x10: + break; + case 0x11: + break; + case 0x46: + break; + case 0x47: + break; + case 0x48: + break; + case 0x49: + break; + case 0x4A: + break; + case 0x4B: + break; + case 0x4C: + break; + case 0x4D: + break; + case 0x4E: + break; + case 0x4F: + break; + case 0x50: + break; + case 0x51: + break; + default: + break; + } + + PrintWait(event.time); +} + void PrintExtendedOp(const Event& event) { // TODO: support for other extended commands @@ -280,16 +361,19 @@ void PrintControllerOp(const Event& event) break; case 0x0C: case 0x10: - // TODO: memacc + PrintMemAcc(event); break; case 0x0D: - // TODO: memacc var + s_memaccOp = event.param2; + PrintWait(event.time); break; case 0x0E: - // TODO: memacc var + s_memaccParam1 = event.param2; + PrintWait(event.time); break; case 0x0F: - // TODO: memacc var + s_memaccParam2 = event.param2; + PrintWait(event.time); break; case 0x11: std::fprintf(g_outputFile, "%s_%u_L%u:\n", g_asmLabel.c_str(), g_agbTrack, event.param2); -- cgit v1.2.3 From f143e184a87d95338b95a34bfd64a3aff7258dee Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 25 Sep 2018 23:09:18 -0500 Subject: Fix compression score code bug reintroduction --- tools/mid2agb/midi.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index b49970282..e506fcb09 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -785,7 +785,7 @@ int CalculateCompressionScore(std::vector& events, int index) if (events[index].type == EventType::Note) { // Bug reintroduction - lastParam1 |= events[index].note + 0x40; + lastParam1 = events[index].note + 0x40; } if (events[index].time > 0) @@ -842,7 +842,7 @@ int CalculateCompressionScore(std::vector& events, int index) } else { - score++; + score += 2; } } @@ -851,7 +851,7 @@ int CalculateCompressionScore(std::vector& events, int index) if (events[i].type == EventType::Note) { // Bug reintroduction - lastParam1 |= events[i].note + 0x40; + lastParam1 = events[i].note + 0x40; } lastType = events[i].type; -- cgit v1.2.3 From 6a82bbe973740afa871a488022550711ff37de12 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Sat, 29 Sep 2018 14:46:59 -0500 Subject: Fix the fix that was buggy --- tools/mid2agb/midi.cpp | 19 +++---------------- 1 file changed, 3 insertions(+), 16 deletions(-) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index e506fcb09..93600d30e 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -776,18 +776,12 @@ void CalculateWaits(std::vector& events) int CalculateCompressionScore(std::vector& events, int index) { int score = 0; - std::uint8_t lastParam1 = (std::uint8_t)events[index].type; + std::uint8_t lastParam1 = events[index].param1; std::uint8_t lastVelocity = 0x80u; EventType lastType = events[index].type; std::int32_t lastDuration = 0x80000000; std::uint8_t lastNote = 0x40u; - if (events[index].type == EventType::Note) - { - // Bug reintroduction - lastParam1 = events[index].note + 0x40; - } - if (events[index].time > 0) score++; @@ -846,18 +840,11 @@ int CalculateCompressionScore(std::vector& events, int index) } } - // BUG: uses type instead of param1 - lastParam1 = (std::uint8_t)events[i].type; - if (events[i].type == EventType::Note) - { - // Bug reintroduction - lastParam1 = events[i].note + 0x40; - } - + lastParam1 = events[i].param1; lastType = events[i].type; if (events[i].time) - ++score; + score++; } return score; -- cgit v1.2.3 From dc53e35a6055aa983589a818cea94e41d8e7e3d8 Mon Sep 17 00:00:00 2001 From: Kermalis <29823718+Kermalis@users.noreply.github.com> Date: Sat, 29 Sep 2018 21:18:30 -0400 Subject: Fix mid2agb argument parsing --- tools/mid2agb/main.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'tools') diff --git a/tools/mid2agb/main.cpp b/tools/mid2agb/main.cpp index ece8e2556..ea2b294ac 100644 --- a/tools/mid2agb/main.cpp +++ b/tools/mid2agb/main.cpp @@ -138,7 +138,7 @@ int main(int argc, char** argv) if (option[0] == '-' && option[1] != '\0') { - const char *arg = GetArgument(argc, argv, i); + const char *arg; switch (std::toupper(option[1])) { @@ -146,11 +146,13 @@ int main(int argc, char** argv) g_exactGateTime = true; break; case 'G': + arg = GetArgument(argc, argv, i); if (arg == nullptr) PrintUsage(); g_voiceGroup = std::stoi(arg); break; case 'L': + arg = GetArgument(argc, argv, i); if (arg == nullptr) PrintUsage(); g_asmLabel = arg; @@ -159,16 +161,19 @@ int main(int argc, char** argv) g_compressionEnabled = false; break; case 'P': + arg = GetArgument(argc, argv, i); if (arg == nullptr) PrintUsage(); g_priority = std::stoi(arg); break; case 'R': + arg = GetArgument(argc, argv, i); if (arg == nullptr) PrintUsage(); g_reverb = std::stoi(arg); break; case 'V': + arg = GetArgument(argc, argv, i); if (arg == nullptr) PrintUsage(); g_masterVolume = std::stoi(arg); -- cgit v1.2.3 From c13d2b567c28f2e837be2210c83a250c0de4778f Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 2 Oct 2018 12:07:02 -0500 Subject: mid2agb fix: compare whole note details before compression --- tools/mid2agb/midi.cpp | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'tools') diff --git a/tools/mid2agb/midi.cpp b/tools/mid2agb/midi.cpp index 93600d30e..fa7d9ce28 100644 --- a/tools/mid2agb/midi.cpp +++ b/tools/mid2agb/midi.cpp @@ -852,6 +852,12 @@ int CalculateCompressionScore(std::vector& events, int index) bool IsCompressionMatch(std::vector& events, int index1, int index2) { + if (events[index1].type != events[index2].type || + events[index1].note != events[index2].note || + events[index1].param1 != events[index2].param1 || + events[index1].time != events[index2].time) + return false; + index1++; index2++; -- cgit v1.2.3