Category : Windows 3.X Files
Archive   : SNDHACK.ZIP
Filename : PLAY.C

 
Output of file : PLAY.C contained in archive : SNDHACK.ZIP
#include
#include
#include
#include
#include "app.h"

/*
* Module: play.c
*
* Contains: All functions associated with interpreting
* and playing the Edit buffer should go here.
*
*/


/*********************************************************************/
/* Local Function Prototypes */
/*********************************************************************/

BOOL PlayLine( void );
BOOL PlayTokens( int );
BOOL PlayFunction( int );
int PlayGetToken(char **, char *, char *);
void PlayError(char *);

BOOL PlayCloseSound( void );
BOOL PlayCountVoiceNotes( void );
BOOL PlayGetThresholdEvent( void );
BOOL PlayGetThresholdStatus( void );
BOOL PlayOpenSound( void );
BOOL PlaySetSoundNoise( void );
BOOL PlaySetVoiceAccent( void );
BOOL PlaySetVoiceEnvelope( void );
BOOL PlaySetVoiceNote( void );
BOOL PlaySetVoiceQueueSize( void );
BOOL PlaySetVoiceSound( void );
BOOL PlaySetVoiceThreshold( void );
BOOL PlayStartSound( void );
BOOL PlayStopSound( void );
BOOL PlaySyncAllVoices( void );
BOOL PlayWaitSoundState( void );

BOOL PlayIntConvert(char *, int *);
BOOL PlayLongConvert(char *, long *);


/*********************************************************************/
/* Local data and structures */
/*********************************************************************/
#define MAXLINE 80
#define MAXPARM 6
#define MAXPARMLEN 33

extern SndDef SndState;

static BOOL b;
static int rc;
static char rcmsg[80];

static char pfunction[MAXPARMLEN];
static char parms[MAXPARM][MAXPARMLEN];
static char *parm[MAXPARM];

static int ebuffchar;
static char ebuffline[MAXLINE];

static struct {
char *fname;
int parms;
BOOL (*func)(void);
} wsound[] = {
"CloseSound", 0, PlayCloseSound,
"CountVoiceNotes", 1, PlayCountVoiceNotes,
"GetThresholdEvent", 0, PlayGetThresholdEvent,
"GetThresholdStatus", 0, PlayGetThresholdStatus,
"OpenSound", 0, PlayOpenSound,
"SetSoundNoise", 2, PlaySetSoundNoise,
"SetVoiceAccent", 5, PlaySetVoiceAccent,
"SetVoiceEnvelope", 3, PlaySetVoiceEnvelope,
"SetVoiceNote", 4, PlaySetVoiceNote,
"SetVoiceQueueSize", 2, PlaySetVoiceQueueSize,
"SetVoiceSound", 3, PlaySetVoiceSound,
"SetVoiceThreshold", 2, PlaySetVoiceThreshold,
"StartSound", 0, PlayStartSound,
"StopSound", 0, PlayStopSound,
"SyncAllVoices", 0, PlaySyncAllVoices,
"WaitSoundState", 1, PlayWaitSoundState,
};

/*********************************************************************/
/* Global functions */
/*********************************************************************/

/*-------------------------------------------------------------------*/
/* The Play 'button' was hit, try and play contents of edit buffer */
/*-------------------------------------------------------------------*/
void Play(void)
{
HANDLE hEditBuffer; /* handle to editing buffer */
PSTR pEditBuffer; /* address of the edit buffer */
PSTR pscan;
int i = 0, numchar = 0;
/* Get Edit window text */
hEditBuffer = SendMessage(hEditWindow, EM_GETHANDLE, 0, 0L);
pEditBuffer = LocalLock(hEditBuffer);
if (pEditBuffer == NULL) {
PlayError("Could not lock edit buffer");
return;
}

ebuffline[0] = '\0'; /* Break the text buffer up into */
pscan = pEditBuffer; /* lines and ship it off to */
while (*pscan) { /* PlayLine for execution */
switch( *pscan ) {
case '\n':
ebuffline[i] = '\0';
if (PlayLine() == FALSE) {
LocalUnlock(hEditBuffer);
return;
}
i = 0;
break;
case '\r':
break;
default:
if (i == MAXLINE-1) {
ebuffline[i] = '\0';
PlayError("Line is too long");
return;
}
ebuffline[i++] = *pscan;
break;
}
pscan++;
numchar++;
}

if (i > 0) { /* Watch out for any text left */
ebuffline[i] = '\0'; /* over if we hit a null before */
PlayLine(); /* finding a \n for the last line*/
}
LocalUnlock(hEditBuffer); /* Release the edit buffer text */
}

