Skip to content

Commit 2a48893

Browse files
committed
feat(project): add option to create json files
add support to create instance json files for the Analogue Pocket
1 parent b300147 commit 2a48893

File tree

8 files changed

+195
-32
lines changed

8 files changed

+195
-32
lines changed

CMakeLists.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ endif ()
66

77
# Project Information
88
project(ORCA
9-
VERSION "0.1.0"
9+
VERSION "0.2.0"
1010
DESCRIPTION "Open ROM Conversion Assistant"
1111
HOMEPAGE_URL "https://github.com/opengateware/tools-orca"
1212
LANGUAGES C)

src/arc.c

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,6 @@
2626
#include "globals.h"
2727
#include "utils.h"
2828

29-
#define MAX_LINE_LENGTH 256
30-
#define MAX_CONTENT_LENGTH 25
31-
#define MAX_CONF_OPT_LENGTH 128
32-
3329
char *format_bits(t_mra *mra, t_dip *dip) {
3430
char buffer[256] = "O";
3531
int start = 1;
@@ -70,8 +66,8 @@ char *format_bits(t_mra *mra, t_dip *dip) {
7066
}
7167

7268
int check_ids_len(t_dip *dip) {
73-
int nlen;
74-
int tlen;
69+
unsigned long nlen;
70+
unsigned long tlen;
7571
char copy[MAX_LINE_LENGTH];
7672
char *tok;
7773

@@ -80,7 +76,7 @@ int check_ids_len(t_dip *dip) {
8076
tok = strtok(copy, ",");
8177
tlen = nlen;
8278
while(tok) {
83-
int j = strlen(tok);
79+
unsigned long j = strlen(tok);
8480
tlen += j + 1;
8581
if(tlen > MAX_CONF_OPT_LENGTH) {
8682
return 1;
@@ -146,7 +142,7 @@ int write_arc(t_mra *mra, char *filename) {
146142
fwrite(buffer, 1, n, out);
147143

148144
if(mra->switches.n_dips && mra->switches.defaults) {
149-
n = snprintf(buffer, MAX_LINE_LENGTH, "DEFAULT=0x%llX\n", mra->switches.defaults << mra->switches.base);
145+
n = snprintf(buffer, MAX_LINE_LENGTH, "DEFAULT=0x%X\n", mra->switches.defaults << mra->switches.base);
150146
fwrite(buffer, 1, n, out);
151147
}
152148
if(mra->switches.page_id && mra->switches.page_name) {

src/arc.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,12 @@
2323

2424
#include "mra.h"
2525

26+
#define MAX_LINE_LENGTH 256
27+
#define MAX_CONTENT_LENGTH 25
28+
#define MAX_CONF_OPT_LENGTH 128
29+
2630
int write_arc(t_mra *mra, char *filename);
31+
char *format_bits(t_mra *mra, t_dip *dip);
32+
int check_ids_len(t_dip *dip);
2733

2834
#endif

src/json.c

Lines changed: 110 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
/*******************************************************************************
2+
* SPDX-License-Identifier: MPL-2.0
3+
* SPDX-FileType: SOURCE
4+
* SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors
5+
*******************************************************************************
6+
*
7+
* ORCA (Open ROM Conversion Assistant)
8+
* Copyright (c) 2022, OpenGateware authors and contributors (see AUTHORS file)
9+
*
10+
* This Source Code Form is subject to the terms of the Mozilla Public
11+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
12+
* You can obtain one at https://mozilla.org/MPL/2.0/.
13+
*
14+
******************************************************************************/
15+
16+
/*!*****************************************************************************
17+
* @file build.cpp
18+
* @brief
19+
******************************************************************************/
20+
21+
#include <stdio.h>
22+
#include <string.h>
23+
24+
#include "globals.h"
25+
#include "arc.h"
26+
#include "json.h"
27+
28+
int write_json(t_mra *mra, char *filename) {
29+
FILE *out;
30+
char buffer[MAX_JSON_LENGTH + 1];
31+
int i, n;
32+
unsigned int mod = 0;
33+
char mode[8] = "";
34+
35+
36+
out = fopen(filename, "wb");
37+
if(out == NULL) {
38+
fprintf(stderr, "Couldn't open %s for writing!\n", filename);
39+
return -1;
40+
}
41+
42+
i = mra_get_rom_by_index(mra, 1, 0);
43+
if(i != -1 && mra->roms[i].n_parts == 1 && !mra->roms[i].parts[0].is_group) {
44+
for(size_t k = mra->roms[i].parts[0].p.data_length; k-- > 0;) {
45+
char temp[2 + 1] = "";
46+
sprintf(temp, "%02X", mra->roms[i].parts[0].p.data[k]);
47+
strcat(mode, temp);
48+
}
49+
sscanf(mode, "%x", &mod);
50+
}
51+
52+
const char *json = "{\n"
53+
"\t\"instance\": {\n"
54+
"\t\t\"magic\": \"APF_VER_1\",\n"
55+
"\t\t\"variant_select\": {\n"
56+
"\t\t\t\"id\": 777,\n"
57+
"\t\t\t\"select\": false\n"
58+
"\t\t},\n"
59+
"\t\t\"data_slots\": [\n"
60+
"\t\t\t{\n"
61+
"\t\t\t\t\"id\": 1,\n"
62+
"\t\t\t\t\"filename\": \"%s.rom\"\n"
63+
"\t\t\t}\n"
64+
"\t\t],\n"
65+
"\t\t\"memory_writes\": [\n"
66+
"\t\t\t{\n"
67+
"\t\t\t\t\"address\": \"0xfd000000\",\n"
68+
"\t\t\t\t\"data\": \"0x%08x\"\n"
69+
"\t\t\t},\n"
70+
"\t\t\t{\n"
71+
"\t\t\t\t\"address\": \"0xfe000000\",\n"
72+
"\t\t\t\t\"data\": \"0x%02x\"\n"
73+
"\t\t\t}\n"
74+
"\t\t]\n"
75+
"\t}\n"
76+
"}";
77+
78+
n = snprintf(buffer, MAX_JSON_LENGTH, json, rom_basename, mra->switches.defaults << mra->switches.base, (mod != -1 ? mod : 0));
79+
if(n >= MAX_JSON_LENGTH) {
80+
printf("%s:%d: warning: line was truncated while writing in JSON file!\n", __FILE__, __LINE__);
81+
}
82+
fwrite(buffer, 1, n, out);
83+
84+
fclose(out);
85+
return 0;
86+
}
87+
88+
void write_interact(t_mra *mra) {
89+
// if(mra->switches.page_id && mra->switches.page_name) {
90+
// n = snprintf(buffer, MAX_JSON_LINE_LENGTH, "CONF=\"P%d,%s\"\n", mra->switches.page_id, mra->switches.page_name);
91+
// fwrite(buffer, 1, n, out);
92+
// }
93+
// for(i = 0; i < mra->switches.n_dips; i++) {
94+
// t_dip *dip = mra->switches.dips + i;
95+
// if(!strstr(str_tolower(dip->name), "unused")) {
96+
// if(dip->ids) {
97+
// n = snprintf(buffer, MAX_JSON_LINE_LENGTH, "CONF=\"%s,%s,%s\"\n", format_bits(mra, dip), dip->name, dip->ids);
98+
// } else {
99+
// n = snprintf(buffer, MAX_JSON_LINE_LENGTH, "CONF=\"%s,%s\"\n", format_bits(mra, dip), dip->name);
100+
// }
101+
// if(n >= MAX_JSON_LINE_LENGTH) {
102+
// printf("%s:%d: warning (%s): line was truncated while writing in JSON file!\n", __FILE__, __LINE__, mra->setname);
103+
// continue;
104+
// }
105+
// fwrite(buffer, 1, n, out);
106+
// } else {
107+
// printf("warning (%s): \"%s\" dip setting skipped (unused)\n", mra->setname, dip->name);
108+
// }
109+
// }
110+
}

src/json.h

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*******************************************************************************
2+
* SPDX-License-Identifier: MPL-2.0
3+
* SPDX-FileType: SOURCE
4+
* SPDX-FileCopyrightText: (c) 2022, OpenGateware authors and contributors
5+
*******************************************************************************
6+
*
7+
* ORCA (Open ROM Conversion Assistant)
8+
* Copyright (c) 2022, OpenGateware authors and contributors (see AUTHORS file)
9+
*
10+
* This Source Code Form is subject to the terms of the Mozilla Public
11+
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
12+
* You can obtain one at https://mozilla.org/MPL/2.0/.
13+
*
14+
******************************************************************************/
15+
16+
/*!*****************************************************************************
17+
* @file build.cpp
18+
* @brief
19+
******************************************************************************/
20+
21+
#ifndef ORCA_JSON_H
22+
#define ORCA_JSON_H
23+
24+
#define MAX_JSON_LENGTH 8192
25+
26+
int write_json(t_mra *mra, char *filename);
27+
28+
#endif // ORCA_JSON_H

src/main.c

Lines changed: 40 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include "rom.h"
2929
#include "utils.h"
3030
#include "version.h"
31+
#include "json.h"
3132

3233
int trace = 0;
3334
int verbose = 0;
@@ -40,31 +41,33 @@ void print_version() {
4041
void print_usage() {
4142
printf(PROJECT_NAME " v%s [%s] (%s)\n", PROJECT_VER, BUILD_REF, BUILD_DATE);
4243
printf("Usage:\n");
43-
printf(" orca [-vlzoOaA] <recipe.xml>\n");
44-
printf("\nConvert ROM recipes to a single file for usage with arcade cores.\nOptionally creates the associated support files.\n\n");
44+
printf(" orca [-vlzoOaAJ] <recipe.xml>\n");
45+
printf("\nConvert ROM recipes to a single file for usage with arcade cores.\nOptionally creates the associated metadata files.\n\n");
4546
printf("Options:\n");
4647
printf(" -h\t\tthis help.\n");
4748
printf(" -v\t\twhen it is the only parameter, display version information and exit. Otherwise, set Verbose on (default: off).\n");
4849
printf(" -l\t\tlist recipe content instead of creating the ROM file.\n");
4950
printf(" -z directory\tadd directory to include zip files. Directories added with -z have priority over the current dir.\n");
5051
printf(" -o filename\tset the output ROM file name. Overrides the internal generation of the filename.\n");
51-
printf(" -O directory\tset the output directory. By default, ROM and ARC files are created in the current directory.\n");
52-
printf(" -a filename\tset the output ARC file name. Overrides the internal generation of the filename.\n");
52+
printf(" -O directory\tset the output directory. By default, ROM and metadata files are created in the current directory.\n");
53+
printf(" -a filename\tset the output metadata file name. Overrides the internal generation of the filename.\n");
5354
printf(" -A\t\tcreate ARC file. This is done in addition to creating the ROM file.\n");
54-
printf(" -s\t\tskip ROM creation. This is useful if only the ARC file is required.\n");
55+
printf(" -J\t\tcreate JSON file. This is done in addition to creating the ROM file.\n");
56+
printf(" -s\t\tskip ROM creation. This is useful if only the metadata file is required.\n");
5557
}
5658

5759
int main(int argc, char **argv) {
5860
char *rom_filename = NULL;
5961
char *arc_filename = NULL;
60-
char *output_dir = NULL;
62+
char *output_dir = NULL;
6163
char *mra_filename;
6264
char *mra_basename;
6365
t_string_list *dirs = string_list_new(NULL);
6466
int i, res;
65-
int dump_mra = 0;
66-
int dump_rom = -1;
67+
int dump_mra = 0;
68+
int dump_rom = -1;
6769
int create_arc = 0;
70+
int create_json = 0;
6871

6972
if(trace > 0) {
7073
for(i = 0; i < argc; i++) {
@@ -83,24 +86,21 @@ int main(int argc, char **argv) {
8386
// put ':' in the starting of the
8487
// string so that program can
8588
// distinguish between '?' and ':'
86-
while((opt = getopt(argc, argv, ":vlhAo:a:O:z:s")) != -1) {
89+
while((opt = getopt(argc, argv, ":vlhAJo:a:O:z:s")) != -1) {
8790
switch(opt) {
8891
case 'v': verbose = -1; break;
8992
case 'l': dump_mra = -1; break;
9093
case 'A': create_arc = -1; break;
94+
case 'J': create_json = -1; break;
9195
case 'z': string_list_add(dirs, replace_backslash(optarg)); break;
9296
case 'O': output_dir = replace_backslash(strndup(optarg, 1024)); break;
9397
case 'o': rom_filename = replace_backslash(strndup(optarg, 1024)); break;
9498
case 'a': arc_filename = replace_backslash(strndup(optarg, 1024)); break;
9599
case 's': dump_rom = 0; break;
96100
case 'h': print_usage(); exit(0);
97-
case ':':
98-
printf("option needs a value\n");
99-
case '?':
100-
printf("unknown option: %c\n", optopt);
101-
default:
102-
print_usage();
103-
exit(-1);
101+
case ':': printf("option needs a value\n");
102+
case '?': printf("unknown option: %c\n", optopt);
103+
default: print_usage(); exit(-1);
104104
}
105105
}
106106

@@ -174,7 +174,6 @@ int main(int argc, char **argv) {
174174
if(trace > 0) {
175175
printf("create_arc set...\n");
176176
}
177-
178177
if(arc_filename) {
179178
if(output_dir) {
180179
arc_filename = get_filename(output_dir, get_basename(arc_filename, 1), "arc");
@@ -195,6 +194,30 @@ int main(int argc, char **argv) {
195194
exit(EXIT_FAILURE);
196195
}
197196
arc_filename = NULL;
197+
198+
}
199+
200+
if(create_json) {
201+
if(trace > 0) {
202+
printf("create_json set...\n");
203+
}
204+
205+
char *arc_mra_filename = strdup(mra.name ? mra.name : mra_basename);
206+
make_fat32_compatible(arc_mra_filename, 1);
207+
arc_filename = get_filename(output_dir ? output_dir : ".", arc_mra_filename, "json");
208+
free(arc_mra_filename);
209+
210+
if(verbose) {
211+
printf("Creating JSON file %s\n", arc_filename);
212+
}
213+
res = write_json(&mra, arc_filename);
214+
if(res != 0) {
215+
printf("Writing JSON file failed with error code: %d\n. Retry without -J if you still want to create the ROM file.\n", res);
216+
exit(EXIT_FAILURE);
217+
}
218+
arc_filename = NULL;
219+
220+
198221
}
199222
if(dump_rom) {
200223
if(trace > 0) {

src/mra.c

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -239,9 +239,9 @@ int read_switches(XMLNode *node, t_switches *switches) {
239239
// Read all attributes
240240
for(i = 0; i < node->n_attributes; i++) {
241241
XMLAttribute *attr = &node->attributes[i];
242-
if(strncmp(attr->name, "base", 10) == 0) {
242+
if(strncmp(attr->name, "base", 4) == 0) {
243243
switches->base = strtol(strndup(attr->value, 256), NULL, 0);
244-
} else if(strncmp(attr->name, "default", 8) == 0) {
244+
} else if(strncmp(attr->name, "default", 7) == 0) {
245245
int a, b, c, d, n; // up to four values
246246
// Fix incorrect spaces
247247
char *temp = attr->value;
@@ -264,17 +264,17 @@ int read_switches(XMLNode *node, t_switches *switches) {
264264
if(n-- > 0) {
265265
switches->defaults |= ((d & 0xff) << 24);
266266
}
267-
} else if(strncmp(attr->name, "page_id", 8) == 0) {
267+
} else if(strncmp(attr->name, "page_id", 7) == 0) {
268268
switches->page_id = strtol(strndup(attr->value, 256), NULL, 0);
269-
} else if(strncmp(attr->name, "page_name", 10) == 0) {
269+
} else if(strncmp(attr->name, "page_name", 9) == 0) {
270270
switches->page_name = strndup(attr->value, 26);
271271
}
272272
}
273273

274274
// Read DIPs
275275
for(i = 0; i < node->n_children; i++) {
276276
XMLNode *child = node->children[i];
277-
if(strncmp(child->tag, "dip", 4) == 0) {
277+
if(strncmp(child->tag, "dip", 3) == 0) {
278278
switches->n_dips++;
279279
switches->dips = (t_dip *)realloc(switches->dips, sizeof(t_dip) * (switches->n_dips));
280280
read_dip_switch(child, switches->dips + switches->n_dips - 1);

src/mra.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,7 +77,7 @@ typedef struct s_dip {
7777
typedef struct s_switches {
7878
t_dip *dips;
7979
int n_dips;
80-
long long defaults;
80+
uint32_t defaults;
8181
int base;
8282
int page_id;
8383
char *page_name;

0 commit comments

Comments
 (0)