Initial (manual) import
This commit is contained in:
1 parent
f39611c506
commit
895fe109de
661 files changed
+245862
No files matched your search
@@ -0,0 +1,24 @@
|
||||
//9 has words
|
||||
U0 Song()
|
||||
{
|
||||
Fs->task_end_cb=&SndTaskEndCB;
|
||||
MusicSettingsRst;
|
||||
music.tempo= 2.480;
|
||||
music.stacatto_factor= 0.902;
|
||||
try {
|
||||
while (!ScanKey) {
|
||||
Play("5qEsCDCDqCDeEGsE4B5E4B5eC4B5sD4A5D4A",
|
||||
"Be \0like \0 \0a \0 \0child \0 \0 \0 \0"
|
||||
"some \0 \0re\0 \0spect.\n\0 \0 \0 \0 \0 \0");
|
||||
Play("5qEsCDCDqCDeEGsE4B5E4B5eC4B5sD4A5D4A",
|
||||
"Ma\0tur\0 \0i\0 \0ty \0 \0 \0 \0don't \0 \0"
|
||||
"ne\0 \0glect.\n\0 \0 \0 \0 \0 \0");
|
||||
Play("4eB5DqF4sGAGAqAAA5etD4AA5sD4B5D4B");
|
||||
Play("4eB5DqF4sGAGAqAAA5etD4AA5sD4B5D4B");
|
||||
}
|
||||
} catch
|
||||
PutExcept;
|
||||
Snd;
|
||||
}
|
||||
|
||||
Song;
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,24 @@
|
||||
$WW,1$$FG,5$$TX+CX,"Psalmody Help"$$FG$
|
||||
|
||||
* The keyboard can be used as an organ by typing letter keys or clicking the mouse on the keyboard diagram$FG$. You can "record" notes by pressing the red bttn and typing letters. They will appear on the musical staff. You can edit and save them.
|
||||
|
||||
* The clipboard can be used to cut and paste.
|
||||
|
||||
* $FG,2$Psalmody$FG$ uses $LK,"HolyC",A="FI:::/Doc/HolyC.DD"$ files as the song format! See $LK,"::/Apps/Psalmody/Examples/prosper.HC"$. The $FG,2$Psalmody$FG$ program does not fully parse the songs when loading them back in, so changes made outside $FG,2$Psalmody$FG$ will be lost, like if you add graphics.
|
||||
|
||||
* The first line of the $LK,"HolyC",A="FI:::/Doc/HolyC.DD"$ song files is a comment with a category recognized by $LK,"JukeBox",A="FF:::/Apps/Psalmody/JukeBox.HC,JukeBox"$(). The categories are $FG,2$"no nothing"$FG$, $FG,2$"has words"$FG$, $FG,2$"has graphics"$FG$, or $FG,2$"special"$FG$. The third character in the song comment is a digit rating number, shown in $LK,"JukeBox",A="FF:::/Apps/Psalmody/JukeBox.HC,JukeBox"$(). You can set the song rating in $LK,"JukeBox",A="FF:::/Apps/Psalmody/JukeBox.HC,JukeBox"$() by pressing $FG,2$0$FG$-$FG,2$9$FG$. You can press $FG,2$<DELETE>$FG$ to delete songs.
|
||||
|
||||
* You can take the $LK,"Play",A="MN:Play"$() stmts out of a song file and place them in your programs. You can also add a song to a document with $FG,2$<CTRL-l>$FG$, but you should do it after pressing $FG,2$<CTRL-t>$FG$ because the clipboard-insert in $FG,2$<CTRL-l>$FG$ is screwy. See this $SO,"<Song>",A="4qG5EC4BeGG5qCeFD4sB5G4B5G4qG5EC4BeGG5qCeFD4sB5G4B5GqEeEFqE4BeG5FetC4A5GqFCEeEFqE4BeG5FetC4A5GqFC"$ after pressing $FG,2$<CTRL-t>$FG$, now.
|
||||
|
||||
* You can call $LK,"JukeBox",A="FF:::/Apps/Psalmody/JukeBox.HC,JukeBox"$("~/Psalmody"); to play your songs.
|
||||
|
||||
* To create a $FG,2$.SND$FG$ file which can be exported and played under Windows, set the $FG,2$Bool$FG$ $LK,"snd.record",A="MN:CSndGlbls"$ to $FG,2$TRUE$FG$, play music, and set it to $FG,2$FALSE$FG$. Then, call $LK,"SndFileCreate",A="MN:SndFileCreate"$(). You might wish to make a $FG,2$<CTRL-ALT-key>$FG$ to toggle this system level recording feat. See $LK,"Snd",A="MN:Snd"$(). Add this code to your $LK,"~/HomeKeyPlugIns.HC"$ file.
|
||||
|
||||
$FG,5$U0 CtrlAltR(I64)
|
||||
{
|
||||
snd.record=!snd.record;
|
||||
}
|
||||
CtrlAltCBSet('R',&CtrlAltR,"Cmd /Toggle snd.record");$FG$
|
||||
|
||||
* When calling $LK,"SndFileCreate",A="MN:SndFileCreate"$() you can set a waveform. The PC speaker is $LK,"WF_SQUARE",A="MN:WF_SQUARE"$. You can sel reverb and averaging, also.
|
||||
|
||||
@@ -0,0 +1,2 @@
|
||||
if (!FileFind("~/Psalmody",,FUF_JUST_DIRS))
|
||||
MkDir("~/Psalmody");
|
||||
@@ -0,0 +1,138 @@
|
||||
CTask *SingleSong(U8 *msg,U8 *name)
|
||||
{
|
||||
CTask *task=Spawn(&SrvCmdLine,NULL,name,,Fs);
|
||||
StrCpy(task->task_title,name);
|
||||
task->title_src=TTS_LOCKED_CONST;
|
||||
TaskExe(task,Fs,";",1<<JOBf_WAKE_MASTER|1<<JOBf_FREE_ON_COMPLETE);
|
||||
WinHorz(task->win_left,task->win_left+50,task);
|
||||
WinVert(2,2+8,task);
|
||||
TaskExe(task,NULL,msg,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
|
||||
DocPut(task)->max_entries=100;
|
||||
return task;
|
||||
}
|
||||
|
||||
#define JB_RUN_LEVEL_NULL 0
|
||||
#define JB_RUN_LEVEL_ONE 1
|
||||
#define JB_RUN_LEVEL_TWO 2
|
||||
|
||||
Bool JBPutKey(CDoc *doc,U8 *,I64 ch,I64 sc)
|
||||
{//ch=ASCII; sc=scan_code
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_e;
|
||||
CDirEntry *tmpde;
|
||||
CDoc *s;
|
||||
if (!(sc&(SCF_ALT|SCF_CTRL|SCF_SHIFT))
|
||||
&& doc_ce->type_u8==DOCT_MENU_VAL && doc_ce->left_exp>=0) {
|
||||
tmpde=doc_ce->left_exp;
|
||||
if (sc.u8[0]==SC_DELETE ) {
|
||||
Beep;
|
||||
Silent;
|
||||
Del(tmpde->full_name);
|
||||
Silent(OFF);
|
||||
} else if ('0'<=ch<='9') {
|
||||
if (StrLen(doc_ce->tag)>1)
|
||||
doc_ce->tag[0]=ch;
|
||||
s=DocRead(tmpde->full_name);
|
||||
doc_e=s->head.next;
|
||||
while (doc_e!=s && doc_e->type_u8!=DOCT_TEXT)
|
||||
doc_e=doc_e->next;
|
||||
if (doc_e!=s && doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=3) {
|
||||
doc_e->tag[2]=ch;
|
||||
DocWrite(s);
|
||||
}
|
||||
DocDel(s);
|
||||
return TRUE;
|
||||
} else if (ch==CH_SPACE||ch==CH_ESC)
|
||||
tmpde->user_data++; //JB_RUN_LEVEL++
|
||||
//<SPACE> is followed by <ESC> --> JB_RUN_LEVEL_TWO
|
||||
//Actual <ESC> just exits --> JB_RUN_LEVEL_ONE
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public U0 JukeBox(U8 *dirname="~/Psalmody",U8 **_filename=NULL)
|
||||
{//_filename is for using this as a song-chooser program.
|
||||
I64 i=0,rating;
|
||||
U8 *st,*st2;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
CDoc *doc=DocNew,*s;
|
||||
CDocEntry *doc_e;
|
||||
CTask *task=NULL;
|
||||
if (_filename)
|
||||
*_filename=NULL;
|
||||
dirname=StrNew(dirname);
|
||||
st=MStrPrint("%s/*.HC.Z",dirname);
|
||||
tmpde=tmpde1=FilesFind(st);
|
||||
Free(st);
|
||||
Free(dirname);
|
||||
doc->user_put_key=&JBPutKey;
|
||||
DocPrint(doc,
|
||||
"Key: $$GREEN$$Graphics $$BLUE$$Words $$RED$$No Nothing "
|
||||
"$$BLACK$$Incomplete $$CYAN$$Special$$FG$$\n\n"
|
||||
"$$GREEN$$<DELETE>$$FG$$ to delete a song.\n"
|
||||
"Press a number to rate a song.\n");
|
||||
while (tmpde) {
|
||||
if (!(i++%5))
|
||||
DocPrint(doc,"\n");
|
||||
if (FileOcc("Play(",tmpde->full_name,"")) {
|
||||
st=StrNew(tmpde->name);
|
||||
FileExtRem(st);
|
||||
s=DocRead(tmpde->full_name);
|
||||
doc_e=s->head.next;
|
||||
while (doc_e!=s && doc_e->type_u8!=DOCT_TEXT)
|
||||
doc_e=doc_e->next;
|
||||
rating='0';
|
||||
if (doc_e!=s && doc_e->type_u8==DOCT_TEXT) {
|
||||
if ('0'<=doc_e->tag[2]<='9')
|
||||
rating=doc_e->tag[2];
|
||||
if (StrMatch("incomplete",doc_e->tag))
|
||||
DocPrint(doc,"$$BLACK$$");
|
||||
else if (StrMatch("has graphics",doc_e->tag))
|
||||
DocPrint(doc,"$$GREEN$$");
|
||||
else if (StrMatch("has words",doc_e->tag))
|
||||
DocPrint(doc,"$$BLUE$$");
|
||||
else if (StrMatch("special",doc_e->tag))
|
||||
DocPrint(doc,"$$CYAN$$");
|
||||
else if (StrMatch("no nothing",doc_e->tag)) {
|
||||
DocPrint(doc,"$$RED$$");
|
||||
if (FileOcc("\\0",tmpde->full_name,"")) {
|
||||
s->cur_entry=doc_e->next;
|
||||
s->cur_col=0;
|
||||
DocEntryDel(s,doc_e);
|
||||
DocPrint(s,"//0 has words\n");
|
||||
DocWrite(s);
|
||||
}
|
||||
}
|
||||
DocPrint(doc,"$$MU-UL,\"%c%-8ts\",LE=%d$$ ",rating,st,tmpde);
|
||||
tmpde->user_data=JB_RUN_LEVEL_NULL;
|
||||
}
|
||||
DocDel(s);
|
||||
Free(st);
|
||||
}
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
DocPrint(doc,"\n$$CYAN$$$$MU-UL,\"DONE\",LE=%d$$\n",DOCM_CANCEL);
|
||||
while (TRUE) {
|
||||
if (_filename)
|
||||
tmpde=PopUpMenu(doc,DOF_INTERCEPT_TASK_END);
|
||||
else
|
||||
tmpde=PopUpMenu(doc);
|
||||
if (task)
|
||||
Kill(task);
|
||||
if (tmpde<=0) break;
|
||||
st2=StrNew(tmpde->name);
|
||||
if (_filename) {
|
||||
Free(*_filename);
|
||||
*_filename=StrNew(tmpde->full_name);
|
||||
}
|
||||
if (tmpde->user_data==JB_RUN_LEVEL_ONE) break; //<ESC>
|
||||
tmpde->user_data=JB_RUN_LEVEL_NULL; //Rst from <SPACE>
|
||||
FileExtRem(st2);
|
||||
st=MStrPrint("ExeFile(\"%s\");",tmpde->full_name);
|
||||
MusicSettingsRst;
|
||||
task=SingleSong(st,st2);
|
||||
Free(st2);
|
||||
Free(st);
|
||||
}
|
||||
DocDel(doc);
|
||||
DirTreeDel(tmpde1);
|
||||
}
|
||||
@@ -0,0 +1,89 @@
|
||||
U0 SongPuppet(CTask *task,I64 passes)
|
||||
{
|
||||
CDbgInfo *dbg_info;
|
||||
I64 i,start,end,rip,last_rip;
|
||||
CHashFun *tmpf=NULL;
|
||||
for (i=0;i<250 && TaskValidate(task);i++) {
|
||||
if (tmpf=HashFind("Song",task->hash_table,HTT_FUN))
|
||||
break;
|
||||
Sleep(1);
|
||||
}
|
||||
if (tmpf && (dbg_info=tmpf->dbg_info)) {
|
||||
start=dbg_info->body[0];
|
||||
end =dbg_info->body[dbg_info->max_line+1-dbg_info->min_line];
|
||||
last_rip=0;
|
||||
while (TRUE) {
|
||||
i=0;
|
||||
while (TaskValidate(task) && (rip=TaskCaller(task,i++))) {
|
||||
if (start<=rip<end) {
|
||||
if (rip<last_rip && --passes<=0)
|
||||
return;
|
||||
last_rip=rip;
|
||||
}
|
||||
}
|
||||
Sleep(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 JukeSongPuppet(CTask *juke_task,I64 passes,I64 song_num,U8 *name)
|
||||
{
|
||||
Bool found;
|
||||
CTask *task;
|
||||
I64 i;
|
||||
|
||||
if (FileExtDot(name))
|
||||
FileExtRem(name);
|
||||
BirthWait(&juke_task->popup_task);
|
||||
TaskWait(juke_task->popup_task);
|
||||
PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP+SCF_CTRL);
|
||||
TaskWait(juke_task->popup_task);
|
||||
for (i=0;i<song_num;i++) {
|
||||
PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
|
||||
TaskWait(juke_task->popup_task);
|
||||
}
|
||||
|
||||
PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,CH_SPACE,0);
|
||||
TaskWait(juke_task->popup_task);
|
||||
Sleep(500);
|
||||
|
||||
found=FALSE;
|
||||
task=Fs->next_task;
|
||||
while (task!=Fs) {
|
||||
if (!StrCmp(task->task_title,name)) {
|
||||
found=TRUE;
|
||||
break;
|
||||
}
|
||||
task=task->next_task;
|
||||
}
|
||||
|
||||
if (found) {//Position cursor on song title during song
|
||||
TaskWait(juke_task->popup_task);
|
||||
PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_UP+SCF_CTRL);
|
||||
TaskWait(juke_task->popup_task);
|
||||
for (i=0;i<song_num;i++) {
|
||||
PostMsg(juke_task->popup_task,MSG_KEY_DOWN_UP,0,SC_CURSOR_RIGHT);
|
||||
TaskWait(juke_task->popup_task);
|
||||
}
|
||||
SongPuppet(task,passes);
|
||||
}
|
||||
Kill(task);
|
||||
}
|
||||
|
||||
public U0 JukeSongsPuppet(U8 *dirname="~/Psalmody",I64 passes=2,
|
||||
I64 start_song=0,I64 end_song=I64_MAX)
|
||||
{//Help make music video by puppeting JukeBox task.
|
||||
I64 i;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
CTask *juke_task=User("JukeBox(0x%X);\n",dirname);
|
||||
Cd(dirname);
|
||||
tmpde1=FilesFind("*",FUF_RECURSE|FUF_JUST_TXT|FUF_JUST_FILES);
|
||||
for (tmpde=tmpde1,i=0;tmpde && i<start_song;i++)
|
||||
tmpde=tmpde->next;
|
||||
for (i=start_song;tmpde && i<end_song;i++) {
|
||||
JukeSongPuppet(juke_task,passes,i,tmpde->name);
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
DirTreeDel(tmpde1);
|
||||
Kill(juke_task);
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
#help_index "Snd"
|
||||
|
||||
Cd(__DIR__);;
|
||||
#include "JukeBox"
|
||||
#include "JukePuppet"
|
||||
#include "Psalmody"
|
||||
#include "PsalmodyCtrls"
|
||||
#include "PsalmodyDraw"
|
||||
#include "PsalmodyFile"
|
||||
#include "PsalmodyMain"
|
||||
|
||||
#help_index ""
|
||||
@@ -0,0 +1,63 @@
|
||||
/*$WW,1$
|
||||
This uses four types of ctrls
|
||||
|
||||
1) The pull-down menu.
|
||||
|
||||
2) The $LK,"CCtrl",A="MN:CCtrl"$ type for the tempo/stacatto sliders.
|
||||
|
||||
3) The active $LK,"CDoc",A="MN:CDoc"$ sprite bttns with macros for left/record/play/right.
|
||||
|
||||
4) Hand-made ctrls for the kbdgraphic, notes and staff.
|
||||
|
||||
This uses four types of output
|
||||
|
||||
1) The $LK,"CDoc",A="MN:CDoc"$ for the text and bttns and kbdgraphic.
|
||||
|
||||
2) The Fs->draw_it() for the staff region, drawn every refresh.
|
||||
|
||||
3) The gr.dc persistent layer for the note chooser, meter chooser. The persistent layer is used during drag-and-drop.
|
||||
|
||||
4) The Fs->next_ctrl for the tempo/stacatto sliders.
|
||||
|
||||
See $LK,"GrUpdateTaskWin",A="MN:GrUpdateTaskWin"$(), $LK,"GrUpdateTasks",A="MN:GrUpdateTasks"$() and $LK,"GrUpdateScrn",A="MN:GrUpdateScrn"$().
|
||||
$WW,1$$WW,0$*/
|
||||
|
||||
#define PSMT_HEAD 0
|
||||
#define PSMT_NOTE 1
|
||||
#define PSMT_METER 2
|
||||
|
||||
#define PSMf_SEL 0
|
||||
#define PSMF_SEL 1
|
||||
#define PSMf_SHARP 1
|
||||
#define PSMf_FLAT 2
|
||||
#define PSMf_TIE 3
|
||||
|
||||
class PsmNote
|
||||
{
|
||||
PsmNote *next,*last;
|
||||
I64 x,y;
|
||||
U8 *word;
|
||||
I64 type,flags;
|
||||
I64 ona,meter_top,meter_bottom;
|
||||
I64 duration,width;
|
||||
U8 ascii[32];
|
||||
};
|
||||
|
||||
//Tool types
|
||||
#define PSMTT_PTR_TOOL 0
|
||||
#define PSMTT_BOX_TOOL 1
|
||||
|
||||
class PsmCtrl
|
||||
{
|
||||
PsmNote head;
|
||||
PsmNote clipboard;
|
||||
CMenuEntry *incomplete_entry,*record_entry;
|
||||
I64 scrn_x,tool;
|
||||
PsmNote *cur_note;
|
||||
CDC *dc2;
|
||||
Bool playing;
|
||||
} psm;
|
||||
|
||||
U8 *psm_note_lst="A\0A#\0B\0C\0C#\0D\0D#\0E\0F\0F#\0G\0G#\0";
|
||||
U8 psm_note_map[12]={6,6,5,4,4,3,3,2,1,1,0,0};
|
||||
U8 psm_note_inverse_map[7]={10,8,7,5,3,2,0};
|
||||
@@ -0,0 +1,89 @@
|
||||
#define TEMPO_SPACING 15
|
||||
#define TEMPO_RANGE 80
|
||||
#define TEMPO_BORDER 2
|
||||
|
||||
class TempoState
|
||||
{
|
||||
I64 tempo,stacatto;
|
||||
} tempo_state;
|
||||
|
||||
U0 DrawTempoCtrl(CDC *dc,CCtrl *c)
|
||||
{
|
||||
TempoState *s=c->state;
|
||||
|
||||
dc->color=LTGREEN;
|
||||
GrRect(dc, c->left,c->top,TEMPO_SPACING*3+2,TEMPO_SPACING*2+TEMPO_RANGE);
|
||||
dc->color=BLACK;
|
||||
GrRect(dc, c->left+TEMPO_BORDER,c->top+TEMPO_BORDER,
|
||||
TEMPO_SPACING*3+2-2*TEMPO_BORDER,
|
||||
TEMPO_SPACING*2+TEMPO_RANGE-2*TEMPO_BORDER);
|
||||
dc->color=WHITE;
|
||||
GrLine(dc,c->left+TEMPO_SPACING,c->top+TEMPO_SPACING,
|
||||
c->left+TEMPO_SPACING,c->top+TEMPO_SPACING+TEMPO_RANGE-1);
|
||||
GrLine(dc,c->left+2*TEMPO_SPACING+1,c->top+TEMPO_SPACING,
|
||||
c->left+2*TEMPO_SPACING+1,c->top+TEMPO_SPACING+TEMPO_RANGE-1);
|
||||
|
||||
dc->color=LTGREEN;
|
||||
GrPrint(dc,c->left+TEMPO_SPACING-FONT_WIDTH/2,
|
||||
c->top+TEMPO_SPACING+TEMPO_RANGE+3,"%d",s->tempo*10/TEMPO_RANGE);
|
||||
GrPrint(dc,c->left+2*TEMPO_SPACING+1-FONT_WIDTH/2,
|
||||
c->top+TEMPO_SPACING+TEMPO_RANGE+3,"%d",
|
||||
s->stacatto*10/TEMPO_RANGE);
|
||||
GrRect(dc,c->left+TEMPO_SPACING-3,
|
||||
c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->tempo-2 ,7,5);
|
||||
GrRect(dc,c->left+2*TEMPO_SPACING+1-3,
|
||||
c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->stacatto-2,7,5);
|
||||
dc->color=YELLOW;
|
||||
GrRect(dc,c->left+TEMPO_SPACING-2,
|
||||
c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->tempo-1 ,5,3);
|
||||
GrRect(dc,c->left+2*TEMPO_SPACING+1-2,
|
||||
c->top+TEMPO_SPACING+TEMPO_RANGE-1-s->stacatto-1,5,3);
|
||||
|
||||
dc->color=GREEN;
|
||||
GrVPrint(dc,c->left+TEMPO_BORDER+2,c->top+TEMPO_SPACING+2,"Tempo");
|
||||
GrVPrint(dc,c->right-TEMPO_BORDER-2-FONT_WIDTH,
|
||||
c->top+TEMPO_SPACING+2,"Stacatto");
|
||||
}
|
||||
|
||||
U0 UpdateDerivedTempoCtrl(CCtrl *c)
|
||||
{
|
||||
TempoState *s=c->state;
|
||||
c->right=c->left+TEMPO_SPACING*3+2;
|
||||
c->bottom=c->top+TEMPO_SPACING*2+TEMPO_RANGE;
|
||||
s->tempo =ClampI64(s->tempo,0,TEMPO_RANGE-1);
|
||||
s->stacatto=ClampI64(s->stacatto,0,TEMPO_RANGE-1);
|
||||
}
|
||||
|
||||
U0 LeftClickTempo(CCtrl *c,I64 x,I64 y,Bool)
|
||||
{
|
||||
TempoState *s=c->state;
|
||||
if (x<(c->right+c->left)/2)
|
||||
s->tempo=TEMPO_RANGE-1-(y-(c->top+TEMPO_SPACING));
|
||||
else
|
||||
s->stacatto=TEMPO_RANGE-1-(y-(c->top+TEMPO_SPACING));
|
||||
if (c->update_derived_vals)
|
||||
(*c->update_derived_vals)(c);
|
||||
}
|
||||
|
||||
CCtrl *TempoNew()
|
||||
{
|
||||
CCtrl *c=CAlloc(sizeof(CCtrl));
|
||||
c->win_task=Fs;
|
||||
c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
|
||||
c->type=CTRLT_GENERIC;
|
||||
c->state=&tempo_state;
|
||||
c->draw_it=&DrawTempoCtrl;
|
||||
c->left_click=&LeftClickTempo;
|
||||
c->update_derived_vals=&UpdateDerivedTempoCtrl;
|
||||
c->left=396;
|
||||
c->top=96;
|
||||
QueIns(c,Fs->last_ctrl);
|
||||
TaskDerivedValsUpdate;
|
||||
return c;
|
||||
}
|
||||
|
||||
U0 TempoDel(CCtrl *c)
|
||||
{
|
||||
QueRem(c);
|
||||
Free(c);
|
||||
}
|
||||
@@ -0,0 +1,589 @@
|
||||
|
||||
$ID,8$
|
||||
$SP,"<1>",BI=1$
|
||||
|
||||
$SP,"<2>",BI=2$
|
||||
|
||||
$SP,"<3>",BI=3$
|
||||
|
||||
$SP,"<4>",BI=4$
|
||||
|
||||
$SP,"<5>",BI=5$
|
||||
|
||||
$SP,"<6>",BI=6$
|
||||
|
||||
|
||||
$SP,"<7>",BI=7$
|
||||
|
||||
|
||||
$SP,"<8>",BI=8$
|
||||
|
||||
|
||||
$SP,"<9>",BI=9$
|
||||
|
||||
|
||||
$SP,"<10>",BI=10$
|
||||
|
||||
|
||||
$SP,"<11>",BI=11$
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
$SP,"<12>",BI=12$
|
||||
|
||||
|
||||
|
||||
|
||||
$SP,"<13>",BI=13$
|
||||
|
||||
$SP,"<14>",BI=14$
|
||||
|
||||
$SP,"<15>",BI=15$
|
||||
|
||||
|
||||
$SP,"<16>",BI=16$
|
||||
$ID,-8$
|
||||
#define PSM_NOTE_SPACING 9
|
||||
#define PSM_DURATIONS_NUM 12
|
||||
|
||||
F64 psm_durations[PSM_DURATIONS_NUM+1]={
|
||||
2*.25/3,.25,2*.5/3,.5,2.0/3.0,0.5*1.5,1.0,1.5,2.0,3.0,4.0,6.0,1000000.0};
|
||||
U8 *psm_duration_lst="st\0s\0et\0e\0qt\0e.\0q\0q.\0h\0h.\0w\0w.\0";
|
||||
U8 *psm_duration_imgs[PSM_DURATIONS_NUM]={
|
||||
$IB,"<1>",BI=1$,$IB,"<1>",BI=1$,$IB,"<2>",BI=2$,$IB,"<2>",BI=2$,$IB,"<3>",BI=3$,$IB,"<2>",BI=2$,$IB,"<3>",BI=3$,$IB,"<3>",BI=3$,$IB,"<4>",BI=4$,$IB,"<4>",BI=4$,$IB,"<5>",BI=5$,$IB,"<5>",BI=5$};
|
||||
Bool psm_triplet_durations[PSM_DURATIONS_NUM]={TRUE,FALSE,TRUE,
|
||||
FALSE,TRUE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE,FALSE};
|
||||
|
||||
Bool PsmBlink()
|
||||
{
|
||||
if (Blink || psm.playing)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool PsmHasWords(U8 *st)
|
||||
{
|
||||
if (st && *st && (StrLen(st)>1 || *st!=CH_SPACE && *st!=CH_SHIFT_SPACE))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool PsmIsDotted(I64 duration)
|
||||
{
|
||||
U8 *st=LstSub(duration,psm_duration_lst);
|
||||
if (st[1]=='.')
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 PsmMarkSel(I64 x1,I64 x2,Bool sel)
|
||||
{
|
||||
PsmNote *tmpn=psm.head.next;
|
||||
while (tmpn!=&psm.head) {
|
||||
if (sel) {
|
||||
if (x1<=tmpn->x<=x2)
|
||||
tmpn->flags|=PSMF_SEL;
|
||||
} else
|
||||
tmpn->flags&=~PSMF_SEL;
|
||||
tmpn=tmpn->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 PsmSetWidth(PsmNote *tmpn)
|
||||
{
|
||||
if (tmpn->type==PSMT_METER)
|
||||
tmpn->width=12;
|
||||
else {
|
||||
tmpn->width=PSM_NOTE_SPACING;
|
||||
if (PsmIsDotted(tmpn->duration))
|
||||
tmpn->width+=PSM_NOTE_SPACING/2;
|
||||
if (Bt(&tmpn->flags,PSMf_SHARP) || Bt(&tmpn->flags,PSMf_FLAT))
|
||||
tmpn->width+=PSM_NOTE_SPACING;
|
||||
}
|
||||
}
|
||||
|
||||
U0 PsmSetOctave(I64 octave)
|
||||
{
|
||||
I64 i;
|
||||
U8 buf[STR_LEN];
|
||||
CMenuEntry *tmpse;
|
||||
for (i=1;i<=7;i++) {
|
||||
StrPrint(buf,"Snd/Octave%d",i);
|
||||
if (tmpse=MenuEntryFind(Fs->cur_menu,buf)) {
|
||||
if (i==octave)
|
||||
tmpse->checked=TRUE;
|
||||
else
|
||||
tmpse->checked=FALSE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 DrawNote(CDC *dc,I64 x,I64 y,I64 duration)
|
||||
{
|
||||
if (0<=duration<=PSM_DURATIONS_NUM) {
|
||||
Sprite3(dc,x,y,0,psm_duration_imgs[duration]);
|
||||
if (psm_triplet_durations[duration])
|
||||
Sprite3(dc,x,y,0,$IB,"<16>",BI=16$);
|
||||
if (PsmIsDotted(duration))
|
||||
Sprite3(dc,x,y,0,$IB,"<15>",BI=15$);
|
||||
}
|
||||
}
|
||||
|
||||
U0 DrawTimeSignature(CDC *dc,I64 x,I64 y,I64 top,I64 bottom)
|
||||
{
|
||||
GrPrint(dc,x,y,"%d",top);
|
||||
GrPrint(dc,x,y+FONT_HEIGHT,"%d",bottom);
|
||||
}
|
||||
|
||||
U0 PsmRecalcNoteXY()
|
||||
{
|
||||
F64 measure_len=4,measure_left=measure_len;
|
||||
PsmNote *tmpn=psm.head.next;
|
||||
I64 x=8-psm.scrn_x,ona,note,octave;
|
||||
while (TRUE) {
|
||||
tmpn->x=x;
|
||||
tmpn->y=50;
|
||||
if (tmpn==&psm.head)
|
||||
break;
|
||||
else {
|
||||
if (tmpn->type!=PSMT_METER) {
|
||||
if (tmpn->ona!=ONA_REST) {
|
||||
ona=tmpn->ona;
|
||||
if (Bt(&tmpn->flags,PSMf_SHARP))
|
||||
ona--;
|
||||
if (Bt(&tmpn->flags,PSMf_FLAT))
|
||||
ona++;
|
||||
octave=Ona2Octave(ona);
|
||||
note =Ona2Note (ona);
|
||||
note=music.note_map[*LstSub(note,psm_note_lst)-'A'];
|
||||
if (note<3)
|
||||
octave++;
|
||||
tmpn->y=(15+(psm_note_map[note]-7*(octave-4)))*4;
|
||||
}
|
||||
}
|
||||
x+=tmpn->width;
|
||||
if (tmpn->type==PSMT_METER) {
|
||||
measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;
|
||||
measure_left=0;
|
||||
} else
|
||||
measure_left-=psm_durations[tmpn->duration];
|
||||
if (measure_left<0.001) {
|
||||
x+=PSM_NOTE_SPACING;
|
||||
measure_left=measure_len;
|
||||
}
|
||||
}
|
||||
tmpn=tmpn->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 DrawIt(CTask *task,CDC *dc)
|
||||
{
|
||||
PsmNote *tmpn;
|
||||
I64 i,x,y,
|
||||
w=task->pix_width;
|
||||
F64 measure_len=4,measure_left=measure_len;
|
||||
|
||||
dc->color=BLACK;
|
||||
for (i=1;i<6;i++)
|
||||
GrLine(dc,0,i*8,w,i*8);
|
||||
for (i=7;i<12;i++)
|
||||
GrLine(dc,0,i*8,w,i*8);
|
||||
|
||||
PsmRecalcNoteXY;
|
||||
if (psm.cur_note->x<64) {
|
||||
psm.scrn_x-=128;
|
||||
PsmRecalcNoteXY;
|
||||
}
|
||||
if (psm.cur_note->x>=GR_WIDTH-64) {
|
||||
psm.scrn_x+=128;
|
||||
PsmRecalcNoteXY;
|
||||
}
|
||||
|
||||
tmpn=psm.head.next;
|
||||
while (tmpn!=&psm.head) {
|
||||
x=tmpn->x;
|
||||
y=tmpn->y;
|
||||
if (measure_left<0.001) {
|
||||
dc->color=BLACK;
|
||||
GrLine(dc,x-PSM_NOTE_SPACING,8,x-PSM_NOTE_SPACING,11*8);
|
||||
measure_left=measure_len;
|
||||
}
|
||||
if (tmpn->type==PSMT_METER) {
|
||||
if (tmpn==psm.cur_note && PsmBlink)
|
||||
dc->color=BROWN;
|
||||
else
|
||||
dc->color=BLACK;
|
||||
DrawTimeSignature(dc,x,5*8,tmpn->meter_top,tmpn->meter_bottom);
|
||||
measure_len=tmpn->meter_top*4.0/tmpn->meter_bottom;
|
||||
measure_left=0;
|
||||
} else {
|
||||
if (tmpn==psm.cur_note && PsmBlink) {
|
||||
dc->color=BROWN;
|
||||
GrPrint(dc,x+8,y,"%s",tmpn->word);
|
||||
} else if (tmpn->flags&PSMF_SEL)
|
||||
dc->color=RED;
|
||||
else {
|
||||
if (tmpn->ona!=ONA_REST)
|
||||
dc->color=BLACK;
|
||||
else
|
||||
dc->color=LTGRAY;
|
||||
if (PsmHasWords(tmpn->word))
|
||||
dc->color=GREEN;
|
||||
}
|
||||
DrawNote(dc,x,y,tmpn->duration);
|
||||
if (PsmIsDotted(tmpn->duration))
|
||||
x+=PSM_NOTE_SPACING/2;
|
||||
if (Bt(&tmpn->flags,PSMf_SHARP))
|
||||
Sprite3(dc,x,y,0,$IB,"<13>",BI=13$);
|
||||
else if (Bt(&tmpn->flags,PSMf_FLAT))
|
||||
Sprite3(dc,x,y,0,$IB,"<14>",BI=14$);
|
||||
measure_left-=psm_durations[tmpn->duration];
|
||||
}
|
||||
tmpn=tmpn->next;
|
||||
}
|
||||
|
||||
if (psm.cur_note==&psm.head && PsmBlink)
|
||||
dc->color=BROWN;
|
||||
else
|
||||
dc->color=BLACK;
|
||||
Sprite3(dc,psm.head.x,50,0,$IB,"<12>",BI=12$);
|
||||
}
|
||||
|
||||
#define PSM_NOTE_BOX_X 220
|
||||
#define PSM_NOTE_BOX_Y (13*FONT_HEIGHT+14)
|
||||
U0 PsmSetPickNoteBoxX(I64 duration,I64 *x)
|
||||
{
|
||||
I64 i;
|
||||
*x=PSM_NOTE_BOX_X;
|
||||
for (i=0;i<duration;i++) {
|
||||
if (PsmIsDotted(i))
|
||||
*x+=PSM_NOTE_SPACING/2;
|
||||
*x+=PSM_NOTE_SPACING+4;
|
||||
}
|
||||
}
|
||||
|
||||
I64 PsmGetPickNoteBoxDuration(I64 xx,I64 yy)
|
||||
{
|
||||
I64 i,x1,x2;
|
||||
if (PSM_NOTE_BOX_Y-14<=yy<PSM_NOTE_BOX_Y+6) {
|
||||
for (i=0;i<PSM_DURATIONS_NUM;i++) {
|
||||
PsmSetPickNoteBoxX(i,&x1);
|
||||
PsmSetPickNoteBoxX(i+1,&x2);
|
||||
if (x1<=xx+PSM_NOTE_SPACING/2<x2)
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
U0 DrawPickNoteBox()
|
||||
{
|
||||
I64 i,x;
|
||||
for (i=0;i<PSM_DURATIONS_NUM;i++) {
|
||||
PsmSetPickNoteBoxX(i,&x);
|
||||
if (PsmIsDotted(i))
|
||||
psm.dc2->color=RED;
|
||||
else if (psm_triplet_durations[i])
|
||||
psm.dc2->color=LTRED;
|
||||
else
|
||||
psm.dc2->color=BLACK;
|
||||
DrawNote(psm.dc2,x,PSM_NOTE_BOX_Y,i);
|
||||
}
|
||||
}
|
||||
|
||||
#define PSM_TOOLS_X 450
|
||||
#define PSM_TOOLS_Y 13*FONT_HEIGHT
|
||||
|
||||
U0 DrawPickTools()
|
||||
{
|
||||
if (psm.tool==PSMTT_BOX_TOOL)
|
||||
psm.dc2->color=ROPF_DITHER+WHITE<<16+RED;
|
||||
else
|
||||
psm.dc2->color=ROPF_DITHER+WHITE<<16+BLACK;
|
||||
GrBorder(psm.dc2,PSM_TOOLS_X,PSM_TOOLS_Y,PSM_TOOLS_X+10,PSM_TOOLS_Y+10);
|
||||
|
||||
if (psm.tool==PSMTT_PTR_TOOL)
|
||||
psm.dc2->color=RED;
|
||||
else
|
||||
psm.dc2->color=BLACK;
|
||||
(*gr.fp_draw_ms)(psm.dc2,PSM_TOOLS_X+15,PSM_TOOLS_Y);
|
||||
psm.dc2->color=BLACK;
|
||||
}
|
||||
|
||||
Bool PsmGetPickToolBox(I64 xx,I64 yy)
|
||||
{
|
||||
if (PSM_TOOLS_X<=xx<PSM_TOOLS_X+27 && PSM_TOOLS_Y<=yy<PSM_TOOLS_Y+15) {
|
||||
PsmMarkSel(0,0,FALSE);
|
||||
if (xx<PSM_TOOLS_X+13)
|
||||
psm.tool=PSMTT_BOX_TOOL;
|
||||
else
|
||||
psm.tool=PSMTT_PTR_TOOL;
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define PSM_METERS_NUM 7
|
||||
I64 meter_tops[PSM_METERS_NUM] ={2,3,4,5,6,7,9},
|
||||
meter_bottoms[PSM_METERS_NUM]={4,4,4,4,8,8,8};
|
||||
|
||||
#define PSM_METER_X 485
|
||||
#define PSM_METER_Y 13*FONT_HEIGHT
|
||||
#define PSM_METER_W 12
|
||||
Bool PsmGetPickMeterBox(I64 xx,I64 yy,I64 *top,I64 *bottom)
|
||||
{
|
||||
I64 i;
|
||||
if (PSM_METER_X<=xx<PSM_METER_X+PSM_METER_W*PSM_METERS_NUM &&
|
||||
PSM_METER_Y<=yy<PSM_METER_Y+2*FONT_HEIGHT) {
|
||||
i=(xx-PSM_METER_X)/PSM_METER_W;
|
||||
*top=meter_tops[i];
|
||||
*bottom=meter_bottoms[i];
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 DrawPickMeterBox()
|
||||
{
|
||||
I64 i;
|
||||
psm.dc2->color=BLACK;
|
||||
for (i=0;i<PSM_METERS_NUM;i++)
|
||||
DrawTimeSignature(psm.dc2,PSM_METER_X+i*PSM_METER_W,PSM_METER_Y,
|
||||
meter_tops[i],meter_bottoms[i]);
|
||||
}
|
||||
|
||||
U0 DrawDC2()
|
||||
{
|
||||
DCFill;
|
||||
DrawPickNoteBox;
|
||||
DrawPickMeterBox;
|
||||
DrawPickTools;
|
||||
}
|
||||
|
||||
|
||||
$SP,"<17>",BI=17$
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
U0 PsmMenu(I64 psm_octave)
|
||||
{
|
||||
DocClear;
|
||||
"$$BG,WHITE$$$$FD,GREEN$$$$CM,0,12$$\n";
|
||||
Sprite($IB,"<17>",BI=17$);
|
||||
'\n\n\n\n\n';
|
||||
|
||||
DrawDC2;
|
||||
|
||||
"$$LTGREEN$$<SPACE>$$FG$$\t\tRest\n"
|
||||
"$$LTGREEN$$<BACKSPACE>$$FG$$\tDeletes Last Note\n"
|
||||
"$$LTGREEN$$Left Mouse$$FG$$\tDrag note or shift word\n"
|
||||
"$$LTGREEN$$Right Mouse$$FG$$\tChange duration or set word\n";
|
||||
Sprite($IB,"<6>",BI=6$,"$$SP+LIS,\"\","
|
||||
"LM=\"Msg(MSG_KEY_DOWN,0,SCF_CTRL|SC_CURSOR_LEFT);\",BI=%d$$");
|
||||
" ";
|
||||
if (psm.playing)
|
||||
Sprite($IB,"<9>",BI=9$,"$$SP,\"\",LM=\"x\",BI=%d$$");
|
||||
else
|
||||
Sprite($IB,"<8>",BI=8$,"$$SP,\"\",LM=\"x\",BI=%d$$");
|
||||
" ";
|
||||
if (psm.record_entry->checked) {
|
||||
psm.record_entry->checked=TRUE;
|
||||
Sprite($IB,"<10>",BI=10$,"$$SP,\"\",LM=\"z\",BI=%d$$");
|
||||
} else
|
||||
Sprite($IB,"<11>",BI=11$,"$$SP,\"\",LM=\"z\",BI=%d$$");
|
||||
" ";
|
||||
Sprite($IB,"<7>",BI=7$,"$$SP+LIS,\"\","
|
||||
"LM=\"Msg(MSG_KEY_DOWN,0,SCF_CTRL|SC_CURSOR_RIGHT);\",BI=%d$$");
|
||||
"$$CM+LX,0,6$$";
|
||||
PsmSetOctave(psm_octave);
|
||||
Refresh(2);
|
||||
}
|
||||
| ||||