/*-------------------------------------------------------------------*/
/* Try and convert a text string to a note value. */
/*-------------------------------------------------------------------*/

BOOL PlayNoteConvert(parm, pvalue)
char *parm;
int *pvalue;
{
int value;


if (PlayIntConvert(parm,&value) == TRUE)
;
else if (strlen(parm) == 2 || strlen(parm) == 3) {
switch( *parm ){
case 'A':
value = 10;
break;
case 'B':
value = 12;
break;
case 'C':
value = 1;
break;
case 'D':
value = 3;
break;
case 'E':
value = 5;
break;
case 'F':
value = 6;
break;
case 'G':
value = 8;
break;
default:
return(FALSE);
}
if (strlen(parm) == 3) {
if ( *(parm+1) == '#' || *(parm+1) == '+' ) {
switch( *parm ){
case 'A':
case 'C':
case 'D':
case 'F':
case 'G':
value++;
parm++;
break;
default:
return(FALSE);
}
}
else if ( *(parm+1) == '-' ) {
switch( *parm ){
case 'A':
case 'B':
case 'D':
case 'E':
case 'G':
value--;
parm++;
break;
default:
return(FALSE);
}
}
else
return(FALSE);
}
parm++;
if (*parm >= '1' && *parm <= '7')
value += (*parm - '1') * 12;
else
return(FALSE);
}
else
return(FALSE);

*pvalue = value;
return(TRUE);
}


/*********************************************************************/
/* Local functions */
/*********************************************************************/

/*-------------------------------------------------------------------*/
/* Parse a line into its components and try to execute it */
/*-------------------------------------------------------------------*/

BOOL PlayLine()
{
int numparms, curparm;
char *pline = ebuffline;
int scnt = 0;

memset(pfunction,'\0',MAXPARMLEN);/* Initialize parm pointer array */
for (curparm = 0; curparm < MAXPARM; curparm++) {
parm[curparm] = parms[curparm];
memset(parm[curparm],'\0',MAXPARMLEN);
}

while (*pline) { /* Ignore anything after a */
if (*pline == ';') /* terminating semicolon, ';' */
*pline = '\0';
else {
if (!isspace(*pline)) /* count non-blank characters */
scnt++;
pline++;
}
}
if (scnt == 0) /* If zero non-blank characters */
return(TRUE); /* then skip the empty line */

pline = ebuffline;
if ( PlayGetToken(&pline,pfunction,"(") != '(' ) {
PlayError("Syntax Error");
return(FALSE);
}
pline++;

curparm = 0;
while(*pline && curparm < MAXPARM) {
switch( PlayGetToken(&pline,parm[curparm],",)") ) {
case ',':
pline++;
curparm++;
if (curparm == MAXPARM) {
PlayError("Too many parameters");
return(FALSE);
}
break;

case ')':
if (strlen(parm[curparm]) > 0)
numparms = curparm+1;
else
numparms = curparm;
curparm = MAXPARM;
break;

default:
PlayError("Syntax Error");
return(FALSE);
}
}
if (*pline == '\0') {
PlayError("Syntax Error");
return(FALSE);
}
return( PlayFunction(numparms) );
}


/*-------------------------------------------------------------------*/
/* Try and execute a parsed line */
/*-------------------------------------------------------------------*/

