X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=teensytas.git;a=blobdiff_plain;f=host%2Fmain.c;h=bf6966d6962f550214bedd1befa4ece0e2e73677;hp=52579796d8ca01da0ba23aa80b65e1426f8f456f;hb=HEAD;hpb=ec7c7d4a8ae250565606ba026c83a19967c610e1 diff --git a/host/main.c b/host/main.c index 5257979..bf6966d 100644 --- a/host/main.c +++ b/host/main.c @@ -455,33 +455,33 @@ struct gmv_tas { uint8_t data[0][3]; }; -static uint8_t *import_gmv(FILE *f, long size, int *byte_count, FILE *logf) +static int import_gmv(FILE *f, long size, + uint8_t *out[2], int out_byte_count[2], FILE *logf) { struct gmv_tas *gmv; int frame_count; int count = 0; uint16_t val; - uint8_t *out; int ret; int i; - *byte_count = 0; + out_byte_count[0] = out_byte_count[1] = 0; if (size < (long)sizeof(*gmv)) { fprintf(stderr, "bad gmv size: %ld\n", size); - return NULL; + return -1; } gmv = malloc(size); if (gmv == NULL) { fprintf(stderr, "OOM?\n"); - return NULL; + return -1; } ret = fread(gmv, 1, size, f); if (ret != size) { fprintf(stderr, "fread %d/%ld: ", ret, size); perror(""); - return NULL; + return -1; } frame_count = (size - sizeof(*gmv)) / sizeof(gmv->data[0]); @@ -489,25 +489,25 @@ static uint8_t *import_gmv(FILE *f, long size, int *byte_count, FILE *logf) /* check the GMV.. */ if (frame_count <= 0 || size != sizeof(*gmv) + frame_count * 3) { fprintf(stderr, "broken gmv? frames=%d\n", frame_count); - return NULL; + return -1; } if (strncmp(gmv->sig, "Gens Movie TEST", 15) != 0) { fprintf(stderr, "bad GMV sig\n"); - return NULL; + return -1; } if (gmv->ctrl1 != '3') { fprintf(stderr, "unhandled controlled config: '%c'\n", gmv->ctrl1); - //return NULL; + //return -1; } if (gmv->ver >= 'A') { if (gmv->flags & 0x40) { fprintf(stderr, "unhandled flag: movie requires a savestate\n"); - return NULL; + return -1; } if (gmv->flags & 0x20) { fprintf(stderr, "unhandled flag: 3-player movie\n"); - return NULL; + return -1; } if (gmv->flags & ~0x80) { //fprintf(stderr, "unhandled flag(s): %04x\n", gmv->flags); @@ -519,15 +519,15 @@ static uint8_t *import_gmv(FILE *f, long size, int *byte_count, FILE *logf) printf("%d frames, %u rerecords\n", frame_count, gmv->rerecord_count); - out = malloc(frame_count * MAX_INPUT_BYTES); - if (out == NULL) { + out[0] = malloc(frame_count * MAX_INPUT_BYTES); + if (out[0] == NULL) { fprintf(stderr, "OOM?\n"); - return NULL; + return -1; } for (i = 0; i < frame_count; i++) { val = gmv->data[i][0] | ((gmv->data[i][2] & 0x0f) << 8); - count += tas_data_to_teensy(val, out + count, logf); + count += tas_data_to_teensy(val, out[0] + count, logf); if (gmv->data[i][1] != 0xff || gmv->data[i][2] != 0xff) { @@ -536,8 +536,8 @@ static uint8_t *import_gmv(FILE *f, long size, int *byte_count, FILE *logf) } } - *byte_count = count; - return out; + out_byte_count[0] = count; + return 0; } static int do_bkm_char(char c, char expect, uint16_t *val, int bit) @@ -554,18 +554,21 @@ static int do_bkm_char(char c, char expect, uint16_t *val, int bit) return 1; } -static uint8_t *import_bkm(FILE *f, int *byte_count, FILE *logf) +static int import_bkm(FILE *f, uint8_t *out[2], int out_byte_count[2], + FILE *logf) { - uint8_t *out = NULL; - uint16_t val; + int teensy_bytes = 0; + int have_pl2 = 0; + int have_xyz = 0; int frames = 0; int count = 0; int alloc = 0; int line = 0; char buf[256]; const char *r; + uint16_t val; char *p; - int i; + int pl, i; while ((p = fgets(buf, sizeof(buf), f)) != NULL) { @@ -581,53 +584,78 @@ static uint8_t *import_bkm(FILE *f, int *byte_count, FILE *logf) if (count >= alloc - MAX_INPUT_BYTES) { alloc = alloc * 2 + 64; - out = realloc(out, alloc * sizeof(out[0])); - if (out == NULL) { - fprintf(stderr, "OOM?\n"); - return NULL; + for (pl = 0; pl < 2; pl++) { + out[pl] = realloc(out[pl], alloc * sizeof(out[0][0])); + if (out[pl] == NULL) { + fprintf(stderr, "OOM?\n"); + return -1; + } } } - val = 0xfff; - if (strncmp(p, "|.|", 3) != 0) goto unhandled_line; p += 3; - const char ref[] = "UDLRABCS"; - for (r = ref, i = 0; *r != 0; p++, r++, i++) { - if (do_bkm_char(*p, *r, &val, i)) + for (pl = 0; pl < 2; pl++) { + static const char ref[] = "UDLRABCSXYZM"; + + val = 0xfff; + for (r = ref, i = 0; *r != 0; p++, r++, i++) { + if (do_bkm_char(*p, *r, &val, i)) + goto unhandled_line; + } + + if (*p++ != '|') goto unhandled_line; + + teensy_bytes = tas_data_to_teensy(val, out[pl] + count, logf); + + if ((val & 0xf00) != 0xf00) + have_xyz = 1; + if (pl == 1) + have_pl2 |= (val != 0xfff); } + count += teensy_bytes; - if (strcmp(p, "....|............||") != 0) + if (strcmp(p, "|") != 0) goto unhandled_line; - count += tas_data_to_teensy(val, out + count, logf); frames++; continue; unhandled_line: fprintf(stderr, "unhandled bkm line %d: '%s'\n", line, buf); - return NULL; + return -1; } - printf("loaded bkm, %d frames, %d bytes\n", frames, count); - *byte_count = count; - return out; + printf("loaded bkm, %d players, %d frames, %d bytes, have_xyz=%d\n", + have_pl2 ? 2 : 1, frames, count, have_xyz); + out_byte_count[0] = count; + if (have_pl2) + out_byte_count[1] = count; + else { + free(out[1]); + out[1] = NULL; + } + + return 0; } -static uint8_t *import_raw(FILE *f, int *byte_count, FILE *logf) +static int import_raw(FILE *f, uint8_t **out, int *out_byte_count, + FILE *logf) { - uint8_t *out = NULL, val; int count = 0; int alloc = 0; int line = 0; int first = 1; char buf[256]; + uint8_t val; char *p; int i; + *out_byte_count = 0; + while ((p = fgets(buf, sizeof(buf), f)) != NULL) { line++; @@ -655,27 +683,27 @@ static uint8_t *import_raw(FILE *f, int *byte_count, FILE *logf) if (count >= alloc) { alloc = alloc * 2 + 64; - out = realloc(out, alloc * sizeof(out[0])); - if (out == NULL) { + *out = realloc(*out, alloc * sizeof((*out)[0])); + if (*out == NULL) { fprintf(stderr, "OOM?\n"); - return NULL; + return -1; } } if (logf) fwrite(&val, 1, 1, logf); - out[count++] = val & 0x3f; + (*out)[count++] = val & 0x3f; continue; bad: fprintf(stderr, "bad raw line %d: '%s'\n", line, buf); - return NULL; + return -1; } printf("loaded raw, %d bytes\n", count); - *byte_count = count; - return out; + *out_byte_count = count; + return 0; } static int write_bkm_frame(FILE *f, const uint8_t *data) @@ -744,14 +772,15 @@ int main(int argc, char *argv[]) int pending_urbs = 0; fd_set rfds, wfds; const char *tasfn = NULL; + const char *tasfn_p2 = NULL; const char *outfn = NULL; const char *logfn = NULL; - uint8_t *tas_data = NULL; - int tas_data_size = 0; - int bytes_sent = 0; + uint8_t *tas_data[2] = { NULL, NULL }; + int tas_data_size[2] = { 0, 0 }; + int bytes_sent[2] = { 0, 0 }; int use_vsync = 0; // frame increment on vsync + int separate_2p = 0; int no_start_seq = 0; - int tas_skip = 0; int enable_sent = 0; int abort_sent = 0; int frame_count = 0; @@ -774,23 +803,23 @@ int main(int argc, char *argv[]) missing_arg(i); tasfn = argv[i]; continue; - case 'w': + case '2': i++; if (argv[i] == NULL) missing_arg(i); - outfn = argv[i]; + tasfn_p2 = argv[i]; continue; - case 'l': + case 'w': i++; if (argv[i] == NULL) missing_arg(i); - logfn = argv[i]; + outfn = argv[i]; continue; - case 's': + case 'l': i++; if (argv[i] == NULL) missing_arg(i); - tas_skip = atoi(argv[i]); + logfn = argv[i]; continue; case 'v': use_vsync = 1; @@ -838,9 +867,9 @@ int main(int argc, char *argv[]) } if (tasfn != NULL) { + FILE *f, *f_p2 = NULL; const char *ext; long size; - FILE *f; f = fopen(tasfn, "rb"); if (f == NULL) { @@ -849,6 +878,15 @@ int main(int argc, char *argv[]) return 1; } + if (tasfn_p2 != NULL) { + f_p2 = fopen(tasfn_p2, "rb"); + if (f_p2 == NULL) { + fprintf(stderr, "fopen %s: ", tasfn_p2); + perror(""); + return 1; + } + } + fseek(f, 0, SEEK_END); size = ftell(f); fseek(f, 0, SEEK_SET); @@ -864,50 +902,41 @@ int main(int argc, char *argv[]) ext++; if (strcasecmp(ext, "gmv") == 0) - tas_data = import_gmv(f, size, &tas_data_size, logf); + ret = import_gmv(f, size, tas_data, tas_data_size, logf); else if (strcasecmp(ext, "bkm") == 0) - tas_data = import_bkm(f, &tas_data_size, logf); + ret = import_bkm(f, tas_data, tas_data_size, logf); else if (strcasecmp(ext, "txt") == 0) - tas_data = import_raw(f, &tas_data_size, logf); + ret = import_raw(f, &tas_data[0], &tas_data_size[0], logf); else { fprintf(stderr, "unknown movie type: '%s'\n", ext); return 1; } fclose(f); - if (logf != NULL) { - rewind(logf); - logf = NULL; - } - - if (tas_data == NULL) { + if (ret != 0 || tas_data[0] == NULL || tas_data_size[0] <= 0) { fprintf(stderr, "failed fo parse %s\n", tasfn); return 1; } - if (tas_skip != 0) { - // FIXME: no longer a byte - if (tas_skip >= tas_data_size || tas_skip <= -tas_data_size) { - printf("skip out of range: %d/%d\n", tas_skip, tas_data_size); + // separate file with p2 input? + if (f_p2 != NULL) { + ret = import_raw(f_p2, &tas_data[1], &tas_data_size[1], NULL); + if (ret != 0 || tas_data[1] == NULL || tas_data_size[1] <= 0) { + fprintf(stderr, "failed fo parse %s\n", tasfn_p2); return 1; } - if (tas_skip > 0) { - tas_data_size -= tas_skip; - memmove(&tas_data[0], &tas_data[tas_skip], - sizeof(tas_data[0]) * tas_data_size); - } - else { - tas_data = realloc(tas_data, - (tas_data_size - tas_skip) * sizeof(tas_data[0])); - if (tas_data == NULL) { - fprintf(stderr, "OOM?\n"); - return 1; - } - memmove(&tas_data[-tas_skip], &tas_data[0], - sizeof(tas_data[0]) * tas_data_size); - memset(&tas_data[0], 0xff, sizeof(tas_data[0]) * -tas_skip); - tas_data_size -= tas_skip; - } + fclose(f_p2); + separate_2p = 1; + } + + if (logf != NULL) { + fclose(logf); + logf = NULL; + } + + if (tas_data_size[1] != 0 && tas_data[1] == NULL) { + fprintf(stderr, "missing tas_data[1]\n"); + return 1; } } @@ -944,7 +973,8 @@ int main(int argc, char *argv[]) wait_device = 0; pending_urbs = 0; enable_sent = 0; - bytes_sent = 0; + bytes_sent[0] = 0; + bytes_sent[1] = 0; /* we wait first, then send commands, but if teensy * is started already, it won't send anything */ @@ -1047,21 +1077,25 @@ int main(int argc, char *argv[]) } else if (reaped_urb == &urb[URB_DATA_IN]) { + int p; + /* some request from teensy */ switch (pkt_in.type) { case PKT_STREAM_REQ: - printf("req: %d/%d/%d\n", pkt_in.req.frame * 2, - bytes_sent, tas_data_size); + p = pkt_in.req.is_p2 ? 1 : 0; + printf("req%d: %d/%d/%d\n", pkt_in.req.is_p2, + pkt_in.req.frame * 2, bytes_sent[p], tas_data_size[p]); pkt_out.size = 0; - if (bytes_sent < tas_data_size) { - pkt_out.type = PKT_STREAM_DATA_TO; + if (bytes_sent[p] < tas_data_size[p]) { + pkt_out.type = p ? PKT_STREAM_DATA_TO_P2 + : PKT_STREAM_DATA_TO_P1; - i = tas_data_size - bytes_sent; + i = tas_data_size[p] - bytes_sent[p]; if (i > sizeof(pkt_out.data)) i = sizeof(pkt_out.data); - memcpy(pkt_out.data, tas_data + bytes_sent, i); - bytes_sent += i; + memcpy(pkt_out.data, tas_data[p] + bytes_sent[p], i); + bytes_sent[p] += i; pkt_out.size = i; } else { @@ -1117,13 +1151,20 @@ int main(int argc, char *argv[]) // can't do that yet continue; - if ((tas_data != NULL || outf != NULL) && !enable_sent) { + if ((tas_data[0] != NULL || outf != NULL) && !enable_sent) { memset(&pkt_out, 0, sizeof(pkt_out)); pkt_out.type = PKT_STREAM_ENABLE; - pkt_out.enable.stream_to = (tas_data != NULL); + pkt_out.enable.stream_to = (tas_data[0] != NULL); pkt_out.enable.stream_from = (outf != NULL); - pkt_out.enable.use_readinc = !use_vsync; pkt_out.enable.no_start_seq = no_start_seq; + if (use_vsync) + pkt_out.enable.inc_mode = INC_MODE_VSYNC; + else if (tas_data_size[1] != 0 && separate_2p) + pkt_out.enable.inc_mode = INC_MODE_SEPARATE; + else if (tas_data_size[1] != 0) + pkt_out.enable.inc_mode = INC_MODE_SHARED_PL2; + else + pkt_out.enable.inc_mode = INC_MODE_SHARED_PL1; ret = submit_urb(dev.fd, &urb[URB_DATA_OUT], dev.ifaces[0].ep_out, &pkt_out, sizeof(pkt_out)); @@ -1133,10 +1174,11 @@ int main(int argc, char *argv[]) } pending_urbs |= 1 << URB_DATA_OUT; enable_sent = 1; - bytes_sent = 0; + bytes_sent[0] = 0; + bytes_sent[1] = 0; continue; } - if (tas_data == NULL && fixed_input_changed) { + if (tas_data[0] == NULL && fixed_input_changed) { memset(&pkt_out, 0, sizeof(pkt_out)); pkt_out.type = PKT_FIXED_STATE; memcpy(pkt_out.data, fixed_input_state, sizeof(fixed_input_state));