#define INCL_DOSFILEMGR #define INCL_DOSDEVICES #define INCL_DOSPROCESS #include #include #include #include #include "struct.h" #include "ultradev.h" #include "s3mload.h" SAMPINFO *Samples; HFILE GUSHandle, modin; APIRET SampleMemFree(void); static S3MHEADER header; static unsigned char PatternOrder[256]; static SCREAMSAMPLE s; int main(int argc, char *argv[]) { ULONG Wrote, Action; int i, j, lo, temprep, hdr; short int *paraptr; char *SampMem; /* tijdelijke buffer om samples naar GUS te sturen */ SAMPINFO *SampInfo; int foffset; //offset sample inside s3m file APIRET rc; Action = 2; if(argc != 2) return(FALSE); rc = DosOpen(argv[1], /* file name from Open dialog */ &modin, /* file handle returned */ &Action, 0L, FILE_NORMAL, OPEN_ACTION_FAIL_IF_NEW | OPEN_ACTION_OPEN_IF_EXISTS, OPEN_FLAGS_SEQUENTIAL | OPEN_ACCESS_READONLY | OPEN_SHARE_DENYWRITE, (PEAOP2)NULL); ON_ERROR(rc, S3MTestAndLoad_Err); DosSetFilePtr(modin, 0, FILE_BEGIN, &Wrote); rc = DosRead(modin, &header, sizeof(S3MHEADER), &Wrote); ON_ERROR(rc, S3MTestAndLoad_Err); rc = memcmp(header.scrm, "SCRM", 4); if(rc) return(2); rc = DosAllocMem(&Samples, (header.insnum+1)*sizeof(SAMPINFO), PAG_COMMIT | PAG_WRITE); ON_ERROR(rc, S3MTestAndLoad_Err); DosSetFilePtr(modin, 0x60, FILE_BEGIN, &Wrote); //bepaal song lengte rc = DosRead(modin, &PatternOrder, header.ordnum, &Wrote); ON_ERROR(rc, S3MTestAndLoad_Err); //reserveer geheugen voor paraptrs naar instruments + patterns rc = DosAllocMem(¶ptr, 2*(header.patnum + header.insnum), PAG_COMMIT | PAG_WRITE); ON_ERROR(rc, S3MTestAndLoad_Err); rc = DosRead(modin, paraptr, 2*(header.patnum + header.insnum), &Wrote); ON_ERROR(rc, S3MTestAndLoad_Err); InitDevice(); /* Samples oversturen naar de GUS Aanname: Samples =< 128K */ rc = DosAllocMem(&SampMem, (128*1024), PAG_COMMIT | PAG_WRITE); ON_ERROR(rc, S3MTestAndLoad_Err); //plus een voor null sample SampInfo = Samples + 1; for(i=1;i<(header.insnum+1);i++) { printf("Downloading voice %d....", i); fflush(stdout); DosSetFilePtr(modin, (int)paraptr[i-1]<<4, FILE_BEGIN, &Wrote); // and load sample info rc = DosRead(modin, &s, sizeof(SCREAMSAMPLE), &Wrote); ON_ERROR(rc, S3MTestAndLoad_Err); strncpy(SampInfo->Name, s.sampname,28); SampInfo->Name[28] = 0; SampInfo->Finetune = s.c2spd & 0xFFFF; //lower 16 bits only SampInfo->Length = s.length; SampInfo->Repeat = s.loopbeg; SampInfo->End = s.loopend - 1; SampInfo->Volume = s.volume; SampInfo->Mode = 0; hdr = 0; if(s.flags & 1) SampInfo->Mode |= VC_LOOP_ENABLE; if(s.flags & 4) { hdr |= DMA_16; SampInfo->Mode |= VC_DATA_TYPE; } if(header.fileformat != 1) hdr |= DMA_CVT_2; if(memcmp(s.scrs,"SCRS",4) !=0) { SampInfo->Length = 0; SampInfo->Volume = 0; } else { foffset = ( ( ( (int)s.memsegh) <<16 ) | s.memsegl ) << 4; DosSetFilePtr(modin, foffset, FILE_BEGIN, &Wrote); rc = DosRead(modin, SampMem, SampInfo->Length, &Wrote); ON_ERROR(rc, S3MTestAndLoad_Err); rc = UltiMODMemAlloc(SampInfo->Length + 16, &SampInfo->Offset); ON_ERROR(rc, S3MTestAndLoad_Err); rc = UltraDownload(SampMem, hdr, SampInfo->Offset, SampInfo->Length, TRUE); if(SampInfo->Mode & VC_LOOP_ENABLE) { temprep = SampInfo->Repeat; SampInfo->Repeat += SampInfo->Offset; SampInfo->End += SampInfo->Offset; //anti-click for end of sample for(j=0;j<16;j++) if(hdr & DMA_CVT_2) { lo = SampInfo->Repeat + j; UltraPeekData(&lo); UltraPokeData(SampInfo->End + j, lo); } else UltraPokeData(SampInfo->End + j, *(SampMem + j + temprep)); } else { SampInfo->End = SampInfo->Offset + SampInfo->Length; SampInfo->Repeat = SampInfo->Offset; //anti-click for end of sample for(j=0;j<16;j++) UltraPokeData(SampInfo->End + j, 0); } UltraStartVoice(0,SampInfo->Offset,SampInfo->Repeat,SampInfo->End, SampInfo->Mode); UltraSetFrequency(0, 22050); UltraVectorLinearVolume(0, 200, (unsigned char)0x2F,(unsigned char)0); DosSleep(1000); hdr = 0; UltraVoiceStopped(&hdr); if(hdr) printf("Sample finished playing.\n"); else printf("Sample is still playing.\n"); if((SampInfo->Mode & VC_LOOP_ENABLE) && !hdr) { UltraSetLoopMode(0, 0x00); //stop loop printf("Stopped loop.\n"); } DosSleep(2000); UltraStopVoice(0); } SampInfo++; } S3MTestAndLoad_Err: UltiMODMemFree(); DosFreeMem(Samples); DosFreeMem(SampMem); DosFreeMem(paraptr); StopPlaying(); return(TRUE); } int InitDevice() { APIRET status; ULONG action; int k; status = DosOpen( "ULTRA1$", &GUSHandle, &action, 0, FILE_NORMAL, FILE_OPEN, OPEN_ACCESS_READWRITE | OPEN_SHARE_DENYNONE | OPEN_FLAGS_WRITE_THROUGH, NULL ); if(status) return(FALSE); if(UltraGetAccess() != 0) { DosClose(GUSHandle); return(FALSE); //not only owner } if(UltraGetDriverVersion(&k)) { DosClose(GUSHandle); return(FALSE); //driver too old! } if(k < 85) { DosClose(GUSHandle); return(FALSE); //driver too old! } return(TRUE); } int StopPlaying() { APIRET rc; UltraDisableOutput(); rc = UltraReleaseAccess(); //gives other programs access to the GUS rc = DosClose(GUSHandle); return(TRUE); }