BOOL PlayFunction(numparms)
int numparms;
{
char dmsg[80];
int i;

for(i = 0; i < sizeof(wsound)/sizeof(wsound[0]); i++) {
if (strcmp(wsound[i].fname,pfunction) == 0) {
if (numparms != wsound[i].parms) {
strcpy(dmsg,"Wrong number of parameters for ");
strcat(dmsg,pfunction);
PlayError(dmsg);
return(FALSE);
}
return( (*wsound[i].func)() );
}
}
strcpy(dmsg,"Unrecognized function ");
strcat(dmsg,pfunction);
PlayError(dmsg);
return(FALSE);
}


/*-------------------------------------------------------------------*/
/* Close the sound device */
/*-------------------------------------------------------------------*/

BOOL PlayCloseSound( void )
{
CloseSound();
SndState.open = 0;
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Retrieves the count of notes in the specified queue. */
/*-------------------------------------------------------------------*/

BOOL PlayCountVoiceNotes( void )
{
if (PlayIntConvert(parm[0],&SndState.voice) == FALSE) {
PlayError("CountVoiceNotes voice parameter must be numeric");
return(FALSE);
}
CountVoiceNotes(SndState.voice);
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Retrieves a flag that identifies a recent threshold event. */
/*-------------------------------------------------------------------*/

BOOL PlayGetThresholdEvent( void )
{
GetThresholdEvent();
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Retrieves the threshold-event status for each voice. */
/*-------------------------------------------------------------------*/

BOOL PlayGetThresholdStatus( void )
{
GetThresholdStatus();
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Opens the play device and prevents it from being opened by others.*/
/*-------------------------------------------------------------------*/

BOOL PlayOpenSound( void )
{
switch (rc = OpenSound()) {
case S_SERDVNA:
PlayError("The play device is in use");
return(FALSE);
case S_SEROFM:
PlayError("Out of memory");
return(FALSE);
default:
break;
}
SndState.numvoices = rc;
SndState.open = 1;
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Sets the source and duration of a noise. */
/*-------------------------------------------------------------------*/

BOOL PlaySetSoundNoise( void )
{
if (strcmp(parm[0],"S_PERIOD512") == 0)
SndState.source = S_PERIOD512;
else if (strcmp(parm[0],"S_PERIOD1024") == 0)
SndState.source = S_PERIOD1024;
else if (strcmp(parm[0],"S_PERIOD2048") == 0)
SndState.source = S_PERIOD2048;
else if (strcmp(parm[0],"S_PERIODVOICE") == 0)
SndState.source = S_PERIODVOICE;
else if (strcmp(parm[0],"S_WHITE512") == 0)
SndState.source = S_WHITE512;
else if (strcmp(parm[0],"S_WHITE1024") == 0)
SndState.source = S_WHITE1024;
else if (strcmp(parm[0],"S_WHITE2048") == 0)
SndState.source = S_WHITE2048;
else if (strcmp(parm[0],"S_WHITEVOICE") == 0)
SndState.source = S_WHITEVOICE;
else {
PlayError("SetSoundNoise source parameter is invalid");
return(FALSE);
}
if (PlayIntConvert(parm[1],&SndState.duration) == FALSE) {
PlayError("SetSoundNoise duration parameter must be numeric");
return(FALSE);
}

rc = SetSoundNoise(
SndState.source,
SndState.duration);

switch (rc) {
case S_SERDSR:
PlayError("SetSoundNoise Error: Invalid Source");
return(FALSE);
case 0:
break;
default:
wsprintf(rcmsg,"SetSoundNoise Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Puts an accent (tempo, volume, mode, and pitch) in a voice queue. */
/*-------------------------------------------------------------------*/

BOOL PlaySetVoiceAccent( void )
{
if (PlayIntConvert(parm[0],&SndState.voice) == FALSE) {
PlayError("SetVoiceAccent voice parameter must be numeric");
return(FALSE);
}
if (PlayIntConvert(parm[1],&SndState.tempo) == FALSE) {
PlayError("SetVoiceAccent tempo parameter must be numeric");
return(FALSE);
}
if (PlayIntConvert(parm[2],&SndState.volume) == FALSE) {
PlayError("SetVoiceAccent volume parameter must be numeric");
return(FALSE);
}
if (strcmp(parm[3],"S_LEGATO") == 0)
SndState.mode = S_LEGATO;
else if (strcmp(parm[3],"S_NORMAL") == 0)
SndState.mode = S_NORMAL;
else if (strcmp(parm[3],"S_STACCATO") == 0)
SndState.mode = S_STACCATO;
else {
PlayError("SetVoiceAccent mode parameter choices: S_LEGATO, S_NORMAL, S_STACCATO");
return(FALSE);
}
if (PlayIntConvert(parm[4],&SndState.pitch) == FALSE) {
PlayError("SetVoiceAccent pitch parameter must be numeric");
return(FALSE);
}

rc = SetVoiceAccent(
SndState.voice,
SndState.tempo,
SndState.volume,
SndState.mode,
SndState.pitch);

switch (rc) {
case S_SERDMD:
PlayError("SetVoiceAccent Error: Invalid Mode");
return(FALSE);
case S_SERDTP:
PlayError("SetVoiceAccent Error: Invalid Tempo");
return(FALSE);
case S_SERDVL:
PlayError("SetVoiceAccent Error: Invalid Volume");
return(FALSE);
case S_SERQFUL:
PlayError("SetVoiceAccent Error: Queue full");
return(FALSE);
case 0:
break;
default:
wsprintf(rcmsg,"SetVoiceAccent Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Queues an envelope (wave shape and repeat count) into the */
/* specified voice queue. */
/*-------------------------------------------------------------------*/

BOOL PlaySetVoiceEnvelope( void )
{
if (PlayIntConvert(parm[0],&SndState.voice) == FALSE) {
PlayError("SetVoiceEnvelope voice parameter must be numeric");
return(FALSE);
}
if (PlayIntConvert(parm[1],&SndState.shape) == FALSE) {
PlayError("SetVoiceEnvelope shape parameter must be numeric");
return(FALSE);
}
if (PlayIntConvert(parm[2],&SndState.repeat) == FALSE) {
PlayError("SetVoiceEnvelope repeat parameter must be numeric");
return(FALSE);
}

rc = SetVoiceEnvelope(SndState.voice, SndState.shape, SndState.repeat);
switch (rc) {
case S_SERDSH:
PlayError("SetVoiceEnvelope Error: Invalid shape");
return(FALSE);
case S_SERQFUL:
PlayError("SetVoiceEnvelope Error: Queue full");
return(FALSE);
case 0:
break;
default:
wsprintf(rcmsg,"SetVoiceEnvelope Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Queues a note that has value, length, and cdots qualities */
/* into the specified voice queue. */
/*-------------------------------------------------------------------*/

BOOL PlaySetVoiceNote( void )
{
if (PlayIntConvert(parm[0],&SndState.voice) == FALSE) {
PlayError("SetVoiceNote voice parameter must be numeric");
return(FALSE);
}
if (PlayNoteConvert(parm[1],&SndState.value) == FALSE ) {
PlayError("SetVoiceNote value parameter is invalid");
return(FALSE);
}
if (PlayIntConvert(parm[2],&SndState.length) == FALSE) {
PlayError("SetVoiceNote length parameter must be numeric");
return(FALSE);
}
if (PlayIntConvert(parm[3],&SndState.cdots) == FALSE) {
PlayError("SetVoiceNote cdots parameter must be numeric");
return(FALSE);
}

rc = SetVoiceNote(
SndState.voice,
SndState.value,
SndState.length,
SndState.cdots);

switch (rc) {
case S_SERDCC:
PlayError("SetVoiceNote Error: Invalid dot count");
return(FALSE);
case S_SERDLN:
PlayError("SetVoiceNote Error: Invalid note length");
return(FALSE);
case S_SERBDNT:
PlayError("SetVoiceNote Error: Invalid note");
return(FALSE);
case S_SERQFUL:
PlayError("SetVoiceNote Error: Queue full");
return(FALSE);
case 0:
break;
default:
wsprintf(rcmsg,"SetVoiceNote Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Sets the size of a voice queue */
/*-------------------------------------------------------------------*/

BOOL PlaySetVoiceQueueSize( void )
{
if (PlayIntConvert(parm[0],&SndState.voice) == FALSE) {
PlayError("SetVoiceQueueSize voice parameter must be numeric");
return(FALSE);
}
if (PlayIntConvert(parm[1],&SndState.qsize) == FALSE) {
PlayError("SetVoiceQueueSize bytes parameter must be numeric");
return(FALSE);
}

rc = SetVoiceQueueSize(
SndState.voice,
SndState.qsize);

switch (rc) {
case S_SERMACT:
PlayError("SetVoiceQueueSize Error: Music Active");
return(FALSE);
case S_SEROFM:
PlayError("SetVoiceQueueSize Error: Out of Memory");
return(FALSE);
case 0:
break;
default:
wsprintf(rcmsg,"SetVoiceQueueSize Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Queues a sound frequency and duration into the */
/* specified voice queue. */
/*-------------------------------------------------------------------*/

BOOL PlaySetVoiceSound( void )
{
if (PlayIntConvert(parm[0],&SndState.voice) == FALSE) {
PlayError("SetVoiceSound voice parameter must be numeric");
return(FALSE);
}
if (PlayLongConvert(parm[1],&SndState.lfreq) == FALSE) {
PlayError("SetVoiceSound frequency parameter must be numeric");
return(FALSE);
}
else {
SndState.frequency = (int)(SndState.lfreq >> 16);
SndState.fraction = (int)(SndState.lfreq & 0xff);
}
if (PlayIntConvert(parm[2],&SndState.duration) == FALSE) {
PlayError("SetVoiceSound duration parameter must be numeric");
return(FALSE);
}

rc = SetVoiceSound(SndState.voice, SndState.lfreq, SndState.duration);
switch (rc) {
case S_SERDDR:
PlayError("SetVoiceSound Error: Invalid duration");
return(FALSE);
case S_SERDFQ:
PlayError("SetVoiceSound Error: Invalid frequency");
return(FALSE);
case S_SERQFUL:
PlayError("SetVoiceSound Error: Queue full");
return(FALSE);
case 0:
break;
default:
wsprintf(rcmsg,"SetVoiceSound Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Sets a voice queues threshold level. */
/*-------------------------------------------------------------------*/

BOOL PlaySetVoiceThreshold( void )
{
if (PlayIntConvert(parm[0],&SndState.voice) == FALSE) {
PlayError("SetVoiceThreshold voice parameter must be numeric");
return(FALSE);
}

if (PlayIntConvert(parm[1],&SndState.tcount) == FALSE) {
PlayError("SetVoiceThreshold note count parameter must be numeric");
return(FALSE);
}

if ( (rc = SetVoiceThreshold(SndState.voice, SndState.tcount)) != 0) {
wsprintf(rcmsg,"SetVoiceThreshold Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Starts play in each voice queue, non-destructive. */
/*-------------------------------------------------------------------*/

BOOL PlayStartSound( void )
{
StartSound();
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Stops playing all voice queues. */
/*-------------------------------------------------------------------*/

BOOL PlayStopSound( void )
{
StopSound();
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Puts a sync mark into each voice queue. */
/*-------------------------------------------------------------------*/

BOOL PlaySyncAllVoices( void )
{
switch (rc = SyncAllVoices()) {
case S_SERQFUL:
PlayError("SyncAllVoices Error: Queue full");
return(FALSE);
case 0:
break;
default:
wsprintf(rcmsg,"SyncAllVoices Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Waits for the sound device to enter a specified state. */
/*-------------------------------------------------------------------*/

BOOL PlayWaitSoundState( void )
{
HANDLE oldCursor;

if (strcmp(parm[0],"S_ALLTHRESHOLD") == 0)
SndState.waitstate = S_ALLTHRESHOLD;
else if (strcmp(parm[0],"S_QUEUEEMPTY") == 0)
SndState.waitstate = S_QUEUEEMPTY;
else if (strcmp(parm[0],"S_THRESHOLD") == 0)
SndState.waitstate = S_THRESHOLD;
else {
PlayError("WaitSoundState parameter choices: S_ALLTHRESHOLD, S_QUEUEEMPTY, S_THRESHOLD");
return(FALSE);
}

oldCursor = SetCursor(hNote);
rc = WaitSoundState(SndState.waitstate);
SetCursor(oldCursor);
switch (rc) {
case S_SERDST:
PlayError("WaitSoundState Error: Invalid State");
return(FALSE);
case 0:
break;
default:
wsprintf(rcmsg,"WaitSoundState Error: Non zero return (%d)",rc);
PlayError(rcmsg);
return(FALSE);
}
return(TRUE);
}

/*-------------------------------------------------------------------*/
/* Parse a token from an input line given a set of terminators. */
/*-------------------------------------------------------------------*/

int PlayGetToken(alptr, tptr, endchars)
char **alptr;
char * tptr;
char * endchars;
{
int curchar = 0;
enum {PREWHITE, INTOKEN, POSTWHITE};
int state = PREWHITE;
char *lptr = *alptr;
char tmsg[80];

while ( *lptr && strchr(endchars, *lptr) == NULL ) {
switch (state) {
case PREWHITE:
if ( !isspace(*lptr) )
state = INTOKEN;
else
lptr++;
break;

case INTOKEN:
if (!isspace(*lptr)) {
if (curchar >= MAXPARMLEN-1)
return('\0');
*(tptr + curchar) = *lptr;
curchar++;
}
else
state = POSTWHITE;
lptr++;
break;

case POSTWHITE:
default:
if (!isspace(*lptr))
return('\0');
lptr++;
break;
}
}
*alptr = lptr;
return(*lptr);
}


/*-------------------------------------------------------------------*/
/* Try and convert a character string into a numeric integer. */
/*-------------------------------------------------------------------*/

BOOL PlayIntConvert(parm, iptr)
char *parm;
int *iptr;
{
char *s;
int i = 0;
char c;

if (strspn(parm,"0123456789") == strlen(parm) )
i = atoi(parm);
else if (strlen(parm) > 2 && strnicmp(parm,"0x",2) == 0) {
for(s = parm+2; *s; s++) {
switch (c = toupper(*s)) {
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
i = (i * 0x10) + (c - 'A' + 0xA);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
i = (i * 0x10) + (c - '0');
break;
default:
return(FALSE);
}
}
}
else
return(FALSE);

*iptr = i;
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Try and convert a character string into a numeric long value. */
/*-------------------------------------------------------------------*/

BOOL PlayLongConvert(parm, iptr)
char *parm;
long *iptr;
{
char *s;
long i = 0;
char c;

if (strspn(parm,"0123456789") == strlen(parm) )
i = atol(parm);
else if (strlen(parm) > 2 && strnicmp(parm,"0x",2) == 0) {
for(s = parm+2; *s; s++) {
switch (c = toupper(*s)) {
case 'A':
case 'B':
case 'C':
case 'D':
case 'E':
case 'F':
i = (i * 0x10) + (c - 'A' + 0xA);
break;
case '0':
case '1':
case '2':
case '3':
case '4':
case '5':
case '6':
case '7':
case '8':
case '9':
i = (i * 0x10) + (c - '0');
break;
default:
return(FALSE);
}
}
}
else
return(FALSE);

*iptr = i;
return(TRUE);
}


/*-------------------------------------------------------------------*/
/* Display an error message */
/*-------------------------------------------------------------------*/

void PlayError(char *Text)
{
MessageBox(
GetFocus(),
(LPSTR)ebuffline,
(LPSTR)Text,
MB_OK);
}



  3 Responses to “Category : Windows 3.X Files
Archive   : SNDHACK.ZIP
Filename : PLAY.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/