-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
tool.c
131 lines (109 loc) · 2.94 KB
/
tool.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
#include <stdio.h>
#include <stdlib.h>
#include "clowncommon/clowncommon.h"
#include "compress.h"
#include "decompress.h"
static int InputCallback(void* const user_data)
{
FILE* const file = (FILE*)user_data;
const int character = fgetc(file);
if (character == EOF)
{
if (ferror(file))
return CLOWNNEMESIS_ERROR;
rewind(file);
return CLOWNNEMESIS_EOF;
}
return character;
}
static int OutputCallback(void* const user_data, const unsigned char byte)
{
const int return_value = fputc(byte, (FILE*)user_data);
return return_value == EOF ? CLOWNNEMESIS_ERROR : return_value;
}
int main(const int argc, char** const argv)
{
int exit_code;
exit_code = EXIT_FAILURE;
if (argc < 4)
{
const char* const usage =
"clownnemesis v1.1.1, by Clownacy.\n"
"This is a Nemesis compressor and decompressor, which can compress data\n"
"identically to Sega's original Nemesis compressor.\n"
"\n"
"Usage: %s options input output\n"
"\n"
"Options:\n"
" -c - Compress (better, but not accurate to Sega's compressor)\n"
" -ca - Compress (worse, but accurate to Sega's compressor)\n"
" -d - Decompress\n";
fprintf(stderr, usage, argv[0]);
}
else
{
cc_bool compress, accurate, unrecognised;
unrecognised = cc_false;
if (argv[1][0] == '-' && argv[1][1] == 'c' && argv[1][2] == '\0')
{
compress = cc_true;
accurate = cc_false;
}
else if (argv[1][0] == '-' && argv[1][1] == 'c' && argv[1][2] == 'a' && argv[1][3] == '\0')
{
compress = cc_true;
accurate = cc_true;
}
else if (argv[1][0] == '-' && argv[1][1] == 'd' && argv[1][2] == '\0')
{
compress = cc_false;
accurate = cc_false;
}
else
{
unrecognised = cc_true;
}
if (unrecognised)
{
fprintf(stderr, "Error: Unrecognised option '%s'.\n", argv[1]);
}
else
{
FILE *const input_file = fopen(argv[2], "rb");
if (input_file == NULL)
{
fputs("Error: Could not open input file for reading.\n", stderr);
}
else
{
FILE *const output_file = fopen(argv[3], "wb");
if (output_file == NULL)
{
fputs("Error: Could not open output file for writing.\n", stderr);
}
else
{
int success;
if (compress)
success = ClownNemesis_Compress(accurate, InputCallback, input_file, OutputCallback, output_file);
else
success = ClownNemesis_Decompress(InputCallback, input_file, OutputCallback, output_file);
if (!success)
{
if (compress)
fputs("Error: Could not compress data.\nThe input data is either too large or its size is not a multiple of 0x20 bytes.\n", stderr);
else
fputs("Error: Could not decompress data. The input data is not valid Nemesis data.\n", stderr);
}
else
{
exit_code = EXIT_SUCCESS;
}
fclose(output_file);
}
fclose(input_file);
}
}
}
return exit_code;
}