Пример #1
0
/**
 * @relates texteditor
 * @brief Play any ZZM music found in the editor.
 *
 * @param slurflag  Slur notes together when true (ZZT-style).
 */
void texteditZZMPlay(texteditor * editor, int slurflag)
{
	/** @TODO: do a damn good job of testing music */
	/* Idea: create a copy of *editor so that we can mess around with curline and
	 * pos and such, using existing functions to do the bulk of the display. */
#if 0
	editor->text->cur = editor->curline;
	testMusic(editor->text, slurflag, editor->linewidth, flags, editor->d);
#endif

	/* Create a new view of the editor data. This allows us to move the cursor
	 * and change display settings for the new view without affecting editor. */
	const char* playString = "#play ";
	const int playStringLen = 6;

	texteditor editorCopy = *editor;
	texteditor* view = &editorCopy;

	int done;

#ifdef SDL
	SDL_AudioSpec spec;
#endif

	/* Display everything, in case the editor has not been displayed recently. */
	view->updateflags |= TUD_ALL;

#ifdef SDL
	/* IF opening the audio device fails, return now before we crash something. */
	if (OpenSynth(&spec))
		return;
#endif

	done = 0;

	/* Loop through the stringvector looking for #play statements */
	while (view->curline != NULL && !done) {
		char* tune = strstr(view->curline->s, "#");
		if (tune != NULL && str_equ(tune, playString, STREQU_UNCASE | STREQU_RFRONT)) {
			/* Current note and settings */
			musicalNote note = zzmGetDefaultNote();
			musicSettings settings = zzmGetDefaultSettings();

			int xoffset = tune - view->curline->s + playStringLen;
			tune += playStringLen;  /* Advance to notes! */

			/* Change the slur setting */
			note.slur = slurflag;

			while (note.src_pos < strlen(tune) && !done) {
				if (view->d->getkey() != DKEY_NONE)
					done = 1;

				/* Move the cursor and re-display before playing note. */
				view->pos = note.src_pos + xoffset;
				texteditUpdateDisplay(view);

				note = zzmGetNote(tune, note);

#ifdef DOS
				pcSpeakerPlayNote(note, settings);
#elif defined SDL
				SynthPlayNote(spec, note, settings);
#endif
			}
		}
		view->curline = view->curline->next;

		/* Re-display edit area since the current line has changed. */
		view->updateflags |= TUD_EDITAREA;
	}

#ifdef SDL
	/* TODO: instead of just sitting here, display the progress of playback */
	/* Wait until the music is done or the user presses a key */
	while (!IsSynthBufferEmpty() && view->d->getkey() == DKEY_NONE)
		;

	CloseSynth();
#elif defined DOS
	pcSpeakerFinish();
#endif

	/* No need to free the view, it only exists on the stack. */

	/* The edit area needs to be redisplayed now. */
	editor->updateflags |= TUD_EDITAREA;
}
Пример #2
0
void testMusic(stringvector* sv, int slur, int editwidth, int flags, displaymethod* d)
{
	int done;
#ifdef SDL
	SDL_AudioSpec spec;

	/* IF opening the audio device fails, return now before we crash something. */
	if (OpenSynth(&spec))
		return;
#endif

	done = 0;

	/* Loop through the stringvector looking for #play statements */
	while (sv->cur != NULL && !done) {
		char* tune = strstr(sv->cur->s, "#");
		if (tune != NULL && str_equ(tune, "#play ", STREQU_UNCASE | STREQU_RFRONT)) {
			/* Current note and settings */
			musicalNote note = zzmGetDefaultNote();
			musicSettings settings = zzmGetDefaultSettings();

#ifdef DOS
			int xoff = tune - sv->cur->s;
#endif
			tune += 6;  /* Advance to notes! */

			/* Change the slur setting */
			note.slur = slur;

			/* Update everything because we have likely shifted to a new line. */
			updateditbox(d, sv, U_EDITAREA, editwidth, flags, "", 1);

			while (note.src_pos < strlen(tune) && !done) {
#ifdef DOS
				int oldpos = note.src_pos;
				char* strpart;
#endif

				if (d->getkey() != DKEY_NONE)
					done = 1;

				note = zzmGetNote(tune, note);

#ifdef DOS
				/* In DOS, display everything as we go along */
				/* Display the whole line */
				updateditbox(d, sv, U_CENTER, editwidth, flags, "", 1);

				/* Display the part of the string which will be played now */
				strpart = str_duplen(tune + oldpos, note.src_pos - oldpos);
				d->print(oldpos + 15 + xoff, 13, ZOC_MPLAY_COLOUR, strpart);
				free(strpart);
				d->cursorgo(oldpos + 15 + xoff, 13);

				pcSpeakerPlayNote(note, settings);
#elif defined SDL
				SynthPlayNote(spec, note, settings);
#endif
			}
		}
		sv->cur = sv->cur->next;
	}

#ifdef SDL
	/* TODO: instead of just sitting here, display the progress of playback */
	/* Wait until the music is done or the user presses a key */
	while (!IsSynthBufferEmpty() && d->getkey() == DKEY_NONE)
		;

	CloseSynth();
#elif defined DOS
	pcSpeakerFinish();
#endif
}
Пример #3
0
/* -----------------------------------------------------------------------------*/
Boolean Start() {return OpenSynth();}