Mercurial > hg > dmlib
comparison tools/xm2jss.c @ 2476:90eec3e1f85f
Use DMResource I/O instead of stdio for writing JSSMOD module.
author | Matti Hamalainen <ccr@tnsp.org> |
---|---|
date | Mon, 27 Apr 2020 18:33:18 +0300 |
parents | b9734859db5c |
children | 7151597d8ec6 |
comparison
equal
deleted
inserted
replaced
2475:b9734859db5c | 2476:90eec3e1f85f |
---|---|
508 | 508 |
509 #undef JSFOREACHNOTE1 | 509 #undef JSFOREACHNOTE1 |
510 #undef JSFOREACHNOTE2 | 510 #undef JSFOREACHNOTE2 |
511 | 511 |
512 | 512 |
513 static BOOL jssMODWriteEnvelope(FILE *outFile, JSSEnvelope *env, const char *name, const int ninst) | 513 static BOOL jssMODWriteEnvelope(DMResource *outFile, const JSSEnvelope *env, const char *name, const int ninst) |
514 { | 514 { |
515 BOOL ok = | 515 BOOL ok = |
516 dm_fwrite_byte(outFile, env->flags) && | 516 dmf_write_byte(outFile, env->flags) && |
517 dm_fwrite_byte(outFile, env->npoints) && | 517 dmf_write_byte(outFile, env->npoints) && |
518 dm_fwrite_byte(outFile, env->sustain) && | 518 dmf_write_byte(outFile, env->sustain) && |
519 dm_fwrite_byte(outFile, env->loopS) && | 519 dmf_write_byte(outFile, env->loopS) && |
520 dm_fwrite_byte(outFile, env->loopE); | 520 dmf_write_byte(outFile, env->loopE); |
521 | 521 |
522 for (int i = 0; ok && i < env->npoints; i++) | 522 for (int i = 0; ok && i < env->npoints; i++) |
523 { | 523 { |
524 ok = | 524 ok = |
525 dm_fwrite_le16(outFile, env->points[i].frame) && | 525 dmf_write_le16(outFile, env->points[i].frame) && |
526 dm_fwrite_le16(outFile, env->points[i].value); | 526 dmf_write_le16(outFile, env->points[i].value); |
527 } | 527 } |
528 | 528 |
529 if (!ok) | 529 if (!ok) |
530 { | 530 { |
531 JSSERROR(DMERR_FWRITE, ok, | 531 JSSERROR(DMERR_FWRITE, ok, |
537 } | 537 } |
538 | 538 |
539 | 539 |
540 /* Save a JSSMOD file | 540 /* Save a JSSMOD file |
541 */ | 541 */ |
542 int jssSaveJSSMOD(FILE *outFile, JSSModule *module, int patMode, int flags8, int flags16) | 542 int jssSaveJSSMOD(DMResource *outFile, const JSSModule *module, |
543 const int patMode, const int flags8, const int flags16) | |
543 { | 544 { |
544 JSSMODHeader jssH; | 545 JSSMODHeader jssH; |
545 const size_t patBufSize = 512*1024; // 256kB pattern buffer | 546 const size_t patBufSize = 512*1024; // 256kB pattern buffer |
546 Uint8 *patBuf; | 547 Uint8 *patBuf; |
547 size_t totalSize; | 548 size_t totalSize; |
580 jssH.defSpeed = module->defSpeed; | 581 jssH.defSpeed = module->defSpeed; |
581 jssH.defTempo = module->defTempo; | 582 jssH.defTempo = module->defTempo; |
582 jssH.patMode = patMode; | 583 jssH.patMode = patMode; |
583 | 584 |
584 // Write header | 585 // Write header |
585 if (!dm_fwrite_str(outFile, jssH.idMagic, sizeof(jssH.idMagic)) || | 586 if (!dmf_write_str(outFile, jssH.idMagic, sizeof(jssH.idMagic)) || |
586 !dm_fwrite_byte(outFile, jssH.idVersion) || | 587 !dmf_write_byte(outFile, jssH.idVersion) || |
587 | 588 |
588 !dm_fwrite_le16(outFile, jssH.defFlags) || | 589 !dmf_write_le16(outFile, jssH.defFlags) || |
589 !dm_fwrite_le16(outFile, jssH.intVersion) || | 590 !dmf_write_le16(outFile, jssH.intVersion) || |
590 !dm_fwrite_le16(outFile, jssH.norders) || | 591 !dmf_write_le16(outFile, jssH.norders) || |
591 !dm_fwrite_le16(outFile, jssH.npatterns) || | 592 !dmf_write_le16(outFile, jssH.npatterns) || |
592 !dm_fwrite_le16(outFile, jssH.nextInstruments) || | 593 !dmf_write_le16(outFile, jssH.nextInstruments) || |
593 !dm_fwrite_le16(outFile, jssH.ninstruments) || | 594 !dmf_write_le16(outFile, jssH.ninstruments) || |
594 !dm_fwrite_le16(outFile, jssH.defRestartPos) || | 595 !dmf_write_le16(outFile, jssH.defRestartPos) || |
595 | 596 |
596 !dm_fwrite_byte(outFile, jssH.nchannels) || | 597 !dmf_write_byte(outFile, jssH.nchannels) || |
597 !dm_fwrite_byte(outFile, jssH.defSpeed) || | 598 !dmf_write_byte(outFile, jssH.defSpeed) || |
598 !dm_fwrite_byte(outFile, jssH.defTempo) || | 599 !dmf_write_byte(outFile, jssH.defTempo) || |
599 !dm_fwrite_byte(outFile, jssH.patMode)) | 600 !dmf_write_byte(outFile, jssH.patMode)) |
600 { | 601 { |
601 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | 602 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
602 "Error writing JSSMOD header!\n"); | 603 "Error writing JSSMOD header!\n"); |
603 } | 604 } |
604 | 605 |
618 } | 619 } |
619 | 620 |
620 if (tmp == jsetNotSet) | 621 if (tmp == jsetNotSet) |
621 tmp = 0xffff; | 622 tmp = 0xffff; |
622 | 623 |
623 if (!dm_fwrite_le16(outFile, tmp)) | 624 if (!dmf_write_le16(outFile, tmp)) |
624 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | 625 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
625 "Could not write JSSMOD orders list entry #%d (%d).\n", | 626 "Could not write JSSMOD orders list entry #%d (%d).\n", |
626 index, tmp); | 627 index, tmp); |
627 | 628 |
628 totalSize += sizeof(Uint16); | 629 totalSize += sizeof(Uint16); |
694 dmMsg(3, " - Pattern %d size %" DM_PRIu_SIZE_T " bytes\n", | 695 dmMsg(3, " - Pattern %d size %" DM_PRIu_SIZE_T " bytes\n", |
695 index, dataSize); | 696 index, dataSize); |
696 | 697 |
697 totalSize += dataSize + sizeof(JSSMODPattern); | 698 totalSize += dataSize + sizeof(JSSMODPattern); |
698 | 699 |
699 if (!dm_fwrite_le32(outFile, dataSize) || | 700 if (!dmf_write_le32(outFile, dataSize) || |
700 !dm_fwrite_le16(outFile, pattern->nrows) || | 701 !dmf_write_le16(outFile, pattern->nrows) || |
701 !dm_fwrite_le16(outFile, pattern->nmap)) | 702 !dmf_write_le16(outFile, pattern->nmap)) |
702 { | 703 { |
703 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | 704 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
704 "Error writing JSSMOD pattern header #%d.\n", | 705 "Error writing JSSMOD pattern header #%d.\n", |
705 index); | 706 index); |
706 } | 707 } |
707 | 708 |
708 if (pattern->nmap != pattern->nchannels) | 709 if (pattern->nmap != pattern->nchannels) |
709 { | 710 { |
710 if (!dm_fwrite_str(outFile, pattern->map, | 711 if (!dmf_write_str(outFile, pattern->map, |
711 sizeof(pattern->map[0]) * pattern->nmap)) | 712 sizeof(pattern->map[0]) * pattern->nmap)) |
712 { | 713 { |
713 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | 714 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
714 "Error writing JSSMOD channel map for pattern #%d.\n", | 715 "Error writing JSSMOD channel map for pattern #%d.\n", |
715 index); | 716 index); |
716 } | 717 } |
717 } | 718 } |
718 | 719 |
719 if (!dm_fwrite_str(outFile, patBuf, dataSize)) | 720 if (!dmf_write_str(outFile, patBuf, dataSize)) |
720 { | 721 { |
721 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | 722 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
722 "Error writing JSSMOD pattern data #%d.\n", | 723 "Error writing JSSMOD pattern data #%d.\n", |
723 index); | 724 index); |
724 } | 725 } |
743 index); | 744 index); |
744 } | 745 } |
745 | 746 |
746 // Misc data | 747 // Misc data |
747 BOOL ok = | 748 BOOL ok = |
748 dm_fwrite_byte(outFile, einst->nsamples) && | 749 dmf_write_byte(outFile, einst->nsamples) && |
749 dm_fwrite_byte(outFile, einst->vibratoType) && | 750 dmf_write_byte(outFile, einst->vibratoType) && |
750 dm_fwrite_le16(outFile, einst->vibratoSweep) && | 751 dmf_write_le16(outFile, einst->vibratoSweep) && |
751 dm_fwrite_le16(outFile, einst->vibratoDepth) && | 752 dmf_write_le16(outFile, einst->vibratoDepth) && |
752 dm_fwrite_le16(outFile, einst->vibratoRate) && | 753 dmf_write_le16(outFile, einst->vibratoRate) && |
753 dm_fwrite_le16(outFile, einst->fadeOut); | 754 dmf_write_le16(outFile, einst->fadeOut); |
754 | 755 |
755 // Sample number for note(s) | 756 // Sample number for note(s) |
756 for (int i = 0; ok && i < jsetNNotes; i++) | 757 for (int i = 0; ok && i < jsetNNotes; i++) |
757 { | 758 { |
758 int snum = einst->sNumForNotes[i]; | 759 int snum = einst->sNumForNotes[i]; |
759 Uint32 tmp = (snum != jsetNotSet) ? snum + 1 : 0; | 760 Uint32 tmp = (snum != jsetNotSet) ? snum + 1 : 0; |
760 ok = dm_fwrite_le32(outFile, tmp); | 761 ok = dmf_write_le32(outFile, tmp); |
761 } | 762 } |
762 | 763 |
763 // Envelopes | 764 // Envelopes |
764 if (!ok || | 765 if (!ok || |
765 !jssMODWriteEnvelope(outFile, &einst->volumeEnv, "volume", index) || | 766 !jssMODWriteEnvelope(outFile, &einst->volumeEnv, "volume", index) || |
786 inst->convFlags = (inst->flags & jsf16bit) ? flags16 : flags8; | 787 inst->convFlags = (inst->flags & jsf16bit) ? flags16 : flags8; |
787 if (inst->data != NULL) | 788 if (inst->data != NULL) |
788 inst->convFlags |= jsampHasData; | 789 inst->convFlags |= jsampHasData; |
789 | 790 |
790 // Write instrument header | 791 // Write instrument header |
791 if (!dm_fwrite_le32(outFile, inst->size) || | 792 if (!dmf_write_le32(outFile, inst->size) || |
792 !dm_fwrite_le32(outFile, inst->loopS) || | 793 !dmf_write_le32(outFile, inst->loopS) || |
793 !dm_fwrite_le32(outFile, inst->loopE) || | 794 !dmf_write_le32(outFile, inst->loopE) || |
794 !dm_fwrite_le16(outFile, inst->flags) || | 795 !dmf_write_le16(outFile, inst->flags) || |
795 !dm_fwrite_le16(outFile, inst->C4BaseSpeed) || | 796 !dmf_write_le16(outFile, inst->C4BaseSpeed) || |
796 !dm_fwrite_le16(outFile, inst->ERelNote) || | 797 !dmf_write_le16(outFile, inst->ERelNote) || |
797 !dm_fwrite_le16(outFile, inst->EFineTune) || | 798 !dmf_write_le16(outFile, inst->EFineTune) || |
798 !dm_fwrite_le16(outFile, inst->EPanning) || | 799 !dmf_write_le16(outFile, inst->EPanning) || |
799 !dm_fwrite_byte(outFile, inst->volume) || | 800 !dmf_write_byte(outFile, inst->volume) || |
800 !dm_fwrite_byte(outFile, inst->convFlags)) | 801 !dmf_write_byte(outFile, inst->convFlags)) |
801 { | 802 { |
802 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | 803 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
803 "Error writing JSSMOD instrument #%d.\n", | 804 "Error writing JSSMOD instrument #%d.\n", |
804 index); | 805 index); |
805 } | 806 } |
839 JSSERROR(res, res, | 840 JSSERROR(res, res, |
840 "Error encoding sample for instrument #%d: %s\n", | 841 "Error encoding sample for instrument #%d: %s\n", |
841 index, dmErrorStr(res)); | 842 index, dmErrorStr(res)); |
842 } | 843 } |
843 | 844 |
844 if (!dm_fwrite_str(outFile, inst->data, bsize)) | 845 if (!dmf_write_str(outFile, inst->data, bsize)) |
845 { | 846 { |
846 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, | 847 JSSERROR(DMERR_FWRITE, DMERR_FWRITE, |
847 "Error writing JSSMOD sample data for instrument #%d.\n", | 848 "Error writing JSSMOD sample data for instrument #%d.\n", |
848 index); | 849 index); |
849 } | 850 } |
1294 } | 1295 } |
1295 | 1296 |
1296 | 1297 |
1297 int main(int argc, char *argv[]) | 1298 int main(int argc, char *argv[]) |
1298 { | 1299 { |
1299 DMResource *inFile = NULL; | 1300 DMResource *inFile = NULL, *outFile = NULL; |
1300 FILE *outFile = NULL; | |
1301 JSSModule *src = NULL, *dst = NULL; | 1301 JSSModule *src = NULL, *dst = NULL; |
1302 int res = DMERR_OK; | 1302 int res = DMERR_OK; |
1303 | 1303 |
1304 dmInitProg("xm2jss", "XM to JSSMOD converter", "0.8", NULL, NULL); | 1304 dmInitProg("xm2jss", "XM to JSSMOD converter", "0.8", NULL, NULL); |
1305 dmVerbosity = 0; | 1305 dmVerbosity = 0; |
1391 } | 1391 } |
1392 else | 1392 else |
1393 dst = src; | 1393 dst = src; |
1394 | 1394 |
1395 // Write output file | 1395 // Write output file |
1396 if ((outFile = fopen(optOutFilename, "wb")) == NULL) | 1396 if ((res = dmf_open_stdio(optOutFilename, "wb", &outFile)) != DMERR_OK) |
1397 { | 1397 { |
1398 res = dmGetErrno(); | |
1399 dmErrorMsg("Error creating output file '%s': %s\n", | 1398 dmErrorMsg("Error creating output file '%s': %s\n", |
1400 optOutFilename, dmErrorStr(res)); | 1399 optOutFilename, dmErrorStr(res)); |
1401 goto out; | 1400 goto out; |
1402 } | 1401 } |
1403 | 1402 |
1404 dmMsg(1, "Writing JSSMOD-format file [patMode=0x%04x, samp8=0x%02x, samp16=0x%02x]\n", | 1403 dmMsg(1, "Writing JSSMOD-format file [patMode=0x%04x, samp8=0x%02x, samp16=0x%02x]\n", |
1405 optPatternMode, optSampMode8, optSampMode16); | 1404 optPatternMode, optSampMode8, optSampMode16); |
1406 | 1405 |
1407 res = jssSaveJSSMOD(outFile, dst, optPatternMode, optSampMode8, optSampMode16); | 1406 res = jssSaveJSSMOD(outFile, dst, optPatternMode, optSampMode8, optSampMode16); |
1408 | 1407 |
1409 fclose(outFile); | 1408 dmf_close(outFile); |
1410 | 1409 |
1411 if (res != 0) | 1410 if (res != 0) |
1412 { | 1411 { |
1413 dmErrorMsg( | 1412 dmErrorMsg( |
1414 "Error while saving JSSMOD file: %s\n" | 1413 "Error while saving JSSMOD file: %s\n" |