mirror of https://github.com/zeldaret/tmc.git
				
				
				
			
		
			
				
	
	
		
			202 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			202 lines
		
	
	
		
			5.1 KiB
		
	
	
	
		
			C
		
	
	
		
			Executable File
		
	
	
| // Copyright(c) 2015-2016 YamaArashi
 | |
| //
 | |
| // Permission is hereby granted, free of charge, to any person obtaining a copy
 | |
| // of this software and associated documentation files (the "Software"), to deal
 | |
| // in the Software without restriction, including without limitation the rights
 | |
| // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 | |
| // copies of the Software, and to permit persons to whom the Software is
 | |
| // furnished to do so, subject to the following conditions:
 | |
| //
 | |
| // The above copyright notice and this permission notice shall be included in
 | |
| // all copies or substantial portions of the Software.
 | |
| //
 | |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 | |
| // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 | |
| // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 | |
| // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 | |
| // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 | |
| // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 | |
| // THE SOFTWARE.
 | |
| 
 | |
| #include <stdio.h>
 | |
| #include <stdlib.h>
 | |
| #include <string.h>
 | |
| #include <stdbool.h>
 | |
| 
 | |
| #ifdef _MSC_VER
 | |
| 
 | |
| #define FATAL_ERROR(format, ...)          \
 | |
| do                                        \
 | |
| {                                         \
 | |
|     fprintf(stderr, format, __VA_ARGS__); \
 | |
|     exit(1);                              \
 | |
| } while (0)
 | |
| 
 | |
| #else
 | |
| 
 | |
| #define FATAL_ERROR(format, ...)            \
 | |
| do                                          \
 | |
| {                                           \
 | |
|     fprintf(stderr, format, ##__VA_ARGS__); \
 | |
|     exit(1);                                \
 | |
| } while (0)
 | |
| 
 | |
| #endif // _MSC_VER
 | |
| 
 | |
| unsigned char *ReadWholeFile(char *path, int *size)
 | |
| {
 | |
|     FILE *fp = fopen(path, "rb");
 | |
| 
 | |
|     if (fp == NULL)
 | |
|         FATAL_ERROR("Failed to open \"%s\" for reading.\n", path);
 | |
| 
 | |
|     fseek(fp, 0, SEEK_END);
 | |
| 
 | |
|     *size = ftell(fp);
 | |
| 
 | |
|     unsigned char *buffer = malloc(*size);
 | |
| 
 | |
|     if (buffer == NULL)
 | |
|         FATAL_ERROR("Failed to allocate memory for reading \"%s\".\n", path);
 | |
| 
 | |
|     rewind(fp);
 | |
| 
 | |
|     if (fread(buffer, *size, 1, fp) != 1)
 | |
|         FATAL_ERROR("Failed to read \"%s\".\n", path);
 | |
| 
 | |
|     fclose(fp);
 | |
| 
 | |
|     return buffer;
 | |
| }
 | |
| 
 | |
| int ExtractData(unsigned char *buffer, int offset, int size)
 | |
| {
 | |
|     switch (size)
 | |
|     {
 | |
|     case 1:
 | |
|         return buffer[offset];
 | |
|     case 2:
 | |
|         return (buffer[offset + 1] << 8)
 | |
|              | buffer[offset];
 | |
|     case 4:
 | |
|         return (buffer[offset + 3] << 24)
 | |
|              | (buffer[offset + 2] << 16)
 | |
|              | (buffer[offset + 1] << 8)
 | |
|              | buffer[offset];
 | |
|     default:
 | |
|         FATAL_ERROR("Invalid size passed to ExtractData.\n");
 | |
|     }
 | |
| }
 | |
| 
 | |
| int main(int argc, char **argv)
 | |
| {
 | |
|     if (argc < 3)
 | |
|         FATAL_ERROR("Usage: bin2c INPUT_FILE VAR_NAME [OPTIONS...]\n");
 | |
| 
 | |
|     int fileSize;
 | |
|     unsigned char *buffer = ReadWholeFile(argv[1], &fileSize);
 | |
|     char *var_name = argv[2];
 | |
|     int col = 1;
 | |
|     int pad = 0;
 | |
|     int size = 1;
 | |
|     bool isSigned = false;
 | |
|     bool isStatic = false;
 | |
|     bool isDecimal = false;
 | |
| 
 | |
|     for (int i = 3; i < argc; i++)
 | |
|     {
 | |
|         if (!strcmp(argv[i], "-col"))
 | |
|         {
 | |
|             i++;
 | |
| 
 | |
|             if (i >= argc)
 | |
|                 FATAL_ERROR("Missing argument after '-col'.\n");
 | |
| 
 | |
|             col = atoi(argv[i]);
 | |
|         }
 | |
|         else if (!strcmp(argv[i], "-pad"))
 | |
|         {
 | |
|             i++;
 | |
| 
 | |
|             if (i >= argc)
 | |
|                 FATAL_ERROR("Missing argument after '-pad'.\n");
 | |
| 
 | |
|             pad = atoi(argv[i]);
 | |
|         }
 | |
|         else if (!strcmp(argv[i], "-size"))
 | |
|         {
 | |
|             i++;
 | |
| 
 | |
|             if (i >= argc)
 | |
|                 FATAL_ERROR("Missing argument after '-size'.\n");
 | |
| 
 | |
|             size = atoi(argv[i]);
 | |
| 
 | |
|             if (size != 1 && size != 2 && size != 4)
 | |
|                 FATAL_ERROR("Size must be 1, 2, or 4.\n");
 | |
|         }
 | |
|         else if (!strcmp(argv[i], "-signed"))
 | |
|         {
 | |
|             isSigned = true;
 | |
|             isDecimal = true;
 | |
|         }
 | |
|         else if (!strcmp(argv[i], "-static"))
 | |
|         {
 | |
|             isStatic = true;
 | |
|         }
 | |
|         else if (!strcmp(argv[i], "-decimal"))
 | |
|         {
 | |
|             isDecimal = true;
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             FATAL_ERROR("Unrecognized option '%s'.\n", argv[i]);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     if ((fileSize & (size - 1)) != 0)
 | |
|         FATAL_ERROR("Size %d doesn't evenly divide file size %d.\n", size, fileSize);
 | |
| 
 | |
|     printf("// Generated file. Do not edit.\n\n");
 | |
| 
 | |
|     if (isStatic)
 | |
|         printf("static ");
 | |
| 
 | |
|     printf("const ");
 | |
| 
 | |
|     if (isSigned)
 | |
|         printf("s%d ", 8 * size);
 | |
|     else
 | |
|         printf("u%d ", 8 * size);
 | |
| 
 | |
|     printf("%s[] =\n{", var_name);
 | |
| 
 | |
|     int count = fileSize / size;
 | |
|     int offset = 0;
 | |
| 
 | |
|     for (int i = 0; i < count; i++)
 | |
|     {
 | |
|         if (i % col == 0)
 | |
|             printf("\n    ");
 | |
| 
 | |
|         int data = ExtractData(buffer, offset, size);
 | |
|         offset += size;
 | |
| 
 | |
|         if (isDecimal)
 | |
|         {
 | |
|             if (isSigned)
 | |
|                 printf("%*d, ", pad, data);
 | |
|             else
 | |
|                 printf("%*uu, ", pad, data);
 | |
|         }
 | |
|         else
 | |
|         {
 | |
|             printf("%#*xu, ", pad, data);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     printf("\n};\n");
 | |
| 
 | |
|     return 0;
 | |
| }
 |