#define INCL_DOSFILEMGR
#define INCL_DOSDEVICES
#define INCL_DOSPROCESS
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#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);
}