Add TempleOS files
This commit is contained in:
commit
55c64e6758
24
Copy.HC
Executable file
24
Copy.HC
Executable file
@ -0,0 +1,24 @@
|
||||
// Copies all source files uncompressed into the home directory
|
||||
|
||||
CDirEntry *start_entry = FilesFind(
|
||||
"/*.Z;!/Home/*",
|
||||
FUF_RECURSE | FUF_JUST_FILES
|
||||
);
|
||||
|
||||
CDirEntry *entry = start_entry;
|
||||
|
||||
do {
|
||||
|
||||
Print("%s", entry->full_name);
|
||||
|
||||
U8 *new_name = MAlloc(StrLen(entry->full_name) * 2);
|
||||
StrPrint(new_name, "/Home/Src%s", entry->full_name + 2);
|
||||
new_name[StrLen(new_name) - 2] = NULL;
|
||||
|
||||
Print(" -> %s\n", new_name);
|
||||
|
||||
Copy(entry->full_name, new_name);
|
||||
|
||||
} while (entry = entry->next);
|
||||
|
||||
DirTreeDel(start_entry);
|
||||
252
temple-src/Adam/ABlkDev/ADskA.HC
Executable file
252
temple-src/Adam/ABlkDev/ADskA.HC
Executable file
@ -0,0 +1,252 @@
|
||||
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
|
||||
public U8 *DBlk(I64 blk,Bool write=FALSE)
|
||||
{//Dump disk block. Optionally, write.
|
||||
//If you set write to TRUE, the block will
|
||||
//be written when you press <ESC>.
|
||||
//See $LK,"::/Demo/Dsk/DskRaw.HC"$.
|
||||
U8 *buf=MAlloc(BLK_SIZE);
|
||||
|
||||
BlkRead(Fs->cur_dv,buf,blk,1);
|
||||
DocD(buf,BLK_SIZE);
|
||||
if (write) {
|
||||
"Edit and press <ESC> to write or <SHIFT-ESC>\n";
|
||||
if (View) {
|
||||
"Write\n";
|
||||
BlkWrite(Fs->cur_dv,buf,blk,1);
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
public U8 *DClus(I64 c,Bool write=FALSE,I64 num=0)
|
||||
{//Dump disk clus. Optionally, write.
|
||||
//If you set write to TRUE, the clus will
|
||||
//be written when you press <ESC>.
|
||||
//See $LK,"::/Demo/Dsk/DskRaw.HC"$.
|
||||
//Do $LK,"Dir",A="MN:Dir"$("*",TRUE); to get clus numbers of files.
|
||||
U8 *buf=MAlloc(Fs->cur_dv->spc<<BLK_SIZE_BITS);
|
||||
c=ClusNumNext(Fs->cur_dv,c,num);
|
||||
ClusRead(Fs->cur_dv,buf,c,1);
|
||||
"Clus:%X\n",c;
|
||||
DocD(buf,Fs->cur_dv->spc<<BLK_SIZE_BITS);
|
||||
if (write) {
|
||||
"Edit and press <ESC> to write or <SHIFT-ESC>\n";
|
||||
if (View) {
|
||||
"Write\n";
|
||||
ClusWrite(Fs->cur_dv,buf,c,1);
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
public U8 *Dump(U8 *filename,Bool write=FALSE)
|
||||
{//Dump file. Optionally, write.
|
||||
//If you set write to TRUE, the file will
|
||||
//be written when you press <ESC>.
|
||||
U8 *buf;
|
||||
I64 size;
|
||||
if (buf=FileRead(filename,&size)) {
|
||||
DocD(buf,size);
|
||||
if (write) {
|
||||
"Edit and press <ESC> to write or <SHIFT-ESC>\n";
|
||||
if (View) {
|
||||
"Write\n";
|
||||
FileWrite(filename,buf,size);
|
||||
}
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
public Bool Copy(U8 *src_files_find_mask,U8 *dst_files_find_mask=".")
|
||||
{//Copy files.
|
||||
//If the name ends in ".Z", it will
|
||||
//be stored compressed. If not ".Z"
|
||||
//it will be stored uncompressed.
|
||||
Bool res=TRUE;
|
||||
CDirContext *dirc;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
U8 *st;
|
||||
if (!(tmpde1=FilesFind(src_files_find_mask,FUF_CLUS_ORDER)))
|
||||
return FALSE;
|
||||
if (IsDir(dst_files_find_mask)) {
|
||||
if (dirc=DirContextNew(dst_files_find_mask,TRUE)) {
|
||||
tmpde=tmpde1;
|
||||
while (tmpde) {
|
||||
if (!(tmpde->attr & RS_ATTR_DIR)) {
|
||||
st=FileNameAbs(tmpde->name);
|
||||
if (!CopySingle(tmpde->full_name,st))
|
||||
res=FALSE;
|
||||
Free(st);
|
||||
}
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
DirContextDel(dirc);
|
||||
}
|
||||
DirTreeDel(tmpde1);
|
||||
return res;
|
||||
} else {
|
||||
DirTreeDel(tmpde1);
|
||||
return CopySingle(src_files_find_mask,dst_files_find_mask);
|
||||
}
|
||||
}
|
||||
|
||||
public Bool Move(U8 *f1,U8 *f2)
|
||||
{//Move files from one location to another or rename.
|
||||
if (Copy(f1,f2)) {
|
||||
Del(f1);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
I64 CopyTree2(CDirEntry *tmpde,I64 src_dir_len,I64 dst_dir_len,U8 *dst_dir)
|
||||
{
|
||||
U8 *st;
|
||||
I64 res=1;
|
||||
while (tmpde) {
|
||||
st=MAlloc(StrLen(tmpde->full_name)+dst_dir_len+2);
|
||||
MemCpy(st,dst_dir,dst_dir_len);
|
||||
StrCpy(st+dst_dir_len,tmpde->full_name+src_dir_len);
|
||||
if (tmpde->attr & RS_ATTR_DIR) {
|
||||
DirMk(st,LinkedLstCnt(tmpde->sub));
|
||||
res+=CopyTree2(tmpde->sub,src_dir_len,dst_dir_len,dst_dir);
|
||||
} else
|
||||
if (CopySingle(tmpde->full_name,st))
|
||||
res++;
|
||||
Free(st);
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public I64 CopyTree(U8 *src_files_find_mask,U8 *dst_files_find_mask,
|
||||
Bool no_mask=TRUE)
|
||||
{//Copy directory tree.
|
||||
//Returns the count of copied files (not dirs).
|
||||
CDirContext *dirc;
|
||||
CDirEntry *tmpde=NULL;
|
||||
I64 res=0,i1,i2;
|
||||
U8 *st1,*st2;
|
||||
|
||||
st1=DirNameAbs(src_files_find_mask);
|
||||
st2=DirNameAbs(dst_files_find_mask);
|
||||
i1=StrLen(st1);
|
||||
if (!StrNCmp(st1,st2,i1) && (st2[i1]=='/' || !st2[i1]) ) {
|
||||
Free(st1);
|
||||
Free(st2);
|
||||
return 0;
|
||||
}
|
||||
Free(st1);
|
||||
Free(st2);
|
||||
if (dirc=DirContextNew(src_files_find_mask,TRUE,,no_mask)) {
|
||||
tmpde=FilesFind(dirc->mask,FUF_RECURSE);
|
||||
st1=DirCur;
|
||||
DirContextDel(dirc);
|
||||
i1=StrLen(st1);
|
||||
if (i1==3) i1--;
|
||||
if (dirc=DirContextNew(dst_files_find_mask,TRUE,TRUE)) {
|
||||
st2=DirCur;
|
||||
i2=StrLen(st2);
|
||||
if (i2==3) i2--;
|
||||
res=CopyTree2(tmpde,i1,i2,st2);
|
||||
DirContextDel(dirc);
|
||||
Free(st2);
|
||||
}
|
||||
DirTreeDel(tmpde);
|
||||
Free(st1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 DelTreeDirs(CDirEntry *tmpde1)
|
||||
{
|
||||
I64 res=0;
|
||||
CDirEntry *tmpde2;
|
||||
while (tmpde1) {
|
||||
tmpde2=tmpde1->next;
|
||||
if (tmpde1->attr & RS_ATTR_DIR) {
|
||||
if (tmpde1->sub)
|
||||
res+=DelTreeDirs(tmpde1->sub);
|
||||
res+=Del(tmpde1->full_name,TRUE,TRUE);
|
||||
}
|
||||
DirEntryDel(tmpde1);
|
||||
tmpde1=tmpde2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
I64 DelTreeFiles(CDirEntry *tmpde1)
|
||||
{
|
||||
I64 res=0;
|
||||
CDirEntry *tmpde2;
|
||||
while (tmpde1) {
|
||||
tmpde2=tmpde1->next;
|
||||
if (tmpde1->attr & RS_ATTR_DIR) {
|
||||
if (tmpde1->sub)
|
||||
res+=DelTreeFiles(tmpde1->sub);
|
||||
} else
|
||||
res+=Del(tmpde1->full_name,FALSE,TRUE);
|
||||
DirEntryDel(tmpde1);
|
||||
tmpde1=tmpde2;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public I64 DelTree(U8 *files_find_mask,U8 *fu_flags=NULL)
|
||||
{//Delete directory tree.
|
||||
I64 res=0,fuf_flags=0;
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
|
||||
if (IsDir(files_find_mask)) {
|
||||
res=DelTreeDirs(FilesFind(files_find_mask,fuf_flags));
|
||||
res+=Del(files_find_mask,TRUE,TRUE);
|
||||
res+=Del(files_find_mask,FALSE,TRUE);
|
||||
} else
|
||||
res=DelTreeFiles(FilesFind(files_find_mask,fuf_flags));
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 TouchFile(U8 *filename,U8 *attr,CDate cdt=I64_MIN)
|
||||
{
|
||||
CDrv *dv=Let2Drv(*filename);
|
||||
CDirEntry de;
|
||||
U8 *cur_dir=StrNew(filename),buf[STR_LEN];
|
||||
if (FileFind(filename,&de,FUF_JUST_FILES)) {
|
||||
Free(de.full_name);
|
||||
if (!StrCmp(attr,"+?"))
|
||||
"%-48ts%s\n",filename,StrPrintFlags(buf,Define("ST_FILE_ATTRS"),de.attr);
|
||||
else {
|
||||
StrFirstRem(cur_dir,":");
|
||||
StrLastRem(cur_dir,"/");
|
||||
if (!*cur_dir)
|
||||
StrCpy(cur_dir,"/");
|
||||
ScanFlags(&de.attr,Define("ST_FILE_ATTRS"),attr);
|
||||
if (cdt==I64_MIN)
|
||||
de.datetime=Now;
|
||||
else
|
||||
de.datetime=cdt;
|
||||
DirNew(dv,cur_dir,&de,FALSE);
|
||||
}
|
||||
} else
|
||||
PrintErr("File not found: \"%s\".\n",filename);
|
||||
Free(cur_dir);
|
||||
}
|
||||
public U0 Touch(U8 *files_find_mask="*",U8 *attr="+?",
|
||||
U8 *fu_flags=NULL,CDate cdt=I64_MIN)
|
||||
{/*Touch file attributes and DateTime.
|
||||
Default lists attributes.
|
||||
attr: "+?" =show current
|
||||
"+T" =resident
|
||||
$LK,"RS_ATTR_READ_ONLY",A="MN:RS_ATTR_READ_ONLY"$ $LK,"ST_FILE_ATTRS",A="MN:ST_FILE_ATTRS"$
|
||||
To Set DateL:
|
||||
Touch(filename,"",,datetime);
|
||||
*/
|
||||
I64 fuf_flags=0;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+f+F");
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
|
||||
tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
|
||||
while (tmpde) {
|
||||
TouchFile(tmpde->full_name,attr,cdt);
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
DirTreeDel(tmpde1);
|
||||
}
|
||||
191
temple-src/Adam/ABlkDev/ADskB.HC
Executable file
191
temple-src/Adam/ABlkDev/ADskB.HC
Executable file
@ -0,0 +1,191 @@
|
||||
#help_index "File/Internal"
|
||||
I64 DirTreeSerializeSize(CDirEntry *tmpde)
|
||||
{
|
||||
I64 res=0;
|
||||
while (tmpde) {
|
||||
res+=CDIR_SIZE+1;
|
||||
if (tmpde->attr & RS_ATTR_DIR)
|
||||
res+=DirTreeSerializeSize(tmpde->sub);
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
return res+1;
|
||||
}
|
||||
I64 DirTreeSerializeFill(CDirEntry *tmpde,U8 *dst)
|
||||
{
|
||||
I64 res=0,i;
|
||||
while (tmpde) {
|
||||
*dst++=1;
|
||||
res++;
|
||||
MemCpy(dst,&tmpde->start,CDIR_SIZE);
|
||||
dst+=CDIR_SIZE;
|
||||
res+=CDIR_SIZE;
|
||||
if (tmpde->attr & RS_ATTR_DIR) {
|
||||
i=DirTreeSerializeFill(tmpde->sub,dst);
|
||||
dst+=i;
|
||||
res+=i;
|
||||
}
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
*dst=0;
|
||||
return res+1;
|
||||
}
|
||||
public U8 *DirTreeSerialize(CDirEntry *tmpde,I64 *_size=NULL)
|
||||
{//Serialize tree returned from $LK,"FilesFind",A="MN:FilesFind"$() into a one contiguous U8 array.
|
||||
I64 size=DirTreeSerializeSize(tmpde);
|
||||
U8 *buf=MAlloc(size);
|
||||
DirTreeSerializeFill(tmpde,buf);
|
||||
if (_size) *_size=size;
|
||||
return buf;
|
||||
}
|
||||
|
||||
U8 *DirTreeUnserialize2(U8 *src,CDirEntry **tmpde)
|
||||
{
|
||||
CDirEntry *tmpde1;
|
||||
if (*src++) {
|
||||
tmpde1=CAlloc(sizeof(CDirEntry));
|
||||
*tmpde=tmpde1;
|
||||
MemCpy(&tmpde1->start,src,CDIR_SIZE);
|
||||
src+=CDIR_SIZE;
|
||||
if (tmpde1->attr & RS_ATTR_DIR)
|
||||
src=DirTreeUnserialize2(src,&tmpde1->sub);
|
||||
src=DirTreeUnserialize2(src,&tmpde1->next);
|
||||
} else
|
||||
*tmpde=NULL;
|
||||
return src;
|
||||
}
|
||||
public CDirEntry *DirTreeUnserialize(U8 *src)
|
||||
{//Unserialize tree to make it like a tree returned from $LK,"FilesFind",A="MN:FilesFind"$().
|
||||
CDirEntry *tmpde=NULL;
|
||||
DirTreeUnserialize2(src,&tmpde);
|
||||
return tmpde;
|
||||
}
|
||||
|
||||
#help_index "File/Program Routines"
|
||||
U0 FOFlatten(CDirEntry *tmpde,CDirEntry **a,I64 *i)
|
||||
{
|
||||
CDirEntry *tmpde1;
|
||||
while (tmpde) {
|
||||
tmpde1=tmpde->next;
|
||||
if (tmpde->attr&RS_ATTR_DIR) {
|
||||
FOFlatten(tmpde->sub,a,i);
|
||||
DirEntryDel(tmpde);
|
||||
} else {
|
||||
a[*i]=tmpde;
|
||||
*i=*i+1;
|
||||
}
|
||||
tmpde=tmpde1;
|
||||
}
|
||||
}
|
||||
|
||||
I64 Size1(CDirEntry *tmpde,I64 *_fuf_flags,I64 round_to)
|
||||
{
|
||||
U8 buf[BLK_SIZE];
|
||||
I64 res=0,i;
|
||||
CDrv *dv;
|
||||
while (tmpde) {
|
||||
if ((i=tmpde->size) && Bt(_fuf_flags,FUf_EXPAND) &&
|
||||
!(tmpde->attr&RS_ATTR_DIR) &&
|
||||
FileAttr(tmpde->name)&RS_ATTR_COMPRESSED) {
|
||||
dv=Let2Drv(*tmpde->full_name);
|
||||
BlkRead(dv,buf,Clus2Blk(dv,tmpde->clus),1);
|
||||
i=(&buf)(CArcCompress *)->expanded_size;
|
||||
}
|
||||
if (round_to)
|
||||
i=CeilU64(tmpde->size,round_to);
|
||||
if (tmpde->attr&RS_ATTR_DIR)
|
||||
i+=Size1(tmpde->sub,_fuf_flags,round_to);
|
||||
tmpde->user_data=i;
|
||||
res+=i;
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
public I64 Size(U8 *files_find_mask="/*",U8 *fu_flags=NULL,I64 round_to=0)
|
||||
{//Total size of files in mask. "+x" for expanded size.
|
||||
//Does not include directory size of base directory, but
|
||||
//does include size of sub directories.
|
||||
I64 fuf_flags=0,res=0;
|
||||
CDirEntry *tmpde1=NULL;
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
|
||||
if (tmpde1=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND)) {
|
||||
fuf_flags&=FUF_EXPAND;
|
||||
res=Size1(tmpde1,&fuf_flags,round_to);
|
||||
DirTreeDel(tmpde1);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 FileCnt(CDirEntry *tmpde)
|
||||
{//Cnt of files in $LK,"CDirEntry",A="MN:CDirEntry"$ tree.
|
||||
I64 cnt=0;
|
||||
while (tmpde) {
|
||||
if (tmpde->attr&RS_ATTR_DIR)
|
||||
cnt+=FileCnt(tmpde->sub);
|
||||
else
|
||||
cnt++;
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
|
||||
public I64 FF(U8 *files_find_mask,U8 *fu_flags=NULL)
|
||||
{//Files find. List files matching mask.
|
||||
I64 cnt=0,fuf_flags=0;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F");
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
|
||||
tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
|
||||
while (tmpde) {
|
||||
PutFileLink(tmpde->full_name);
|
||||
'\n';
|
||||
cnt++;
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
DirTreeDel(tmpde1);
|
||||
return cnt;
|
||||
}
|
||||
|
||||
public I64 Zip(U8 *files_find_mask="*",U8 *fu_flags=NULL)
|
||||
{//Compress files by moving to .Z filename.
|
||||
U8 *st;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
I64 res=0,fuf_flags=0;
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+O");
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
|
||||
tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
|
||||
while (tmpde) {
|
||||
if (!IsDotZ(tmpde->full_name)) {
|
||||
st=MStrPrint("%s.Z",tmpde->full_name);
|
||||
res+=Move(tmpde->full_name,st);
|
||||
Free(st);
|
||||
}
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
DirTreeDel(tmpde1);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 Unzip(U8 *files_find_mask="*.Z",U8 *fu_flags=NULL)
|
||||
{//Uncompress files by moving to not .Z filename.
|
||||
//You don't have to do this for normal operation.
|
||||
//It automatically unzips ".Z" files.
|
||||
U8 *st;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
I64 res=0,fuf_flags=0;
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+O");
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
|
||||
tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
|
||||
while (tmpde) {
|
||||
if (IsDotZ(tmpde->full_name)) {
|
||||
st=StrNew(tmpde->full_name);
|
||||
StrLastRem(st,".");
|
||||
res+=Move(tmpde->full_name,st);
|
||||
Free(st);
|
||||
}
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
DirTreeDel(tmpde1);
|
||||
return res;
|
||||
}
|
||||
444
temple-src/Adam/ABlkDev/DskChk.HC
Executable file
444
temple-src/Adam/ABlkDev/DskChk.HC
Executable file
@ -0,0 +1,444 @@
|
||||
#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically)"
|
||||
Bool ChkDskConfirm(Bool *_fix,Bool *_confirm)
|
||||
{
|
||||
if (*_fix && *_confirm) {
|
||||
"Fix ";
|
||||
if (!YorN)
|
||||
*_fix=FALSE;
|
||||
*_confirm=FALSE;
|
||||
}
|
||||
return *_fix;
|
||||
}
|
||||
|
||||
I64 RedSeaChkDskLst(CDrv *dv,CDirEntry *tmpde1,
|
||||
U8 *bits,U8 *bits2,I64 size,I64 bpc)
|
||||
{
|
||||
CDirEntry *tmpde2;
|
||||
I64 i,j,errs=0;
|
||||
while (tmpde1) {
|
||||
tmpde2=tmpde1->next;
|
||||
if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)
|
||||
errs+=RedSeaChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);
|
||||
j=(tmpde1->size+bpc-1)/bpc;
|
||||
for (i=0;i<j;i++) {
|
||||
if (i+tmpde1->clus-dv->data_area>size) {
|
||||
PrintErr("Invalid Clus:%s Clus:%X\n",tmpde1->full_name,
|
||||
i+tmpde1->clus);
|
||||
errs++;
|
||||
break;
|
||||
}
|
||||
if (LBts(bits,i+tmpde1->clus-dv->data_area)) {
|
||||
PrintErr("Dbl Alloc:%s Clus:%X\n",tmpde1->full_name,
|
||||
i+tmpde1->clus);
|
||||
errs++;
|
||||
}
|
||||
if (!LBtr(bits2,i+tmpde1->clus-dv->data_area)) {
|
||||
PrintErr("UnAlloc:%s Clus:%X\n",tmpde1->full_name,
|
||||
i+tmpde1->clus);
|
||||
errs++;
|
||||
}
|
||||
}
|
||||
DirEntryDel(tmpde1);
|
||||
tmpde1=tmpde2;
|
||||
}
|
||||
return errs;
|
||||
}
|
||||
|
||||
I64 RedSeaChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)
|
||||
{
|
||||
I64 i,j,bpc,size,errs=0;
|
||||
CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
|
||||
U8 *files_find_mask=MStrPrint("%c:/*",Drv2Let(dv)),
|
||||
*old_dir=StrNew(Fs->cur_dir),
|
||||
*bits,*bits2;
|
||||
CDirEntry *ptr,*ptr2;
|
||||
|
||||
Drv(drv_let);
|
||||
"Scanning...\n";
|
||||
size=(dv->size-(dv->data_area-dv->drv_offset))/dv->spc;
|
||||
bpc=dv->spc<<BLK_SIZE_BITS;
|
||||
bits=CAlloc((size+7)>>3);
|
||||
bits2=CAlloc((size+7)>>3+BLK_SIZE);
|
||||
BlkRead(dv,bits2,dv->fat1,((size+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS);
|
||||
|
||||
//Get Root Dir size
|
||||
ptr2=MAlloc(bpc);
|
||||
BlkRead(dv,ptr2,dv->root_clus,1);
|
||||
ptr=ptr2(U8 *)-offset(CDirEntry.start);
|
||||
j=(ptr->size+bpc-1)/bpc;
|
||||
Free(ptr2);
|
||||
|
||||
for (i=0;i<j;i++) {
|
||||
if (i+dv->root_clus-dv->data_area>size) {
|
||||
PrintErr("Invalid Clus: RootDir Clus:%X\n",i+dv->root_clus);
|
||||
errs++;
|
||||
break;
|
||||
}
|
||||
if (LBts(bits,i+dv->root_clus-dv->data_area)) {
|
||||
PrintErr("Dbl Alloc: RootDir Clus:%X\n",i+dv->root_clus);
|
||||
errs++;
|
||||
}
|
||||
if (!LBtr(bits2,i+dv->root_clus-dv->data_area)) {
|
||||
PrintErr("UnAlloc: RootDir Clus:%X\n",i+dv->root_clus);
|
||||
errs++;
|
||||
}
|
||||
}
|
||||
|
||||
errs+=RedSeaChkDskLst(dv,FilesFind(files_find_mask,FUF_RECURSE),
|
||||
bits,bits2,size,bpc);
|
||||
for (i=1;i<size;i++)
|
||||
if (Bt(bits2,i)) {
|
||||
PrintWarn("Shouldn't Alloc Clus:%0X\n",i+dv->data_area);
|
||||
errs++;
|
||||
if (ChkDskConfirm(_fix,_confirm))
|
||||
RedSeaFreeClus(dv,i+dv->data_area,1);
|
||||
}
|
||||
|
||||
Free(files_find_mask);
|
||||
Free(bits);
|
||||
Free(bits2);
|
||||
Drv(Drv2Let(old_dv));
|
||||
Cd(old_dir);
|
||||
Free(old_dir);
|
||||
return errs;
|
||||
}
|
||||
|
||||
I64 FAT32ChkDskLst(CDrv *dv,CDirEntry *tmpde1,
|
||||
U8 *bits,U32 *bits2,I64 size,I64 bpc)
|
||||
{
|
||||
CDirEntry *tmpde2;
|
||||
I64 i,c,errs=0;
|
||||
while (tmpde1) {
|
||||
tmpde2=tmpde1->next;
|
||||
if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)
|
||||
errs+=FAT32ChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);
|
||||
i=0;
|
||||
c=tmpde1->clus;
|
||||
while (0<c<0x0FFFFFF8) {
|
||||
if (c>size) {
|
||||
PrintErr("Invalid Clus:%s Clus:%X\n",tmpde1->full_name,c);
|
||||
errs++;
|
||||
break;
|
||||
}
|
||||
if (LBts(bits,c)) {
|
||||
PrintErr("Dbl Alloc:%s Clus:%X\n",tmpde1->full_name,c);
|
||||
errs++;
|
||||
}
|
||||
if (!bits2[c]) {
|
||||
PrintErr("UnAlloc:%s Clus:%X\n",tmpde1->full_name,c);
|
||||
errs++;
|
||||
} else
|
||||
bits2[c]=0;
|
||||
c=ClusNumNext(dv,c);
|
||||
i++;
|
||||
}
|
||||
if (!(tmpde1->attr & RS_ATTR_DIR)) {
|
||||
i*=bpc;
|
||||
if (tmpde1->size>i) {
|
||||
PrintErr("Alloced File Too Short:%s\n",tmpde1->full_name);
|
||||
errs++;
|
||||
}
|
||||
if (i>tmpde1->size+bpc-1) {
|
||||
PrintWarn("Alloced File Too Long:%s\n",tmpde1->full_name);
|
||||
errs++;
|
||||
}
|
||||
}
|
||||
DirEntryDel(tmpde1);
|
||||
tmpde1=tmpde2;
|
||||
}
|
||||
return errs;
|
||||
}
|
||||
|
||||
I64 FAT32ChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)
|
||||
{
|
||||
I64 i,bpc,size,c,errs=0;
|
||||
CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
|
||||
U8 *files_find_mask=MStrPrint("%c:/*",Drv2Let(dv)),
|
||||
*old_dir=StrNew(Fs->cur_dir),
|
||||
*bits;
|
||||
U32 *bits2;
|
||||
Drv(drv_let);
|
||||
"Scanning...\n";
|
||||
size=(dv->size-(dv->data_area-dv->drv_offset))/dv->spc;
|
||||
bpc=dv->spc<<BLK_SIZE_BITS;
|
||||
bits=CAlloc((size+7)>>3);
|
||||
bits2=CAlloc(size*4+BLK_SIZE);
|
||||
BlkRead(dv,bits2,dv->fat1,(size*4+BLK_SIZE-1)>>BLK_SIZE_BITS);
|
||||
|
||||
c=dv->root_clus;
|
||||
while (0<c<0x0FFFFFF8) {
|
||||
if (c>size) {
|
||||
PrintErr("Invalid Clus: RootDir Clus:%X\n",c);
|
||||
errs++;
|
||||
break;
|
||||
}
|
||||
if (LBts(bits,c)) {
|
||||
PrintErr("Dbl Alloc: RootDir Clus:%X\n",c);
|
||||
errs++;
|
||||
}
|
||||
if (!bits2[c]) {
|
||||
PrintErr("UnAlloc: RootDir Clus:%X\n",c);
|
||||
errs++;
|
||||
} else
|
||||
bits2[c]=0;
|
||||
c=ClusNumNext(dv,c);
|
||||
}
|
||||
|
||||
errs+=FAT32ChkDskLst(dv,FilesFind(files_find_mask,FUF_RECURSE),
|
||||
bits,bits2,size,bpc);
|
||||
|
||||
bits2[1]=0; //See $LK,"FAT32Fmt",A="MN:FAT32Fmt"$()
|
||||
for (i=1;i<size;i++)
|
||||
if (bits2[i]) {
|
||||
PrintWarn("Shouldn't Alloc Clus:%0X\n",i);
|
||||
errs++;
|
||||
if (ChkDskConfirm(_fix,_confirm))
|
||||
FAT32FreeClus(dv,i);
|
||||
}
|
||||
Free(files_find_mask);
|
||||
Free(bits);
|
||||
Free(bits2);
|
||||
Drv(Drv2Let(old_dv));
|
||||
Cd(old_dir);
|
||||
Free(old_dir);
|
||||
return errs;
|
||||
}
|
||||
|
||||
public I64 DskChk(U8 drv_let=0,Bool fix=FALSE,Bool confirm=TRUE)
|
||||
{//Check disk for allocation errors and, optionally, fix.
|
||||
//You probably want to reformat and reinstall.
|
||||
I64 errs=0;
|
||||
CDrv *dv=Let2Drv(drv_let);
|
||||
switch (dv->fs_type) {
|
||||
case FSt_REDSEA:
|
||||
errs=RedSeaChkDsk(drv_let,&fix,&confirm);
|
||||
break;
|
||||
case FSt_FAT32:
|
||||
errs=FAT32ChkDsk(drv_let,&fix,&confirm);
|
||||
break;
|
||||
default:
|
||||
PrintErr("File System Not Supported\n");
|
||||
}
|
||||
if (errs) {
|
||||
if (fix)
|
||||
"It might be a little better.";
|
||||
"Copy files to another partition or CD/DVD, "
|
||||
"reformat, and copy back."
|
||||
"Or, copy from a back-up.\n";
|
||||
}
|
||||
return errs;
|
||||
}
|
||||
|
||||
U0 RedSeaDrvView(U8 drv_let=0)
|
||||
{
|
||||
CDrv *dv=Let2Drv(drv_let);
|
||||
I64 lohi,c1,i,x,y,l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
|
||||
s=dv->size+dv->drv_offset-dv->data_area;
|
||||
U8 *bitmap;
|
||||
CDC *dc=DCAlias;
|
||||
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
WinMax;
|
||||
WinBorder(ON);
|
||||
DocCursor;
|
||||
DocClear;
|
||||
DCFill;
|
||||
try {
|
||||
i=((s+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
bitmap=MAlloc(i<<BLK_SIZE_BITS);
|
||||
BlkRead(dv,bitmap,dv->fat1,i);
|
||||
i=0;
|
||||
for (y=0;y<GR_HEIGHT-3*FONT_HEIGHT;y++) {
|
||||
if (ScanKey)
|
||||
break;
|
||||
for (x=0;x<GR_WIDTH-FONT_WIDTH<<1;x++) {
|
||||
lohi=i*s;
|
||||
c1=lohi/l;
|
||||
if (Bt(bitmap,c1))
|
||||
dc->color=ROP_XOR+BLUE^TRANSPARENT;
|
||||
else
|
||||
dc->color=ROP_XOR+WHITE^TRANSPARENT;
|
||||
GrPlot(dc,x,y);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
Free(bitmap);
|
||||
} catch
|
||||
DrvUnlock(dv);
|
||||
GetChar;
|
||||
|
||||
SettingsPop;
|
||||
DCFill;
|
||||
DCDel(dc);
|
||||
}
|
||||
U0 FAT32DrvView(U8 drv_let=0)
|
||||
{
|
||||
CDrv *dv=Let2Drv(drv_let);
|
||||
I64 lohi,c1,i,x,y,l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
|
||||
s=(dv->size+dv->spc-1)/dv->spc-(2+dv->data_area-dv->drv_offset);
|
||||
U32 *bitmap;
|
||||
CDC *dc=DCAlias;
|
||||
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
WinMax;
|
||||
WinBorder(ON);
|
||||
DocCursor;
|
||||
DocClear;
|
||||
DCFill;
|
||||
try {
|
||||
i=(s*4+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
bitmap=MAlloc(i<<BLK_SIZE_BITS);
|
||||
BlkRead(dv,bitmap,dv->fat1,i);
|
||||
i=0;
|
||||
for (y=0;y<GR_HEIGHT-3*FONT_HEIGHT;y++) {
|
||||
if (ScanKey)
|
||||
break;
|
||||
for (x=0;x<GR_WIDTH-FONT_WIDTH<<1;x++) {
|
||||
lohi=i*s;
|
||||
c1=lohi/l;
|
||||
if (bitmap[c1])
|
||||
dc->color=ROP_XOR+BLUE^TRANSPARENT;
|
||||
else
|
||||
dc->color=ROP_XOR+WHITE^TRANSPARENT;
|
||||
GrPlot(dc,x,y);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
Free(bitmap);
|
||||
} catch
|
||||
DrvUnlock(dv);
|
||||
GetChar;
|
||||
|
||||
SettingsPop;
|
||||
DCFill;
|
||||
DCDel(dc);
|
||||
}
|
||||
public U0 DrvView(U8 drv_let=0)
|
||||
{//Drive view. Graph the allocation map's fragmentation.
|
||||
CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
|
||||
Drv(drv_let);
|
||||
switch (dv->fs_type) {
|
||||
case FSt_REDSEA:
|
||||
RedSeaDrvView(drv_let);
|
||||
break;
|
||||
case FSt_FAT32:
|
||||
FAT32DrvView(drv_let);
|
||||
break;
|
||||
default:
|
||||
PrintErr("File System Not Supported\n");
|
||||
}
|
||||
Drv(Drv2Let(old_dv));
|
||||
}
|
||||
|
||||
public U0 DskView(U8 drv_let=0)
|
||||
{//Disk view. Pie chart of partition sizes.
|
||||
I64 i,j,attr,
|
||||
h=Fs->pix_width,
|
||||
v=Fs->pix_height,
|
||||
radius;
|
||||
CDrv *dv;
|
||||
CBlkDev *bd=Let2BlkDev(drv_let);
|
||||
CDC *dc=DCAlias;
|
||||
F64 sect_start,sect_end;
|
||||
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
DocCursor;
|
||||
DocClear;
|
||||
DCFill;
|
||||
if (h<v)
|
||||
radius=0.4*h;
|
||||
else
|
||||
radius=0.4*v;
|
||||
dc->color=BLACK;
|
||||
GrCircle(dc,h>>1,v>>1,radius);
|
||||
|
||||
j=1;
|
||||
for (i=0;i<DRVS_NUM;i++) {
|
||||
dv=&blkdev.drvs[i];
|
||||
if (bd==dv->bd && dv->fs_type) {
|
||||
sect_start=-(dv->drv_offset*2*ã/(bd->max_blk+1));
|
||||
sect_end =-((dv->drv_offset+dv->size)*2*ã/(bd->max_blk+1));
|
||||
dc->color=BLACK;
|
||||
GrLine(dc,h>>1,v>>1,
|
||||
h>>1+radius*Cos(sect_start),
|
||||
v>>1+radius*Sin(sect_start));
|
||||
GrLine(dc,h>>1,v>>1,
|
||||
h>>1+radius*Cos(sect_end),
|
||||
v>>1+radius*Sin(sect_end));
|
||||
|
||||
attr=DrvTextAttrGet(Drv2Let(dv));
|
||||
dc->color=attr&15;
|
||||
GrPrint(dc,0,v-FONT_HEIGHT*j,"%C %-8Z",Drv2Let(dv),
|
||||
dv->fs_type,"ST_DRV_TYPES");
|
||||
dc->color.c1=attr>>4;
|
||||
dc->color|=ROPF_DITHER;
|
||||
GrFloodFill(dc,
|
||||
h>>1+(radius-4)*Cos((sect_start+sect_end)/2),
|
||||
v>>1+(radius-4)*Sin((sect_start+sect_end)/2),FALSE);
|
||||
j++;
|
||||
}
|
||||
}
|
||||
|
||||
GetChar(,FALSE);
|
||||
SettingsPop;
|
||||
DCFill;
|
||||
DCDel(dc);
|
||||
}
|
||||
|
||||
I64 RedSeaUnusedDrvSpace(U8 drv_let=0)
|
||||
{
|
||||
CDrv *dv=Let2Drv(drv_let);
|
||||
I64 res=0,i,l;
|
||||
U8 *bitmap;
|
||||
try {
|
||||
l=dv->size+dv->drv_offset-dv->data_area;
|
||||
i=((l+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
bitmap=MAlloc(i<<BLK_SIZE_BITS);
|
||||
BlkRead(dv,bitmap,dv->fat1,i);
|
||||
for (i=0;i<l;i++)
|
||||
if (!Bt(bitmap,i))
|
||||
res++;
|
||||
Free(bitmap);
|
||||
} catch
|
||||
DrvUnlock(dv);
|
||||
return res*BLK_SIZE*dv->spc;
|
||||
}
|
||||
I64 FAT32UnusedDrvSpace(U8 drv_let=0)
|
||||
{
|
||||
CDrv *dv=Let2Drv(drv_let);
|
||||
I64 res=0,i,l;
|
||||
U32 *bitmap;
|
||||
try {
|
||||
l=(dv->size+dv->spc-1)/dv->spc-(2+dv->data_area-dv->drv_offset);
|
||||
i=(l*4+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
bitmap=MAlloc(i<<BLK_SIZE_BITS);
|
||||
BlkRead(dv,bitmap,dv->fat1,i);
|
||||
for (i=0;i<l;i++)
|
||||
if (!bitmap[i])
|
||||
res++;
|
||||
Free(bitmap);
|
||||
} catch
|
||||
DrvUnlock(dv);
|
||||
return res*BLK_SIZE*dv->spc;
|
||||
}
|
||||
public I64 DrvUnused(U8 drv_let=0)
|
||||
{//Returns unused size in bytes.
|
||||
CDrv *dv=Let2Drv(drv_let),*old_dv=Fs->cur_dv;
|
||||
U8 *old_dir=StrNew(Fs->cur_dir);
|
||||
I64 res=0;
|
||||
Drv(drv_let);
|
||||
switch (dv->fs_type) {
|
||||
case FSt_REDSEA:
|
||||
res=RedSeaUnusedDrvSpace(drv_let);
|
||||
break;
|
||||
case FSt_FAT32:
|
||||
res=FAT32UnusedDrvSpace(drv_let);
|
||||
break;
|
||||
default:
|
||||
PrintErr("File System Not Supported\n");
|
||||
}
|
||||
Drv(Drv2Let(old_dv));
|
||||
Cd(old_dir);
|
||||
Free(old_dir);
|
||||
return res;
|
||||
}
|
||||
167
temple-src/Adam/ABlkDev/DskPrt.HC
Executable file
167
temple-src/Adam/ABlkDev/DskPrt.HC
Executable file
@ -0,0 +1,167 @@
|
||||
#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically)"
|
||||
|
||||
#define ROUND_DRV_TO (63*255)
|
||||
#define DRV_HEADER 63
|
||||
|
||||
class CPlannedDrv
|
||||
{
|
||||
CPlannedDrv *next,*last;
|
||||
I64 size;
|
||||
Bool pri;
|
||||
};
|
||||
|
||||
public I64 DskPrt(U8 drv_let=0,...)
|
||||
{/*Partition the disk containing partition drv_let.
|
||||
|
||||
drv_let=0 means add new drive that is not already mounted.
|
||||
|
||||
>DskPrt('C',0.5,0.25,0.25); //Make three. 50% C, 25% D, 25% E, round-up to blk.
|
||||
|
||||
*/
|
||||
CBlkDev *bd;
|
||||
CPlannedDrv head,*tmppp;
|
||||
CMasterBoot mbr;
|
||||
Bool pri=TRUE;
|
||||
I64 ext_base,drv_let2,pri_cnt=0,i,start_offset,offset,
|
||||
total,remaining,cur_arg=0;
|
||||
"This command does not play well\n"
|
||||
"with other operating systems.\n"
|
||||
"You really should use another\n"
|
||||
"operating system's partitioner.\n"
|
||||
"If you use this, it may, in fact,\n"
|
||||
"make your hard drive impossible\n"
|
||||
"to repartition with other operating\n"
|
||||
"until you set block zero to zero\n"
|
||||
"with $$LK,\"BootMHDZero\",\"MN:BootMHDZero\"$$()\n\n\n"
|
||||
"Continue";
|
||||
if (argc<=cur_arg && !YorN)
|
||||
return 0;
|
||||
'\n';
|
||||
|
||||
if (drv_let && !Let2BlkDev(drv_let,FALSE))
|
||||
drv_let=0;
|
||||
if (!drv_let && !(drv_let=Mount(TRUE)) ||
|
||||
!(bd=Let2BlkDev(drv_let,FALSE)) || bd->type!=BDT_ATA)
|
||||
return 0;
|
||||
|
||||
total=bd->max_blk+1;
|
||||
QueInit(&head);
|
||||
drv_let2=bd->first_drv_let;
|
||||
remaining=FloorU64(bd->max_blk+1,ROUND_DRV_TO);
|
||||
while (FloorU64(remaining,ROUND_DRV_TO)>=ROUND_DRV_TO) {
|
||||
tmppp=MAlloc(sizeof(CPlannedDrv));
|
||||
do {
|
||||
"$$RED$$Partition %C$$FG$$\n",drv_let2;
|
||||
tmppp->pri=FALSE;
|
||||
if (pri) {
|
||||
"Primary Partition";
|
||||
if (argc>cur_arg || YorN) {
|
||||
pri_cnt++;
|
||||
tmppp->pri=TRUE;
|
||||
if (pri_cnt==3)
|
||||
pri=FALSE;
|
||||
} else
|
||||
pri=FALSE;
|
||||
}
|
||||
"\nBlocks Remaining:%d (0x%X)\n",
|
||||
remaining-DRV_HEADER,remaining-DRV_HEADER;
|
||||
if (argc>cur_arg)
|
||||
tmppp->size=MinI64(CeilU64(MaxI64(remaining,DRV_HEADER),ROUND_DRV_TO),
|
||||
CeilU64(argv[cur_arg++](F64)*total,ROUND_DRV_TO));
|
||||
else
|
||||
tmppp->size=CeilU64(GetI64("Size in Blocks:",
|
||||
remaining-DRV_HEADER)+DRV_HEADER,ROUND_DRV_TO);
|
||||
} while (!(ROUND_DRV_TO<=tmppp->size<=FloorU64(remaining,ROUND_DRV_TO)));
|
||||
QueIns(tmppp,head.last);
|
||||
remaining-=tmppp->size;
|
||||
drv_let2++;
|
||||
}
|
||||
|
||||
"\n\n!!! Repartition Drive !!!\n\n";
|
||||
tmppp=head.next;
|
||||
drv_let2=bd->first_drv_let;
|
||||
while (tmppp!=&head) {
|
||||
"Drive %C:%08X ",drv_let2,tmppp->size;
|
||||
if (tmppp->pri)
|
||||
"Primary\n";
|
||||
else
|
||||
"Logical\n";
|
||||
tmppp=tmppp->next;
|
||||
drv_let2++;
|
||||
}
|
||||
if (!argc && !AreYouSure)
|
||||
goto pd_done;
|
||||
|
||||
remaining=FloorU64(bd->max_blk+1,ROUND_DRV_TO)-ROUND_DRV_TO;
|
||||
tmppp=head.next;
|
||||
MemSet(&mbr,0,BLK_SIZE);
|
||||
mbr.signature=0xAA55;
|
||||
offset=0;
|
||||
for (i=0;i<pri_cnt;i++) {
|
||||
mbr.p[i].active=0x80;
|
||||
mbr.p[i].start_head=0;
|
||||
mbr.p[i].start_cyl=0x101;
|
||||
mbr.p[i].type=1; //Will get set different.
|
||||
mbr.p[i].end_head=0xFE;
|
||||
mbr.p[i].end_cyl=0xFFFF;
|
||||
mbr.p[i].offset=DRV_HEADER+offset;
|
||||
mbr.p[i].size=tmppp->size-DRV_HEADER;
|
||||
offset+=tmppp->size;
|
||||
remaining-=tmppp->size;
|
||||
tmppp=tmppp->next;
|
||||
}
|
||||
if (!i) i++;
|
||||
if (tmppp!=&head) {
|
||||
mbr.p[i].active=0x80;
|
||||
mbr.p[i].start_head=0;
|
||||
mbr.p[i].start_cyl=0x101;
|
||||
mbr.p[i].type=0xF;
|
||||
mbr.p[i].end_head=0xFE;
|
||||
mbr.p[i].end_cyl=0xFFFF;
|
||||
mbr.p[i].offset=offset;
|
||||
mbr.p[i].size=remaining;
|
||||
ext_base=offset;
|
||||
}
|
||||
ATAWriteBlks(bd,&mbr,0,1);
|
||||
|
||||
while (tmppp!=&head) {
|
||||
start_offset=offset;
|
||||
MemSet(&mbr,0,BLK_SIZE);
|
||||
mbr.signature=0xAA55;
|
||||
|
||||
mbr.p[0].active=0x80;
|
||||
mbr.p[0].start_head=1;
|
||||
mbr.p[0].start_cyl=0x101;
|
||||
mbr.p[0].type=1; //Will get set different.
|
||||
mbr.p[0].end_head=0xFE;
|
||||
mbr.p[0].end_cyl=0xFFFF;
|
||||
mbr.p[0].offset=DRV_HEADER;
|
||||
mbr.p[0].size=tmppp->size-DRV_HEADER;
|
||||
offset+=tmppp->size;
|
||||
tmppp=tmppp->next;
|
||||
if (tmppp!=&head) {
|
||||
mbr.p[1].active=0x80;
|
||||
mbr.p[1].start_head=0;
|
||||
mbr.p[1].start_cyl=0x101;
|
||||
mbr.p[1].type=5;
|
||||
mbr.p[1].end_head=0xFE;
|
||||
mbr.p[1].end_cyl=0xFFFF;
|
||||
mbr.p[1].offset=offset-ext_base;
|
||||
mbr.p[1].size=tmppp->size;
|
||||
}
|
||||
ATAWriteBlks(bd,&mbr,start_offset,1);
|
||||
}
|
||||
|
||||
bd->flags&=~(BDF_INITIALIZED | BDF_INIT_IN_PROGRESS);
|
||||
BlkDevAdd(bd,,FALSE,TRUE);
|
||||
for (i=bd->first_drv_let;i<drv_let2;i++)
|
||||
Fmt(i,,FALSE);
|
||||
|
||||
pd_done:
|
||||
while (head.next!=&head) {
|
||||
tmppp=head.next;
|
||||
QueRem(tmppp);
|
||||
Free(tmppp);
|
||||
}
|
||||
return total;
|
||||
}
|
||||
791
temple-src/Adam/ABlkDev/FileMgr.HC
Executable file
791
temple-src/Adam/ABlkDev/FileMgr.HC
Executable file
@ -0,0 +1,791 @@
|
||||
#help_index "DolDoc/Output;StdOut/DolDoc"
|
||||
U0 DirFileDoc(CDoc *doc,CDirEntry *tmpde)
|
||||
{
|
||||
while (tmpde) {
|
||||
if (tmpde->attr & RS_ATTR_DIR) {
|
||||
tmpde->user_data=DocPrint(doc,"$$TR,\"%s\",U=0x%X$$",tmpde->name,tmpde);
|
||||
DocPrint(doc,"\n$$ID,+2$$");
|
||||
if (tmpde->sub)
|
||||
DirFileDoc(doc,tmpde->sub);
|
||||
DocPrint(doc,"$$ID,-2$$");
|
||||
} else {
|
||||
tmpde->user_data=DocPrint(doc,"$$MU,\"%s\",U=0x%X$$",tmpde->name,tmpde);
|
||||
DocPrint(doc,"\n");
|
||||
}
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
|
||||
|
||||
#define FM_NORMAL 0
|
||||
#define FM_PICK_FILE 1
|
||||
#define FM_PICK_DIR 2
|
||||
|
||||
class CFMUncollapsedLst
|
||||
{
|
||||
CFMUncollapsedLst *next;
|
||||
U8 *name;
|
||||
};
|
||||
|
||||
CFMUncollapsedLst *FMCollectUncollapsedLst(CDoc *doc)
|
||||
{
|
||||
CDocEntry *doc_e=doc->head.next;
|
||||
CFMUncollapsedLst *res=NULL,*tmpc;
|
||||
CDirEntry *tmpde;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->type_u8==DOCT_TREE) {
|
||||
if (!(doc_e->de_flags&DOCEF_CHECKED_COLLAPSED)) {
|
||||
if (tmpde=doc_e->user_data) {
|
||||
tmpc=MAlloc(sizeof(CFMUncollapsedLst));
|
||||
tmpc->next=res;
|
||||
res=tmpc;
|
||||
tmpc->name=StrNew(tmpde->full_name);
|
||||
}
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 FMMarkUncollapsed(CDoc *doc,CFMUncollapsedLst *tmpc,
|
||||
U8 *cur_entry,U8 *next_entry)
|
||||
{
|
||||
CDocEntry *doc_e=doc->head.next;
|
||||
CFMUncollapsedLst *tmpc1;
|
||||
CDirEntry *tmpde;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->type_u8==DOCT_TREE) {
|
||||
tmpde=doc_e->user_data;
|
||||
tmpc1=tmpc;
|
||||
while (tmpc1) {
|
||||
if (!StrCmp(tmpc1->name,tmpde->full_name)) {
|
||||
doc_e->de_flags&=~DOCEF_CHECKED_COLLAPSED;
|
||||
break;
|
||||
}
|
||||
tmpc1=tmpc1->next;
|
||||
}
|
||||
if (cur_entry) {
|
||||
if (!StrNCmp(cur_entry,tmpde->full_name,StrLen(tmpde->full_name))) {
|
||||
doc->cur_entry=doc_e;
|
||||
if (StrLen(tmpde->full_name)==StrLen(cur_entry))
|
||||
cur_entry=NULL;
|
||||
} else if (next_entry) {
|
||||
if (!StrNCmp(next_entry,
|
||||
tmpde->full_name,StrLen(tmpde->full_name))) {
|
||||
doc->cur_entry=doc_e;
|
||||
if (StrLen(tmpde->full_name)==StrLen(next_entry))
|
||||
cur_entry=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (doc_e->type_u8==DOCT_MENU_VAL) {
|
||||
tmpde=doc_e->user_data;
|
||||
if (cur_entry) {
|
||||
if (!StrNCmp(cur_entry,tmpde->full_name,StrLen(tmpde->full_name))) {
|
||||
doc->cur_entry=doc_e;
|
||||
if (StrLen(tmpde->full_name)==StrLen(cur_entry))
|
||||
cur_entry=NULL;
|
||||
} else if (next_entry) {
|
||||
if (!StrNCmp(next_entry,
|
||||
tmpde->full_name,StrLen(tmpde->full_name))) {
|
||||
doc->cur_entry=doc_e;
|
||||
if (StrLen(tmpde->full_name)==StrLen(next_entry))
|
||||
cur_entry=NULL;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 FMDelUncollapsedLst(CFMUncollapsedLst *tmpc)
|
||||
{
|
||||
CFMUncollapsedLst *tmpc1;
|
||||
while (tmpc) {
|
||||
tmpc1=tmpc->next;
|
||||
Free(tmpc->name);
|
||||
Free(tmpc);
|
||||
tmpc=tmpc1;
|
||||
}
|
||||
}
|
||||
|
||||
CDirEntry *FMRebuildDocDrv(U8 drv_let,CDoc *doc,CDirEntry **_head,Bool init)
|
||||
{
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
U8 *st;
|
||||
tmpde=CAlloc(sizeof(CDirEntry));
|
||||
tmpde->full_name=MStrPrint("%C:/",drv_let);
|
||||
tmpde->attr=RS_ATTR_DIR;
|
||||
st=MStrPrint("%c:/*",drv_let);
|
||||
if (init)
|
||||
tmpde->sub=tmpde1=FilesFind(st,FUF_RECURSE);
|
||||
else
|
||||
tmpde1=NULL;
|
||||
Free(st);
|
||||
tmpde->user_data=DocPrint(doc,"$$TR,\"%s\",U=0x%X$$",tmpde->full_name,tmpde);
|
||||
tmpde->next=*_head;
|
||||
*_head=tmpde;
|
||||
DocPrint(doc,"\n$$ID,+2$$");
|
||||
DocBottom(doc);
|
||||
if (init) {
|
||||
DirFileDoc(doc,tmpde1);
|
||||
while (tmpde1) {
|
||||
tmpde1->parent=tmpde;
|
||||
tmpde1=tmpde1->next;
|
||||
}
|
||||
}
|
||||
DocPrint(doc,"$$ID,-2$$");
|
||||
return tmpde;
|
||||
}
|
||||
|
||||
#define DEF2_PROCESSED 1
|
||||
#define DEF2_NOT_INITIALIZED 2
|
||||
|
||||
U0 FMRebuildDoc(CDoc **_doc,CDirEntry **_head,I64 mode)
|
||||
{
|
||||
CDrv *dv;
|
||||
I64 i;
|
||||
CDoc *doc=*_doc,*doc2=sys_clip_doc,*parent_doc;
|
||||
CFMUncollapsedLst *tmpc=NULL;
|
||||
U8 *cur_entry=NULL,*next_entry=NULL;
|
||||
CDocEntry *doc_ce;
|
||||
CDirEntry *tmpde,*tmpde1,*cur_tree_entry;
|
||||
if (!doc)
|
||||
parent_doc=DocPut;
|
||||
else {
|
||||
parent_doc=doc->parent_doc;
|
||||
Fs->put_doc=Fs->display_doc=NULL;
|
||||
DocUnlock(doc);
|
||||
Refresh;
|
||||
DocLock(doc);
|
||||
cur_tree_entry=NULL;
|
||||
doc_ce=doc->cur_entry;
|
||||
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
cur_tree_entry=doc_ce->user_data;
|
||||
if (cur_tree_entry)
|
||||
cur_entry=StrNew(cur_tree_entry->full_name);
|
||||
tmpde=NULL;
|
||||
if (doc_ce!=doc)
|
||||
doc_ce=doc_ce->next;
|
||||
while (doc_ce!=doc) {
|
||||
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
tmpde=doc_ce->user_data;
|
||||
else
|
||||
tmpde=NULL;
|
||||
if (tmpde) {
|
||||
tmpde1=tmpde->parent;
|
||||
while (tmpde1) {
|
||||
if (tmpde1==cur_tree_entry) {
|
||||
tmpde=NULL;
|
||||
break;
|
||||
} else
|
||||
tmpde1=tmpde1->parent;
|
||||
}
|
||||
if (tmpde)
|
||||
break;
|
||||
}
|
||||
doc_ce=doc_ce->next;
|
||||
}
|
||||
if (tmpde)
|
||||
next_entry=StrNew(tmpde->full_name);
|
||||
|
||||
tmpc=FMCollectUncollapsedLst(doc);
|
||||
DocDel(doc);
|
||||
}
|
||||
if (*_head) {
|
||||
DirTreeDel(*_head);
|
||||
*_head=NULL;
|
||||
}
|
||||
doc=DocNew;
|
||||
doc->desc='FileMan';
|
||||
doc->parent_doc=parent_doc;
|
||||
doc->flags|=DOCF_FORM;
|
||||
switch (mode) {
|
||||
case FM_NORMAL:
|
||||
DocPrint(doc,"$$PURPLE$$File Manager\n\n"
|
||||
"$$LK,\"Click for Help\",A=\"FI:::/Doc/FileMgr.DD\"$$\n\n");
|
||||
break;
|
||||
case FM_PICK_FILE:
|
||||
DocPrint(doc,"$$PURPLE$$Pick file and press <ESC>\n\n");
|
||||
doc->flags|=DOCF_SIZE_MIN;
|
||||
break;
|
||||
case FM_PICK_DIR:
|
||||
DocPrint(doc,"$$PURPLE$$Pick directory and press <ESC>\n\n");
|
||||
doc->flags|=DOCF_SIZE_MIN;
|
||||
break;
|
||||
}
|
||||
DocPrint(doc,"$$LTBLUE$$");
|
||||
for (i=0;i<DRVS_NUM;i++) {
|
||||
dv=&blkdev.drvs[i];
|
||||
if (dv->bd->type==BDT_ATAPI) {
|
||||
if (dv->bd->flags&BDF_INITIALIZED)
|
||||
tmpde=FMRebuildDocDrv(Drv2Let(dv),doc,_head,TRUE);
|
||||
else {
|
||||
tmpde=FMRebuildDocDrv(Drv2Let(dv),doc,_head,FALSE);
|
||||
tmpde->user_data2|=DEF2_NOT_INITIALIZED;
|
||||
}
|
||||
} else if (dv->fs_type==FSt_REDSEA || dv->fs_type==FSt_FAT32)
|
||||
FMRebuildDocDrv(Drv2Let(dv),doc,_head,TRUE);
|
||||
}
|
||||
DocTop(doc);
|
||||
FMMarkUncollapsed(doc,tmpc,cur_entry,next_entry);
|
||||
DocCenter(doc);
|
||||
DocRst(doc2,TRUE);
|
||||
FMDelUncollapsedLst(tmpc);
|
||||
Free(cur_entry);
|
||||
Free(next_entry);
|
||||
*_doc=doc;
|
||||
DocLock(doc);
|
||||
Fs->put_doc=Fs->display_doc=doc;
|
||||
}
|
||||
|
||||
U0 FMRename(CDoc *doc)
|
||||
{
|
||||
CEdFileName fn;
|
||||
CDocEntry *doc_e=doc->cur_entry;
|
||||
CDirEntry *tmpde=NULL,*parent;
|
||||
if (doc_e->type_u8==DOCT_MENU_VAL) {
|
||||
tmpde=doc_e->user_data;
|
||||
if (parent=tmpde->parent) {
|
||||
Cd(parent->full_name);
|
||||
StrCpy(fn.name,tmpde->name);
|
||||
if (DocForm(&fn)) {
|
||||
Silent;
|
||||
Move(tmpde->name,fn.name);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
} else if (doc_e->type_u8==DOCT_TREE) {
|
||||
tmpde=doc_e->user_data;
|
||||
if (parent=tmpde->parent) {
|
||||
Cd(parent->full_name);
|
||||
StrCpy(fn.name,tmpde->name);
|
||||
if (DocForm(&fn)) {
|
||||
if (StrCmp(tmpde->name,fn.name)) {
|
||||
Silent;
|
||||
if (CopyTree(tmpde->name,fn.name))
|
||||
DelTree(tmpde->name);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 FMMkDir(CDoc *doc)
|
||||
{
|
||||
CEdFileName fn;
|
||||
CDocEntry *doc_e=doc->cur_entry;
|
||||
CDirEntry *tmpde=NULL,*parent;
|
||||
*fn.name=0;
|
||||
if (doc_e->type_u8==DOCT_MENU_VAL) {
|
||||
tmpde=doc_e->user_data;
|
||||
if (parent=tmpde->parent) {
|
||||
Cd(parent->full_name);
|
||||
if (DocForm(&fn)) {
|
||||
Silent;
|
||||
DirMk(fn.name);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
} else if (doc_e->type_u8==DOCT_TREE) {
|
||||
tmpde=doc_e->user_data;
|
||||
Cd(tmpde->full_name);
|
||||
if (DocForm(&fn)) {
|
||||
Silent;
|
||||
DirMk(fn.name);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 FMDelete(CDoc *doc)
|
||||
{
|
||||
U8 *st;
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
CDirEntry *tmpde;
|
||||
if (doc_ce->type_u8==DOCT_MENU_VAL) {
|
||||
tmpde=doc_ce->user_data;
|
||||
Silent;
|
||||
st=MStrPrint("Delete: %s",tmpde->full_name);
|
||||
if (PopUpCancelOk(st))
|
||||
Del(tmpde->full_name);
|
||||
Free(st);
|
||||
Silent(OFF);
|
||||
} else if (doc_ce->type_u8==DOCT_TREE) {
|
||||
tmpde=doc_ce->user_data;
|
||||
Silent;
|
||||
st=MStrPrint("Delete: %s",tmpde->full_name);
|
||||
if (PopUpCancelOk(st))
|
||||
DelTree(tmpde->full_name);
|
||||
Free(st);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
|
||||
U0 FMChgDsk(CDoc *doc)
|
||||
{
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
CDirEntry *tmpde;
|
||||
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
tmpde=doc_ce->user_data;
|
||||
else
|
||||
tmpde=NULL;
|
||||
if (tmpde) {
|
||||
while (tmpde->parent)
|
||||
tmpde=tmpde->parent;
|
||||
Silent;
|
||||
DskChg(*tmpde->full_name);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
|
||||
U0 FMMountISO(CDoc *doc)
|
||||
{
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
CDirEntry *tmpde;
|
||||
if (doc_ce->type_u8==DOCT_MENU_VAL && (tmpde=doc_ce->user_data))
|
||||
MountFile(tmpde->full_name);
|
||||
}
|
||||
|
||||
U0 FMUnmount(CDoc *doc)
|
||||
{
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
CDirEntry *tmpde;
|
||||
I64 drv_let;
|
||||
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
tmpde=doc_ce->user_data;
|
||||
else
|
||||
tmpde=NULL;
|
||||
if (tmpde) {
|
||||
while (tmpde->parent)
|
||||
tmpde=tmpde->parent;
|
||||
drv_let=*tmpde->full_name;
|
||||
if (Let2BlkDev(drv_let)!=Let2BlkDev(':'))
|
||||
Unmount(drv_let);
|
||||
}
|
||||
}
|
||||
|
||||
U0 FMFmtDrv(CDoc *doc)
|
||||
{
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
CDirEntry *tmpde;
|
||||
U8 *st=NULL;
|
||||
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
tmpde=doc_ce->user_data;
|
||||
else
|
||||
tmpde=NULL;
|
||||
if (tmpde) {
|
||||
while (tmpde->parent)
|
||||
tmpde=tmpde->parent;
|
||||
st=MStrPrint("Format Drive '%c'?\nAre You Sure?\n",*tmpde->full_name);
|
||||
if (PopUpCancelOk(st)) {
|
||||
Silent;
|
||||
Fmt(*tmpde->full_name,,FALSE);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
Free(st);
|
||||
}
|
||||
|
||||
U0 FMMakeISO(CDoc *doc)
|
||||
{
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
CDirEntry *tmpde;
|
||||
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
tmpde=doc_ce->user_data;
|
||||
else
|
||||
tmpde=NULL;
|
||||
if (tmpde) {
|
||||
if (doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
tmpde=tmpde->parent;
|
||||
if (tmpde && *tmpde->full_name) {
|
||||
Silent;
|
||||
RedSeaISO(,tmpde->full_name);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 FMBurnISO(CDoc *doc)
|
||||
{
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
CDirEntry *tmpde;
|
||||
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
tmpde=doc_ce->user_data;
|
||||
else
|
||||
tmpde=NULL;
|
||||
if (tmpde) {
|
||||
while (tmpde->parent)
|
||||
tmpde=tmpde->parent;
|
||||
Silent;
|
||||
DVDImageWrite(*tmpde->full_name);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
|
||||
U0 FMCopy(CDoc *doc)
|
||||
{
|
||||
CDoc *doc2=sys_clip_doc;
|
||||
U8 *st;
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_e;
|
||||
CDirEntry *tmpde,*tmpde1=NULL,*tmpde2;
|
||||
Bool unlock_doc2=DocLock(doc2);
|
||||
doc_e=doc2->head.next;
|
||||
|
||||
tmpde1=doc_ce->user_data;
|
||||
if (doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
tmpde1=tmpde1->parent;
|
||||
else if (doc_ce->type_u8!=DOCT_TREE)
|
||||
tmpde1=NULL;
|
||||
if (tmpde1) {
|
||||
while (doc_e!=doc2) {
|
||||
if (doc_e->type_u8==DOCT_MENU_VAL) {
|
||||
tmpde=doc_e->user_data;
|
||||
tmpde->user_data2|=DEF2_PROCESSED;
|
||||
tmpde2=tmpde->parent;
|
||||
if (!tmpde2 || !(tmpde2->user_data2&DEF2_PROCESSED)) {
|
||||
Silent;
|
||||
Copy(tmpde->full_name,tmpde1->full_name);
|
||||
Silent(OFF);
|
||||
}
|
||||
} else if (doc_e->type_u8==DOCT_TREE) {
|
||||
tmpde=doc_e->user_data;
|
||||
tmpde->user_data2|=DEF2_PROCESSED;
|
||||
tmpde2=tmpde->parent;
|
||||
if (!tmpde2 || !(tmpde2->user_data2&DEF2_PROCESSED)) {
|
||||
Silent;
|
||||
if (*tmpde1->name)
|
||||
st=MStrPrint("%s/%s",tmpde1->full_name,tmpde->name);
|
||||
else
|
||||
st=MStrPrint("%s%s",tmpde1->full_name,tmpde->name);
|
||||
CopyTree(tmpde->full_name,st);
|
||||
Free(st);
|
||||
Silent(OFF);
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
}
|
||||
if (unlock_doc2)
|
||||
DocUnlock(doc2);
|
||||
}
|
||||
|
||||
#define FMR_INCLUDE 0
|
||||
#define FMR_ADAM_INCLUDE 1
|
||||
#define FMR_DELETE 2
|
||||
#define FMR_RENAME 3
|
||||
#define FMR_MKDIR 4
|
||||
#define FMR_PLAIN 5
|
||||
#define FMR_PASTE 6
|
||||
#define FMR_CHG_DSK 7
|
||||
#define FMR_FORMAT 8
|
||||
#define FMR_MOUNT_REDSEA_ISO_C 9
|
||||
#define FMR_UNMOUNT 10
|
||||
#define FMR_MAKE_REDSEA_ISO_C 11
|
||||
#define FMR_BURN_ISO 12
|
||||
#define FMR_HELP 13
|
||||
|
||||
I64 PopUpFMRight(U8 *header=NULL,U8 *footer=NULL)
|
||||
{
|
||||
I64 i;
|
||||
CDoc *doc=DocNew;
|
||||
if (header) DocPrint(doc,"%s",header);
|
||||
DocPrint(doc,"$$CM+LX,1,1 $$$$BT,\"INCLUDE\",LE=FMR_INCLUDE$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"ADAMINCLUDE\",LE=FMR_ADAM_INCLUDE$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"DELETE\",LE=FMR_DELETE$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"RENAME\",LE=FMR_RENAME$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"MAKEDIRECTORY\",LE=FMR_MKDIR$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"PLAIN-TEXTEDIT\",LE=FMR_PLAIN$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"PASTECLIPFILES\",LE=FMR_PASTE$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"CHANGEDISK(MOUNTIT)\",LE=FMR_CHG_DSK$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"FORMAT\",LE=FMR_FORMAT$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"MOUNTISO.CFILE\","
|
||||
"LE=FMR_MOUNT_REDSEA_ISO_C$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"UNMOUNT\",LE=FMR_UNMOUNT$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"MAKEISO.C(CD/DVD)FILE\",LE=FMR_MAKE_REDSEA_ISO_C$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"BURNISO(CD/DVD)FILE\",LE=FMR_BURN_ISO$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"HELP\",LE=FMR_HELP$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"CANCEL\",LE=DOCM_CANCEL$$\n");
|
||||
if (footer) DocPrint(doc,"%s",footer);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
U0 FMRightClick()
|
||||
{
|
||||
switch (PopUpFMRight) {
|
||||
case FMR_INCLUDE:
|
||||
Msg(MSG_KEY_DOWN,0,0x3F0000003F);
|
||||
break;
|
||||
case FMR_ADAM_INCLUDE:
|
||||
Msg(MSG_KEY_DOWN,0,0x23F0000023F);
|
||||
break;
|
||||
case FMR_DELETE:
|
||||
Msg(MSG_KEY_DOWN,CH_CTRLY,0);
|
||||
break;
|
||||
case FMR_RENAME:
|
||||
Msg(MSG_KEY_DOWN,'r',0);
|
||||
break;
|
||||
case FMR_MKDIR:
|
||||
Msg(MSG_KEY_DOWN,'d',0);
|
||||
break;
|
||||
case FMR_PLAIN:
|
||||
Msg(MSG_KEY_DOWN,CH_SHIFT_SPACE,0);
|
||||
break;
|
||||
case FMR_PASTE:
|
||||
Msg(MSG_KEY_DOWN,0,SC_INS+SCF_SHIFT);
|
||||
break;
|
||||
case FMR_CHG_DSK:
|
||||
Msg(MSG_KEY_DOWN,'c',0);
|
||||
break;
|
||||
case FMR_FORMAT:
|
||||
Msg(MSG_KEY_DOWN,'f',0);
|
||||
break;
|
||||
case FMR_MOUNT_REDSEA_ISO_C:
|
||||
Msg(MSG_KEY_DOWN,'i',0);
|
||||
break;
|
||||
case FMR_UNMOUNT:
|
||||
Msg(MSG_KEY_DOWN,'u',0);
|
||||
break;
|
||||
case FMR_MAKE_REDSEA_ISO_C:
|
||||
Msg(MSG_KEY_DOWN,'m',0);
|
||||
break;
|
||||
case FMR_BURN_ISO:
|
||||
Msg(MSG_KEY_DOWN,'B',0);
|
||||
break;
|
||||
case FMR_HELP:
|
||||
Msg(MSG_KEY_DOWN,CH_CTRLM,0x43200000432);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
U8 *fm_ms_str=NULL;
|
||||
U0 (*fp_old_final_scrn_update)(CDC *dc);
|
||||
|
||||
U0 FMFinalScrnUpdate(CDC *dc)
|
||||
{
|
||||
if (fm_ms_str) {
|
||||
dc->color=LTRED;
|
||||
GrPrint(dc,ms.pos.x,ms.pos.y,"%s",fm_ms_str);
|
||||
}
|
||||
(*fp_old_final_scrn_update)(dc);
|
||||
}
|
||||
|
||||
public U8 *FileMgr(I64 mode=FM_NORMAL,CTask *mem_task=NULL)
|
||||
{//File manager. Also, used to choose files and dirs.
|
||||
CDirEntry *head=NULL,*tmpde,*tmpde1,*tmpde2;
|
||||
I64 sc,ch,arg1,arg2,msg_code;
|
||||
CDoc *doc=NULL,*old_put_doc=DocPut,*old_display_doc=DocDisplay;
|
||||
U8 *res=NULL,*st,*st2,*old_cur_dir=DirCur;
|
||||
CDocEntry *doc_ce=NULL,*doc_e;
|
||||
Bool okay;
|
||||
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
fp_old_final_scrn_update=gr.fp_final_scrn_update;
|
||||
MenuFilePush("::/Doc/FileMgrPullDown.DD");
|
||||
FMRebuildDoc(&doc,&head,mode);
|
||||
if (tmpde1=Cd2DirEntry(head,old_cur_dir))
|
||||
doc->cur_entry=tmpde1->user_data;
|
||||
while (tmpde1) {
|
||||
if (tmpde1->attr&RS_ATTR_DIR)
|
||||
tmpde1->user_data(CDocEntry *)->de_flags&=~DOCEF_CHECKED_COLLAPSED;
|
||||
tmpde1=tmpde1->parent;
|
||||
}
|
||||
do {
|
||||
DocUnlock(doc);
|
||||
do msg_code=GetMsg(&arg1,&arg2,
|
||||
1<<MSG_KEY_DOWN|1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|1<<MSG_MS_R_UP);
|
||||
while (Fs!=sys_focus_task);
|
||||
DocLock(doc);
|
||||
switch (msg_code) {
|
||||
case MSG_MS_R_UP:
|
||||
DocUnlock(doc);
|
||||
FMRightClick;
|
||||
DocLock(doc);
|
||||
break;
|
||||
case MSG_MS_L_DOWN:
|
||||
doc_ce=doc->cur_entry;
|
||||
fm_ms_str=doc_ce->tag;
|
||||
gr.fp_final_scrn_update=&FMFinalScrnUpdate;
|
||||
break;
|
||||
case MSG_MS_L_UP:
|
||||
if (doc_ce) {
|
||||
gr.fp_final_scrn_update=fp_old_final_scrn_update;
|
||||
if (WinCursorPosSet(Fs,arg1+Fs->pix_left+Fs->scroll_x,
|
||||
arg2+Fs->pix_top+Fs->scroll_y,TRUE)) {
|
||||
doc_e=doc->cur_entry;
|
||||
if (doc_e!=doc_ce) {
|
||||
st2=NULL;
|
||||
if (doc_e->type_u8==DOCT_MENU_VAL) {
|
||||
tmpde1=doc_e->user_data;
|
||||
if (tmpde1=tmpde1->parent)
|
||||
st2=StrNew(tmpde1->full_name);
|
||||
} else if (doc_e->type_u8==DOCT_TREE) {
|
||||
tmpde1=doc_e->user_data;
|
||||
st2=StrNew(tmpde1->full_name);
|
||||
}
|
||||
if (st2 && doc_ce->type_u8==DOCT_MENU_VAL) {
|
||||
tmpde=doc_ce->user_data;
|
||||
Silent;
|
||||
Move(tmpde->full_name,st2);
|
||||
Silent(OFF);
|
||||
FMRebuildDoc(&doc,&head,mode);
|
||||
} else if (st2 && doc_ce->type_u8==DOCT_TREE) {
|
||||
tmpde=doc_ce->user_data;
|
||||
okay=TRUE;
|
||||
tmpde2=tmpde1;
|
||||
while (tmpde2) {
|
||||
if (tmpde2!=tmpde)
|
||||
tmpde2=tmpde2->parent;
|
||||
else {
|
||||
okay=FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (okay) {
|
||||
if (*tmpde1->name)
|
||||
st=MStrPrint("%s/%s",tmpde1->full_name,tmpde->name);
|
||||
else
|
||||
st=MStrPrint("%s%s",tmpde1->full_name,tmpde->name);
|
||||
if (StrCmp(tmpde->full_name,st)) {
|
||||
Silent;
|
||||
CopyTree(tmpde->full_name,st);
|
||||
DelTree(tmpde->full_name);
|
||||
Silent(OFF);
|
||||
FMRebuildDoc(&doc,&head,mode);
|
||||
}
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
Free(st2);
|
||||
FlushMsgs;
|
||||
} else
|
||||
if (doc_e->type_u8==DOCT_MENU_VAL) {
|
||||
DocUnlock(doc);
|
||||
Ed(doc_e->user_data(CDirEntry *)->full_name);
|
||||
DocLock(doc);
|
||||
}
|
||||
doc_ce=NULL;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MSG_KEY_DOWN:
|
||||
doc_ce=NULL;
|
||||
ch=arg1; sc=arg2;
|
||||
if (sc.u8[0]==SC_DELETE && !(sc&(SCF_SHIFT|SCF_CTRL)))
|
||||
ch=CH_CTRLY;
|
||||
if (ch && sc&SCF_ALT) goto fm_regular_key;
|
||||
switch (ch) {
|
||||
case '\n':
|
||||
DocUnlock(doc);
|
||||
FMRightClick;
|
||||
DocLock(doc);
|
||||
break;
|
||||
start:
|
||||
DocUnlock(doc);
|
||||
case CH_CTRLV:
|
||||
FMCopy(doc);
|
||||
break;
|
||||
case 'r':
|
||||
FMRename(doc);
|
||||
break;
|
||||
case 'd':
|
||||
FMMkDir(doc);
|
||||
break;
|
||||
case CH_CTRLY:
|
||||
FMDelete(doc);
|
||||
break;
|
||||
case 'c':
|
||||
FMChgDsk(doc);
|
||||
break;
|
||||
case 'i':
|
||||
FMMountISO(doc);
|
||||
break;
|
||||
case 'u':
|
||||
FMUnmount(doc);
|
||||
break;
|
||||
case 'm':
|
||||
FMMakeISO(doc);
|
||||
break;
|
||||
case 'B':
|
||||
FMBurnISO(doc);
|
||||
break;
|
||||
case 'f':
|
||||
FMFmtDrv(doc);
|
||||
break;
|
||||
end:
|
||||
FMRebuildDoc(&doc,&head,mode);
|
||||
break;
|
||||
case CH_SHIFT_ESC:
|
||||
break;
|
||||
case CH_SPACE:
|
||||
if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
|
||||
DocUnlock(doc);
|
||||
Ed(doc->cur_entry->user_data(CDirEntry *)->full_name);
|
||||
DocLock(doc);
|
||||
} else
|
||||
goto fm_regular_key;
|
||||
break;
|
||||
case CH_SHIFT_SPACE:
|
||||
if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
|
||||
DocUnlock(doc);
|
||||
Plain(doc->cur_entry->user_data(CDirEntry *)->full_name);
|
||||
DocLock(doc);
|
||||
} else
|
||||
goto fm_regular_key;
|
||||
break;
|
||||
case CH_ESC:
|
||||
doc_ce=doc->cur_entry;
|
||||
tmpde=doc_ce->user_data;
|
||||
if (mode==FM_PICK_FILE && doc_ce->type_u8==DOCT_MENU_VAL)
|
||||
res=StrNew(tmpde->full_name,mem_task);
|
||||
else if (mode==FM_PICK_DIR) {
|
||||
if (doc_ce->type_u8==DOCT_TREE)
|
||||
res=StrNew(tmpde->full_name,mem_task);
|
||||
else if (doc_ce->type_u8==DOCT_MENU_VAL &&
|
||||
(tmpde=tmpde->parent))
|
||||
res=StrNew(tmpde->full_name,mem_task);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (sc.u8[0]==SC_INS && sc&SCF_SHIFT && !(sc&SCF_CTRL)) {
|
||||
FMCopy(doc);
|
||||
FMRebuildDoc(&doc,&head,mode);
|
||||
} else if (sc.u8[0]==SC_F5) {
|
||||
if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
|
||||
tmpde=doc->cur_entry->user_data;
|
||||
DocUnlock(doc);
|
||||
if (sc&SCF_SHIFT)
|
||||
AdamFile(tmpde->full_name);
|
||||
else
|
||||
PopUpFile(tmpde->full_name);
|
||||
DocLock(doc);
|
||||
}
|
||||
} else {
|
||||
fm_regular_key:
|
||||
DocUnlock(doc);
|
||||
PutKey(ch,sc);
|
||||
DocLock(doc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
|
||||
gr.fp_final_scrn_update=fp_old_final_scrn_update;
|
||||
Fs->put_doc =old_put_doc;
|
||||
Fs->display_doc=old_display_doc;
|
||||
SettingsPop;
|
||||
DocDel(doc);
|
||||
DirTreeDel(head);
|
||||
Cd(old_cur_dir);
|
||||
Free(old_cur_dir);
|
||||
if (mode!=FM_NORMAL && !res)
|
||||
res=StrNew("",mem_task);
|
||||
MenuPop;
|
||||
return res;
|
||||
}
|
||||
8
temple-src/Adam/ABlkDev/MakeABlkDev.HC
Executable file
8
temple-src/Adam/ABlkDev/MakeABlkDev.HC
Executable file
@ -0,0 +1,8 @@
|
||||
Cd(__DIR__);;
|
||||
#include "ADskA"
|
||||
#include "ADskB"
|
||||
#include "DskPrt"
|
||||
#include "Mount"
|
||||
#include "DskChk"
|
||||
#include "FileMgr"
|
||||
Cd("..");;
|
||||
159
temple-src/Adam/ABlkDev/Mount.HC
Executable file
159
temple-src/Adam/ABlkDev/Mount.HC
Executable file
@ -0,0 +1,159 @@
|
||||
#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);"
|
||||
U8 Mount2(U8 boot_drv_let,CDoc *_doc,Bool _caller_is_prtdsk)
|
||||
{//If _doc, called by $LK,"::/Kernel/KCfg.HC"$ else called by $LK,"Mount",A="MN:Mount"$().
|
||||
I64 cnt,total=0,num_hints,drv_let,type,unit,prt_num;
|
||||
U8 blks_buf[STR_LEN],addr_buf[STR_LEN],base0_buf[STR_LEN],base1_buf[STR_LEN],
|
||||
*filename=NULL,*filename2=NULL,res=0;
|
||||
CATARep *head=NULL,*tmpha;
|
||||
Bool whole_drv,make_free;
|
||||
CDoc *doc;
|
||||
if (boot_drv_let)
|
||||
boot_drv_let=Let2Let(boot_drv_let);
|
||||
do {
|
||||
cnt=0;
|
||||
if (!_doc)
|
||||
DrvRep;
|
||||
"\n****** Mount Drives ******\n"
|
||||
"$$GREEN$$A$$FG$$-$$GREEN$$B$$FG$$ are RAM drives.\n"
|
||||
"$$GREEN$$C$$FG$$-$$GREEN$$L$$FG$$ are ATA hard drives.\n"
|
||||
"$$GREEN$$M$$FG$$-$$GREEN$$P$$FG$$ are ISO file read drives.\n"
|
||||
"$$GREEN$$Q$$FG$$-$$GREEN$$S$$FG$$ are ISO file write drives.\n"
|
||||
"$$GREEN$$T$$FG$$-$$GREEN$$Z$$FG$$ are ATAPI CD/DVD drives.\n"
|
||||
"\nDrive Letter ($$PURPLE$$<ENTER>$$FG$$ to exit):";
|
||||
drv_let=Let2Let(GetChar);
|
||||
'\n';
|
||||
if (type=Let2BlkDevType(drv_let)) {
|
||||
whole_drv=FALSE;
|
||||
if (_doc) { //Called by $LK,"::/Kernel/KCfg.HC"$
|
||||
doc=_doc;
|
||||
make_free=FALSE;
|
||||
} else { //Called by $LK,"Mount",A="MN:Mount"$()
|
||||
doc=DocNew;
|
||||
DocPrint(doc,"CBlkDev *bd;\n");
|
||||
make_free=TRUE;
|
||||
}
|
||||
unit=0;
|
||||
prt_num=I64_MIN;
|
||||
switch (type) {
|
||||
case BDT_RAM:
|
||||
"Addr of RAM disk ($$PURPLE$$<ENTER>$$FG$$ to MAlloc):";
|
||||
GetS(addr_buf,STR_LEN);
|
||||
case BDT_ISO_FILE_WRITE:
|
||||
"Blks of 512 bytes:";
|
||||
GetS(blks_buf,STR_LEN);
|
||||
break;
|
||||
case BDT_ISO_FILE_READ:
|
||||
filename=GetStr("File Name:");
|
||||
break;
|
||||
case BDT_ATA:
|
||||
prt_num=GetI64("Partition Num (Default=All):",prt_num);
|
||||
case BDT_ATAPI:
|
||||
num_hints=ATARep(,,&head);
|
||||
if (type==BDT_ATAPI && boot_drv_let)
|
||||
"<ENTER> to use booted CD/DVD\n"; //Only $LK,"::/Kernel/KCfg.HC"$
|
||||
do {
|
||||
if (num_hints)
|
||||
"Enter dev number or\nport with $$PURPLE$$0x$$FG$$ prefix.\n"
|
||||
"I/O Port Base0:\n";
|
||||
else
|
||||
"Include $$PURPLE$$0x$$FG$$ prefix.\nI/O Port Base0:\n";
|
||||
GetS(base0_buf,STR_LEN);
|
||||
} while (!Str2I64(base0_buf) && (type!=BDT_ATAPI || !boot_drv_let));
|
||||
if (1<=Str2I64(base0_buf)<=num_hints) {
|
||||
tmpha=ATARepFind(head,Str2I64(base0_buf));
|
||||
StrPrint(base0_buf,"0x%X",tmpha->base0);
|
||||
StrPrint(base1_buf,"0x%X",tmpha->base1);
|
||||
unit=tmpha->unit;
|
||||
} else if (type!=BDT_ATAPI || *base0_buf) {
|
||||
if (type==BDT_ATAPI)
|
||||
StrCpy(base1_buf,"0");
|
||||
else
|
||||
do {
|
||||
"I/O Port Base1:\n";
|
||||
GetS(base1_buf,STR_LEN);
|
||||
} while (!Str2I64(base1_buf));
|
||||
do {
|
||||
"\t$$PURPLE$$0$$FG$$=Master\n\t$$PURPLE$$1$$FG$$=Slave\nUnit:";
|
||||
unit=GetChar-'0';
|
||||
} while (!(0<=unit<=1));
|
||||
'\n';
|
||||
}
|
||||
LinkedLstDel(head);
|
||||
break;
|
||||
}
|
||||
DocPrint(doc,"bd=BlkDevNextFreeSlot(\'%C\',%d);bd->unit=%d;\n",
|
||||
drv_let,type,unit);
|
||||
switch (type) {
|
||||
case BDT_RAM:
|
||||
if (!*addr_buf) StrCpy(addr_buf,"0");
|
||||
DocPrint(doc,"bd->RAM_dsk=%s;\n",addr_buf);
|
||||
case BDT_ISO_FILE_WRITE:
|
||||
if (!*blks_buf) StrCpy(blks_buf,"0");
|
||||
DocPrint(doc,"bd->max_blk=(%s)-1;\n",blks_buf);
|
||||
DocPrint(doc,"bd->drv_offset=19<<2+"
|
||||
"(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;\n");
|
||||
break;
|
||||
case BDT_ISO_FILE_READ:
|
||||
filename2=FileNameAbs(filename);
|
||||
DocPrint(doc,"bd->file_dsk_name=AStrNew(\"%s\");\n",filename2);
|
||||
DocPrint(doc,"bd->drv_offset=19<<2+"
|
||||
"(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;\n");
|
||||
break;
|
||||
case BDT_ATA:
|
||||
case BDT_ATAPI:
|
||||
if (type==BDT_ATAPI && !*base0_buf) {
|
||||
DocPrint(doc,"GetBaseUnit(bd);\n"); //Only $LK,"::/Kernel/KCfg.HC"$
|
||||
if (drv_let==boot_drv_let)
|
||||
make_free=TRUE;
|
||||
} else
|
||||
DocPrint(doc,"bd->base0=%s;bd->base1=%s;\n",base0_buf,base1_buf);
|
||||
if (type==BDT_ATA && _caller_is_prtdsk) {
|
||||
"\nReformat WHOLE drive!";
|
||||
whole_drv=YorN;
|
||||
}
|
||||
break;
|
||||
}
|
||||
DocPrint(doc,"BlkDevAdd(bd,%d,%d,%d);\n",prt_num,whole_drv,make_free);
|
||||
if (_doc) //Called by $LK,"::/Kernel/KCfg.HC"$
|
||||
cnt++;
|
||||
else { //Called by $LK,"Mount",A="MN:Mount"$()
|
||||
if ((cnt=ExeDoc(doc)) && whole_drv) {
|
||||
if (_caller_is_prtdsk) {
|
||||
res=drv_let;
|
||||
DskPrt(drv_let,1.0); //First mount whole drive.
|
||||
} else
|
||||
DskPrt(drv_let);
|
||||
}
|
||||
DocDel(doc);
|
||||
}
|
||||
}
|
||||
total+=cnt;
|
||||
} while (cnt && !_caller_is_prtdsk ||
|
||||
!total && _doc); //At least 1 if Called by $LK,"::/Kernel/KCfg.HC"$
|
||||
Free(filename);
|
||||
Free(filename2);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 Mount(Bool caller_is_prtdsk=FALSE)
|
||||
{//Mount drives. Called from $LK,"DskPrt(Mount)",A="FF:::/Adam/ABlkDev/DskPrt.HC,Mount("$.
|
||||
return Mount2(0,NULL,caller_is_prtdsk);
|
||||
}
|
||||
|
||||
public U0 Unmount(U8 drv_let=0)
|
||||
{//Unmount drive(s).
|
||||
BlkDevDel(Let2BlkDev(drv_let));
|
||||
}
|
||||
|
||||
public U8 MountFile(U8 *filename)
|
||||
{//Mount ISO.C file.
|
||||
U8 *filename2=ExtDft(filename,"ISO.C"),*filename3=FileNameAbs(filename2);
|
||||
CDrv *dv=DrvMakeFreeSlot(DrvNextFreeLet('M')); //First $LK,"BDT_ISO_FILE_READ",A="MN:BDT_ISO_FILE_READ"$
|
||||
CBlkDev *bd=BlkDevNextFreeSlot(dv->drv_let,BDT_ISO_FILE_READ);
|
||||
bd->drv_offset=19<<2+(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;
|
||||
bd->file_dsk_name=AStrNew(filename3);
|
||||
BlkDevAdd(bd,,TRUE,TRUE);
|
||||
Free(filename3);
|
||||
Free(filename2);
|
||||
return dv->drv_let;
|
||||
}
|
||||
270
temple-src/Adam/ADbg.HC
Executable file
270
temple-src/Adam/ADbg.HC
Executable file
@ -0,0 +1,270 @@
|
||||
#help_index "Debugging/Dump"
|
||||
Bool ClassRep2(CDoc *doc,U8 *_d,U8 *class_name=lastclass,
|
||||
I64 depth,I64 max_depth,Bool dynamic,I64 types=HTT_CLASS,I64 offset=0)
|
||||
{//See $LK,"::/Demo/LastClass.HC"$.
|
||||
I64 i,j,stars,*ptr;
|
||||
CMemberLst *ml;
|
||||
CDocEntry *doc_e;
|
||||
Bool unlock;
|
||||
CHashClass *tmpc,*tmpc2;
|
||||
if (depth>=max_depth) return TRUE;
|
||||
if (!(tmpc=HashFind(class_name,Fs->hash_table,types))) {
|
||||
DocPrint(doc,"Class Not Found.\n");
|
||||
return FALSE;
|
||||
}
|
||||
if (!ChkPtr(_d) || !ChkPtr(_d(U8 *)+tmpc->size)) {
|
||||
DocPrint(doc,"Bad Ptr:%016X\n",_d);
|
||||
return FALSE;
|
||||
}
|
||||
if (tmpc->base_class && !ClassRep2(doc,_d,tmpc->base_class->str,
|
||||
depth,max_depth,dynamic,types,offset))
|
||||
return FALSE;
|
||||
unlock=DocLock(doc);
|
||||
DocPrint(doc,"Class:\"%s\"\n",class_name);
|
||||
ml=tmpc->member_lst_and_root;
|
||||
while (ml) {
|
||||
tmpc2=ml->member_class;
|
||||
ptr=_d(U8 *)+ml->offset;
|
||||
DocPrint(doc,"%08X ",ptr(U8 *)+offset);
|
||||
stars=tmpc2->ptr_stars_cnt;
|
||||
tmpc2=OptClassFwd(tmpc2);
|
||||
tmpc2-=tmpc2->ptr_stars_cnt;
|
||||
if (tmpc2->type & HTT_INTERNAL_TYPE) {
|
||||
DocPrint(doc,"$$GREEN$$%-20ts:$$FG$$",ml->str);
|
||||
if (stars==1 && (tmpc2->raw_type==RT_I8 || tmpc2->raw_type==RT_U8)) {
|
||||
ptr=*ptr;
|
||||
if (ChkPtr(ptr)) {
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$$\n");
|
||||
doc_e->data=ptr;
|
||||
DocDataFmt(doc,doc_e);
|
||||
} else
|
||||
DocPrint(doc,"%40ts\n",ptr);
|
||||
}
|
||||
} else if (!stars) {
|
||||
j=MinI64(ml->dim.total_cnt,32);
|
||||
if (tmpc2->raw_type==RT_I8 || tmpc2->raw_type==RT_U8) {
|
||||
if (j==1) {
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U8,A=\"%%c\"$$\n");
|
||||
doc_e->data=ptr;
|
||||
} else
|
||||
DocPrint(doc,"%c\n",*ptr(U8 *));
|
||||
} else {
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$$\n");
|
||||
doc_e->data=ptr;
|
||||
DocDataFmt(doc,doc_e);
|
||||
} else
|
||||
DocPrint(doc,"%40ts\n",ptr);
|
||||
}
|
||||
}
|
||||
for (i=0;i<j;i++) {
|
||||
switch (tmpc2->raw_type) {
|
||||
case RT_I0:
|
||||
case RT_U0:
|
||||
break;
|
||||
case RT_I8:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=I8,A=\"%%02X\"$$ ");
|
||||
doc_e->data=ptr(I8 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%02X ",*ptr(I8 *)++);
|
||||
break;
|
||||
case RT_U8:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U8,A=\"%%02X\"$$ ");
|
||||
doc_e->data=ptr(U8 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%02X ",*ptr(U8 *)++);
|
||||
break;
|
||||
case RT_I16:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=I16,A=\"%%04X\"$$ ");
|
||||
doc_e->data=ptr(I16 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%04X ",*ptr(I16 *)++);
|
||||
break;
|
||||
case RT_U16:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U16,A=\"%%04X\"$$ ");
|
||||
doc_e->data=ptr(U16 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%04X ",*ptr(U16 *)++);
|
||||
break;
|
||||
case RT_I32:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=I32,A=\"%%08X\"$$ ");
|
||||
doc_e->data=ptr(I32 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%08X ",*ptr(I32 *)++);
|
||||
break;
|
||||
case RT_U32:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U32,A=\"%%08X\"$$ ");
|
||||
doc_e->data=ptr(U32 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%08X ",*ptr(U32 *)++);
|
||||
break;
|
||||
case RT_U64:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U64,A=\"%%08X\"$$ ");
|
||||
doc_e->data=ptr(U64 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%08X ",*ptr(U64 *)++);
|
||||
break;
|
||||
case RT_F64:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=F64,A=\"%%16g\"$$ ");
|
||||
doc_e->data=ptr(F64 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%16g ",*ptr(I64 *)++);
|
||||
break;
|
||||
default:
|
||||
if (dynamic) {
|
||||
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,A=\"%%016X\"$$ ");
|
||||
doc_e->data=ptr(I64 *)++;
|
||||
} else
|
||||
DocPrint(doc,"%016X ",*ptr(I64 *)++);
|
||||
}
|
||||
if (dynamic)
|
||||
DocDataFmt(doc,doc_e);
|
||||
}
|
||||
if (j<ml->dim.total_cnt)
|
||||
DocPrint(doc,"...");
|
||||
} else
|
||||
DocPrint(doc,"%016X",*ptr);
|
||||
DocPrint(doc,"\n");
|
||||
} else {
|
||||
if (depth<2) {
|
||||
if (stars==1 && !ChkPtr(*ptr))
|
||||
DocPrint(doc,"%-20ts:%016X\n",ml->str,*ptr);
|
||||
else {
|
||||
DocPrint(doc,"$$TR,\"%s\"$$\n",ml->str);
|
||||
DocPrint(doc,"$$ID,2$$");
|
||||
if (!stars)
|
||||
ClassRep2(doc,ptr,tmpc2->str,depth+1,max_depth,dynamic);
|
||||
else if (stars==1)
|
||||
ClassRep2(doc,*ptr,tmpc2->str,depth+1,max_depth,dynamic);
|
||||
DocPrint(doc,"$$ID,-2$$");
|
||||
}
|
||||
} else
|
||||
DocPrint(doc,"%-20ts\n",ml->str);
|
||||
}
|
||||
ml=ml->next;
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public U0 ClassRep(U8 *_d,U8 *class_name=lastclass,
|
||||
I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
|
||||
{//Displays members of a record by using the compiler's info.
|
||||
CDoc *doc;
|
||||
if (IsRaw)
|
||||
doc=DocNew;
|
||||
else {
|
||||
DocMax;
|
||||
doc=DocPut;
|
||||
}
|
||||
if (fun)
|
||||
ClassRep2(doc,_d,class_name,0,max_depth,FALSE,HTT_FUN,offset);
|
||||
else
|
||||
ClassRep2(doc,_d,class_name,0,max_depth,FALSE,HTT_CLASS,offset);
|
||||
DocPrint(doc,"\n");
|
||||
DocRecalc(doc);
|
||||
if (IsRaw) {
|
||||
DocDump(doc,100000);
|
||||
DocDel(doc);
|
||||
}
|
||||
}
|
||||
|
||||
public U0 ClassRepD(U8 *_d,U8 *class_name=lastclass,
|
||||
I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
|
||||
{//Dynamic ClassRep. Uses hex_ed widgit for live changes.
|
||||
CDoc *doc;
|
||||
if (IsRaw)
|
||||
doc=DocNew;
|
||||
else {
|
||||
DocMax;
|
||||
doc=DocPut;
|
||||
}
|
||||
if (fun)
|
||||
ClassRep2(doc,_d,class_name,0,max_depth,TRUE,HTT_FUN,offset);
|
||||
else
|
||||
ClassRep2(doc,_d,class_name,0,max_depth,TRUE,HTT_CLASS,offset);
|
||||
DocPrint(doc,"\n");
|
||||
DocRecalc(doc);
|
||||
if (IsRaw) {
|
||||
DocDump(doc,100000);
|
||||
DocDel(doc);
|
||||
}
|
||||
}
|
||||
|
||||
U0 UpdateRegVarImg(CHashFun *tmpf,U8 *_b,CTask *task)
|
||||
{
|
||||
CMemberLst *ml;
|
||||
CHashClass *tmpc;
|
||||
ml=tmpf->member_lst_and_root;
|
||||
while (ml) {
|
||||
if (ml->reg!=REG_NONE) {
|
||||
tmpc=OptClassFwd(ml->member_class);
|
||||
MemCpy(_b+ml->offset,TaskRegAddr(task,ml->reg),tmpc->size);
|
||||
}
|
||||
ml=ml->next;
|
||||
}
|
||||
}
|
||||
|
||||
public U0 FunRep(U8 *st,U8 *rbp=NULL,I64 max_depth=2,CTask *task=NULL)
|
||||
{//Shows names and vals of a fun's local vars using compiler's info.
|
||||
I64 size;
|
||||
U8 *img;
|
||||
CHashFun *tmpf=HashFind(st,Fs->hash_table,HTT_FUN);
|
||||
CMemberLst *tmpm;
|
||||
if (tmpf) {
|
||||
if (rbp) {
|
||||
if (task) {
|
||||
//tmpf->size is negative.It's the bottom
|
||||
//of the fun local var space relative to RBP .
|
||||
size=tmpf->arg_cnt*8-tmpf->size+16;
|
||||
|
||||
img=MAlloc(size);
|
||||
MemCpy(img,rbp+tmpf->size,size);
|
||||
UpdateRegVarImg(tmpf,img-tmpf->size,task);
|
||||
ClassRep(img-tmpf->size,st,max_depth,TRUE,rbp-img+tmpf->size);
|
||||
Free(img);
|
||||
} else
|
||||
ClassRep(rbp,st,max_depth,TRUE);
|
||||
} else {
|
||||
tmpm=tmpf->member_lst_and_root;
|
||||
while (tmpm) {
|
||||
if (0<=tmpm->reg<REG_REGS_NUM)
|
||||
"%08Z %s\n",tmpm->reg,"ST_U64_REGS",tmpm->str;
|
||||
else
|
||||
"%08tX %s\n",tmpm->offset,tmpm->str;
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
"%08tX Stk Size\n",tmpf->size;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "Debugging/Unassemble"
|
||||
public U0 Uf(U8 *st)
|
||||
{//Unassembles a named fun
|
||||
I64 i;
|
||||
CHashSrcSym *tmpf;
|
||||
CDbgInfo *dbg_info;
|
||||
if (tmpf=HashFind(st,Fs->hash_table,HTT_FUN|HTT_EXPORT_SYS_SYM)) {
|
||||
if (tmpf->type&HTT_FUN)
|
||||
FunRep(st);
|
||||
if (dbg_info=tmpf->dbg_info) {
|
||||
i=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
|
||||
-dbg_info->body[0];
|
||||
Un(dbg_info->body[0],i);
|
||||
"Code Size:%04X\n",i;
|
||||
} else
|
||||
U(HashVal(tmpf));
|
||||
}
|
||||
}
|
||||
38
temple-src/Adam/ADefine.HC
Executable file
38
temple-src/Adam/ADefine.HC
Executable file
@ -0,0 +1,38 @@
|
||||
#help_index "Define;Char/Define"
|
||||
|
||||
U0 LoadDocDefines()
|
||||
{
|
||||
CBinFile *bfh=mem_boot_base-sizeof(CBinFile);
|
||||
|
||||
DefinePrint("DD_OS_NAME_VERSION","TempleOS V%0.2f",sys_os_version);
|
||||
DefinePrint("DD_TEMPLEOS_AGE","%0.1f",
|
||||
(Now-Str2Date("8/1/2003"))/ToF64(1<<32)/CDATE_YEAR_DAYS);
|
||||
|
||||
DefinePrint("DD_KERNEL","%08X",bfh);
|
||||
bfh(I64)+=bfh->file_size-1;
|
||||
DefinePrint("DD_KERNEL_END","%08X",bfh);
|
||||
|
||||
//$LK,"DD_BOOT_HIGH_LOC_DVD",A="FF:::/Adam/Opt/Boot/BootDVD.HC,DD_BOOT_HIGH_LOC_DVD"$
|
||||
|
||||
$TR,"LineRep"$
|
||||
$ID,2$DefinePrint("DD_TEMPLEOS_LOC","80,849");
|
||||
$ID,-2$
|
||||
DefinePrint("DD_MP_VECT","%08X",MP_VECT_ADDR);
|
||||
DefinePrint("DD_MP_VECT_END","%08X",
|
||||
MP_VECT_ADDR+COREAP_16BIT_INIT_END-COREAP_16BIT_INIT-1);
|
||||
|
||||
DefinePrint("DD_SYS_FIXED_AREA_BASE","%08X",SYS_FIXED_AREA);
|
||||
DefinePrint("DD_SYS_FIXED_AREA_END","%08X",
|
||||
SYS_FIXED_AREA+sizeof(CSysFixedArea)-1);
|
||||
DefinePrint("DD_MEM_HEAP_BASE","%08X",mem_heap_base);
|
||||
DefinePrint("DD_MEM_HEAP_LIMIT","%08X",mem_heap_limit);
|
||||
DefinePrint("DD_MEM_MIN_MEG","%dMeg",MEM_MIN_MEG);
|
||||
DefinePrint("DD_UNCACHED_ALIAS","%010X",dev.uncached_alias);
|
||||
DefinePrint("DD_PHYSICAL_SPACE_END","%010X",
|
||||
mem_physical_space-1);
|
||||
DefinePrint("DD_MAPPED_SPACE_END","%010X",
|
||||
mem_mapped_space-1);
|
||||
DefinePrint("DD_JIFFY_HZ","%dHz",JIFFY_FREQ);
|
||||
}
|
||||
|
||||
LoadDocDefines;
|
||||
95
temple-src/Adam/AExts.HC
Executable file
95
temple-src/Adam/AExts.HC
Executable file
@ -0,0 +1,95 @@
|
||||
extern U0 ACDDef(I64 n,CTask *parent=NULL);
|
||||
extern U0 ACDDefsPut(CDoc *doc=NULL,U8 *st,I64 num=-1);
|
||||
extern U0 ACDFillin(I64 n);
|
||||
extern U0 ACFillIn(I64 n);
|
||||
extern U0 ACMan(I64 n,CTask *parent_task=NULL);
|
||||
extern I64 AdamFile(U8 *filename,Bool warn_ext=TRUE);
|
||||
extern Bool AutoComplete(Bool val=OFF);
|
||||
extern U0 ClipDel();
|
||||
extern CCtrl *CtrlFindUnique(CTask *haystack_task,I64 needle_type);
|
||||
extern Bool CtrlInside(CCtrl *c,I64 x,I64 y);
|
||||
extern U8 *DC2Sprite(CDC *tmpb);
|
||||
extern U0 DocBinDel(CDoc *doc,CDocBin *b);
|
||||
extern U0 DocBinsValidate(CDoc *doc);
|
||||
extern U0 DocBottom(CDoc *doc=NULL);
|
||||
extern U0 DocCenter(CDoc *doc=NULL,I64 recalc_flags=RECALCt_NORMAL);
|
||||
extern U0 DocClear(CDoc *doc=NULL,Bool clear_holds=FALSE);
|
||||
extern Bool DocCursor(Bool show=OFF,CDoc *doc=NULL);
|
||||
extern U0 DocD(U8 *buf,I64 cnt=0x80);
|
||||
extern U0 DocDataFmt(CDoc *doc,CDocEntry *doc_e,I64 d=DOCM_CANCEL);
|
||||
extern U0 DocDel(CDoc *doc);
|
||||
extern CDoc *DocDisplay(CTask *task=NULL);
|
||||
extern U0 DocDump(CDoc *doc,I64 uS_delay=0);
|
||||
extern CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e);
|
||||
extern U0 DocEntryDel(CDoc *doc,CDocEntry *doc_e);
|
||||
extern Bool DocForm(U8 *_d,U8 *class_name=lastclass,
|
||||
I64 dof_flags=0,U8 *header=NULL,U8 *footer=NULL);
|
||||
extern U0 DocHelpIdx(CDoc *doc,U8 *idx);
|
||||
extern Bool DocHighlightCursor(Bool show=OFF,CDoc *doc=NULL);
|
||||
extern U0 DocInsDoc(CDoc *doc=NULL,CDoc *doc2);
|
||||
extern U0 DocInsEntry(CDoc *doc,CDocEntry *doc_e);
|
||||
extern Bool DocLock(CDoc *doc);
|
||||
extern I64 DocMax(I64 i=I64_MAX);
|
||||
extern CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL);
|
||||
extern CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...);
|
||||
extern CDoc *DocPut(CTask *task=NULL);
|
||||
extern CDoc *DocRead(U8 *name=NULL,I64 flags=0);
|
||||
extern Bool DocRecalc(CDoc *doc,I64 recalc_flags=RECALCt_NORMAL);
|
||||
extern U0 DocRst(CDoc *doc,Bool is_old);
|
||||
extern CDocEntry *DocSprite(CDoc *doc=NULL,U8 *elems,U8 *fmt=NULL);
|
||||
extern U0 DocTop(CDoc *doc=NULL);
|
||||
extern Bool DocUnlock(CDoc *doc);
|
||||
extern U0 DocUpdateTaskDocs(CTask *task);
|
||||
extern U0 DrawCtrls(CTask *task);
|
||||
extern Bool Ed(U8 *link_st,I64 edf_dof_flags=0);
|
||||
extern U0 EdCodeTools(CDoc *doc);
|
||||
extern U8 *EdSprite(I64 bin_num);
|
||||
extern I64 ExeDoc(CDoc *doc,I64 ccf_flags=0);
|
||||
extern I64 FindWiz();
|
||||
extern I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=I64_MIN,I64 hi=I64_MAX);
|
||||
extern Bool GrPlot0(CDC *dc,I64 x,I64 y);
|
||||
extern CMenuEntry *MenuEntryFind(CMenu *haystack_menu,U8 *needle_full_name);
|
||||
extern CMenu *MenuFilePush(U8 *filename);
|
||||
extern U0 MenuPop();
|
||||
extern CMenu *MenuPush(U8 *st);
|
||||
extern U8 Mount(Bool caller_is_prtdsk=FALSE);
|
||||
extern CTask *Noise(I64 mS,F64 min_ona,F64 max_ona);
|
||||
extern Bool Plain(U8 *filename,I64 edf_dof_flags=0);
|
||||
extern Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL);
|
||||
extern I64 PopUpColor(U8 *header=NULL,
|
||||
Bool allow_transparent=TRUE,Bool allow_dft=TRUE);
|
||||
extern I64 PopUpColorDither(U8 *header=NULL);
|
||||
extern I64 PopUpColorLighting(U8 *header=NULL);
|
||||
extern I64 PopUpFile(U8 *filename,
|
||||
Bool warn_ext=TRUE,CTask *parent=NULL,CTask **_pu_task=NULL);
|
||||
extern Bool PopUpForm(U8 *_d,U8 *class_name=lastclass,
|
||||
I64 dof_flags=DOF_SIZE_MIN,U8 *header=NULL,U8 *footer=NULL);
|
||||
extern I64 PopUpGetI64(U8 *msg,I64 dft,I64 lo=I64_MIN,I64 hi=I64_MAX);
|
||||
extern U8 *PopUpGetStr(U8 *header=NULL);
|
||||
extern I64 PopUpMenu(CDoc *doc,I64 dof_flags=0);
|
||||
extern Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL);
|
||||
extern Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL);
|
||||
extern I64 PopUpRangeI64(
|
||||
I64 lo,I64 hi,I64 step=1,U8 *header=NULL,U8 *footer=NULL);
|
||||
extern Bool PopUpTransform(I64 *r);
|
||||
extern I64 RedSeaISO(U8 *_iso_filename=NULL,U8 *_src_dir,
|
||||
U8 *_stage2_filename=NULL);
|
||||
extern U0 Refresh(I64 cnt=1,Bool force=FALSE);
|
||||
extern U0 RegOneTimePopUp(I64 flag_num,U8 *msg);
|
||||
extern Bool RegWrite(U8 *path,U8 *fmt,...);
|
||||
extern U0 SettingsPop(CTask *task=NULL,I64 flags=0);
|
||||
extern CTaskSettings *SettingsPush(CTask *task=NULL,I64 flags=0);
|
||||
extern U0 TemplateCtrlSlider(CDoc *doc);
|
||||
extern Bool View();
|
||||
extern U0 ViewAnglesDel(CTask *task=NULL);
|
||||
extern CCtrl *ViewAnglesNew(CTask *task=NULL);
|
||||
extern Bool WinBorder(Bool val=OFF,CTask *task=NULL);
|
||||
extern CDoc *WinCursorPosSet(CTask *task,I64 msx,I64 msy,Bool set_cursor=TRUE);
|
||||
extern Bool WinHorz(I64 left,I64 right,CTask *task=NULL);
|
||||
extern U0 WinMax(CTask *task=NULL);
|
||||
extern U0 WinScrollNull(CTask *task,CD3I64 *s);
|
||||
extern U0 WinScrollRestore(CTask *task,CD3I64 *s);
|
||||
extern U0 WinScrollsInit(CTask *task);
|
||||
extern I64 WinToTop(CTask *task=NULL,Bool update_z_buf=TRUE);
|
||||
extern Bool WinVert(I64 top,I64 bottom,CTask *task=NULL);
|
||||
extern CWinMgrGlbls winmgr;
|
||||
431
temple-src/Adam/AHash.HC
Executable file
431
temple-src/Adam/AHash.HC
Executable file
@ -0,0 +1,431 @@
|
||||
#help_index "Info;Hash/System;Cmd Line (Typically)"
|
||||
class CWho
|
||||
{
|
||||
CHashGeneric *h;
|
||||
U8 *idx;
|
||||
};
|
||||
|
||||
I64 HashEntriesCompare(CWho *h1,CWho *h2)
|
||||
{
|
||||
I64 i1,i2;
|
||||
if (i1=StrCmp(h1->h->str,h2->h->str))
|
||||
return i1;
|
||||
i1=HashTypeNum(h1->h);
|
||||
i2=HashTypeNum(h2->h);
|
||||
return i1-i2;
|
||||
}
|
||||
|
||||
I64 HashEntriesCompare2(CWho *h1,CWho *h2)
|
||||
{
|
||||
CHashFun *tmpf1=h1->h,*tmpf2=h2->h;
|
||||
I64 i1=HashVal(tmpf1),i2=HashVal(tmpf2);
|
||||
if (i1==i2) {
|
||||
i1=HashTypeNum(tmpf1);
|
||||
i2=HashTypeNum(tmpf2);
|
||||
if (i1==i2)
|
||||
return StrCmp(tmpf1->str,tmpf2->str);
|
||||
}
|
||||
return i1-i2;
|
||||
}
|
||||
|
||||
I64 HelpIndexCnt(U8 *ptr,U8 *idx)
|
||||
{
|
||||
I64 cnt=0,ch,idx_len=StrLen(idx);
|
||||
while (*ptr) {
|
||||
if (!StrNCmp(ptr,idx,idx_len))
|
||||
cnt++;
|
||||
while (ch=*ptr++)
|
||||
if (ch==';')
|
||||
break;
|
||||
if (!ch)
|
||||
ptr--;
|
||||
}
|
||||
return cnt;
|
||||
}
|
||||
|
||||
U8 *HelpIndexStr(U8 **_ptr,U8 *idx)
|
||||
{
|
||||
U8 *ptr=*_ptr,*ptr2,*res;
|
||||
I64 ch,idx_len=StrLen(idx);
|
||||
while (*ptr) {
|
||||
ptr2=ptr;
|
||||
while (ch=*ptr++)
|
||||
if (ch==';')
|
||||
break;
|
||||
if (!ch)
|
||||
ptr--;
|
||||
*_ptr=ptr;
|
||||
if (!StrNCmp(ptr2,idx,idx_len)) {
|
||||
if (ch==';')
|
||||
ptr--;
|
||||
*ptr=0;
|
||||
res=StrNew(ptr2);
|
||||
*ptr=ch;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U8 *HelpComment(CTask *task,CHash *tmph,U8 *_src_link)
|
||||
{
|
||||
CDoc *doc;
|
||||
CDocEntry *doc_e;
|
||||
U8 *res=NULL,*ptr,*ptr2,*src_link=StrNew(_src_link);
|
||||
|
||||
if (*src_link=='F' && src_link[2]==':')
|
||||
*src_link='P';
|
||||
XTalkWait(task,"Ed(0x%X,DOF_DONT_WINMGR_SYNC|DOF_DONT_SHOW);\n",src_link);
|
||||
Free(src_link);
|
||||
|
||||
doc=DocPut(task);
|
||||
doc_e=doc->cur_entry;
|
||||
if (tmph->type&HTT_FUN) {
|
||||
if (Bt(&tmph(CHashFun *)->flags,Ff__EXTERN) ||
|
||||
Bt(&tmph(CHashFun *)->flags,Ff_INTERNAL))
|
||||
while (doc_e!=doc &&
|
||||
(!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,';')))
|
||||
doc_e=doc_e->next;
|
||||
else
|
||||
while (doc_e!=doc &&
|
||||
(!(doc_e->de_flags&DOCEF_TAG)||!StrOcc(doc_e->tag,'{')))
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
if (doc_e!=doc) {
|
||||
if (doc_e->de_flags&DOCEF_TAG) {
|
||||
ptr=doc_e->tag;
|
||||
if (ptr2=StrMatch("//",ptr))
|
||||
ptr=ptr2+2;
|
||||
else if (ptr2=StrMatch("/*",ptr))
|
||||
ptr=ptr2+2;
|
||||
else if (!StrNCmp(ptr,"public",6))
|
||||
ptr+=6;
|
||||
while (*ptr==CH_SPACE)
|
||||
ptr++;
|
||||
res=StrNew(ptr);
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
|
||||
if (doc_e->type_u8==DOCT_TAB) {
|
||||
ptr=MStrPrint("%s",res);
|
||||
Free(res);
|
||||
res=ptr;
|
||||
} else if (doc_e->de_flags&DOCEF_TAG) {
|
||||
ptr=MStrPrint("%s%s",res,doc_e->tag);
|
||||
Free(res);
|
||||
res=ptr;
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
}
|
||||
XTalkWait(task,"%c",CH_SHIFT_ESC);
|
||||
if (res) {
|
||||
ptr=MStrUtil(res,SUF_REM_TRAILING|SUF_REM_LEADING|SUF_SINGLE_SPACE);
|
||||
Free(res);
|
||||
res=ptr;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 HashEntriesCompare3(CWho *h1,CWho *h2)
|
||||
{
|
||||
I64 i,i1=0,i2=0;
|
||||
i=StrCmp(h1->idx,h2->idx);
|
||||
if (i)
|
||||
return i;
|
||||
else {
|
||||
if (h1->h->type&HTT_HELP_FILE)
|
||||
i1=1;
|
||||
if (h2->h->type&HTT_HELP_FILE)
|
||||
i2=1;
|
||||
i=i2-i1;
|
||||
if (i)
|
||||
return i;
|
||||
else
|
||||
return StrCmp(h1->h->str,h2->h->str);
|
||||
}
|
||||
}
|
||||
|
||||
public U0 Who(U8 *fu_flags=NULL,CHashTable *h=NULL,
|
||||
U8 *idx=NULL,CDoc *doc=NULL)
|
||||
{//Dump hash symbol table.
|
||||
// "+p" for only public symbols
|
||||
// "+m" to order by number (normally alphabetical)
|
||||
// "-r" just local hash table
|
||||
CHashTable *table;
|
||||
CHashSrcSym *tmph;
|
||||
CHashGeneric *ptr;
|
||||
CWho *lst;
|
||||
I64 cnt,i,j,k,f=0;
|
||||
U8 buf[512],*last_idx=StrNew(""),*cur_idx,*comment;
|
||||
Bool recurse,publics,map;
|
||||
CTask *task;
|
||||
|
||||
ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r");
|
||||
ScanFlags(&f,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
|
||||
if (f&~(FUF_RECURSE|FUF_PUBLIC|FUF_MAP))
|
||||
throw('FUF');
|
||||
recurse=Bt(&f,FUf_RECURSE);
|
||||
publics=Bt(&f,FUf_PUBLIC);
|
||||
map =Bt(&f,FUf_MAP);
|
||||
|
||||
if (!h) h=Fs->hash_table;
|
||||
|
||||
if (idx) {
|
||||
task=User;
|
||||
TaskWait(task);
|
||||
LBtr(&task->display_flags,DISPLAYf_SHOW);
|
||||
} else
|
||||
task=NULL;
|
||||
|
||||
cnt=0;
|
||||
table=h;
|
||||
while (table) {
|
||||
for (i=0;i<=table->mask;i++) {
|
||||
tmph=table->body[i];
|
||||
while (tmph) {
|
||||
if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
|
||||
(tmph->type & HTF_PUBLIC || !publics)) {
|
||||
if (!idx)
|
||||
cnt++;
|
||||
else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx))
|
||||
cnt+=HelpIndexCnt(cur_idx,idx);
|
||||
}
|
||||
tmph=tmph->next;
|
||||
}
|
||||
}
|
||||
if (recurse)
|
||||
table=table->next;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (!cnt) goto wh_done;
|
||||
|
||||
lst=CAlloc(cnt*sizeof(CWho));
|
||||
j=0;
|
||||
table=h;
|
||||
while (table) {
|
||||
for (i=0;i<=table->mask;i++) {
|
||||
tmph=table->body[i];
|
||||
while (tmph) {
|
||||
if (!(tmph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
|
||||
(tmph->type & HTF_PUBLIC || !publics))
|
||||
if (!idx)
|
||||
lst[j++].h=tmph;
|
||||
else if (tmph->type&HTG_SRC_SYM && (cur_idx=tmph->idx) &&
|
||||
(k=HelpIndexCnt(cur_idx,idx)))
|
||||
while (k--) {
|
||||
lst[j].idx=HelpIndexStr(&cur_idx,idx);
|
||||
lst[j++].h=tmph;
|
||||
}
|
||||
tmph=tmph->next;
|
||||
}
|
||||
}
|
||||
if (recurse)
|
||||
table=table->next;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
if (map)
|
||||
QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare2);
|
||||
else if (idx)
|
||||
QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare3);
|
||||
else
|
||||
QSort(lst,cnt,sizeof(CWho),&HashEntriesCompare);
|
||||
|
||||
if (idx) {
|
||||
progress1_max=cnt;
|
||||
progress1=0;
|
||||
}
|
||||
for (i=0;i<cnt;i++) {
|
||||
comment=NULL;
|
||||
ptr=lst[i].h;
|
||||
if (idx)
|
||||
if (cur_idx=lst[i].idx) {
|
||||
if (StrCmp(cur_idx,last_idx)) {
|
||||
Free(last_idx);
|
||||
last_idx=StrNew(cur_idx);
|
||||
if (i)
|
||||
DocPrint(doc,"\n\n");
|
||||
DocPrint(doc,"$$WW,0$$$$PURPLE$$$$TX+CX,\"%$$Q\"$$$$FG$$\n",cur_idx);
|
||||
}
|
||||
}
|
||||
|
||||
if (idx && ptr->type & HTT_HELP_FILE) {
|
||||
DocPrint(doc,"$$WW,1$$");
|
||||
DocType(doc,ptr->str);
|
||||
DocPrint(doc,"$$WW,0$$");
|
||||
} else {
|
||||
if (ptr->type&HTG_SRC_SYM && ptr(CHashSrcSym *)->src_link) {
|
||||
DocPrint(doc,"$$LK,\"%-20s\",A=\"%s\"$$",
|
||||
ptr->str,ptr(CHashSrcSym *)->src_link);
|
||||
if (idx)
|
||||
comment=HelpComment(task,ptr,ptr(CHashSrcSym *)->src_link);
|
||||
} else
|
||||
DocPrint(doc,"%-20s",ptr->str);
|
||||
|
||||
if (!idx) {
|
||||
if (ptr->type & HTT_DEFINE_STR) {
|
||||
j=ptr(CHashDefineStr *)->cnt;
|
||||
if (j==-1)
|
||||
StrPrint(buf,"%-10t$$Q",ptr(CHashDefineStr *)->data);
|
||||
else
|
||||
StrPrint(buf,"%-10t$$Q %02X",ptr(CHashDefineStr *)->data,j);
|
||||
} else if (ptr->type & HTT_GLBL_VAR)
|
||||
StrPrint(buf,"%010X",ptr(CHashGlblVar *)->data_addr);
|
||||
else
|
||||
StrPrint(buf,"%010X",HashVal(ptr));
|
||||
j=HashEntrySize(ptr);
|
||||
if (j==-1)
|
||||
CatPrint(buf," %04X ",ptr->use_cnt);
|
||||
else
|
||||
CatPrint(buf," %04X %010X ",ptr->use_cnt,j);
|
||||
} else
|
||||
*buf=0;
|
||||
|
||||
k=ptr->type;
|
||||
if (publics)
|
||||
k&=~HTF_PUBLIC;
|
||||
if (!(k&HTG_TYPE_MASK))
|
||||
CatPrint(buf,"NULL ");
|
||||
while (k) {
|
||||
j=Bsf(k);
|
||||
if (j<0)
|
||||
break;
|
||||
Btr(&k,j);
|
||||
CatPrint(buf,"%Z ",j,"ST_HTT_TYPES");
|
||||
}
|
||||
DocPrint(doc,"%s",buf);
|
||||
if (comment) {
|
||||
DocPrint(doc,"$$GREEN$$%s$$FG$$",comment);
|
||||
Free(comment);
|
||||
}
|
||||
DocPrint(doc,"\n");
|
||||
}
|
||||
Free(lst[i].idx);
|
||||
if (idx)
|
||||
progress1++;
|
||||
}
|
||||
Free(lst);
|
||||
if (idx)
|
||||
progress1=progress1_max=0;
|
||||
|
||||
wh_done:
|
||||
if (doc) {
|
||||
if (doc->head.next==doc)
|
||||
DocPrint(doc,"No Match");
|
||||
else
|
||||
DocRecalc(doc);
|
||||
}
|
||||
Free(last_idx);
|
||||
Kill(task);
|
||||
}
|
||||
|
||||
#help_index "Info;Hash;Cmd Line (Typically)"
|
||||
|
||||
#define HDR_NUM 16
|
||||
public I64 HashDepthRep(CHashTable *table=NULL)
|
||||
{//Hash table linked-list chain depth report.
|
||||
//Histogram of collision count.
|
||||
I64 i,j,longest=0,cnt=0,a[HDR_NUM];
|
||||
CHash *tmph;
|
||||
if (!table) table=Fs->hash_table;
|
||||
MemSet(a,0,sizeof(a));
|
||||
for (i=0;i<=table->mask;i++) {
|
||||
tmph=table->body[i];
|
||||
if (tmph) {
|
||||
j=LinkedLstCnt(tmph);
|
||||
if (j<HDR_NUM)
|
||||
a[j]++;
|
||||
cnt+=j;
|
||||
if (j>longest)
|
||||
longest=j;
|
||||
}
|
||||
}
|
||||
"Histogram\n";
|
||||
for (i=0;i<HDR_NUM;i++)
|
||||
if (a[i])
|
||||
"%02d:%d\n",i,a[i];
|
||||
"Size:%dCount:%dLongest:%d\n",
|
||||
table->mask+1,cnt,longest;
|
||||
return longest;
|
||||
}
|
||||
|
||||
#help_index "Help System"
|
||||
#help_file "::/Doc/HelpSystem"
|
||||
|
||||
public U0 DocHelpIdx(CDoc *doc,U8 *idx)
|
||||
{//Put to doc report for given help idx.
|
||||
Who("+p",,idx,doc);
|
||||
}
|
||||
|
||||
public U0 PopUpHelpIndex(U8 *idx,CTask *parent=NULL)
|
||||
{//PopUp win report for given help idx.
|
||||
U8 *buf;
|
||||
buf=MStrPrint("DocHelpIdx(DocPut,\"%s\");View;",idx);
|
||||
PopUp(buf,parent);
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
#help_index "Hash/System"
|
||||
public U0 MapFileLoad(U8 *filename)
|
||||
{//Load map file so we have src line info.
|
||||
U8 *st,*ptr,*name=ExtDft(filename,"MAP.Z"),
|
||||
*absname=FileNameAbs(name);
|
||||
CDoc *doc=DocRead(name);
|
||||
CDocEntry *doc_e;
|
||||
CHashSrcSym *tmph;
|
||||
I64 i,j,base=0;
|
||||
CDbgInfo *dbg_info;
|
||||
|
||||
FileExtRem(absname);
|
||||
if (absname[1]==':' && StrLen(absname)>2 &&
|
||||
(tmph=HashSingleTableFind(absname+2,Fs->hash_table,HTT_MODULE)))
|
||||
base=tmph(CHashGeneric *)->user_data0+sizeof(CBinFile);
|
||||
|
||||
if (!doc) return;
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->type_u8==DOCT_LINK) {
|
||||
if (*doc_e->tag)
|
||||
st=MStrUtil(doc_e->tag,SUF_REM_TRAILING);
|
||||
else
|
||||
st=MStrUtil(doc_e->aux_str,SUF_REM_TRAILING);
|
||||
if (tmph=HashSingleTableFind(st,Fs->hash_table,HTG_SRC_SYM)) {
|
||||
if (*doc_e->tag) {
|
||||
Free(tmph->src_link);
|
||||
tmph->src_link=doc_e->aux_str;
|
||||
ptr=tmph->src_link;
|
||||
if (ptr[0] && ptr[1] && ptr[2]==':') {
|
||||
if (ptr[3]==':')
|
||||
ptr[3]=blkdev.boot_drv_let;
|
||||
else if (ptr[3]=='~')
|
||||
ptr[3]=*blkdev.home_dir;
|
||||
}
|
||||
doc_e->aux_str=NULL;
|
||||
}
|
||||
if (tmph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM) &&
|
||||
!(dbg_info=tmph->dbg_info) && doc_e->bin_data &&
|
||||
(dbg_info=doc_e->bin_data->data)) {
|
||||
if (doc_e->bin_data->size>MSize(dbg_info))
|
||||
"Corrupt Map Entry\n";
|
||||
else {
|
||||
doc_e->bin_data->data=NULL;
|
||||
tmph->dbg_info=dbg_info;
|
||||
for (i=dbg_info->min_line;i<=dbg_info->max_line+1;i++) {
|
||||
j=i-dbg_info->min_line;
|
||||
if (dbg_info->body[j])
|
||||
dbg_info->body[j]=dbg_info->body[j]+base;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(st);
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
DocDel(doc);
|
||||
Free(name);
|
||||
Free(absname);
|
||||
}
|
||||
135
temple-src/Adam/AMath.HC
Executable file
135
temple-src/Adam/AMath.HC
Executable file
@ -0,0 +1,135 @@
|
||||
#help_index "Math"
|
||||
public U0 R2P(F64 *_mag=NULL,F64 *_arg=NULL,F64 x,F64 y)
|
||||
{//Rect to polar
|
||||
//Returns angle in range (-ã,ã]
|
||||
if (_arg)
|
||||
*_arg=Arg(x,y);
|
||||
if (_mag)
|
||||
*_mag=Sqrt(x*x+y*y);
|
||||
}
|
||||
|
||||
public U0 P2R(F64 *_x=NULL,F64 *_y=NULL,F64 mag,F64 arg)
|
||||
{//Polar to Rect
|
||||
if (_x)
|
||||
*_x=mag*Cos(arg);
|
||||
if (_y)
|
||||
*_y=mag*Sin(arg);
|
||||
}
|
||||
|
||||
public F64 Wrap(F64 é,F64 base=-ã)
|
||||
{//Returns angle in range [base,base+2*ã)
|
||||
F64 res=é%(2*ã);
|
||||
if (res>=base+2*ã)
|
||||
res-=2*ã;
|
||||
else if (res<base)
|
||||
res+=2*ã;
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 DistSqrI64(I64 x1,I64 y1,I64 x2,I64 y2)
|
||||
{//Distance-squared between 2 points.
|
||||
I64 dx=x1-x2,dy=y1-y2;
|
||||
return dx*dx+dy*dy;
|
||||
}
|
||||
|
||||
public F64 ASin(F64 s)
|
||||
{//Arc Sin (Inverse Sin).
|
||||
F64 c;
|
||||
c=s*s;
|
||||
if (c>=1.0)
|
||||
return ã/2.0;
|
||||
c=Sqrt(1.0-c);
|
||||
return ATan(s/c);
|
||||
}
|
||||
|
||||
public F64 ACos(F64 c)
|
||||
{//Arc Cos (Inverse Cos).
|
||||
F64 s;
|
||||
if (!c)
|
||||
return ã/2.0;
|
||||
s=c*c;
|
||||
if (s>=1.0)
|
||||
return 0.0;
|
||||
s=Sqrt(1.0-s);
|
||||
return ATan(s/c);
|
||||
}
|
||||
|
||||
public F64 Sinh(F64 x)
|
||||
{//Hyperbolic Sine.
|
||||
return 0.5*(Exp(x)-Exp(-x));
|
||||
}
|
||||
|
||||
public F64 Cosh(F64 x)
|
||||
{//Hyperbolic Cosine.
|
||||
return 0.5*(Exp(x)+Exp(-x));
|
||||
}
|
||||
|
||||
#help_index "Math/Complex;Data Types/Complex"
|
||||
public Complex *CAdd(Complex *sum,Complex *n1,Complex *n2)
|
||||
{//sum=n1+n2
|
||||
sum->x=n1->x+n2->x;
|
||||
sum->y=n1->y+n2->y;
|
||||
return sum;
|
||||
}
|
||||
|
||||
public Complex *CSub(Complex *diff,Complex *n1,Complex *n2)
|
||||
{//diff=n1-n2
|
||||
diff->x=n1->x-n2->x;
|
||||
diff->y=n1->y-n2->y;
|
||||
return diff;
|
||||
}
|
||||
|
||||
public Complex *CMul(Complex *prod,Complex *n1,Complex *n2)
|
||||
{//prod=n1*n2
|
||||
prod->x=n1->x*n2->x-n1->y*n2->y;
|
||||
prod->y=n1->x*n2->y+n1->y*n2->x;
|
||||
return prod;
|
||||
}
|
||||
|
||||
public Complex *CDiv(Complex *quot,Complex *n1,Complex *n2)
|
||||
{//quot=n1/n2
|
||||
F64 m1,arg1,m2,arg2;
|
||||
R2P(&m1,&arg1,n1->x,n1->y);
|
||||
R2P(&m2,&arg2,n2->x,n2->y);
|
||||
m1/=m2;
|
||||
arg1-=arg2;
|
||||
quot->x=m1*Cos(arg1);
|
||||
quot->y=m1*Sin(arg1);
|
||||
return quot;
|
||||
}
|
||||
|
||||
public Complex *CScale(Complex *dst,F64 s)
|
||||
{//dst*=s
|
||||
dst->x*=s;
|
||||
dst->y*=s;
|
||||
return dst;
|
||||
}
|
||||
|
||||
public Complex *CCopy(Complex *dst,Complex *src)
|
||||
{//dst=src
|
||||
dst->x=src->x;
|
||||
dst->y=src->y;
|
||||
return dst;
|
||||
}
|
||||
|
||||
public Complex *CEqu(Complex *dst,F64 x,F64 y)
|
||||
{//dst=(x,y)
|
||||
dst->x=x;
|
||||
dst->y=y;
|
||||
return dst;
|
||||
}
|
||||
|
||||
public Complex *CPoly(Complex *dst,I64 n,Complex *zeros,Complex *x)
|
||||
{//Eval complex polynomial
|
||||
I64 i;
|
||||
Complex n1,n2;
|
||||
if (n>0) {
|
||||
CSub(dst,x,&zeros[0]);
|
||||
for (i=1;i<n;i++) {
|
||||
CCopy(&n1,dst);
|
||||
CMul(dst,&n1,CSub(&n2,x,&zeros[i]));
|
||||
}
|
||||
} else
|
||||
CEqu(dst,1.0,0.0);
|
||||
return dst;
|
||||
}
|
||||
688
temple-src/Adam/AMathODE.HC
Executable file
688
temple-src/Adam/AMathODE.HC
Executable file
@ -0,0 +1,688 @@
|
||||
#help_index "Math/ODE"
|
||||
#help_file "::/Doc/ODE"
|
||||
|
||||
//See $LK,"::/Doc/Credits.DD"$.
|
||||
|
||||
F64 LowPass1(F64 a,F64 y0,F64 y,F64 dt=1.0)
|
||||
{//First order low pass filter
|
||||
dt=Exp(-a*dt);
|
||||
return y0*dt+y*(1.0-dt);
|
||||
}
|
||||
|
||||
U0 ODERstPtrs(CMathODE *ode)
|
||||
{
|
||||
I64 s=ode->n_internal*sizeof(F64);
|
||||
F64 *ptr=ode->array_base;
|
||||
ode->state_internal=ptr; ptr(I64)+=s;
|
||||
ode->state_scale=ptr; ptr(I64)+=s;
|
||||
ode->DstateDt=ptr; ptr(I64)+=s;
|
||||
ode->initial_state=ptr; ptr(I64)+=s;
|
||||
ode->tmp0=ptr; ptr(I64)+=s;
|
||||
ode->tmp1=ptr; ptr(I64)+=s;
|
||||
ode->tmp2=ptr; ptr(I64)+=s;
|
||||
ode->tmp3=ptr; ptr(I64)+=s;
|
||||
ode->tmp4=ptr; ptr(I64)+=s;
|
||||
ode->tmp5=ptr; ptr(I64)+=s;
|
||||
ode->tmp6=ptr; ptr(I64)+=s;
|
||||
ode->tmp7=ptr;
|
||||
}
|
||||
|
||||
public CMathODE *ODENew(I64 n,F64 max_tolerance=1e-6,I64 flags=0)
|
||||
{//Make differential equation ctrl struct. See $LK,"flags",A="MN:ODEF_HAS_MASSES"$.
|
||||
//The tolerance is not precise.
|
||||
//You can min_tolerance and it will
|
||||
//dynamically adjust tolerance to utilize
|
||||
//the CPU.
|
||||
I64 s=n*sizeof(F64);
|
||||
CMathODE *ode=CAlloc(sizeof(CMathODE));
|
||||
ode->t_scale=1.0;
|
||||
ode->flags=flags;
|
||||
ode->n_internal=ode->n=n;
|
||||
ode->h=1e-6;
|
||||
ode->h_min=1e-64;
|
||||
ode->h_max=1e32;
|
||||
ode->max_tolerance=ode->min_tolerance=ode->tolerance_internal=max_tolerance;
|
||||
ode->win_task=ode->mem_task=Fs;
|
||||
QueInit(&ode->next_mass);
|
||||
QueInit(&ode->next_spring);
|
||||
ode->state=CAlloc(s);
|
||||
ode->array_base=MAlloc(12*s);
|
||||
ODERstPtrs(ode);
|
||||
return ode;
|
||||
}
|
||||
|
||||
|
||||
public Bool ODEPause(CMathODE *ode,Bool val=ON)
|
||||
{//Pause ODE.
|
||||
Bool res;
|
||||
if (!ode) return OFF;
|
||||
res=LBEqu(&ode->flags,ODEf_PAUSED,val);
|
||||
if (val)
|
||||
while (Bt(&ode->flags,ODEf_BUSY))
|
||||
Yield;
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 ODEDel(CMathODE *ode)
|
||||
{//Free ODE node, but not masses or springs.
|
||||
I64 i;
|
||||
if (!ode) return;
|
||||
ODEPause(ode);
|
||||
Free(ode->state);
|
||||
Free(ode->array_base);
|
||||
if (ode->slave_tasks) {
|
||||
for (i=0;i<mp_cnt;i++)
|
||||
Kill(ode->slave_tasks[i]);
|
||||
Free(ode->slave_tasks);
|
||||
}
|
||||
Free(ode);
|
||||
}
|
||||
|
||||
public I64 ODESize(CMathODE *ode)
|
||||
{//Mem size of ode ctrl, but not masses and springs.
|
||||
if (!ode)
|
||||
return 0;
|
||||
else
|
||||
return MSize2(ode->state)+MSize2(ode->array_base)+MSize2(ode);
|
||||
}
|
||||
|
||||
U0 ODESetMassesPtrs(CMathODE *ode,F64 *state,F64 *DstateDt)
|
||||
{
|
||||
COrder2D3 *ptr1=state(F64 *)+ode->n,
|
||||
*ptr2=DstateDt(F64 *)+ode->n;
|
||||
CMass *tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
tmpm->state=ptr1++;
|
||||
tmpm->DstateDt=ptr2++;
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODEState2Internal(CMathODE *ode)
|
||||
{
|
||||
CMass *tmpm;
|
||||
F64 *old_array_base;
|
||||
I64 mass_cnt;
|
||||
|
||||
if (ode->flags&ODEF_HAS_MASSES) {
|
||||
mass_cnt=0;
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
mass_cnt++;
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
old_array_base=ode->array_base;
|
||||
ode->n_internal=ode->n+6*mass_cnt;
|
||||
ode->array_base=MAlloc(12*ode->n_internal*sizeof(F64),ode->mem_task);
|
||||
Free(old_array_base);
|
||||
ODERstPtrs(ode);
|
||||
|
||||
ODESetMassesPtrs(ode,ode->state_internal,ode->state_internal);
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
MemCpy(tmpm->state,&tmpm->saved_state,sizeof(COrder2D3));
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
}
|
||||
MemCpy(ode->state_internal,ode->state,ode->n*sizeof(F64));
|
||||
}
|
||||
|
||||
U0 ODEInternal2State(CMathODE *ode)
|
||||
{
|
||||
CMass *tmpm;
|
||||
MemCpy(ode->state,ode->state_internal,ode->n*sizeof(F64));
|
||||
if (ode->flags&ODEF_HAS_MASSES) {
|
||||
ODESetMassesPtrs(ode,ode->state_internal,ode->state_internal);
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
MemCpy(&tmpm->saved_state,tmpm->state,sizeof(COrder2D3));
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public U0 ODERenum(CMathODE *ode)
|
||||
{//Renumber masses and springs.
|
||||
I64 i;
|
||||
CSpring *tmps;
|
||||
CMass *tmpm;
|
||||
|
||||
i=0;
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
tmpm->num=i++;
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
|
||||
i=0;
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
tmps->num=i++;
|
||||
tmps->end1_num=tmps->end1->num;
|
||||
tmps->end2_num=tmps->end2->num;
|
||||
tmps=tmps->next;
|
||||
}
|
||||
}
|
||||
|
||||
public CMass *MassFind(CMathODE *ode,F64 x,F64 y,F64 z=0)
|
||||
{//Search for mass nearest to x,y,z.
|
||||
CMass *tmpm,*best_mass=NULL;
|
||||
F64 dd,best_dd=F64_MAX;
|
||||
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
dd=Sqr(tmpm->x-x)+Sqr(tmpm->y-y)+Sqr(tmpm->z-z);
|
||||
if (dd<best_dd) {
|
||||
best_dd=dd;
|
||||
best_mass=tmpm;
|
||||
}
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
return best_mass;
|
||||
}
|
||||
|
||||
public CSpring *SpringFind(CMathODE *ode,F64 x,F64 y,F64 z=0)
|
||||
{//Find spring midpoint nearest x,y,z.
|
||||
CSpring *tmps,*best_spring=NULL;
|
||||
F64 dd,best_dd=F64_MAX;
|
||||
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
dd=Sqr((tmps->end1->x+tmps->end2->x)/2-x)+
|
||||
Sqr((tmps->end1->y+tmps->end2->y)/2-y)+
|
||||
Sqr((tmps->end1->z+tmps->end2->z)/2-z);
|
||||
if (dd<best_dd) {
|
||||
best_dd=dd;
|
||||
best_spring=tmps;
|
||||
}
|
||||
tmps=tmps->next;
|
||||
}
|
||||
return best_spring;
|
||||
}
|
||||
|
||||
public U0 MassOrSpringFind(
|
||||
CMathODE *ode,CMass **res_mass,CSpring **res_spring,
|
||||
F64 x,F64 y,F64 z=0)
|
||||
{//Find spring or mass nearest x,y,z.
|
||||
CMass *tmpm,*best_mass=NULL;
|
||||
CSpring *tmps,*best_spring=NULL;
|
||||
F64 dd,best_dd=F64_MAX;
|
||||
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
dd=Sqr(tmpm->x-x)+Sqr(tmpm->y-y)+Sqr(tmpm->z-z);
|
||||
if (dd<best_dd) {
|
||||
best_dd=dd;
|
||||
best_mass=tmpm;
|
||||
}
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
dd=Sqr((tmps->end1->x+tmps->end2->x)/2-x)+
|
||||
Sqr((tmps->end1->y+tmps->end2->y)/2-y)+
|
||||
Sqr((tmps->end1->z+tmps->end2->z)/2-z);
|
||||
if (dd<best_dd) {
|
||||
best_dd=dd;
|
||||
best_spring=tmps;
|
||||
best_mass=NULL;
|
||||
}
|
||||
tmps=tmps->next;
|
||||
}
|
||||
if (res_mass) *res_mass =best_mass;
|
||||
if (res_spring) *res_spring=best_spring;
|
||||
}
|
||||
|
||||
public CMass *MassFindNum(CMathODE *ode,I64 num)
|
||||
{//Return mass number N.
|
||||
CMass *tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
if (tmpm->num==num)
|
||||
return tmpm;
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public U0 ODERstInactive(CMathODE *ode)
|
||||
{//Set all masses and springs to ACTIVE for new trial.
|
||||
CMass *tmpm;
|
||||
CSpring *tmps;
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
tmpm->flags&=~MSF_INACTIVE;
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
tmps=ode->next_spring;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
tmps->flags&=~SSF_INACTIVE;
|
||||
tmps=tmps->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODECalcSprings(CMathODE *ode)
|
||||
{
|
||||
CSpring *tmps=ode->next_spring;
|
||||
CMass *e1,*e2;
|
||||
F64 d;
|
||||
CD3 p;
|
||||
while (tmps!=&ode->next_spring) {
|
||||
if (tmps->flags&SSF_INACTIVE) {
|
||||
tmps->displacement=0;
|
||||
tmps->f=0;
|
||||
} else {
|
||||
e1=tmps->end1;
|
||||
e2=tmps->end2;
|
||||
d=D3Norm(D3Sub(&p,&e2->state->x,&e1->state->x));
|
||||
tmps->displacement=d-tmps->rest_len;
|
||||
tmps->f=tmps->displacement*tmps->const;
|
||||
if (tmps->f>0 && tmps->flags&SSF_NO_TENSION)
|
||||
tmps->f=0;
|
||||
else if (tmps->f<0 && tmps->flags&SSF_NO_COMPRESSION)
|
||||
tmps->f=0;
|
||||
if (d>0) {
|
||||
D3MulEqu(&p,tmps->f/d);
|
||||
D3AddEqu(&e1->DstateDt->DxDt,&p);
|
||||
D3SubEqu(&e2->DstateDt->DxDt,&p);
|
||||
}
|
||||
}
|
||||
tmps=tmps->next;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODECalcDrag(CMathODE *ode)
|
||||
{
|
||||
CMass *tmpm;
|
||||
F64 d,dd;
|
||||
CD3 p;
|
||||
if (ode->drag_v || ode->drag_v2 || ode->drag_v3) {
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
if (!(tmpm->flags & MSF_INACTIVE) &&
|
||||
tmpm->drag_profile_factor &&
|
||||
(dd=D3NormSqr(&tmpm->state->DxDt))) {
|
||||
d=ode->drag_v;
|
||||
if (ode->drag_v2)
|
||||
d+=ode->drag_v2*Sqrt(dd);
|
||||
if (ode->drag_v3)
|
||||
d+=dd*ode->drag_v3;
|
||||
D3SubEqu(&tmpm->DstateDt->DxDt,
|
||||
D3Mul(&p,d*tmpm->drag_profile_factor,&tmpm->state->DxDt));
|
||||
}
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODEApplyAccelerationLimit(CMathODE *ode)
|
||||
{
|
||||
CMass *tmpm;
|
||||
F64 d;
|
||||
if (ode->acceleration_limit) {
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
if (!(tmpm->flags & MSF_INACTIVE) &&
|
||||
(d=D3Norm(&tmpm->DstateDt->DxDt))>ode->acceleration_limit)
|
||||
D3MulEqu(&tmpm->DstateDt->DxDt,ode->acceleration_limit/d);
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODEMPTask(CMathODE *ode)
|
||||
{
|
||||
while (TRUE) {
|
||||
while (!Bt(&ode->mp_not_done_flags,Gs->num))
|
||||
Yield;
|
||||
if (ode->mp_derive)
|
||||
(*ode->mp_derive)(ode,ode->mp_t,
|
||||
Gs->num,ode->mp_state,ode->mp_DstateDt);
|
||||
LBtr(&ode->mp_not_done_flags,Gs->num);
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODEMPWake(CMathODE *ode)
|
||||
{
|
||||
I64 i;
|
||||
if (!ode->slave_tasks) {
|
||||
ode->slave_tasks=CAlloc(mp_cnt*sizeof(CTask *));
|
||||
for (i=0;i<mp_cnt;i++)
|
||||
ode->slave_tasks[i]=Spawn(&ODEMPTask,ode,"ODE Slave",i);
|
||||
}
|
||||
for (i=0;i<mp_cnt;i++) {
|
||||
Suspend(ode->slave_tasks[i],FALSE);
|
||||
MPInt(I_WAKE,i);
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODEMPSleep(CMathODE *ode)
|
||||
{
|
||||
I64 i;
|
||||
if (ode->slave_tasks) {
|
||||
while (ode->mp_not_done_flags)
|
||||
Yield;
|
||||
for (i=0;i<mp_cnt;i++)
|
||||
Suspend(ode->slave_tasks[i]);
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODECallMPDerivative(CMathODE *ode,F64 t,F64 *state,F64 *DstateDt)
|
||||
{
|
||||
ode->mp_t=t;
|
||||
ode->mp_state=state;
|
||||
ode->mp_DstateDt=DstateDt;
|
||||
ode->mp_not_done_flags=1<<mp_cnt-1;
|
||||
do Yield;
|
||||
while (ode->mp_not_done_flags);
|
||||
}
|
||||
|
||||
U0 ODECallDerivative(CMathODE *ode,F64 t,F64 *state,F64 *DstateDt)
|
||||
{
|
||||
CMass *tmpm;
|
||||
if (ode->flags&ODEF_HAS_MASSES) {
|
||||
ODESetMassesPtrs(ode,state,DstateDt);
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
if (!(tmpm->flags&MSF_INACTIVE)) {
|
||||
D3Zero(&tmpm->DstateDt->DxDt);
|
||||
D3Copy(&tmpm->DstateDt->x,&tmpm->state->DxDt);
|
||||
}
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
ODECalcSprings(ode);
|
||||
ODECalcDrag(ode);
|
||||
if (ode->mp_derive)
|
||||
ODECallMPDerivative(ode,t,state,DstateDt);
|
||||
if (ode->derive)
|
||||
(*ode->derive)(ode,t,state,DstateDt);
|
||||
tmpm=ode->next_mass;
|
||||
while (tmpm!=&ode->next_mass) {
|
||||
if (!(tmpm->flags&MSF_INACTIVE)) {
|
||||
if (tmpm->flags&MSF_FIXED) {
|
||||
D3Zero(&tmpm->DstateDt->DxDt);
|
||||
D3Zero(&tmpm->DstateDt->x);
|
||||
} else if (tmpm->mass)
|
||||
D3DivEqu(&tmpm->DstateDt->DxDt,tmpm->mass);
|
||||
}
|
||||
tmpm=tmpm->next;
|
||||
}
|
||||
ODEApplyAccelerationLimit(ode);
|
||||
} else {
|
||||
if (ode->mp_derive)
|
||||
ODECallMPDerivative(ode,t,state,DstateDt);
|
||||
if (ode->derive)
|
||||
(*ode->derive)(ode,t,state,DstateDt);
|
||||
}
|
||||
}
|
||||
|
||||
U0 ODEOneStep(CMathODE *ode)
|
||||
{
|
||||
I64 i;
|
||||
ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
|
||||
for (i=0;i<ode->n_internal;i++)
|
||||
ode->state_internal[i]+=ode->h*ode->DstateDt[i];
|
||||
ode->t+=ode->h;
|
||||
}
|
||||
|
||||
U0 ODERK4OneStep(CMathODE *ode)
|
||||
{
|
||||
I64 i,n=ode->n_internal;
|
||||
F64 xh,hh,h6,*dym,*dyt,*yt,*DstateDt;
|
||||
|
||||
dym =ode->tmp0;
|
||||
dyt =ode->tmp1;
|
||||
yt =ode->tmp2;
|
||||
DstateDt=ode->tmp3;
|
||||
hh =0.5*ode->h;
|
||||
h6 =ode->h / 6.0;
|
||||
xh =ode->t + hh;
|
||||
|
||||
ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
|
||||
for (i=0;i<n;i++)
|
||||
yt[i]=ode->state_internal[i]+hh*DstateDt[i];
|
||||
ODECallDerivative(ode,xh,yt,dyt);
|
||||
for (i=0;i<n;i++)
|
||||
yt[i]=ode->state_internal[i]+hh*dyt[i];
|
||||
ODECallDerivative(ode,xh,yt,dym);
|
||||
for (i=0;i<n;i++) {
|
||||
yt[i]=ode->state_internal[i]+ode->h*dym[i];
|
||||
dym[i]+=dyt[i];
|
||||
}
|
||||
ode->t+=ode->h;
|
||||
ODECallDerivative(ode,ode->t,yt,dyt);
|
||||
for (i=0;i<n;i++)
|
||||
ode->state_internal[i]+=h6*(DstateDt[i]+dyt[i]+2.0*dym[i]);
|
||||
}
|
||||
|
||||
#define ODEa2 0.2
|
||||
#define ODEa3 0.3
|
||||
#define ODEa4 0.6
|
||||
#define ODEa5 1.0
|
||||
#define ODEa6 0.875
|
||||
#define ODEb21 0.2
|
||||
#define ODEb31 (3.0/40.0)
|
||||
#define ODEb32 (9.0/40.0)
|
||||
#define ODEb41 0.3
|
||||
#define ODEb42 (-0.9)
|
||||
#define ODEb43 1.2
|
||||
#define ODEb51 (-11.0/54.0)
|
||||
#define ODEb52 2.5
|
||||
#define ODEb53 (-70.0/27.0)
|
||||
#define ODEb54 (35.0/27.0)
|
||||
#define ODEb61 (1631.0/55296.0)
|
||||
#define ODEb62 (175.0/512.0)
|
||||
#define ODEb63 (575.0/13824.0)
|
||||
#define ODEb64 (44275.0/110592.0)
|
||||
#define ODEb65 (253.0/4096.0)
|
||||
#define ODEc1 (37.0/378.0)
|
||||
#define ODEc3 (250.0/621.0)
|
||||
#define ODEc4 (125.0/594.0)
|
||||
#define ODEc6 (512.0/1771.0)
|
||||
#define ODEdc1 (37.0/378.0-2825.0/27648.0)
|
||||
#define ODEdc3 (250.0/621.0-18575.0/48384.0)
|
||||
#define ODEdc4 (125.0/594.0-13525.0/55296.0)
|
||||
#define ODEdc5 (-277.0/14336.0)
|
||||
#define ODEdc6 (512.0/1771.0-0.25)
|
||||
|
||||
U0 ODECashKarp(CMathODE *ode)
|
||||
{
|
||||
I64 i,n=ode->n_internal;
|
||||
F64 h=ode->h,*state=ode->state_internal,
|
||||
*DstateDt=ode->DstateDt,*ak2,*ak3,*ak4,*ak5,*ak6,
|
||||
*tmpstate,*stateerr,*outstate;
|
||||
|
||||
ak2=ode->tmp0;
|
||||
ak3=ode->tmp1;
|
||||
ak4=ode->tmp2;
|
||||
ak5=ode->tmp3;
|
||||
ak6=ode->tmp4;
|
||||
tmpstate=ode->tmp5;
|
||||
outstate=ode->tmp6;
|
||||
stateerr=ode->tmp7;
|
||||
|
||||
for (i=0;i<n;i++)
|
||||
tmpstate[i]=state[i]+ODEb21*h*DstateDt[i];
|
||||
ODECallDerivative(ode,ode->t+ODEa2*h,tmpstate,ak2);
|
||||
for (i=0;i<n;i++)
|
||||
tmpstate[i]=state[i]+h*(ODEb31*DstateDt[i]+ODEb32*ak2[i]);
|
||||
ODECallDerivative(ode,ode->t+ODEa3*h,tmpstate,ak3);
|
||||
for (i=0;i<n;i++)
|
||||
tmpstate[i]=state[i]+h*(ODEb41*DstateDt[i]+ODEb42*ak2[i]+ODEb43*ak3[i]);
|
||||
ODECallDerivative(ode,ode->t+ODEa4*h,tmpstate,ak4);
|
||||
for (i=0;i<n;i++)
|
||||
tmpstate[i]=state[i]+h*(ODEb51*DstateDt[i]+
|
||||
ODEb52*ak2[i]+ODEb53*ak3[i]+ODEb54*ak4[i]);
|
||||
ODECallDerivative(ode,ode->t+ODEa5*h,tmpstate,ak5);
|
||||
for (i=0;i<n;i++)
|
||||
tmpstate[i]=state[i]+h*(ODEb61*DstateDt[i]+
|
||||
ODEb62*ak2[i]+ODEb63*ak3[i]+ODEb64*ak4[i]+ODEb65*ak5[i]);
|
||||
ODECallDerivative(ode,ode->t+ODEa6*h,tmpstate,ak6);
|
||||
|
||||
for (i=0;i<n;i++)
|
||||
outstate[i]=state[i]+h*(ODEc1*DstateDt[i]+
|
||||
ODEc3*ak3[i]+ODEc4*ak4[i]+ODEc6*ak6[i]);
|
||||
for (i=0;i<n;i++)
|
||||
stateerr[i]=h*(ODEdc1*DstateDt[i]+ODEdc3*ak3[i]+
|
||||
ODEdc4*ak4[i]+ODEdc5*ak5[i]+ODEdc6*ak6[i]);
|
||||
}
|
||||
|
||||
#define SAFETY 0.9
|
||||
#define PGROW (-0.2)
|
||||
#define PSHRNK (-0.25)
|
||||
#define ERRCON 1.89e-4
|
||||
|
||||
U0 ODERK5OneStep(CMathODE *ode)
|
||||
{
|
||||
I64 i;
|
||||
F64 errmax,tmp,*tmpstate=ode->tmp6,*stateerr=ode->tmp7;
|
||||
while (TRUE) {
|
||||
ode->h=Clamp(ode->h,ode->h_min,ode->h_max);
|
||||
ODECashKarp(ode);
|
||||
errmax=0.0;
|
||||
for (i=0;i<ode->n_internal;i++) {
|
||||
tmp=Abs(stateerr[i]/ode->state_scale[i]);
|
||||
if (tmp>errmax)
|
||||
errmax=tmp;
|
||||
}
|
||||
errmax/=ode->tolerance_internal;
|
||||
if (errmax<=1.0 || ode->h==ode->h_min) break;
|
||||
tmp=ode->h*SAFETY*errmax`PSHRNK;
|
||||
if (tmp<0.1*ode->h)
|
||||
ode->h*=0.1;
|
||||
else
|
||||
ode->h=tmp;
|
||||
}
|
||||
ode->t+=ode->h;
|
||||
if (errmax>ERRCON)
|
||||
ode->h*=SAFETY*errmax`PGROW;
|
||||
else
|
||||
ode->h*=5.0;
|
||||
ode->h=Clamp(ode->h,ode->h_min,ode->h_max);
|
||||
MemCpy(ode->state_internal,tmpstate,sizeof(F64)*ode->n_internal);
|
||||
}
|
||||
|
||||
F64 ode_alloced_factor=0.75;
|
||||
|
||||
U0 ODEsUpdate(CTask *task)
|
||||
{/* This routine is called by the $LK,"window mgr",A="FF:::/Adam/Gr/GrScrn.HC,ODEsUpdate"$on a continuous
|
||||
basis to allow real-time simulation.It is intended
|
||||
to provide ress good enough for games.It uses a runge-kutta
|
||||
integrator which is a better algorithm than doing it with Euler.
|
||||
|
||||
It is adaptive step-sized, so it slows down when an important
|
||||
event is taking place to improve accuracy, but in my implementation
|
||||
it has a timeout.
|
||||
*/
|
||||
I64 i;
|
||||
F64 d,start_time,timeout_time,t_desired,t_initial,interpolation;
|
||||
CMathODE *ode;
|
||||
|
||||
if (task->next_ode==&task->next_ode)
|
||||
task->last_ode_time=0;
|
||||
else if (!Bt(&task->win_inhibit,WIf_SELF_ODE)) {
|
||||
//See $LK,"GrUpdateTasks",A="MN:GrUpdateTasks"$() and $LK,"GrUpdateTaskODEs",A="MN:GrUpdateTaskODEs"$().
|
||||
//We will not pick a time limit based on
|
||||
//how busy the CPU is, what percent of the
|
||||
//last refresh cycle was spent on ODE's
|
||||
//and what the refresh cycle rate was.
|
||||
start_time=tS;
|
||||
d=1.0/winmgr.fps;
|
||||
timeout_time=start_time+
|
||||
(task->last_ode_time/d+0.1)/(winmgr.last_ode_time/d+0.1)*
|
||||
ode_alloced_factor*d;
|
||||
ode=task->next_ode;
|
||||
while (ode!=&task->next_ode) {
|
||||
t_initial=ode->t;
|
||||
d=tS;
|
||||
if (!(ode->flags&ODEF_STARTED)) {
|
||||
ode->base_t=d;
|
||||
ode->flags|=ODEF_STARTED;
|
||||
}
|
||||
d-=ode->base_t+t_initial;
|
||||
t_desired=ode->t_scale*d+t_initial;
|
||||
if (ode->flags&ODEF_PAUSED)
|
||||
ode->base_t+=t_desired-ode->t; //Slip
|
||||
else {
|
||||
ode->flags|=ODEF_BUSY;
|
||||
if (ode->flags&ODEF_PAUSED)
|
||||
ode->base_t+=t_desired-ode->t; //Slip
|
||||
else {
|
||||
if (ode->derive || ode->mp_derive) {
|
||||
if (ode->mp_derive)
|
||||
ODEMPWake(ode);
|
||||
ODEState2Internal(ode);
|
||||
MemCpy(ode->initial_state,ode->state_internal,
|
||||
ode->n_internal*sizeof(F64));
|
||||
while (ode->t<t_desired) {
|
||||
ode->h_max=t_desired-ode->t;
|
||||
ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
|
||||
for (i=0;i<ode->n_internal;i++)
|
||||
ode->state_scale[i]=Abs(ode->state_internal[i])+
|
||||
Abs(ode->DstateDt[i]*ode->h)+ode->tolerance_internal;
|
||||
ODERK5OneStep(ode);
|
||||
if (tS>timeout_time) {
|
||||
ode->base_t+=t_desired-ode->t; //Slip
|
||||
goto ode_done;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//Interpolate if end time was not exact.
|
||||
if (ode->t!=t_desired) {
|
||||
if (interpolation=ode->t-t_initial) {
|
||||
interpolation=(t_desired-t_initial)/interpolation;
|
||||
if (interpolation!=1.0)
|
||||
for (i=0;i<ode->n_internal;i++)
|
||||
ode->state_internal[i]=(ode->state_internal[i]-
|
||||
ode->initial_state[i])*interpolation+
|
||||
ode->initial_state[i];
|
||||
}
|
||||
ode->t=t_desired;
|
||||
}
|
||||
ode_done:
|
||||
ODEInternal2State(ode);
|
||||
|
||||
//Convenience call to set vals
|
||||
ODECallDerivative(ode,ode->t,ode->state_internal,ode->DstateDt);
|
||||
|
||||
if (ode->mp_derive)
|
||||
ODEMPSleep(ode);
|
||||
}
|
||||
}
|
||||
ode->flags&=~ODEF_BUSY;
|
||||
}
|
||||
ode->base_t+=(1.0-ode->t_scale)*d;
|
||||
ode=ode->next;
|
||||
}
|
||||
|
||||
//Now, we will dynamically adjust tolerances.
|
||||
|
||||
//We will regulate the tolerances
|
||||
//to fill the time we decided was
|
||||
//okay to devote to ODE's.
|
||||
//Since we might have multiple ODE's
|
||||
//active we scale them by the same factor.
|
||||
|
||||
//This algorithm is probably not stable or very good, but it's something.
|
||||
|
||||
//Target is 75% of alloced time.
|
||||
d=(tS-start_time)/(timeout_time-start_time)-0.75;
|
||||
|
||||
ode=task->next_ode;
|
||||
while (ode!=&task->next_ode) {
|
||||
if (!(ode->flags&ODEF_PAUSED) && ode->derive) {
|
||||
if (ode->min_tolerance!=ode->max_tolerance) {
|
||||
if (d>0)
|
||||
ode->tolerance_internal*=10.0`d;
|
||||
else
|
||||
ode->tolerance_internal*=2.0`d;
|
||||
}
|
||||
ode->tolerance_internal=Clamp(ode->tolerance_internal,
|
||||
ode->min_tolerance,ode->max_tolerance);
|
||||
}
|
||||
ode=ode->next;
|
||||
}
|
||||
winmgr.ode_time+=task->last_ode_time=tS-start_time;
|
||||
}
|
||||
}
|
||||
179
temple-src/Adam/AMem.HC
Executable file
179
temple-src/Adam/AMem.HC
Executable file
@ -0,0 +1,179 @@
|
||||
#help_index "Memory/Task"
|
||||
public I64 TaskMemAlloced(CTask *task=NULL,Bool override_validate=FALSE)
|
||||
{//Count of bytes alloced to a task, used+unused.
|
||||
I64 res;
|
||||
if (!task) task=Fs;
|
||||
if (override_validate || TaskValidate(task)) {
|
||||
res=task->code_heap->alloced_u8s;
|
||||
if (task->code_heap!=task->data_heap)
|
||||
res+=task->data_heap->alloced_u8s;
|
||||
return res;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public I64 TaskMemUsed(CTask *task=NULL,Bool override_validate=FALSE)
|
||||
{//Count of bytes alloced to a task and in use.
|
||||
I64 res;
|
||||
if (!task) task=Fs;
|
||||
if (override_validate || TaskValidate(task)) {
|
||||
res=task->code_heap->used_u8s;
|
||||
if (task->data_heap!=task->code_heap)
|
||||
res+=task->data_heap->used_u8s;
|
||||
return res;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#help_index "Memory/Task;Debugging/Heap;Memory/Debugging"
|
||||
public Bool HeapRep(CTask *task)
|
||||
{//Report status of task's heap.
|
||||
I64 i,cnt;
|
||||
CMemUnused *uum;
|
||||
|
||||
if (!task || task==Fs) {
|
||||
"Task can't HeapRep on self.\n";
|
||||
return FALSE;
|
||||
}
|
||||
if (!TaskValidate(task)) return FALSE;
|
||||
|
||||
PUSHFD
|
||||
CLI
|
||||
while (LBts(&task->code_heap->locked_flags,HClf_LOCKED))
|
||||
PAUSE
|
||||
if (task->data_heap!=task->code_heap)
|
||||
while (LBts(&task->data_heap->locked_flags,HClf_LOCKED))
|
||||
PAUSE
|
||||
|
||||
for (i=0;i<MEM_HEAP_HASH_SIZE>>3;i++) {
|
||||
cnt=0;
|
||||
uum=task->code_heap->heap_hash[i];
|
||||
while (uum) {
|
||||
cnt+=uum->size;
|
||||
uum=uum->next;
|
||||
}
|
||||
if (task->data_heap!=task->code_heap) {
|
||||
uum=task->data_heap->heap_hash[i];
|
||||
while (uum) {
|
||||
cnt+=uum->size;
|
||||
uum=uum->next;
|
||||
}
|
||||
}
|
||||
if (cnt)
|
||||
"%03X:%08X\n",i<<3,cnt;
|
||||
}
|
||||
'\n';
|
||||
|
||||
uum=task->code_heap->malloc_free_lst;
|
||||
while (uum) {
|
||||
"%X, ",uum->size;
|
||||
uum=uum->next;
|
||||
}
|
||||
if (task->data_heap!=task->code_heap) {
|
||||
uum=task->data_heap->malloc_free_lst;
|
||||
while (uum) {
|
||||
"%X, ",uum->size;
|
||||
uum=uum->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (task->data_heap!=task->code_heap)
|
||||
LBtr(&task->data_heap->locked_flags,HClf_LOCKED);
|
||||
LBtr(&task->code_heap->locked_flags,HClf_LOCKED);
|
||||
POPFD
|
||||
|
||||
'\n';
|
||||
}
|
||||
|
||||
#help_index "Memory/HeapCtrl;Debugging/Heap;Memory/Debugging"
|
||||
public Bool IsInHeapCtrl(U8 *a,CHeapCtrl *hc,Bool lock=TRUE)
|
||||
{//Check addr if in HeapCtrl.
|
||||
CMemBlk *m;
|
||||
PUSHFD
|
||||
CLI
|
||||
if (lock)
|
||||
while (LBts(&hc->locked_flags,HClf_LOCKED))
|
||||
PAUSE
|
||||
m=hc->next_mem_blk;
|
||||
while (m!=&hc->next_mem_blk) {
|
||||
if (a>=m && a<m(U8 *)+m->pags<<MEM_PAG_BITS) {
|
||||
if (lock)
|
||||
LBtr(&hc->locked_flags,HClf_LOCKED);
|
||||
POPFD
|
||||
return TRUE;
|
||||
}
|
||||
m=m->next;
|
||||
}
|
||||
if (lock)
|
||||
LBtr(&hc->locked_flags,HClf_LOCKED);
|
||||
POPFD
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public Bool HeapCtrlWalk(CHeapCtrl *hc)
|
||||
{//Check integrity of HeapCtrl.
|
||||
I64 i;
|
||||
CMemUnused *uum;
|
||||
|
||||
PUSHFD
|
||||
CLI
|
||||
while (LBts(&hc->locked_flags,HClf_LOCKED))
|
||||
PAUSE
|
||||
|
||||
for (i=0;i<MEM_HEAP_HASH_SIZE>>3;i++) {
|
||||
uum=hc->heap_hash[i];
|
||||
while (uum) {
|
||||
if (!IsInHeapCtrl(uum,hc,FALSE))
|
||||
goto hc_false;
|
||||
uum=uum->next;
|
||||
}
|
||||
}
|
||||
uum=hc->malloc_free_lst;
|
||||
while (uum) {
|
||||
if (!IsInHeapCtrl(uum,hc,FALSE))
|
||||
goto hc_false;
|
||||
uum=uum->next;
|
||||
}
|
||||
|
||||
#if _CFG_HEAP_DBG
|
||||
CMemUsed *um,*um1;
|
||||
um1=(&hc->next_um)(U8 *)-offset(CMemUsed.next);
|
||||
um=um1->next;
|
||||
while (um!=um1) {
|
||||
if (!IsInHeapCtrl(um,hc,FALSE))
|
||||
goto hc_false;
|
||||
um=um->next;
|
||||
}
|
||||
#endif
|
||||
|
||||
LBtr(&hc->locked_flags,HClf_LOCKED);
|
||||
POPFD
|
||||
return TRUE;
|
||||
|
||||
hc_false:
|
||||
LBtr(&hc->locked_flags,HClf_LOCKED);
|
||||
POPFD
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#help_index "Memory/Task;Debugging/Heap;Memory/Debugging"
|
||||
public Bool IsInHeap(U8 *a,CTask *task=NULL,Bool lock=TRUE)
|
||||
{//Check addr if in task's heaps.
|
||||
if (!task) task=Fs;
|
||||
if (TaskValidate(task) && (IsInHeapCtrl(a,task->code_heap,lock)||
|
||||
task->data_heap!=task->code_heap &&
|
||||
IsInHeapCtrl(a,task->data_heap,lock)))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public Bool HeapWalk(CTask *task=NULL)
|
||||
{//Check integrity of task's heaps.
|
||||
if (!task) task=Fs;
|
||||
if (!TaskValidate(task) || !HeapCtrlWalk(task->code_heap) ||
|
||||
task->data_heap!=task->code_heap && !HeapCtrlWalk(task->data_heap))
|
||||
return FALSE;
|
||||
else
|
||||
return TRUE;
|
||||
}
|
||||
BIN
temple-src/Adam/AMouse.HC
Executable file
BIN
temple-src/Adam/AMouse.HC
Executable file
Binary file not shown.
203
temple-src/Adam/ARegistry.HC
Executable file
203
temple-src/Adam/ARegistry.HC
Executable file
@ -0,0 +1,203 @@
|
||||
#help_index "Registry"
|
||||
#define REGISTRY_FILENAME "~/Registry.HC.Z"
|
||||
CDoc *sys_registry_doc=NULL;
|
||||
I64 sys_msg_flags[1]={0};
|
||||
F64 registry_version;
|
||||
|
||||
Bool RegCache()
|
||||
{
|
||||
Bool old_silent;
|
||||
if (!sys_registry_doc) {
|
||||
old_silent=Silent;
|
||||
sys_registry_doc=DocRead(REGISTRY_FILENAME);
|
||||
Silent(old_silent);
|
||||
return FALSE;
|
||||
} else
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public Bool RegDft(U8 *path,U8 *val,Bool is_adam_entry=FALSE)
|
||||
{//Add code doc tree branch to registry.
|
||||
Bool res,unlock_doc;
|
||||
RegCache;
|
||||
unlock_doc=DocLock(sys_registry_doc);
|
||||
if (!DocTreeFind(sys_registry_doc,path)) {
|
||||
DocTreeMake(sys_registry_doc,path);
|
||||
DocPrint(sys_registry_doc,"%s",val);
|
||||
if (is_adam_entry) {
|
||||
if (Fs==adam_task)
|
||||
ExePrint("%s",val);
|
||||
else
|
||||
Adam("%s",val);
|
||||
}
|
||||
if (DrvIsWritable(*sys_registry_doc->filename.name))
|
||||
DocWrite(sys_registry_doc);
|
||||
res=FALSE;
|
||||
} else
|
||||
res=TRUE;
|
||||
if (unlock_doc)
|
||||
DocUnlock(sys_registry_doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 RegExe(U8 *path)
|
||||
{//Execute doc tree branch in registry.
|
||||
RegCache;
|
||||
return DocTreeExe(sys_registry_doc,path);
|
||||
}
|
||||
|
||||
public Bool RegWrite(U8 *path,U8 *fmt,...)
|
||||
{//Rewrite doc tree branch in registry.
|
||||
Bool res;
|
||||
RegCache;
|
||||
res=DocTreeWriteJoin(sys_registry_doc,path,TRUE,fmt,argc,argv);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 RegCnt(U8 *path)
|
||||
{//Tree branch cnt in registry.
|
||||
I64 res=0;
|
||||
CDocEntry *tree_branch,*start_indent,*end_indent;
|
||||
Bool unlock_doc=DocLock(sys_registry_doc);
|
||||
if (DocTreeFind(sys_registry_doc,path,
|
||||
&tree_branch,&start_indent,&end_indent)) {
|
||||
end_indent=end_indent->next;
|
||||
while (start_indent!=end_indent) {
|
||||
res++;
|
||||
start_indent=start_indent->next;
|
||||
}
|
||||
}
|
||||
if (unlock_doc)
|
||||
DocUnlock(sys_registry_doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool RegAppend(U8 *path,U8 *fmt,...)
|
||||
{//Append to doc tree branch in registry.
|
||||
Bool res;
|
||||
RegCache;
|
||||
res=DocTreeAppendJoin(sys_registry_doc,path,TRUE,fmt,argc,argv);
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool OneTimePopUp(U8 *_flags,I64 flag_num,U8 *msg)
|
||||
{//See $LK,"::/Apps/X-Caliber/X-Caliber.HC"$.
|
||||
Bool res=FALSE;
|
||||
CDoc *doc=DocNew;
|
||||
CDocEntry *doc_e;
|
||||
if (!Bt(_flags,flag_num)) {
|
||||
if (msg) DocPrint(doc,"%s",msg);
|
||||
doc_e=DocPrint(doc,"\n$$CB,\"Do not show this msg again.\",LE=1$$");
|
||||
DocPrint(doc,"$$CM+CX,0,4$$$$BT,\"OKAY\",LE=1$$\n");
|
||||
if (PopUpMenu(doc)==1 && doc_e->de_flags&DOCEF_CHECKED_COLLAPSED) {
|
||||
LBts(_flags,flag_num);
|
||||
res=TRUE;
|
||||
}
|
||||
DocDel(doc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 RegOneTimePopUp(I64 flag_num,U8 *msg)
|
||||
{//You're not supposed to make system pop-up flags, only me.
|
||||
if (OneTimePopUp(sys_msg_flags,flag_num,msg))
|
||||
RegWrite("Adam/SysMsgFlags","sys_msg_flags[0]=0x%X;\n",
|
||||
sys_msg_flags[0]);
|
||||
}
|
||||
|
||||
U0 RegInit()
|
||||
{
|
||||
U8 buf[STR_LEN];
|
||||
Bool version_present;
|
||||
RegDft("Adam/SysMsgFlags","sys_msg_flags[0]=0;\n",TRUE);
|
||||
StrPrint(buf,"registry_version=%4.3f;\n",sys_os_version);
|
||||
version_present=RegDft("Adam/SysRegVer",buf,TRUE);
|
||||
RegExe("Adam");
|
||||
if (registry_version!=sys_os_version) {
|
||||
RegWrite("Adam/SysRegVer",buf);
|
||||
RegExe("Adam");
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "Boot/Once;Registry/Once"
|
||||
#help_file "::/Doc/Once"
|
||||
|
||||
public U0 AOnceFlush()
|
||||
{//Flush AOnce() buf.
|
||||
RegWrite("Once/Adam","");
|
||||
}
|
||||
|
||||
public U0 OnceFlush()
|
||||
{//Flush Once() buf.
|
||||
RegWrite("Once/User","");
|
||||
}
|
||||
|
||||
public U0 AOnce(U8 *fmt,...)
|
||||
{//Add Adam code to $LK,"~/Registry.HC"$, executed next boot.
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
if (!Bt(&sys_run_level,RLf_ONCE_ADAM))
|
||||
AOnceFlush;
|
||||
RegAppend("Once/Adam","%s\n",buf);
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
public U0 Once(U8 *fmt,...)
|
||||
{//Add User code to $LK,"~/Registry.HC"$, executed next boot.
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
if (!Bt(&sys_run_level,RLf_ONCE_USER))
|
||||
OnceFlush;
|
||||
RegAppend("Once/User","%s\n",buf);
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
public U0 AOnceDrv(U8 drv_let=0,U8 *fmt,...)
|
||||
{//Add Adam code to drv $LK,"~/Registry.HC"$, executed next boot.
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
I64 old_drv_let=*sys_registry_doc->filename.name;
|
||||
if (drv_let)
|
||||
*sys_registry_doc->filename.name=drv_let;
|
||||
if (!Bt(&sys_run_level,RLf_ONCE_ADAM))
|
||||
AOnceFlush;
|
||||
RegAppend("Once/Adam","%s\n",buf);
|
||||
Free(buf);
|
||||
*sys_registry_doc->filename.name=old_drv_let;
|
||||
}
|
||||
|
||||
public U0 OnceDrv(U8 drv_let=0,U8 *fmt,...)
|
||||
{//Add User code to drv $LK,"~/Registry.HC"$, executed next boot.
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
I64 old_drv_let=*sys_registry_doc->filename.name;
|
||||
if (drv_let)
|
||||
*sys_registry_doc->filename.name=drv_let;
|
||||
if (!Bt(&sys_run_level,RLf_ONCE_USER))
|
||||
OnceFlush;
|
||||
RegAppend("Once/User","%s\n",buf);
|
||||
Free(buf);
|
||||
*sys_registry_doc->filename.name=old_drv_let;
|
||||
}
|
||||
|
||||
public U0 OnceExe()
|
||||
{//Execute Once code. Call goes in $LK,"~/Once.HC"$.
|
||||
try {
|
||||
|
||||
RegDft("Once/Adam","");
|
||||
if (RegCnt("Once/Adam")>2) {
|
||||
Adam("RegExe(\"Once/Adam\");");
|
||||
AOnceFlush;
|
||||
}
|
||||
LBts(&sys_run_level,RLf_ONCE_ADAM);
|
||||
|
||||
RegDft("Once/User","");
|
||||
if (RegCnt("Once/User")>2) {
|
||||
RegExe("Once/User");
|
||||
OnceFlush;
|
||||
}
|
||||
LBts(&sys_run_level,RLf_ONCE_USER);
|
||||
|
||||
} catch {
|
||||
AOnceFlush;
|
||||
LBts(&sys_run_level,RLf_ONCE_ADAM);
|
||||
OnceFlush;
|
||||
LBts(&sys_run_level,RLf_ONCE_USER);
|
||||
}
|
||||
}
|
||||
409
temple-src/Adam/ASnd.HC
Executable file
409
temple-src/Adam/ASnd.HC
Executable file
@ -0,0 +1,409 @@
|
||||
#help_index "Snd"
|
||||
public U0 SndTaskEndCB()
|
||||
{//Will turn-off snd when a task gets killed.
|
||||
Snd;
|
||||
Exit;
|
||||
}
|
||||
|
||||
#help_index "Snd/Math;Math"
|
||||
public F64 Saw(F64 t,F64 period)
|
||||
{//Sawtooth. 0.0 - 1.0 think "(Sin+1)/2"
|
||||
if (period) {
|
||||
if (t>=0.0)
|
||||
return t%period/period;
|
||||
else
|
||||
return 1.0+t%period/period;
|
||||
} else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public F64 FullSaw(F64 t,F64 period)
|
||||
{//Plus&Minus Sawtooth. 1.0 - -1.0 think "Sin"
|
||||
if (period) {
|
||||
if (t>=0.0)
|
||||
return 2.0*(t%period/period)-1.0;
|
||||
else
|
||||
return 2.0*(t%period/period)+1.0;
|
||||
} else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public F64 Caw(F64 t,F64 period)
|
||||
{//Cawtooth. 1.0 - 0.0 think "(Cos+1)/2"
|
||||
if (period) {
|
||||
if (t>=0.0)
|
||||
return 1.0-t%period/period;
|
||||
else
|
||||
return -(t%period)/period;
|
||||
} else
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public F64 FullCaw(F64 t,F64 period)
|
||||
{//Plus&Minus Cawtooth. 1.0 - -1.0 think "Cos"
|
||||
if (period) {
|
||||
if (t>=0.0)
|
||||
return -2.0*(t%period/period)+1.0;
|
||||
else
|
||||
return -2.0*(t%period/period)-1.0;
|
||||
} else
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
public F64 Tri(F64 t,F64 period)
|
||||
{//Triangle waveform. 0.0 - 1.0 - 0.0
|
||||
if (period) {
|
||||
t=2.0*(Abs(t)%period)/period;
|
||||
if (t<=1.0)
|
||||
return t;
|
||||
else
|
||||
return 2.0-t;
|
||||
} else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
public F64 FullTri(F64 t,F64 period)
|
||||
{//Plus&Minus Triangle waveform. 0.0 - 1.0 - 0.0 - -1.0 -0.0
|
||||
if (period) {
|
||||
t=4.0*(t%period)/period;
|
||||
if (t<=-1.0) {
|
||||
if (t<=-3.0)
|
||||
return t+4.0;
|
||||
else
|
||||
return -2.0-t;
|
||||
} else {
|
||||
if (t<=1.0)
|
||||
return t;
|
||||
else if (t<=3.0)
|
||||
return 2.0-t;
|
||||
else
|
||||
return t-4.0;
|
||||
}
|
||||
} else
|
||||
return 0.0;
|
||||
}
|
||||
|
||||
#help_index "Snd/Music"
|
||||
|
||||
public class CMusicGlbls
|
||||
{
|
||||
U8 *cur_song;
|
||||
CTask *cur_song_task;
|
||||
I64 octave;
|
||||
F64 note_len;
|
||||
U8 note_map[7];
|
||||
Bool mute;
|
||||
I64 meter_top,meter_bottom;
|
||||
F64 tempo,stacatto_factor;
|
||||
|
||||
//If you wish to sync with a
|
||||
//note in a Play() string. 0 is the start
|
||||
I64 play_note_num;
|
||||
|
||||
F64 tM_correction,last_Beat,last_tM;
|
||||
} music={NULL,NULL,4,1.0,{0,2,3,5,7,8,10},FALSE,4,4,2.5,0.9,0,0,0,0};
|
||||
|
||||
#help_index "Snd/Music;Time/Seconds"
|
||||
public F64 tM()
|
||||
{//Time in seconds synced to music subsystem.
|
||||
return (cnts.jiffies+music.tM_correction)/JIFFY_FREQ;
|
||||
}
|
||||
|
||||
public F64 Beat()
|
||||
{//Time in music beats.
|
||||
F64 res,cur_tM;
|
||||
PUSHFD
|
||||
CLI
|
||||
if (mp_cnt>1)
|
||||
while (LBts(&sys_semas[SEMA_TMBEAT],0))
|
||||
PAUSE
|
||||
cur_tM=tM;
|
||||
res=music.last_Beat;
|
||||
if (music.tempo)
|
||||
res+=(cur_tM-music.last_tM)*music.tempo;
|
||||
music.last_tM=cur_tM;
|
||||
music.last_Beat=res;
|
||||
LBtr(&sys_semas[SEMA_TMBEAT],0);
|
||||
POPFD
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "Snd/Music"
|
||||
U8 *MusicSetOctave(U8 *st)
|
||||
{
|
||||
I64 ch;
|
||||
ch=*st++;
|
||||
while ('0'<=ch<='9') {
|
||||
music.octave=ch-'0';
|
||||
ch=*st++;
|
||||
}
|
||||
return --st;
|
||||
}
|
||||
|
||||
U8 *MusicSetMeter(U8 *st)
|
||||
{
|
||||
I64 ch;
|
||||
ch=*st++;
|
||||
while (ch=='M') {
|
||||
ch=*st++;
|
||||
if ('0'<=ch<='9') {
|
||||
music.meter_top=ch-'0';
|
||||
ch=*st++;
|
||||
}
|
||||
if (ch=='/')
|
||||
ch=*st++;
|
||||
if ('0'<=ch<='9') {
|
||||
music.meter_bottom=ch-'0';
|
||||
ch=*st++;
|
||||
}
|
||||
}
|
||||
return --st;
|
||||
}
|
||||
|
||||
U8 *MusicSetNoteLen(U8 *st)
|
||||
{
|
||||
Bool cont=TRUE;
|
||||
do {
|
||||
switch (*st++) {
|
||||
case 'w': music.note_len=4.0; break;
|
||||
case 'h': music.note_len=2.0; break;
|
||||
case 'q': music.note_len=1.0; break;
|
||||
case 'e': music.note_len=0.5; break;
|
||||
case 's': music.note_len=0.25; break;
|
||||
case 't': music.note_len=2.0*music.note_len/3.0; break;
|
||||
case '.': music.note_len=1.5*music.note_len; break;
|
||||
default:
|
||||
st--;
|
||||
cont=FALSE;
|
||||
}
|
||||
} while (cont);
|
||||
return st;
|
||||
}
|
||||
|
||||
public I8 Note2Ona(I64 note,I64 octave=4)
|
||||
{//Note to ona. Mid C is ona=51, note=3 and octave=4.
|
||||
if (note<3)
|
||||
return (octave+1)*12+note;
|
||||
else
|
||||
return octave*12+note;
|
||||
}
|
||||
|
||||
public I8 Ona2Note(I8 ona)
|
||||
{//Ona to note in octave. Mid C is ona=51, note=3 and octave=4.
|
||||
return ona%12;
|
||||
}
|
||||
|
||||
public I8 Ona2Octave(I8 ona)
|
||||
{//Ona to octave. Mid C is ona=51, note=3 and octave=4.
|
||||
I64 note=ona%12,octave=ona/12;
|
||||
if (note<3)
|
||||
return octave-1;
|
||||
else
|
||||
return octave;
|
||||
}
|
||||
|
||||
public U0 Play(U8 *st,U8 *words=NULL)
|
||||
{/* Notes are entered with a capital letter.
|
||||
|
||||
Octaves are entered with a digit and
|
||||
stay set until changed. Mid C is octave 4.
|
||||
|
||||
Durations are entered with
|
||||
'w' whole note
|
||||
'h' half note
|
||||
'q' quarter note
|
||||
'e' eighth note
|
||||
't' sets to 2/3rds the current duration
|
||||
'.' sets to 1.5 times the current duration
|
||||
durations stay set until changed.
|
||||
|
||||
'(' tie, placed before the note to be extended
|
||||
|
||||
$LK,"music.meter_top",A="MN:CMusicGlbls"$,$LK,"music.meter_bottom",A="MN:CMusicGlbls"$ is set with
|
||||
"M3/4"
|
||||
"M4/4"
|
||||
etc.
|
||||
|
||||
Sharp and flat are done with '#' or 'b'.
|
||||
|
||||
The var music.stacatto_factor can
|
||||
be set to a range from 0.0 to 1.0.
|
||||
|
||||
The var music.tempo is quarter-notes
|
||||
per second.It defaults to
|
||||
2.5 and gets faster when bigger.
|
||||
*/
|
||||
U8 *word,*last_st;
|
||||
I64 note,octave,i=0,ona,timeout_val,timeout_val2;
|
||||
Bool tie;
|
||||
F64 d,on_jiffies,off_jiffies;
|
||||
music.play_note_num=0;
|
||||
while (*st) {
|
||||
timeout_val=cnts.jiffies;
|
||||
tie=FALSE;
|
||||
|
||||
do {
|
||||
last_st=st;
|
||||
if (*st=='(') {
|
||||
tie=TRUE;
|
||||
st++;
|
||||
} else {
|
||||
st=MusicSetMeter(st);
|
||||
st=MusicSetOctave(st);
|
||||
st=MusicSetNoteLen(st);
|
||||
}
|
||||
} while (st!=last_st);
|
||||
|
||||
if (!*st) break;
|
||||
note=*st++-'A';
|
||||
if (note<7) {
|
||||
note=music.note_map[note];
|
||||
octave=music.octave;
|
||||
if (*st=='b') {
|
||||
note--;
|
||||
if (note==2)
|
||||
octave--;
|
||||
st++;
|
||||
} else if (*st=='#') {
|
||||
note++;
|
||||
if (note==3)
|
||||
octave++;
|
||||
st++;
|
||||
}
|
||||
ona=Note2Ona(note,octave);
|
||||
} else
|
||||
ona=0;
|
||||
if (words && (word=LstSub(i++,words)) && StrCmp(word,""))
|
||||
"%s",word;
|
||||
|
||||
d=JIFFY_FREQ*music.note_len/music.tempo;
|
||||
on_jiffies =d*music.stacatto_factor;
|
||||
off_jiffies =d*(1.0-music.stacatto_factor);
|
||||
|
||||
timeout_val+=on_jiffies;
|
||||
timeout_val2=timeout_val+off_jiffies;
|
||||
|
||||
if (!music.mute)
|
||||
Snd(ona);
|
||||
SleepUntil(timeout_val);
|
||||
music.tM_correction+=on_jiffies-ToI64(on_jiffies);
|
||||
|
||||
if (!music.mute && !tie)
|
||||
Snd;
|
||||
SleepUntil(timeout_val2);
|
||||
music.tM_correction+=off_jiffies-ToI64(off_jiffies);
|
||||
|
||||
music.play_note_num++;
|
||||
}
|
||||
}
|
||||
|
||||
U0 MusicSettingsRst()
|
||||
{
|
||||
music.play_note_num=0;
|
||||
music.stacatto_factor=0.9;
|
||||
music.tempo=2.5;
|
||||
music.octave=4;
|
||||
music.note_len=1.0;
|
||||
music.meter_top=4;
|
||||
music.meter_bottom=4;
|
||||
SndRst;
|
||||
PUSHFD
|
||||
CLI
|
||||
if (mp_cnt>1)
|
||||
while (LBts(&sys_semas[SEMA_TMBEAT],0))
|
||||
PAUSE
|
||||
music.last_tM=tM;
|
||||
music.last_Beat=0.0;
|
||||
LBtr(&sys_semas[SEMA_TMBEAT],0);
|
||||
POPFD
|
||||
}
|
||||
|
||||
MusicSettingsRst;
|
||||
|
||||
U0 CurSongTask()
|
||||
{
|
||||
Fs->task_end_cb=&SndTaskEndCB;
|
||||
while (TRUE)
|
||||
Play(music.cur_song);
|
||||
}
|
||||
|
||||
#help_index "Snd"
|
||||
|
||||
#define SE_NOISE 0
|
||||
#define SE_SWEEP 1
|
||||
|
||||
class CSoundEffectFrame
|
||||
{
|
||||
I32 type;
|
||||
I8 ona1,ona2;
|
||||
F64 duration;
|
||||
};
|
||||
|
||||
U0 SoundEffectEndTaskCB()
|
||||
{
|
||||
Free(FramePtr("CSoundEffectFrame"));
|
||||
music.mute--;
|
||||
SndTaskEndCB;
|
||||
}
|
||||
|
||||
U0 SoundEffectTask(CSoundEffectFrame *ns)
|
||||
{
|
||||
I64 i,ona;
|
||||
F64 t0=tS,t,timeout=t0+ns->duration;
|
||||
FramePtrAdd("CSoundEffectFrame",ns);
|
||||
Fs->task_end_cb=&SoundEffectEndTaskCB;
|
||||
switch (ns->type) {
|
||||
case SE_NOISE:
|
||||
i=MaxI64(ns->ona2-ns->ona1,1);
|
||||
while (tS<timeout) {
|
||||
ona=RandU16%i+ns->ona1;
|
||||
Snd(ona);
|
||||
t=Clamp(3000.0/Ona2Freq(ona),1.0,50.0);
|
||||
if (t+tS>timeout)
|
||||
t=timeout-tS;
|
||||
Sleep(t);
|
||||
}
|
||||
break;
|
||||
case SE_SWEEP:
|
||||
while (tS<timeout) {
|
||||
t=(tS-t0)/ns->duration;
|
||||
ona=(1.0-t)*ns->ona1+t*ns->ona2;
|
||||
Snd(ona);
|
||||
t=Clamp(3000.0/Ona2Freq(ona),1.0,50.0);
|
||||
if (t+tS>timeout)
|
||||
t=timeout-tS;
|
||||
Sleep(t);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public CTask *Noise(I64 mS,F64 min_ona,F64 max_ona)
|
||||
{//Make white noise for given number of mS.
|
||||
CSoundEffectFrame *ns;
|
||||
if (mS>0) {
|
||||
ns=MAlloc(sizeof(CSoundEffectFrame));
|
||||
ns->type=SE_NOISE;
|
||||
ns->duration=mS/1000.0;
|
||||
ns->ona1=min_ona;
|
||||
ns->ona2=max_ona;
|
||||
music.mute++;
|
||||
return Spawn(&SoundEffectTask,ns,"Noise",,Fs);
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public CTask *Sweep(I64 mS,F64 ona1,F64 ona2)
|
||||
{//Sweep through freq range in given number of mS.
|
||||
CSoundEffectFrame *ns;
|
||||
if (mS>0) {
|
||||
ns=MAlloc(sizeof(CSoundEffectFrame));
|
||||
ns->type=SE_SWEEP;
|
||||
ns->duration=mS/1000.0;
|
||||
ns->ona1=ona1;
|
||||
ns->ona2=ona2;
|
||||
music.mute++;
|
||||
return Spawn(&SoundEffectTask,ns,"Noise",,Fs);
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
261
temple-src/Adam/AutoComplete/ACDictGen.HC
Executable file
261
temple-src/Adam/AutoComplete/ACDictGen.HC
Executable file
@ -0,0 +1,261 @@
|
||||
/*
|
||||
This file is a stand-alone program
|
||||
which will regenerate processed dictionary
|
||||
files from a raw Project Gutenberg
|
||||
dictionary file.
|
||||
|
||||
See $LK,"::/Doc/Credits.DD"$.
|
||||
*/
|
||||
|
||||
U0 ACDPreprocess(U8 *in_name,U8 *out_name)
|
||||
{/*
|
||||
<cr><nl>--> <nl>
|
||||
$$ --> $$$$
|
||||
\'89 --> ‰
|
||||
*/
|
||||
I64 ch,i;
|
||||
U8 *src,*dst;
|
||||
CDoc *doc;
|
||||
CDocEntry *doc_e;
|
||||
if (doc=DocRead(in_name,DOCF_PLAIN_TEXT_TABS|DOCF_DBL_DOLLARS)) {
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->type_u8==DOCT_TEXT) {
|
||||
src=dst=doc_e->tag;
|
||||
while (ch=*src++) {
|
||||
if (ch=='\\' && *src=='\'') {
|
||||
src++;
|
||||
i=0;
|
||||
ch=ToUpper(*src++);
|
||||
if ('0'<=ch<='9')
|
||||
i+=ch-'0';
|
||||
else if ('A'<=ch<='F')
|
||||
i+=ch-'A'+10;
|
||||
i<<=4;
|
||||
ch=ToUpper(*src++);
|
||||
if ('0'<=ch<='9')
|
||||
i+=ch-'0';
|
||||
else if ('A'<=ch<='F')
|
||||
i+=ch-'A'+10;
|
||||
*dst++=i;
|
||||
} else
|
||||
*dst++=ch;
|
||||
}
|
||||
*dst=0;
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
StrCpy(doc->filename.name,out_name);
|
||||
DocWrite(doc);
|
||||
DocDel(doc);
|
||||
}
|
||||
}
|
||||
|
||||
I64 ACDNextCmd(U8 **_ptr)
|
||||
{
|
||||
U8 *ptr=*_ptr,*ptr2;
|
||||
I64 ch,res=-1;
|
||||
do {
|
||||
do {
|
||||
if (!(ch=*ptr++)) goto ncmd_done;
|
||||
} while (ch!='<');
|
||||
|
||||
ptr2=ptr;
|
||||
do {
|
||||
if (!(ch=*ptr2++)) goto ncmd_done;
|
||||
} while (ch!='>');
|
||||
*--ptr2=0;
|
||||
res=LstMatch(ptr,"h1\0/h1\0def\0/def\0hw\0/hw\0tt\0/tt\0"
|
||||
"ety\0@fld\0@cd\0@blockquote\0@wordforms\0@note\0@altname\0@chform\0"
|
||||
"@cref\0@syn\0/ety\0@/fld\0@/cd\0@/blockquote\0@/wordforms\0@/note\0"
|
||||
"@/altname\0@/chform\0@/cref\0@/syn\0");
|
||||
*ptr2++='>';
|
||||
ptr=ptr2;
|
||||
} while (res<0);
|
||||
|
||||
ncmd_done:
|
||||
*_ptr=ptr;
|
||||
return res;
|
||||
}
|
||||
|
||||
U8 *ACDNextEntry(U8 **_ptr)
|
||||
{
|
||||
U8 *res,*ignore,*ptr=*_ptr,buf[ACD_BLK_SIZE],*out_ptr=buf;
|
||||
I64 ch,l;
|
||||
while (TRUE) {
|
||||
while (TRUE) {
|
||||
if (!(ch=*ptr++)) goto nentry_done;
|
||||
if (ch!='<') {
|
||||
*out_ptr++=ch;
|
||||
if (ch=='$$')
|
||||
*out_ptr++=ch;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
ignore="b>\0i>\0ppp>\0/b>\0/i>\0/p>\0"
|
||||
"ets>\0col>\0spn>\0/ets>\0/col>\0/spn>\0er>\0as>\0cs>\0cd>\0ex>\0"
|
||||
"/er>\0/as>\0/cs>\0/cd>\0/ex>\0"
|
||||
"note>\0/note>\0blockquote>\0/blockquote>\0";
|
||||
while (*ignore) {
|
||||
l=StrLen(ignore);
|
||||
if (!StrNCmp(ptr,ignore,l)) {
|
||||
ptr+=l;
|
||||
break;
|
||||
} else
|
||||
ignore+=l+1;
|
||||
}
|
||||
if (!*ignore)
|
||||
break;
|
||||
}
|
||||
nentry_done:
|
||||
*out_ptr++=0;
|
||||
res=StrNew(buf);
|
||||
*_ptr=ptr-1;
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 ACDCompareWords(U8 *e1,U8 *e2)
|
||||
{
|
||||
return StrICmp(e1,e2);
|
||||
}
|
||||
|
||||
U8 *ACDSortWords(U8 *start,I64 size,I64 word_cnt)
|
||||
{
|
||||
U8 **ptr_array=MAlloc(sizeof(U8 *)*word_cnt),
|
||||
*out_start=MAlloc(size),
|
||||
*ptr=start,*ptr2;
|
||||
I64 i=0;
|
||||
while (*ptr) {
|
||||
ptr_array[i++]=ptr;
|
||||
ptr+=StrLen(ptr)+3;
|
||||
}
|
||||
"Sorting...\n"; Sleep(100);
|
||||
QSortI64(ptr_array,word_cnt,&ACDCompareWords);
|
||||
"Done...\n"; Sleep(100);
|
||||
|
||||
ptr=out_start;
|
||||
for (i=0;i<word_cnt;i++) {
|
||||
ptr2=ptr_array[i];
|
||||
while (*ptr2)
|
||||
*ptr++=*ptr2++;
|
||||
*ptr++=*ptr2++; //zero
|
||||
*ptr++=*ptr2++; //blk lo
|
||||
*ptr++=*ptr2++; //blk hi
|
||||
}
|
||||
*ptr++=0;
|
||||
return out_start;
|
||||
}
|
||||
|
||||
U0 ACDGen(U8 *in_file)
|
||||
{
|
||||
I64 cmd,size,word_cnt=0,largest_entry=0;
|
||||
U8 *st,*in_ptr=FileRead(in_file,&size),*in_start=in_ptr,
|
||||
*out_ptr=MAlloc(size),*out_start=out_ptr,
|
||||
*word_ptr=MAlloc(size),*word_start=word_ptr,
|
||||
*last_word="",*def_word_start=out_ptr,
|
||||
*sorted_word_start;
|
||||
U16 *d;
|
||||
if (!in_ptr) return;
|
||||
do {
|
||||
cmd=ACDNextCmd(&in_ptr);
|
||||
if (cmd==ACD_H1) {
|
||||
next_word:
|
||||
if (out_ptr-def_word_start>largest_entry)
|
||||
largest_entry=out_ptr-def_word_start;
|
||||
def_word_start=out_ptr;
|
||||
if (st=ACDNextEntry(&in_ptr)) {
|
||||
if (*st) {
|
||||
if (StrICmp(st,last_word)) {
|
||||
word_cnt++;
|
||||
|
||||
*word_ptr++=ACD_WORD_CHAR;
|
||||
last_word=word_ptr;
|
||||
StrCpy(word_ptr,st);
|
||||
word_ptr+=StrLen(st)+1;
|
||||
|
||||
d=word_ptr;
|
||||
*d=(out_ptr-out_start)/ACD_BLK_SIZE;
|
||||
word_ptr+=2;
|
||||
|
||||
*out_ptr++=ACD_WORD_CHAR;
|
||||
StrCpy(out_ptr,st);
|
||||
out_ptr+=StrLen(st)+1;
|
||||
}
|
||||
Free(st);
|
||||
|
||||
do {
|
||||
do {
|
||||
cmd=ACDNextCmd(&in_ptr);
|
||||
if (cmd==ACD_H1)
|
||||
goto next_word;
|
||||
} while (cmd>=0 && !(cmd==ACD_DEF||cmd==ACD_PRONUNCIATION||
|
||||
cmd==ACD_POS||cmd==ACD_EXTRA));
|
||||
if (cmd==ACD_DEF) {
|
||||
if(st=ACDNextEntry(&in_ptr)) {
|
||||
if (*st) {
|
||||
*out_ptr++=ACD_DEF_CHAR;
|
||||
StrCpy(out_ptr,st);
|
||||
out_ptr+=StrLen(st)+1;
|
||||
}
|
||||
Free(st);
|
||||
}
|
||||
} else if (cmd==ACD_PRONUNCIATION) {
|
||||
if(st=ACDNextEntry(&in_ptr)) {
|
||||
if (*st) {
|
||||
*out_ptr++=ACD_PRONUNCIATION_CHAR;
|
||||
StrCpy(out_ptr,st);
|
||||
out_ptr+=StrLen(st)+1;
|
||||
}
|
||||
Free(st);
|
||||
}
|
||||
} else if (cmd==ACD_POS) {
|
||||
if(st=ACDNextEntry(&in_ptr)) {
|
||||
if (*st) {
|
||||
*out_ptr++=ACD_POS_CHAR;
|
||||
StrCpy(out_ptr,st);
|
||||
out_ptr+=StrLen(st)+1;
|
||||
}
|
||||
Free(st);
|
||||
}
|
||||
} else if (cmd==ACD_EXTRA) {
|
||||
if(st=ACDNextEntry(&in_ptr)) {
|
||||
if (*st) {
|
||||
*out_ptr++=ACD_EXTRA_CHAR;
|
||||
StrCpy(out_ptr,st);
|
||||
out_ptr+=StrLen(st)+1;
|
||||
}
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
} while (cmd==ACD_DEF||cmd==ACD_PRONUNCIATION||
|
||||
cmd==ACD_POS||cmd==ACD_EXTRA);
|
||||
} else
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
} while (cmd>=0);
|
||||
*out_ptr++=ACD_END_CHAR;
|
||||
*word_ptr++=ACD_END_CHAR;
|
||||
|
||||
Free(in_start);
|
||||
|
||||
"Blk Size:%d\n",ACD_BLK_SIZE;
|
||||
"Blk Cnt:%04X\n",(out_ptr-out_start+ACD_BLK_SIZE-1)/ACD_BLK_SIZE;
|
||||
"Largest Entry:%d\n",largest_entry;
|
||||
"Word Count:%d\n",word_cnt;
|
||||
|
||||
FileWrite(ACD_DEF_FILENAME,out_start,out_ptr-out_start);
|
||||
"Def File Size:%d\n",out_ptr-out_start;
|
||||
|
||||
sorted_word_start=ACDSortWords(word_start,word_ptr-word_start,word_cnt);
|
||||
FileWrite(ACD_WORD_FILENAME,sorted_word_start,word_ptr-word_start);
|
||||
"Word File Size:%d\n",word_ptr-word_start;
|
||||
|
||||
Free(out_start);
|
||||
Free(word_start);
|
||||
Free(sorted_word_start);
|
||||
}
|
||||
|
||||
Cd(__DIR__);
|
||||
ACDPreprocess("DICTIONARY.DD","DICTIONARY2.DD");
|
||||
ACDGen("DICTIONARY2.DD");
|
||||
226
temple-src/Adam/AutoComplete/ACFill.HC
Executable file
226
temple-src/Adam/AutoComplete/ACFill.HC
Executable file
@ -0,0 +1,226 @@
|
||||
#help_index "AutoComplete/Dictionary"
|
||||
public U8 *ACDDefGet(U8 *st,I64 def_num=1)
|
||||
{//MAlloc str holding single dict definition of word.
|
||||
CFile *f;
|
||||
CHashGeneric *tmph;
|
||||
U8 *res=NULL,*buf,*in_ptr,
|
||||
*st2=MStrUtil(st,SUF_TO_UPPER);
|
||||
tmph=HashFind(st2,ac.hash_table,HTT_DICT_WORD);
|
||||
Free(st2);
|
||||
if (tmph) {
|
||||
if (f=FOpen(ACD_DEF_FILENAME,"r")) {
|
||||
buf=MAlloc(ACD_BLK_SIZE*2+1);
|
||||
buf[ACD_BLK_SIZE*2]=0; //terminate
|
||||
FBlkRead(f,buf,tmph->user_data0*ACD_BLK_SIZE/BLK_SIZE,
|
||||
ACD_BLK_SIZE*2/BLK_SIZE);
|
||||
FClose(f);
|
||||
in_ptr=buf;
|
||||
while (in_ptr<buf+ACD_BLK_SIZE*2) {
|
||||
while (*in_ptr!=ACD_WORD_CHAR && in_ptr<buf+ACD_BLK_SIZE*2)
|
||||
in_ptr++;
|
||||
if (*in_ptr++==ACD_WORD_CHAR) {
|
||||
if (!StrICmp(st,in_ptr)) {
|
||||
while (def_num && *in_ptr!=ACD_WORD_CHAR
|
||||
&& in_ptr<buf+ACD_BLK_SIZE*2) {
|
||||
if (*in_ptr==ACD_DEF_CHAR) {
|
||||
if (!--def_num)
|
||||
break;
|
||||
else
|
||||
in_ptr++;
|
||||
} else
|
||||
in_ptr++;
|
||||
}
|
||||
if (*in_ptr++==ACD_DEF_CHAR) {
|
||||
res=StrNew(in_ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(buf);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *ACDDefsGet(U8 *st)
|
||||
{//MAlloc str with all dict definitions of word.
|
||||
CFile *f;
|
||||
CHashGeneric *tmph;
|
||||
U8 *res=NULL,*buf,*in_ptr,*in_ptr2,
|
||||
*st2=MStrUtil(st,SUF_TO_UPPER);
|
||||
tmph=HashFind(st2,ac.hash_table,HTT_DICT_WORD);
|
||||
Free(st2);
|
||||
if (tmph) {
|
||||
if (f=FOpen(ACD_DEF_FILENAME,"r")) {
|
||||
buf=MAlloc(ACD_BLK_SIZE*2+1);
|
||||
buf[ACD_BLK_SIZE*2]=0; //terminate
|
||||
FBlkRead(f,buf,tmph->user_data0*ACD_BLK_SIZE/BLK_SIZE,
|
||||
ACD_BLK_SIZE*2/BLK_SIZE);
|
||||
FClose(f);
|
||||
in_ptr=buf;
|
||||
while (in_ptr<buf+ACD_BLK_SIZE*2) {
|
||||
while (*in_ptr!=ACD_WORD_CHAR && in_ptr<buf+ACD_BLK_SIZE*2)
|
||||
in_ptr++;
|
||||
if (*in_ptr++==ACD_WORD_CHAR) {
|
||||
if (!StrICmp(st,in_ptr)) {
|
||||
in_ptr2=in_ptr;
|
||||
in_ptr--;
|
||||
while (*in_ptr2!=ACD_WORD_CHAR
|
||||
&& in_ptr2<buf+ACD_BLK_SIZE*2) {
|
||||
in_ptr2++;
|
||||
}
|
||||
res=MAlloc(in_ptr2+1-in_ptr);
|
||||
MemCpy(res,in_ptr,in_ptr2-in_ptr);
|
||||
res[in_ptr2-in_ptr]=ACD_END_CHAR;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
Free(buf);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
/*Fmt of word lst entry:
|
||||
U8 ACD_WORD_CHAR
|
||||
U8 word[] with terminating zero
|
||||
I16 block;
|
||||
*/
|
||||
public U8 *ACDWordPtAt(U8 *st)
|
||||
{//Point to word in word list.
|
||||
I64 i;
|
||||
U8 *start=acd.word_lst,*r=start,
|
||||
*end=acd.word_lst+acd.word_lst_size;
|
||||
if (!st || !*st)
|
||||
return acd.word_lst;
|
||||
if (acd.word_lst_size) {
|
||||
while (start+3<end) {
|
||||
r=(start+end)>>1;
|
||||
while (TRUE) {
|
||||
while (*r!=ACD_WORD_CHAR && r>acd.word_lst)
|
||||
r--;
|
||||
if ((r[2]==ACD_WORD_CHAR||r[1]==ACD_WORD_CHAR)&&r-3>acd.word_lst)
|
||||
r--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (*r==ACD_WORD_CHAR) {
|
||||
i=StrICmp(st,r+1);
|
||||
if (i<0)
|
||||
end=r-1;
|
||||
else if (i>0)
|
||||
start=r+StrLen(r)+3;
|
||||
else
|
||||
return r;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
r=(start+end)>>1;
|
||||
while (TRUE) {
|
||||
while (*r!=ACD_WORD_CHAR && r>acd.word_lst)
|
||||
r--;
|
||||
if ((r[2]==ACD_WORD_CHAR||r[1]==ACD_WORD_CHAR)&&r-3>acd.word_lst)
|
||||
r--;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (*r==ACD_WORD_CHAR && StrICmp(st,r+1)>0)
|
||||
r+=StrLen(r)+3;
|
||||
}
|
||||
if (*r==ACD_WORD_CHAR)
|
||||
return r;
|
||||
else
|
||||
return acd.word_lst;
|
||||
}
|
||||
|
||||
U0 ACDFillin(I64 n)
|
||||
{
|
||||
U8 *s;
|
||||
I64 len;
|
||||
if (0<=n<acd.num_fillins) {
|
||||
s=acd.fillins[n]+1;
|
||||
len=StrLen(s);
|
||||
if (len>ac.partial_len)
|
||||
In(s+ac.partial_len);
|
||||
}
|
||||
}
|
||||
|
||||
public U0 ACDDefsPut(CDoc *doc=NULL,U8 *st,I64 num=-1)
|
||||
{//Put to doc a dictionary definition(s) of a word.
|
||||
U8 *st2,*st3;
|
||||
I64 ch,i=0;
|
||||
if (!st) return;
|
||||
if (*st==ACD_WORD_CHAR)
|
||||
st++;
|
||||
DocPrint(doc,"$$WW,1$$$$RED$$%s:$$FG$$\n\n",st);
|
||||
if (num<0) {
|
||||
if (st3=ACDDefsGet(st)) {
|
||||
st2=st3;
|
||||
while (ch=*st2++) {
|
||||
switch (ch) {
|
||||
case ACD_WORD_CHAR:
|
||||
break;
|
||||
case ACD_DEF_CHAR:
|
||||
DocPrint(doc,"$$GREEN$$(%d)$$FG$$ %s\n",
|
||||
++i,st2);
|
||||
break;
|
||||
case ACD_PRONUNCIATION_CHAR:
|
||||
DocPrint(doc,"$$LTGREEN$$%s$$FG$$\n",st2);
|
||||
break;
|
||||
case ACD_POS_CHAR:
|
||||
DocPrint(doc,"$$BLACK$$%s$$FG$$\n",st2);
|
||||
break;
|
||||
case ACD_EXTRA_CHAR:
|
||||
DocPrint(doc,"$$LTBLUE$$%s$$FG$$\n",st2);
|
||||
break;
|
||||
}
|
||||
st2+=StrLen(st2)+1;
|
||||
}
|
||||
Free(st3);
|
||||
}
|
||||
} else {
|
||||
while (st2=ACDDefGet(st,++i)) {
|
||||
if (i==num)
|
||||
DocPrint(doc,"$$GREEN$$(%d)$$FG$$ %s\n",
|
||||
i,st2);
|
||||
Free(st2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 ACDPopUpDef(U8 *st,I64 num=-1,CTask *parent=NULL)
|
||||
{
|
||||
U8 *buf;
|
||||
buf=MStrPrint("ACDDefsPut(DocPut,\"%s\",%d);View;",st,num);
|
||||
PopUp(buf,parent);
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
U0 ACDDef(I64 n,CTask *parent=NULL)
|
||||
{
|
||||
if (0<=n<acd.num_fillins)
|
||||
ACDPopUpDef(acd.fillins[n],-1,parent);
|
||||
}
|
||||
|
||||
#help_index "AutoComplete"
|
||||
U0 ACFillIn(I64 n)
|
||||
{
|
||||
U8 *s;
|
||||
if (0<=--n<ac.num_fillins) {
|
||||
s=ac.fillin_matches[n]->str;
|
||||
if (StrLen(s)>ac.partial_len)
|
||||
In(s+ac.partial_len);
|
||||
}
|
||||
}
|
||||
|
||||
U0 ACMan(I64 n,CTask *parent_task=NULL)
|
||||
{
|
||||
CHashAC *tmpw;
|
||||
CHashSrcSym *tmph;
|
||||
if (0<=--n<ac.num_fillins && (tmpw=ac.fillin_matches[n]) &&
|
||||
(tmph=HashFind(tmpw->str,Fs->hash_table,HTG_SRC_SYM)) &&
|
||||
tmph->src_link)
|
||||
PopUpEd(tmph->src_link,parent_task);
|
||||
}
|
||||
169
temple-src/Adam/AutoComplete/ACInit.HC
Executable file
169
temple-src/Adam/AutoComplete/ACInit.HC
Executable file
@ -0,0 +1,169 @@
|
||||
#help_index "AutoComplete/Dictionary"
|
||||
acd.has_words=FileFind(ACD_WORD_FILENAME);
|
||||
acd.has_defs =FileFind(ACD_DEF_FILENAME)||FileFind(ACD_DEF_FILENAME_Z);
|
||||
|
||||
public U0 ACDWordsLoad()
|
||||
{//Put words from word list into hash table.
|
||||
I64 size;
|
||||
CHashGeneric *tmph;
|
||||
U8 *in_ptr,*in_start,*st2;
|
||||
U16 *d;
|
||||
acd.num_words=0;
|
||||
if (in_ptr=FileRead(ACD_WORD_FILENAME,&size)) {
|
||||
in_start=in_ptr;
|
||||
Free(acd.word_lst);
|
||||
acd.word_lst=AMAlloc(size);
|
||||
MemCpy(acd.word_lst,in_start,size);
|
||||
acd.word_lst_size=size;
|
||||
|
||||
while (in_ptr<in_start+size) {
|
||||
if (*in_ptr==ACD_WORD_CHAR)
|
||||
in_ptr++;
|
||||
if (*in_ptr) {
|
||||
st2=MStrUtil(in_ptr,SUF_TO_UPPER);
|
||||
tmph=ACAlloc(sizeof(CHashGeneric)+StrLen(st2)+1);
|
||||
StrCpy(tmph+1,st2);
|
||||
Free(st2);
|
||||
in_ptr+=StrLen(in_ptr)+1;
|
||||
tmph->str=tmph+1;
|
||||
tmph->use_cnt=1;
|
||||
tmph->type=HTT_DICT_WORD;
|
||||
d=in_ptr;
|
||||
tmph->user_data0=*d;
|
||||
in_ptr+=2;
|
||||
HashAdd(tmph,ac.hash_table);
|
||||
acd.num_words++;
|
||||
} else
|
||||
in_ptr+=3;
|
||||
}
|
||||
Free(in_start);
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "AutoComplete"
|
||||
CHashAC *ACHashAdd(U8 *w)
|
||||
{
|
||||
CHashAC *tmpw=HashFind(w,ac.hash_table,HTT_WORD);
|
||||
if (tmpw) {
|
||||
tmpw->hits++;
|
||||
return tmpw;
|
||||
}
|
||||
tmpw=ACAlloc(sizeof(CHashAC));
|
||||
tmpw->str=AStrNew(w);
|
||||
tmpw->type=HTT_WORD;
|
||||
tmpw->use_cnt=1;
|
||||
tmpw->hits=1;
|
||||
HashAdd(tmpw,ac.hash_table);
|
||||
ac.num_words++;
|
||||
return tmpw;
|
||||
}
|
||||
|
||||
U0 ACSingleFileAdd(U8 *buf)
|
||||
{
|
||||
I64 ch;
|
||||
U8 *ptr=buf,*ptr2,*ptr3;
|
||||
while (TRUE) {
|
||||
while (TRUE) {
|
||||
if (ch=*ptr++) {
|
||||
if (Bt(char_bmp_alpha_numeric,ch))
|
||||
break;
|
||||
} else
|
||||
return;
|
||||
}
|
||||
ptr3=ptr;
|
||||
ptr2=ptr;
|
||||
ptr--;
|
||||
while (TRUE) {
|
||||
if (ch=*ptr2++) {
|
||||
if (Bt(char_bmp_alpha_numeric,ch))
|
||||
*ptr3++=ch;
|
||||
else if (ch!=CH_CURSOR)
|
||||
break;
|
||||
} else {
|
||||
ptr2--;
|
||||
break;
|
||||
}
|
||||
}
|
||||
*ptr3=0;
|
||||
ACHashAdd(ptr);
|
||||
ptr=ptr2;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ACMainFileLstTraverse(U8 *files_find_mask)
|
||||
{
|
||||
U8 *buf;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
try {
|
||||
tmpde=tmpde1=FilesFind(files_find_mask,
|
||||
FUF_RECURSE|FUF_JUST_TXT|FUF_JUST_FILES|FUF_CLUS_ORDER);
|
||||
while (tmpde) {
|
||||
"%s\n",tmpde->full_name;
|
||||
buf=FileRead(tmpde->full_name);
|
||||
ACSingleFileAdd(buf);
|
||||
Free(buf);
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
} catch
|
||||
Fs->catch_except=TRUE;
|
||||
DirTreeDel(tmpde1);
|
||||
}
|
||||
|
||||
U0 ACProgressTask(Bool *_start_flag)
|
||||
{
|
||||
I64 start=blkdev.write_cnt;
|
||||
progress1=0;
|
||||
progress1_max=(Size(ACD_DEF_FILENAME_Z,"+x+s")+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
StrCpy(progress1_desc,"Uncompressing Dictionary");
|
||||
start=blkdev.write_cnt;
|
||||
*_start_flag=TRUE;
|
||||
while (progress1<progress1_max) {
|
||||
progress1=blkdev.write_cnt-start;
|
||||
Sleep(10);
|
||||
}
|
||||
*progress1_desc=progress1=progress1_max=0;
|
||||
}
|
||||
|
||||
public U0 ACInit(U8 *mask=NULL)
|
||||
{//Read files and build AutoComplete statistics.
|
||||
Bool start_flag;
|
||||
CBlkDev *bd=Let2BlkDev;
|
||||
|
||||
LBtr(&sys_run_level,RLf_AUTO_COMPLETE);
|
||||
AutoComplete;
|
||||
while (LBts(&ac.flags,ACf_INIT_IN_PROGRESS))
|
||||
Yield;
|
||||
if (DrvIsWritable && FileFind(ACD_DEF_FILENAME_Z) &&
|
||||
!FileFind(ACD_DEF_FILENAME)) {
|
||||
if (bd->type!=BDT_RAM) {
|
||||
start_flag=FALSE;
|
||||
Spawn(&ACProgressTask,&start_flag);
|
||||
while (!start_flag)
|
||||
Yield;
|
||||
}
|
||||
Move(ACD_DEF_FILENAME_Z,ACD_DEF_FILENAME);
|
||||
}
|
||||
|
||||
HashTableDel(ac.hash_table);
|
||||
ac.hash_table=HashTableNew(2048,adam_task);
|
||||
|
||||
ac.num_words=0;
|
||||
Free(ac.cur_word);
|
||||
ac.cur_word=NULL;
|
||||
|
||||
if (mask)
|
||||
ACMainFileLstTraverse(mask);
|
||||
|
||||
ACDWordsLoad;
|
||||
LBtr(&ac.flags,ACf_INIT_IN_PROGRESS);
|
||||
LBts(&sys_run_level,RLf_AUTO_COMPLETE);
|
||||
AutoComplete(ON);
|
||||
}
|
||||
|
||||
I64 AutoCompleteSize()
|
||||
{
|
||||
if (ac.hash_table)
|
||||
return HashTableSize2(ac.hash_table)+MSize2(acd.word_lst);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
283
temple-src/Adam/AutoComplete/ACTask.HC
Executable file
283
temple-src/Adam/AutoComplete/ACTask.HC
Executable file
@ -0,0 +1,283 @@
|
||||
#help_index "AutoComplete/Dictionary"
|
||||
U0 ACDDictWordsAdd(U8 *st)
|
||||
{
|
||||
I64 i;
|
||||
U8 *ptr;
|
||||
if (st && *st && (ptr=ACDWordPtAt(st))) {
|
||||
for (i=0;i<ACD_FILLINS_NUM;i++) {
|
||||
if (*ptr++!=ACD_WORD_CHAR)
|
||||
break;
|
||||
if (i) '\n';
|
||||
acd.fillins[i]=ptr-1;
|
||||
"$$GREEN$$'%d'$$FG$$ %-23ts",i,ptr;
|
||||
ptr+=StrLen(ptr)+3;
|
||||
}
|
||||
acd.num_fillins=i;
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "AutoComplete"
|
||||
U0 ACDocRst(I64 left,I64 top)
|
||||
{
|
||||
CDoc *doc=DocPut;
|
||||
DocRst(doc,TRUE);
|
||||
doc->flags|=DOCF_SIZE_MIN;
|
||||
Fs->border_src=BDS_CONST;
|
||||
Fs->border_attr=LTGRAY<<4+DrvTextAttrGet(':')&15;
|
||||
Fs->text_attr =LTGRAY<<4+BLUE;
|
||||
LBtr(&Fs->display_flags,DISPLAYf_SHOW);
|
||||
WinHorz(left,Fs->win_right);
|
||||
WinVert(top,Fs->win_bottom);
|
||||
DocCursor;
|
||||
}
|
||||
|
||||
I64 ACSkipCrap(U8 *src,I64 len)
|
||||
{
|
||||
I64 j;
|
||||
j=len-1;
|
||||
while (j>=0) {
|
||||
if (Bt(char_bmp_alpha_numeric,src[j]))
|
||||
break;
|
||||
else
|
||||
j--;
|
||||
}
|
||||
return j+1;
|
||||
}
|
||||
|
||||
I64 ACPriorWordInStr(U8 *src,U8 *dst,I64 len,I64 buf_size)
|
||||
{
|
||||
I64 i,j=0,k;
|
||||
i=len-1;
|
||||
while (i>=0)
|
||||
if (!Bt(char_bmp_alpha_numeric,src[i]))
|
||||
break;
|
||||
else
|
||||
i--;
|
||||
if (i>=-1 && len>0)
|
||||
for (k=i+1;k<len && j<buf_size-1;k++)
|
||||
dst[j++]=src[k];
|
||||
dst[j]=0;
|
||||
return i+1;
|
||||
}
|
||||
|
||||
U0 ACFillInAdd(CHashAC *tmpw)
|
||||
{
|
||||
I64 k;
|
||||
if (ac.num_fillins<AC_FILLINS_NUM ||
|
||||
tmpw->hits>ac.fillin_hits[ac.num_fillins-1]) {
|
||||
for (k=ac.num_fillins-1;k>=0;k--) {
|
||||
if (tmpw->hits<=ac.fillin_hits[k])
|
||||
break;
|
||||
else {
|
||||
ac.fillin_matches[k+1]=ac.fillin_matches[k];
|
||||
ac.fillin_hits[k+1] =ac.fillin_hits[k];
|
||||
}
|
||||
}
|
||||
ac.fillin_matches[k+1]=tmpw;
|
||||
ac.fillin_hits[k+1] =tmpw->hits;
|
||||
if (ac.num_fillins<AC_FILLINS_NUM)
|
||||
ac.num_fillins++;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ACPutChoices(CDoc *focus_l,CDocEntry *doc_e,CTask *focus_task,
|
||||
Bool force_refresh)
|
||||
{
|
||||
I64 i,data_col;
|
||||
U8 *buf,*buf1,*src=NULL,*st;
|
||||
CHashAC *tmpw;
|
||||
F64 timeout_time=tS+0.5;
|
||||
CHashSrcSym *tmph;
|
||||
|
||||
src=DocScanLine(focus_l,doc_e,&data_col);
|
||||
DocUnlock(focus_l);
|
||||
i=StrLen(src);
|
||||
buf =MAlloc(MaxI64(i+1,256));
|
||||
buf1=MAlloc(MaxI64(i+1,256));
|
||||
if (data_col==-1)
|
||||
data_col=0;
|
||||
data_col=ACPriorWordInStr(src,buf,data_col,256);
|
||||
ac.partial_len=StrLen(buf);
|
||||
data_col=ACSkipCrap(src,data_col);
|
||||
data_col=ACPriorWordInStr(src,buf1,data_col,256);
|
||||
|
||||
if (!ac.cur_word || StrCmp(ac.cur_word,buf) || force_refresh) {
|
||||
st=ac.cur_word;
|
||||
ac.cur_word=AStrNew(buf);
|
||||
Free(st);
|
||||
ac.num_fillins=0;
|
||||
if (*ac.cur_word)
|
||||
for (i=0;i<=ac.hash_table->mask && tS<timeout_time;i++) {
|
||||
tmpw=ac.hash_table->body[i];
|
||||
while (tmpw) {
|
||||
if (!MemCmp(ac.cur_word,tmpw->str,StrLen(ac.cur_word)))
|
||||
ACFillInAdd(tmpw);
|
||||
tmpw=tmpw->next;
|
||||
}
|
||||
}
|
||||
ACDocRst(51,13);
|
||||
if (ac.cur_word && *ac.cur_word) {
|
||||
"$$PURPLE$$Word:%s$$FG$$\n",ac.cur_word;
|
||||
for (i=0;i<ac.num_fillins;i++) {
|
||||
st=ac.fillin_matches[i]->str;
|
||||
"$$GREEN$$F%02d$$FG$$ ",i+1;
|
||||
if (TaskValidate(focus_task) &&
|
||||
(tmph=HashFind(st,focus_task->hash_table,HTG_SRC_SYM)) &&
|
||||
tmph->src_link) {
|
||||
if (tmph->type&HTF_PUBLIC)
|
||||
"$$RED$$";
|
||||
"$$TX+UL+L+PU,\"%$$Q\",A=\"%s\"$$$$FG$$\n",st,tmph->src_link;
|
||||
} else
|
||||
"%s\n",st;
|
||||
}
|
||||
if (acd.has_words)
|
||||
ACDDictWordsAdd(ac.cur_word);
|
||||
} else if (FileFind("::/Doc/StandBy.DD.Z"))
|
||||
Type("::/Doc/StandBy.DD.Z",0);
|
||||
}
|
||||
Free(src);
|
||||
Free(buf);
|
||||
Free(buf1);
|
||||
}
|
||||
|
||||
U0 ACTaskNormal(I64 sc,I64 last_sc,
|
||||
CTask *focus_task,CTask *original_focus_task)
|
||||
{
|
||||
CDoc *doc;
|
||||
CDocEntry *doc_e;
|
||||
if ((doc=DocPut(focus_task)) &&
|
||||
focus_task!=Fs && Bt(&focus_task->display_flags,DISPLAYf_SHOW)) {
|
||||
DocLock(doc);
|
||||
if (TaskValidate(focus_task) && original_focus_task==sys_focus_task &&
|
||||
doc && doc==DocPut(focus_task) && (doc_e=doc->cur_entry)) {
|
||||
if (doc_e==doc) doc_e=doc_e->last;
|
||||
while (doc_e->last!=doc && (doc_e->type_u8==DOCT_NEW_LINE ||
|
||||
doc_e->type_u8==DOCT_SOFT_NEW_LINE))
|
||||
doc_e=doc_e->last;
|
||||
while (doc_e->last->type_u8!=DOCT_NEW_LINE && doc_e->last!=doc)
|
||||
doc_e=doc_e->last;
|
||||
ACPutChoices(doc,doc_e,focus_task,ToBool(sc!=last_sc));
|
||||
} else
|
||||
DocUnlock(doc);
|
||||
}
|
||||
if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
|
||||
WinZBufUpdate;
|
||||
}
|
||||
|
||||
U0 ACTaskCtrl(I64 sc,I64 last_sc,
|
||||
CTask *focus_task,CTask *original_focus_task)
|
||||
{
|
||||
if (TaskValidate(focus_task) &&
|
||||
(focus_task->scroll_x || focus_task->scroll_y)) {
|
||||
if (LBtr(&Fs->display_flags,DISPLAYf_SHOW))
|
||||
WinZBufUpdate;
|
||||
} else {
|
||||
if (sc!=last_sc) {
|
||||
if (sc&SCF_ALT) {
|
||||
ACDocRst(27,3);
|
||||
if (TaskValidate(original_focus_task) &&
|
||||
!Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC))
|
||||
KeyMapFamily(original_focus_task,0,
|
||||
ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
|
||||
KeyMapCtrlAltFamily(
|
||||
ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
|
||||
} else if (TaskValidate(original_focus_task) &&
|
||||
!Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC)) {
|
||||
ACDocRst(27,3);
|
||||
KeyMapFamily(original_focus_task,SCF_CTRL,
|
||||
ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
|
||||
}
|
||||
}
|
||||
if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
|
||||
WinZBufUpdate;
|
||||
}
|
||||
}
|
||||
|
||||
U0 ACTaskAlt(I64 sc,I64 last_sc,
|
||||
CTask *,CTask *original_focus_task)
|
||||
{
|
||||
if (sc!=last_sc && TaskValidate(original_focus_task) &&
|
||||
!Bt(&original_focus_task->win_inhibit,WIf_SELF_KEY_DESC)) {
|
||||
ACDocRst(27,3);
|
||||
KeyMapFamily(original_focus_task,SCF_ALT,
|
||||
ToBool(!(sc&SCF_SHIFT)),ToBool(sc&SCF_SHIFT));
|
||||
}
|
||||
if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
|
||||
WinZBufUpdate;
|
||||
}
|
||||
|
||||
U0 ACTaskEndCB()
|
||||
{
|
||||
ac.task=NULL;
|
||||
Exit;
|
||||
}
|
||||
|
||||
U0 ACTask(I64)
|
||||
{
|
||||
CTask *focus_task,*original_focus_task;
|
||||
I64 ch,scan_code=0,last_scan_code=0;
|
||||
CDoc *doc;
|
||||
Fs->task_end_cb=&ACTaskEndCB;
|
||||
DocTermNew;
|
||||
LBts(&Fs->display_flags,DISPLAYf_SHOW);
|
||||
WinHorz(51,Fs->win_right);
|
||||
LBts(&Fs->display_flags,DISPLAYf_WIN_ON_TOP);
|
||||
Fs->win_inhibit=WIG_NO_FOCUS_TASK_DFT;
|
||||
Free(ac.cur_word);
|
||||
ac.cur_word=NULL;
|
||||
while (TRUE) {
|
||||
if (scan_code&(SCF_CTRL|SCF_ALT) ||
|
||||
GetTSC>KbdMsEvtTime+cnts.time_stamp_freq>>1) {
|
||||
last_scan_code=scan_code;
|
||||
scan_code=kbd.scan_code;
|
||||
}
|
||||
original_focus_task=focus_task=sys_focus_task;
|
||||
while (TaskValidate(focus_task) &&
|
||||
Bt(&focus_task->task_flags,TASKf_INPUT_FILTER_TASK))
|
||||
focus_task=focus_task->parent_task;
|
||||
if (scan_code&SCF_CTRL)
|
||||
ACTaskCtrl(scan_code,last_scan_code,focus_task,original_focus_task);
|
||||
else if (TaskValidate(focus_task)) {
|
||||
if (scan_code&SCF_ALT)
|
||||
ACTaskAlt(scan_code,last_scan_code,focus_task,original_focus_task);
|
||||
else
|
||||
ACTaskNormal(scan_code,last_scan_code,focus_task,original_focus_task);
|
||||
}
|
||||
Sleep(333);
|
||||
if (ScanMsg(&ch,,1<<MSG_KEY_DOWN) && (ch==CH_ESC||ch==CH_SHIFT_ESC))
|
||||
break;
|
||||
doc=DocPut;
|
||||
DocLock(doc);
|
||||
if (doc->cur_entry->de_flags & DOCEF_LINK) {
|
||||
'' CH_SPACE;
|
||||
doc->cur_entry=doc;
|
||||
}
|
||||
DocUnlock(doc);
|
||||
}
|
||||
}
|
||||
|
||||
public Bool AutoComplete(Bool val=OFF)
|
||||
{//Turn AutoComplete OFF or ON.
|
||||
Bool old_val=FALSE;
|
||||
while (Bt(&ac.flags,ACf_INIT_IN_PROGRESS))
|
||||
Sleep(10);
|
||||
if (val) {
|
||||
if (Bt(&sys_run_level,RLf_AUTO_COMPLETE)) {
|
||||
if (TaskValidate(ac.task))
|
||||
old_val=TRUE;
|
||||
else {
|
||||
ac.task=Spawn(&ACTask,NULL,"AutoComplete");
|
||||
TaskWait(ac.task);
|
||||
}
|
||||
WinToTop(ac.task);
|
||||
}
|
||||
} else {
|
||||
if (TaskValidate(ac.task)) {
|
||||
if (Bt(&sys_run_level,RLf_AUTO_COMPLETE))
|
||||
old_val=TRUE;
|
||||
Kill(ac.task);
|
||||
DeathWait(&ac.task);
|
||||
}
|
||||
}
|
||||
return old_val;
|
||||
}
|
||||
BIN
temple-src/Adam/AutoComplete/ACWords.DATA
Executable file
BIN
temple-src/Adam/AutoComplete/ACWords.DATA
Executable file
Binary file not shown.
6
temple-src/Adam/AutoComplete/MakeAC.HC
Executable file
6
temple-src/Adam/AutoComplete/MakeAC.HC
Executable file
@ -0,0 +1,6 @@
|
||||
//See $LK,"::/Doc/AutoComplete.DD"$
|
||||
Cd(__DIR__);;
|
||||
#include "ACFill"
|
||||
#include "ACTask"
|
||||
#include "ACInit"
|
||||
Cd("..");;
|
||||
72
temple-src/Adam/CPURep.HC
Executable file
72
temple-src/Adam/CPURep.HC
Executable file
@ -0,0 +1,72 @@
|
||||
#help_index "Info;Time/CPU Cycles;Processor"
|
||||
class CCPURep
|
||||
{
|
||||
Bool mp_start,mp_end;
|
||||
I64 mp_not_done_flags,
|
||||
**swaps,
|
||||
**cycles;
|
||||
};
|
||||
|
||||
U0 MPCPURep(CCPURep *cr)
|
||||
{
|
||||
I64 swaps=0,cycles_0,cycles_f;
|
||||
while (!cr->mp_start)
|
||||
Yield;
|
||||
cycles_0=GetTSC;
|
||||
while (!cr->mp_end) {
|
||||
swaps++;
|
||||
Yield;
|
||||
}
|
||||
cycles_f=GetTSC;
|
||||
cr->swaps[Gs->num]=swaps;
|
||||
cr->cycles[Gs->num]=cycles_f-cycles_0;
|
||||
LBtr(&cr->mp_not_done_flags,Gs->num);
|
||||
}
|
||||
|
||||
public U0 CPURep(Bool full=FALSE)
|
||||
{//Report number of cores and clock freq.
|
||||
I64 i,total_swaps,total_cycles;
|
||||
F64 t0,tf;
|
||||
CCPURep cr;
|
||||
|
||||
if (!full)
|
||||
"%03X Cores %6h?nHz\n",mp_cnt,ToF64(cnts.time_stamp_freq);
|
||||
else {
|
||||
cr.swaps=CAlloc(sizeof(I64)*mp_cnt);
|
||||
cr.cycles=CAlloc(sizeof(I64)*mp_cnt);
|
||||
cr.mp_start=cr.mp_end=FALSE;
|
||||
cr.mp_not_done_flags=1<<mp_cnt-1;
|
||||
for (i=0;i<mp_cnt;i++)
|
||||
Spawn(&MPCPURep,&cr,NULL,i);
|
||||
|
||||
t0=tS;
|
||||
cr.mp_start=TRUE;
|
||||
Sleep(2000);
|
||||
cr.mp_end=TRUE;
|
||||
while (cr.mp_not_done_flags)
|
||||
Yield;
|
||||
tf=tS;
|
||||
|
||||
"\n%03X Cores %6h?nHz\n",mp_cnt,ToF64(cnts.time_stamp_freq);
|
||||
"\nContext\n"
|
||||
"CPUSwaps/sCycles\n"
|
||||
"---------------------------------\n";
|
||||
total_swaps=0;
|
||||
total_cycles=0;
|
||||
for (i=0;i<mp_cnt;i++) {
|
||||
"%02X%13,d%17,d\n",i,
|
||||
ToI64(cr.swaps[i]/(tf-t0)),ToI64(cr.cycles[i]/(tf-t0));
|
||||
total_swaps+=cr.swaps[i];
|
||||
total_cycles+=cr.cycles[i];
|
||||
}
|
||||
"---------------------------------\n";
|
||||
"%03X%13,d%17,d\n",i,
|
||||
ToI64(total_swaps/(tf-t0)),ToI64(total_cycles/(tf-t0));
|
||||
"Avg%13,d%17,d\n\n",
|
||||
ToI64(total_swaps/(tf-t0)/i),ToI64(total_cycles/(tf-t0)/i);
|
||||
"Avg Cycles/Swap: %12.6f\n",ToF64(total_cycles)/total_swaps;
|
||||
"Avg Time/Swap: %12.6fns\n\n",(tf-t0)*1000000000.0*i/total_swaps;
|
||||
Free(cr.swaps);
|
||||
Free(cr.cycles);
|
||||
}
|
||||
}
|
||||
388
temple-src/Adam/Ctrls/CtrlsA.HC
Executable file
388
temple-src/Adam/Ctrls/CtrlsA.HC
Executable file
@ -0,0 +1,388 @@
|
||||
public CCtrl *CtrlFindUnique(CTask *haystack_task,I64 needle_type)
|
||||
{//Find task ctrl given $LK,"ctrl_type",A="MN:CTRLT_VIEWING_ANGLES"$.
|
||||
CCtrl *c;
|
||||
c=haystack_task->next_ctrl;
|
||||
while (c!=&haystack_task->next_ctrl) {
|
||||
if (c->type==needle_type)
|
||||
return c;
|
||||
c=c->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U0 CtrlsUpdate(CTask *task)
|
||||
{
|
||||
CCtrl *c;
|
||||
c=task->next_ctrl;
|
||||
while (c!=&task->next_ctrl) {
|
||||
if (c->update_derived_vals)
|
||||
(*c->update_derived_vals)(c);
|
||||
if (c->flags&CTRLF_BORDER) {
|
||||
c->scrn_left =gr.pan_text_x+task->pix_left+c->left-FONT_WIDTH;
|
||||
c->scrn_right =gr.pan_text_x+task->pix_left+c->right-FONT_WIDTH;
|
||||
c->scrn_top =gr.pan_text_y+task->pix_top+c->top-FONT_HEIGHT;
|
||||
c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom-FONT_HEIGHT;
|
||||
} else {
|
||||
c->scrn_left =gr.pan_text_x+task->pix_left+c->left;
|
||||
c->scrn_right =gr.pan_text_x+task->pix_left+c->right;
|
||||
c->scrn_top =gr.pan_text_y+task->pix_top+c->top;
|
||||
c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom;
|
||||
}
|
||||
c=c->next;
|
||||
}
|
||||
}
|
||||
|
||||
fp_update_ctrls=&CtrlsUpdate;
|
||||
|
||||
Bool CtrlInsideRect(CCtrl *c,I64 x,I64 y)
|
||||
{//scrn coordinates
|
||||
if (c->scrn_left<=x<=c->scrn_right &&
|
||||
c->scrn_top<=y<=c->scrn_bottom)
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public Bool CtrlInside(CCtrl *c,I64 x,I64 y)
|
||||
{//Is x,y inside a ctrl?
|
||||
if (c->flags&CTRLF_SHOW) {
|
||||
if (c->inside_ctrl)
|
||||
return (*c->inside_ctrl)(c,x,y);
|
||||
else
|
||||
return CtrlInsideRect(c,x,y);
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
U0 DrawCtrls(CTask *task)
|
||||
{
|
||||
CCtrl *c;
|
||||
CDC *dc=DCAlias(gr.dc2,task);
|
||||
c=task->next_ctrl;
|
||||
while (c!=&task->next_ctrl) {
|
||||
if (c->flags&CTRLF_SHOW) {
|
||||
if (c->flags&CTRLF_BORDER) {
|
||||
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
|
||||
PUSHFD
|
||||
CLI
|
||||
while (LBts(&task->task_flags,TASKf_TASK_LOCK))
|
||||
PAUSE
|
||||
|
||||
task->win_left--; //Allow drawing on border
|
||||
task->win_right++;
|
||||
task->win_top--;
|
||||
task->win_bottom++;
|
||||
WinDerivedValsUpdate(task);
|
||||
|
||||
LBtr(&task->task_flags,TASKf_TASK_LOCK);
|
||||
POPFD
|
||||
|
||||
if (c->draw_it)
|
||||
(*c->draw_it)(dc,c);
|
||||
|
||||
PUSHFD
|
||||
CLI
|
||||
while (LBts(&task->task_flags,TASKf_TASK_LOCK))
|
||||
PAUSE
|
||||
|
||||
task->win_left++;
|
||||
task->win_right--;
|
||||
task->win_top++;
|
||||
task->win_bottom--;
|
||||
WinDerivedValsUpdate(task);
|
||||
|
||||
LBtr(&task->task_flags,TASKf_TASK_LOCK);
|
||||
POPFD
|
||||
}
|
||||
} else
|
||||
if (c->draw_it)
|
||||
(*c->draw_it)(dc,c);
|
||||
}
|
||||
c=c->next;
|
||||
}
|
||||
DCDel(dc);
|
||||
}
|
||||
|
||||
#define WIN_SCROLL_SIZE 8
|
||||
#define WIN_SCROLL_BORDER_BONUS 4
|
||||
U0 DrawWinScroll(CDC *dc,CCtrl *c)
|
||||
{
|
||||
CWinScroll *s=c->state;
|
||||
|
||||
if (c->flags&CTRLF_CLICKED)
|
||||
dc->color=s->color>>4;
|
||||
else
|
||||
dc->color=s->color&0xF;
|
||||
GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);
|
||||
|
||||
if (c->flags&CTRLF_CLICKED)
|
||||
dc->color=s->color&0xF;
|
||||
else
|
||||
dc->color=s->color>>4;
|
||||
GrRect(dc,c->left+2,c->top+2,c->right-c->left+1-4,c->bottom-c->top+1-4);
|
||||
}
|
||||
|
||||
U0 WinDerivedScrollValsUpdate(CCtrl *c)
|
||||
{
|
||||
CWinScroll *s=c->state;
|
||||
I64 range;
|
||||
if (s->max<s->min) s->max=s->min;
|
||||
if (s->pos<s->min) s->pos=s->min;
|
||||
if (s->pos>s->max) s->pos=s->max;
|
||||
s->color=c->win_task->border_attr&0xF^0xF+
|
||||
(c->win_task->border_attr&0xF)<<4;
|
||||
range=s->max-s->min;
|
||||
if (!range) range=1;
|
||||
switch (c->type) {
|
||||
case CTRLT_WIN_HSCROLL:
|
||||
c->left =gr.pan_text_x+FONT_WIDTH-WIN_SCROLL_BORDER_BONUS+
|
||||
(s->pos-s->min)*(c->win_task->pix_width+2*WIN_SCROLL_BORDER_BONUS
|
||||
-WIN_SCROLL_SIZE)/range;
|
||||
c->right =c->left+WIN_SCROLL_SIZE-1;
|
||||
c->top =gr.pan_text_y+FONT_HEIGHT+
|
||||
(FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_height;
|
||||
c->bottom=c->top+WIN_SCROLL_SIZE-1;
|
||||
break;
|
||||
case CTRLT_WIN_VSCROLL:
|
||||
c->left =gr.pan_text_x+FONT_WIDTH+
|
||||
(FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_width;
|
||||
c->right =c->left+WIN_SCROLL_SIZE-1;
|
||||
c->top =gr.pan_text_y+FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS+
|
||||
(s->pos-s->min)*(c->win_task->pix_height+
|
||||
2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE)/range;
|
||||
c->bottom=c->top+WIN_SCROLL_SIZE-1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
U0 LeftClickHWinScroll(CCtrl *c,I64 x,I64,Bool down)
|
||||
{
|
||||
CTask *task=c->win_task;
|
||||
CWinScroll *s=c->state;
|
||||
I64 range=task->pix_width+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;
|
||||
LBts(&s->flags,WSSf_SET_TO_POS);
|
||||
s->pos=((x-(FONT_WIDTH-WIN_SCROLL_BORDER_BONUS))
|
||||
*(s->max-s->min+1)+range/2)/range+s->min;
|
||||
if (down)
|
||||
c->flags|=CTRLF_CLICKED;
|
||||
else
|
||||
c->flags&=~CTRLF_CLICKED;
|
||||
if (c->update_derived_vals)
|
||||
(*c->update_derived_vals)(c);
|
||||
}
|
||||
|
||||
U0 LeftClickVWinScroll(CCtrl *c,I64,I64 y,Bool down)
|
||||
{
|
||||
CTask *task=c->win_task;
|
||||
CWinScroll *s=c->state;
|
||||
I64 range=task->pix_height+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;
|
||||
LBts(&s->flags,WSSf_SET_TO_POS);
|
||||
s->pos=((y-(FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS))
|
||||
*(s->max-s->min+1)+range/2)/range+s->min;
|
||||
if (down)
|
||||
c->flags|=CTRLF_CLICKED;
|
||||
else
|
||||
c->flags&=~CTRLF_CLICKED;
|
||||
if (c->update_derived_vals)
|
||||
(*c->update_derived_vals)(c);
|
||||
}
|
||||
|
||||
U0 WheelChangeWinScroll(CCtrl *c,I64 delta)
|
||||
{
|
||||
CWinScroll *s=c->state;
|
||||
LBts(&s->flags,WSSf_SET_TO_POS);
|
||||
s->pos+=delta;
|
||||
if (c->update_derived_vals)
|
||||
(*c->update_derived_vals)(c);
|
||||
}
|
||||
|
||||
U0 WinScrollsInit(CTask *task)
|
||||
{
|
||||
CCtrl *c;
|
||||
|
||||
if (!CtrlFindUnique(task,CTRLT_WIN_HSCROLL)) {
|
||||
c=CAlloc(sizeof(CCtrl));
|
||||
c->win_task=task;
|
||||
c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;
|
||||
c->type=CTRLT_WIN_HSCROLL;
|
||||
c->state=&task->horz_scroll;
|
||||
c->update_derived_vals=&WinDerivedScrollValsUpdate;
|
||||
c->draw_it=&DrawWinScroll;
|
||||
c->left_click=&LeftClickHWinScroll;
|
||||
QueIns(c,task->last_ctrl);
|
||||
}
|
||||
|
||||
if (!CtrlFindUnique(task,CTRLT_WIN_VSCROLL)) {
|
||||
c=CAlloc(sizeof(CCtrl));
|
||||
c->win_task=task;
|
||||
c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;
|
||||
c->type=CTRLT_WIN_VSCROLL;
|
||||
c->state=&task->vert_scroll;
|
||||
c->update_derived_vals=&WinDerivedScrollValsUpdate;
|
||||
c->draw_it=&DrawWinScroll;
|
||||
c->left_click=&LeftClickVWinScroll;
|
||||
c->wheel_chg=&WheelChangeWinScroll;
|
||||
QueIns(c,task->last_ctrl);
|
||||
}
|
||||
TaskDerivedValsUpdate(task);
|
||||
}
|
||||
#define VIEWANGLES_SPACING 22
|
||||
#define VIEWANGLES_RANGE 48
|
||||
#define VIEWANGLES_BORDER 2
|
||||
#define VIEWANGLES_SNAP 2
|
||||
|
||||
U0 DrawViewAnglesCtrl(CDC *dc,CCtrl *c)
|
||||
{
|
||||
I64 i,j;
|
||||
CViewAngles *s=c->state;
|
||||
|
||||
dc->color=s->cbd;
|
||||
GrRect(dc, c->left,c->top,VIEWANGLES_SPACING*4+3,
|
||||
VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
|
||||
dc->color=s->cbg;
|
||||
GrRect(dc, c->left+VIEWANGLES_BORDER,c->top+VIEWANGLES_BORDER,
|
||||
VIEWANGLES_SPACING*4+3-2*VIEWANGLES_BORDER,
|
||||
VIEWANGLES_SPACING*2+VIEWANGLES_RANGE-2*VIEWANGLES_BORDER);
|
||||
dc->color=s->cfg;
|
||||
GrLine(dc,c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING,
|
||||
c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING+
|
||||
VIEWANGLES_RANGE-1);
|
||||
GrLine(dc,c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING,
|
||||
c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING+
|
||||
VIEWANGLES_RANGE-1);
|
||||
GrLine(dc,c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING,
|
||||
c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING+
|
||||
VIEWANGLES_RANGE-1);
|
||||
for (i=1;i<VIEWANGLES_RANGE+1;i+=2*VIEWANGLES_SNAP) {
|
||||
j=2-i/3&1;
|
||||
GrLine(dc,c->left+VIEWANGLES_SPACING-j,c->bottom-VIEWANGLES_SPACING-i,
|
||||
c->left+VIEWANGLES_SPACING+j,c->bottom
|
||||
-VIEWANGLES_SPACING-i);
|
||||
GrLine(dc,c->left+2*VIEWANGLES_SPACING+1-j,c->bottom-VIEWANGLES_SPACING-i,
|
||||
c->left+2*VIEWANGLES_SPACING+1+j,c->bottom
|
||||
-VIEWANGLES_SPACING-i);
|
||||
GrLine(dc,c->left+3*VIEWANGLES_SPACING+2-j,c->bottom-VIEWANGLES_SPACING-i,
|
||||
c->left+3*VIEWANGLES_SPACING+2+j,c->bottom
|
||||
-VIEWANGLES_SPACING-i);
|
||||
}
|
||||
|
||||
dc->color=s->cx;
|
||||
GrPrint(dc,c->left+VIEWANGLES_SPACING-FONT_WIDTH/2,
|
||||
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"X");
|
||||
GrPrint(dc,c->left+VIEWANGLES_SPACING-3*FONT_WIDTH/2,
|
||||
c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
|
||||
"%3d",s->sx*360/VIEWANGLES_RANGE);
|
||||
i=c->left+VIEWANGLES_SPACING;
|
||||
if (s->sx>VIEWANGLES_RANGE/2)
|
||||
j=-VIEWANGLES_RANGE/2+s->sx;
|
||||
else
|
||||
j=s->sx+VIEWANGLES_RANGE/2;
|
||||
j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
|
||||
GrRect(dc,i-3,j-2,7,5);
|
||||
dc->color=s->cx^8;
|
||||
GrRect(dc,i-2,j-1,5,3);
|
||||
|
||||
dc->color=s->cy;
|
||||
GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-FONT_WIDTH/2,
|
||||
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Y");
|
||||
GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-3*FONT_WIDTH/2,
|
||||
c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
|
||||
"%3d",s->sy*360/VIEWANGLES_RANGE);
|
||||
i=c->left+2*VIEWANGLES_SPACING+1;
|
||||
if (s->sy>VIEWANGLES_RANGE/2)
|
||||
j=-VIEWANGLES_RANGE/2+s->sy;
|
||||
else
|
||||
j=s->sy+VIEWANGLES_RANGE/2;
|
||||
j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
|
||||
GrRect(dc,i-3,j-2,7,5);
|
||||
dc->color=s->cy^8;
|
||||
GrRect(dc,i-2,j-1,5,3);
|
||||
|
||||
dc->color=s->cz;
|
||||
GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-FONT_WIDTH/2,
|
||||
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Z");
|
||||
GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-3*FONT_WIDTH/2,
|
||||
c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
|
||||
"%3d",s->sz*360/VIEWANGLES_RANGE);
|
||||
i=c->left+3*VIEWANGLES_SPACING+2;
|
||||
if (s->sz>VIEWANGLES_RANGE/2)
|
||||
j=-VIEWANGLES_RANGE/2+s->sz;
|
||||
else
|
||||
j=s->sz+VIEWANGLES_RANGE/2;
|
||||
j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
|
||||
GrRect(dc,i-3,j-2,7,5);
|
||||
dc->color=s->cz^8;
|
||||
GrRect(dc,i-2,j-1,5,3);
|
||||
}
|
||||
|
||||
U0 UpdateDerivedViewAnglesCtrl(CCtrl *c)
|
||||
{
|
||||
CViewAngles *s=c->state;
|
||||
c->left=c->win_task->pix_width-(VIEWANGLES_SPACING*4+3);
|
||||
c->right=c->left+VIEWANGLES_SPACING*4+3;
|
||||
c->top=c->win_task->pix_height-(VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
|
||||
c->bottom=c->top+VIEWANGLES_SPACING*2+VIEWANGLES_RANGE;
|
||||
s->sx=ClampI64(RoundI64(s->sx,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
|
||||
s->sy=ClampI64(RoundI64(s->sy,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
|
||||
s->sz=ClampI64(RoundI64(s->sz,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
|
||||
s->ax=2*ã*s->sx/VIEWANGLES_RANGE;
|
||||
s->ay=2*ã*s->sy/VIEWANGLES_RANGE;
|
||||
s->az=2*ã*s->sz/VIEWANGLES_RANGE;
|
||||
}
|
||||
|
||||
U0 LeftClickViewAngles(CCtrl *c,I64 x,I64 y,Bool)
|
||||
{
|
||||
CViewAngles *s=c->state;
|
||||
I64 i;
|
||||
i=VIEWANGLES_RANGE-1-(y-(c->top+VIEWANGLES_SPACING));
|
||||
if (i>=VIEWANGLES_RANGE/2)
|
||||
i-=VIEWANGLES_RANGE/2;
|
||||
else
|
||||
i+=VIEWANGLES_RANGE/2;
|
||||
if (x<c->left+(c->right-c->left)/3)
|
||||
s->sx=i;
|
||||
else if (x<c->left+2*(c->right-c->left)/3)
|
||||
s->sy=i;
|
||||
else
|
||||
s->sz=i;
|
||||
if (c->update_derived_vals)
|
||||
(*c->update_derived_vals)(c);
|
||||
}
|
||||
|
||||
public CCtrl *ViewAnglesNew(CTask *task=NULL)
|
||||
{//Create view angle ctrl. See $LK,"::/Demo/Graphics/Shading.HC"$.
|
||||
CCtrl *c;
|
||||
CViewAngles *s;
|
||||
if (!task) task=Fs;
|
||||
if (!(c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES))) {
|
||||
s=CAlloc(sizeof(CViewAngles),task);
|
||||
c=CAlloc(sizeof(CCtrl));
|
||||
s->cbd=BLUE;
|
||||
s->cbg=LTBLUE;
|
||||
s->cfg=BLACK;
|
||||
s->cx=LTGREEN;
|
||||
s->cy=GREEN;
|
||||
s->cz=LTGREEN;
|
||||
c->win_task=task;
|
||||
c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
|
||||
c->type=CTRLT_VIEWING_ANGLES;
|
||||
c->state=s;
|
||||
c->draw_it=&DrawViewAnglesCtrl;
|
||||
c->left_click=&LeftClickViewAngles;
|
||||
c->update_derived_vals=&UpdateDerivedViewAnglesCtrl;
|
||||
QueIns(c,task->last_ctrl);
|
||||
TaskDerivedValsUpdate(task);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
public U0 ViewAnglesDel(CTask *task=NULL)
|
||||
{//Free view angle ctrl.
|
||||
CCtrl *c;
|
||||
if (!task) task=Fs;
|
||||
if (c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES)) {
|
||||
QueRem(c);
|
||||
Free(c->state);
|
||||
Free(c);
|
||||
}
|
||||
}
|
||||
91
temple-src/Adam/Ctrls/CtrlsBttn.HC
Executable file
91
temple-src/Adam/Ctrls/CtrlsBttn.HC
Executable file
@ -0,0 +1,91 @@
|
||||
#define BTTN_BORDER 2
|
||||
|
||||
#define BTF_DONT_FREE 1
|
||||
|
||||
class CCtrlBttnState
|
||||
{
|
||||
I64 state,num_states,flags;
|
||||
U8 *state_texts;
|
||||
CColorROPU32 *state_colors;
|
||||
};
|
||||
|
||||
U0 DrawCtrlBttn(CDC *dc,CCtrl *c)
|
||||
{
|
||||
CCtrlBttnState *s=c->state;
|
||||
I64 l;
|
||||
U8 *st;
|
||||
|
||||
dc->color=BLACK;
|
||||
GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);
|
||||
if (!(st=LstSub(s->state,s->state_texts)))
|
||||
st=s->state_texts;
|
||||
dc->color=s->state_colors[s->state];
|
||||
l=StrLen(st);
|
||||
GrRect(dc,c->left+BTTN_BORDER,c->top+BTTN_BORDER,
|
||||
c->right-c->left+1-BTTN_BORDER*2,
|
||||
c->bottom-c->top+1-BTTN_BORDER*2);
|
||||
dc->color=s->state_colors[s->state]^(WHITE<<16+WHITE);
|
||||
GrPrint(dc,(c->left+c->right+1-l*FONT_WIDTH)>>1,
|
||||
(c->top+c->bottom+1-FONT_HEIGHT)>>1,"%s",st);
|
||||
}
|
||||
|
||||
U0 LeftClickCtrlBttn(CCtrl *c,I64,I64,Bool down)
|
||||
{
|
||||
CCtrlBttnState *s=c->state;
|
||||
if (down) {
|
||||
s->state++;
|
||||
if (s->state==s->num_states)
|
||||
s->state=0;
|
||||
}
|
||||
}
|
||||
|
||||
public CCtrl *CtrlBttnNew(I64 x,I64 y,I64 width=-1,I64 height=-1,
|
||||
I64 num_states=1,U8 *state_texts,
|
||||
I32 *state_colors,CCtrlBttnState *_s=NULL)
|
||||
{//Create bttn ctrl. See $LK,"::/Apps/Strut/Strut.HC"$.
|
||||
CCtrl *res;
|
||||
CCtrlBttnState *s;
|
||||
I64 i,j,l;
|
||||
U8 *st;
|
||||
if (width<0) {
|
||||
l=1;
|
||||
for (i=0;i<num_states;i++)
|
||||
if (st=LstSub(i,state_texts)) {
|
||||
j=StrLen(st);
|
||||
if (j>l) l=j;
|
||||
}
|
||||
width=BTTN_BORDER*4+l*FONT_WIDTH;
|
||||
}
|
||||
if (height<0) height=BTTN_BORDER*4+FONT_HEIGHT;
|
||||
res=CAlloc(sizeof(CCtrl));
|
||||
if (_s) {
|
||||
s=_s;
|
||||
MemSet(s,0,sizeof(CCtrlBttnState));
|
||||
} else {
|
||||
s=CAlloc(sizeof(CCtrlBttnState));
|
||||
s->flags=BTF_DONT_FREE;
|
||||
}
|
||||
s->num_states=num_states;
|
||||
s->state_texts=state_texts;
|
||||
s->state_colors=state_colors;
|
||||
res->win_task=Fs;
|
||||
res->flags=CTRLF_SHOW;
|
||||
res->type=CTRLT_GENERIC;
|
||||
res->state=s;
|
||||
res->draw_it=&DrawCtrlBttn;
|
||||
res->left_click=&LeftClickCtrlBttn;
|
||||
res->left=x;
|
||||
res->top=y;
|
||||
res->right=res->left+width-1;
|
||||
res->bottom=res->top+height-1;
|
||||
QueIns(res,Fs->last_ctrl);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 CtrlBttnDel(CCtrl *c)
|
||||
{//Free bttn ctrl.
|
||||
QueRem(c);
|
||||
if (!(c->flags&BTF_DONT_FREE))
|
||||
Free(c->state);
|
||||
Free(c);
|
||||
}
|
||||
214
temple-src/Adam/Ctrls/CtrlsSlider.HC
Executable file
214
temple-src/Adam/Ctrls/CtrlsSlider.HC
Executable file
@ -0,0 +1,214 @@
|
||||
class CTemplateCSSlider
|
||||
{
|
||||
CTemplateCSSlider *next,*last;
|
||||
U8 *name;
|
||||
I64 num;
|
||||
};
|
||||
|
||||
class CTemplateCS
|
||||
{
|
||||
CTemplateCSSlider *next_slider,*last_slider;
|
||||
I64 num_sliders,range,spacing,border;
|
||||
U8 *glbl_name;
|
||||
};
|
||||
|
||||
CTemplateCS *CtrlSliderGet()
|
||||
{
|
||||
CTemplateCSSlider *tmps;
|
||||
U8 *st,pmt[STR_LEN];
|
||||
CTemplateCS *res=CAlloc(sizeof(CTemplateCS));
|
||||
|
||||
"$$PURPLE$$Ctrl Slider$$FG$$\n\n";
|
||||
|
||||
res->glbl_name=GetStr("Glbl Struct Name (ENTER for No Glbl):");
|
||||
res->range=GetI64 ("Range (%4d):",30);
|
||||
res->spacing=GetI64("Spacing (%4d):",20);
|
||||
res->border=GetI64 ("Border (%4d):",2);
|
||||
|
||||
res->next_slider=res->last_slider=&res->next_slider;
|
||||
while (TRUE) {
|
||||
StrPrint(pmt,"Slider #%d Name:",res->num_sliders+1);
|
||||
st=GetStr(pmt);
|
||||
if (!*st) {
|
||||
Free(st);
|
||||
break;
|
||||
}
|
||||
tmps=CAlloc(sizeof(CTemplateCSSlider));
|
||||
tmps->name=st;
|
||||
QueIns(tmps,res->last_slider);
|
||||
tmps->num=res->num_sliders++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 TemplateCtrlSlider(CDoc *doc)
|
||||
{
|
||||
CTask *task;
|
||||
CTemplateCS *m=NULL;
|
||||
CTemplateCSSlider *tmps;
|
||||
I64 i;
|
||||
|
||||
DocUnlock(doc);
|
||||
DocRecalc(doc);
|
||||
DocCaptureUndo(doc,TRUE);
|
||||
|
||||
task=User("CTemplateCS **_m=0x%X;*_m=CtrlSliderGet;\n",&m);
|
||||
while (!m)
|
||||
Yield;
|
||||
|
||||
DocPrint(doc,
|
||||
"#define SLIDER_RANGE\t%d
|
||||
#define SLIDER_SPACING\t%d
|
||||
#define SLIDER_BORDER\t%d
|
||||
|
||||
class CSliderState
|
||||
{
|
||||
",m->range,m->spacing,m->border);
|
||||
|
||||
tmps=m->next_slider;
|
||||
while (tmps!=&m->next_slider) {
|
||||
DocPrint(doc,"I64 %s;\n",tmps->name);
|
||||
tmps=tmps->next;
|
||||
}
|
||||
if (*m->glbl_name)
|
||||
DocPrint(doc,"} %s;\n",m->glbl_name);
|
||||
else
|
||||
DocPrint(doc,"};\n");
|
||||
|
||||
DocPrint(doc,
|
||||
"
|
||||
U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
|
||||
{
|
||||
CSliderState *s=c->state;
|
||||
|
||||
dc->color=LTRED;
|
||||
GrRect(dc, c->left,c->top,%d*SLIDER_SPACING+%d,SLIDER_SPACING*2+SLIDER_RANGE);
|
||||
dc->color=BLUE;
|
||||
GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
|
||||
%d*SLIDER_SPACING+%d-2*SLIDER_BORDER,SLIDER_SPACING*2
|
||||
+SLIDER_RANGE-2*SLIDER_BORDER);
|
||||
dc->color=BLACK;
|
||||
",m->num_sliders+1,m->num_sliders,m->num_sliders+1,m->num_sliders);
|
||||
|
||||
for (i=0;i<m->num_sliders;i++)
|
||||
DocPrint(doc,
|
||||
"GrLine(dc,c->left+%d*SLIDER_SPACING+%d,c->top+SLIDER_SPACING,
|
||||
c->left+%d*SLIDER_SPACING+%d,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
|
||||
",i+1,i,i+1,i);
|
||||
|
||||
DocPrint(doc,"dc->color=LTRED;\n");
|
||||
|
||||
tmps=m->next_slider;
|
||||
while (tmps!=&m->next_slider) {
|
||||
DocPrint(doc,
|
||||
"GrPrint(dc,c->left+%d*SLIDER_SPACING+%d-FONT_WIDTH/2,
|
||||
c->top+SLIDER_SPACING+SLIDER_RANGE+3,
|
||||
\"%%d\",s->%s*10/SLIDER_RANGE);\n",
|
||||
tmps->num+1,tmps->num,tmps->name);
|
||||
tmps=tmps->next;
|
||||
}
|
||||
|
||||
tmps=m->next_slider;
|
||||
while (tmps!=&m->next_slider) {
|
||||
DocPrint(doc,
|
||||
"GrRect(dc,c->left+%d*SLIDER_SPACING+%d-3,"
|
||||
"c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-2,7,5);\n",
|
||||
tmps->num+1,tmps->num,tmps->name);
|
||||
tmps=tmps->next;
|
||||
}
|
||||
DocPrint(doc,"dc->color=YELLOW;\n");
|
||||
|
||||
tmps=m->next_slider;
|
||||
while (tmps!=&m->next_slider) {
|
||||
DocPrint(doc,"GrRect(dc,c->left+%d*SLIDER_SPACING+%d-2,"
|
||||
"c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-1,5,3);\n",
|
||||
tmps->num+1,tmps->num,tmps->name);
|
||||
tmps=tmps->next;
|
||||
}
|
||||
DocPrint(doc,
|
||||
"}
|
||||
|
||||
U0 UpdateDerivedCtrlSlider(CCtrl *c)
|
||||
{
|
||||
CSliderState *s=c->state;
|
||||
c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
|
||||
c->right=c->left+%d*SLIDER_SPACING+%d;
|
||||
c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
|
||||
c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
|
||||
",m->num_sliders+1,m->num_sliders);
|
||||
|
||||
tmps=m->next_slider;
|
||||
while (tmps!=&m->next_slider) {
|
||||
DocPrint(doc,"s->%s=ClampI64(s->%s,0,SLIDER_RANGE-1);\n",
|
||||
tmps->name,tmps->name);
|
||||
tmps=tmps->next;
|
||||
}
|
||||
DocPrint(doc,
|
||||
"}
|
||||
|
||||
U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool down)
|
||||
{
|
||||
no_warn down;
|
||||
CSliderState *s=c->state;
|
||||
");
|
||||
|
||||
tmps=m->next_slider;
|
||||
while (tmps!=&m->next_slider) {
|
||||
DocPrint(doc,"");
|
||||
if (tmps!=m->next_slider)
|
||||
DocPrint(doc,"else");
|
||||
if (tmps->next==&m->next_slider)
|
||||
DocPrint(doc,"\n");
|
||||
else
|
||||
DocPrint(doc,"if (x<c->left+%d*SLIDER_SPACING+%d+SLIDER_SPACING/2)\n",
|
||||
tmps->num+1,tmps->num);
|
||||
DocPrint(doc,"s->%s=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));\n",
|
||||
tmps->name);
|
||||
tmps=tmps->next;
|
||||
}
|
||||
|
||||
DocPrint(doc,
|
||||
"if (c->update_derived_vals)
|
||||
(*c->update_derived_vals)(c);
|
||||
}
|
||||
|
||||
CCtrl *SliderNew()
|
||||
{
|
||||
CCtrl *c=CAlloc(sizeof(CCtrl));
|
||||
c->win_task=Fs;
|
||||
c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
|
||||
c->type=CTRLT_GENERIC;
|
||||
");
|
||||
if (*m->glbl_name)
|
||||
DocPrint(doc,"c->state=&%s;\n"
|
||||
"MemSet(&%s,0,sizeof(CSliderState));\n",m->glbl_name,m->glbl_name);
|
||||
else
|
||||
DocPrint(doc, "c->state=CAlloc(sizeof(CSliderState));\n");
|
||||
DocPrint(doc,
|
||||
"c->draw_it=&DrawCtrlSlider;
|
||||
c->left_click=&LeftClickSlider;
|
||||
c->update_derived_vals=&UpdateDerivedCtrlSlider;
|
||||
QueIns(c,Fs->last_ctrl);
|
||||
TaskDerivedValsUpdate;
|
||||
return c;
|
||||
}
|
||||
|
||||
U0 SliderDel(CCtrl *c)
|
||||
{
|
||||
QueRem(c);
|
||||
");
|
||||
if (!*m->glbl_name)
|
||||
DocPrint(doc,"Free(c->state);\n");
|
||||
DocPrint(doc,
|
||||
"Free(c);
|
||||
}
|
||||
");
|
||||
|
||||
Kill(task); //This frees memory.
|
||||
|
||||
RegOneTimePopUp(ARf_MANAGE_SLIDER,
|
||||
"Modify the code to your heart's content.\n"
|
||||
"The code is no longer managed.\n");
|
||||
|
||||
DocLock(doc);
|
||||
}
|
||||
8
temple-src/Adam/Ctrls/MakeCtrls.HC
Executable file
8
temple-src/Adam/Ctrls/MakeCtrls.HC
Executable file
@ -0,0 +1,8 @@
|
||||
Cd(__DIR__);;
|
||||
|
||||
#help_index "Ctrls"
|
||||
#help_file "::/Doc/Ctrls"
|
||||
#include "CtrlsA"
|
||||
#include "CtrlsBttn"
|
||||
#include "CtrlsSlider"
|
||||
Cd("..");;
|
||||
220
temple-src/Adam/DevInfo.HC
Executable file
220
temple-src/Adam/DevInfo.HC
Executable file
@ -0,0 +1,220 @@
|
||||
#help_index "PCI;Processor;Devices;Info"
|
||||
|
||||
//The file was downloaded from
|
||||
//http://www.pcidatabase.com/reports.php?type=tab-delimeted
|
||||
|
||||
#define PCI_DEV_FILE "::/Misc/PCIDevices.DD.Z"
|
||||
|
||||
/****
|
||||
//1) Download http://www.pcidatabase.com/reports.php?type=tab-delimeted
|
||||
//2) Rename to ::/Misc/PCIDevices.DD.Z
|
||||
//3) ToDolDoc("::/Misc/PCIDevices.DD.Z");
|
||||
//4) Edit and remove file header and tail
|
||||
//5) Text find-and-replace "=0A=" with "". (Doesn't seem necessary anmore.)
|
||||
//6) Run PCIDevFileGen(). (Doesn't seem necessary anmore.)
|
||||
|
||||
public U0 PCIDevFileGen()
|
||||
{
|
||||
Bool first=TRUE,del=FALSE,del2=FALSE,cont=FALSE;
|
||||
CDoc *doc=DocRead(PCI_DEV_FILE,
|
||||
DOCF_PLAIN_TEXT|DOCF_DBL_DOLLARS|DOCF_NO_CURSOR);
|
||||
CDocEntry *doc_e=doc->head.next,*doc_e2;
|
||||
while (doc_e!=doc) {
|
||||
doc_e2=doc_e->next;
|
||||
if (first) {
|
||||
if (doc_e->type_u8==DOCT_TEXT) {
|
||||
if (doc_e->tag[0]==';')
|
||||
del=TRUE;
|
||||
}
|
||||
first=FALSE;
|
||||
}
|
||||
if (doc_e->type_u8==DOCT_TEXT && doc_e->tag[StrLen(doc_e->tag)-1]=='=' &&
|
||||
doc_e2->type_u8==DOCT_NEW_LINE) {
|
||||
doc_e->tag[StrLen(doc_e->tag)-1]=CH_SPACE;
|
||||
cont=TRUE;
|
||||
}
|
||||
del2=del;
|
||||
if (doc_e->type_u8==DOCT_NEW_LINE) {
|
||||
first=TRUE;
|
||||
del2=FALSE;
|
||||
if (cont) {
|
||||
del=TRUE;
|
||||
cont=FALSE;
|
||||
}
|
||||
}
|
||||
if (del)
|
||||
DocEntryDel(doc,doc_e);
|
||||
del=del2;
|
||||
doc_e=doc_e2;
|
||||
}
|
||||
DocWrite(doc);
|
||||
}
|
||||
****/
|
||||
|
||||
//$LK,"::/Misc/PCIDevices.DD",A="PI:::/Misc/PCIDevices.DD"$
|
||||
U0 PCILookUpSingle(CDoc *doc,I64 m,I64 d,U8 **_vendor,U8 **_dev)
|
||||
{
|
||||
Bool first=TRUE;
|
||||
U8 buf[8],*vendor=NULL,*dev=NULL;
|
||||
CDocEntry *doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
if (first) {
|
||||
if (doc_e->type_u8==DOCT_TEXT && doc_e->tag[0]!=';' &&
|
||||
StrLen(doc_e->tag)>=4) {
|
||||
buf[0](U16)='0x';
|
||||
buf[2](U32)=doc_e->tag(U32 *)[0];
|
||||
buf[6]=0;
|
||||
if (Str2I64(buf)==m) {
|
||||
doc_e=doc_e->next->next;
|
||||
if (doc_e->type_u8==DOCT_TEXT) {
|
||||
vendor=AStrNew(doc_e->tag);
|
||||
first=FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
first=FALSE;
|
||||
}
|
||||
if (doc_e->type_u8==DOCT_NEW_LINE)
|
||||
first=TRUE;
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
|
||||
if (vendor) {
|
||||
while (doc_e!=doc) {
|
||||
if (first) {
|
||||
if (doc_e->type_u8==DOCT_TAB) {
|
||||
doc_e=doc_e->next;
|
||||
if (doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=4) {
|
||||
buf[0](U16)='0x';
|
||||
buf[2](U32)=doc_e->tag(U32 *)[0];
|
||||
buf[6]=0;
|
||||
if (Str2I64(buf)==d) {
|
||||
doc_e=doc_e->next->next;
|
||||
if (doc_e->type_u8==DOCT_TEXT) {
|
||||
dev=AStrNew(doc_e->tag);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else
|
||||
break;
|
||||
first=FALSE;
|
||||
}
|
||||
if (doc_e->type_u8==DOCT_NEW_LINE)
|
||||
first=TRUE;
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (vendor)
|
||||
*_vendor=vendor;
|
||||
else
|
||||
*_vendor=AStrNew("Unknown");
|
||||
|
||||
if (dev)
|
||||
*_dev=dev;
|
||||
else
|
||||
*_dev=AStrNew("Unknown");
|
||||
}
|
||||
|
||||
U0 PCILookUpDevs()
|
||||
{
|
||||
CPCIDev *tmppci;
|
||||
I64 w1,w2,b,d,f,timeout=32*8*2;
|
||||
CDoc *doc;
|
||||
if (dev.pci_head.next!=&dev.pci_head)
|
||||
return;
|
||||
doc=DocRead(PCI_DEV_FILE,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
|
||||
for (b=0;b<sys_pci_busses;b++)
|
||||
for (d=0;d<32;d++)
|
||||
for (f=0;f<8;f++) {
|
||||
w1=PCIReadU16(b,d,f,0);
|
||||
if (w1!=0xFFFF) {
|
||||
tmppci=ACAlloc(sizeof(CPCIDev));
|
||||
tmppci->bus=b;
|
||||
tmppci->dev=d;
|
||||
tmppci->fun=f;
|
||||
tmppci->vendor=w1;
|
||||
tmppci->dev_id=w2=PCIReadU16(b,d,f,2);
|
||||
tmppci->sub_code=PCIReadU8(b,d,f,0xA);
|
||||
tmppci->base_code=PCIReadU8(b,d,f,0xB);
|
||||
PCILookUpSingle(doc,w1,w2,&tmppci->vendor_str,&tmppci->dev_id_str);
|
||||
QueIns(tmppci,dev.pci_head.last);
|
||||
timeout=32*8*2;
|
||||
} else if (sys_pci_busses==256 && --timeout<=0)
|
||||
goto lud_done;
|
||||
}
|
||||
lud_done:
|
||||
DocDel(doc);
|
||||
}
|
||||
|
||||
public U0 PCIRep()
|
||||
{//Report description of PCI devices.
|
||||
CPCIDev *tmppci;
|
||||
"PCI Busses:%d\n",sys_pci_busses;
|
||||
if (!FileFind(PCI_DEV_FILE)) {
|
||||
"You don't have the PCI device file.\n";
|
||||
return;
|
||||
}
|
||||
PCILookUpDevs;
|
||||
tmppci=dev.pci_head.next;
|
||||
while (tmppci!=&dev.pci_head) {
|
||||
"%02X:%02X:%01X %02X%02X $$GREEN$$%s $$CYAN$$%s$$FG$$\n",
|
||||
tmppci->bus,tmppci->dev,tmppci->fun,
|
||||
tmppci->base_code,tmppci->sub_code,
|
||||
tmppci->vendor_str,tmppci->dev_id_str;
|
||||
tmppci=tmppci->next;
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "Info;Memory/Info"
|
||||
public U0 MemBIOSRep()
|
||||
{//Report the memory ranges reported by the BIOS at boot.
|
||||
U16 *m01=MEM_E801;
|
||||
CMemE820 *m20=MEM_E820;
|
||||
CMemRange *tmpmr;
|
||||
"Standard Addresses\n"
|
||||
"000A0000-000BFFFF VGA\n"
|
||||
"FEE00000-FEE00FFF See $$LK,\"APIC\",A=\"MN:LAPIC_BASE\"$$\n\n"
|
||||
"32 Bit Device Mem\n";
|
||||
while (LBts(&sys_semas[SEMA_DEV_MEM],0))
|
||||
Yield;
|
||||
tmpmr=dev.mem32_head.next;
|
||||
while (tmpmr!=&dev.mem32_head) {
|
||||
"%02X:%016X-%016X\n",
|
||||
tmpmr->type,tmpmr->base,tmpmr->base+tmpmr->size-1;
|
||||
tmpmr=tmpmr->next;
|
||||
}
|
||||
LBtr(&sys_semas[SEMA_DEV_MEM],0);
|
||||
|
||||
"\nBIOS Memory Report 15:E801\n"
|
||||
"01:0000000000000000-%016X\n",0x100000+m01[0]<<10-1;
|
||||
"01:0000000001000000-%016X\n",SYS_16MEG_AREA_LIMIT+m01[1]<<16-1;
|
||||
|
||||
if (m20->type) {
|
||||
'\n';
|
||||
"BIOS Memory Report 15:E820\n";
|
||||
while (m20->type) {
|
||||
"%02X:%016X-%016X\n",m20->type,m20->base,m20->base+m20->len-1;
|
||||
m20++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public U0 MemPageRep()
|
||||
{//Page Table Report.
|
||||
"MAPPED\t:%010Xwith",mem_mapped_space;
|
||||
if (Bt(&mem_page_size,30))
|
||||
"$$RED$$1GIG$$FG$$ pages\n";
|
||||
else
|
||||
"$$RED$$2MEG$$FG$$ pages\n";
|
||||
"PML2\t:%010X2MEG:%08X\n",
|
||||
*MEM_PML2(U64 *),*MEM_2MEG_NUM(U64 *);
|
||||
"PML3\t:%010X1GIG:%08X\n",
|
||||
*MEM_PML3(U64 *),*MEM_1GIG_NUM(U64 *);
|
||||
"PML4\t:%010X512GIG:%08X\n",
|
||||
*MEM_PML4(U64 *),*MEM_512GIG_NUM(U64 *);
|
||||
"FIXED_AREA:%010X\n",SYS_FIXED_AREA;
|
||||
"HEAP_BASE:%010X\nHEAP_LIMIT:%010X\n",mem_heap_base,mem_heap_limit;
|
||||
}
|
||||
142
temple-src/Adam/DolDoc/DocBin.HC
Executable file
142
temple-src/Adam/DolDoc/DocBin.HC
Executable file
@ -0,0 +1,142 @@
|
||||
#help_index "DolDoc/Bin"
|
||||
|
||||
CDocBin *DocBinFindNum(CDoc *haystack_doc,I64 needle_num)
|
||||
{
|
||||
CDocBin *b=haystack_doc->bin_head.next;
|
||||
while (b!=&haystack_doc->bin_head) {
|
||||
if (b->num==needle_num)
|
||||
return b;
|
||||
b=b->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CDocBin *DocBinFindTag(CDoc *haystack_doc,U8 *needle_tag)
|
||||
{
|
||||
CDocBin *b;
|
||||
if (needle_tag) {
|
||||
b=haystack_doc->bin_head.next;
|
||||
while (b!=&haystack_doc->bin_head) {
|
||||
if (b->tag && !StrCmp(b->tag,needle_tag))
|
||||
return b;
|
||||
b=b->next;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
U0 DocBinsValidate(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocBin *b,*b1;
|
||||
CDocEntry *doc_e,*doc_e2;
|
||||
I64 renum_num=0;
|
||||
b=doc->bin_head.next;
|
||||
while (b!=&doc->bin_head) {
|
||||
b->use_cnt=0;
|
||||
b->tmp_use_cnt=0;
|
||||
b->renum_num=-1;
|
||||
Free(b->tag);
|
||||
b->tag=NULL;
|
||||
b=b->next;
|
||||
}
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
doc_e2=doc_e->next;
|
||||
if (doc_e->de_flags & DOCEF_HAS_BIN) {
|
||||
if (b=doc_e->bin_data=DocBinFindNum(doc,doc_e->bin_num)) {
|
||||
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
|
||||
b->tmp_use_cnt=I32_MAX;
|
||||
if (!b->use_cnt++)
|
||||
b->renum_num=++renum_num;
|
||||
doc_e->bin_num=b->renum_num;
|
||||
if (!b->tag && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
|
||||
b->tag=StrNew(doc_e->tag,doc->mem_task);
|
||||
} else {
|
||||
RawPrint(3000,"Bin Not Found");
|
||||
doc_e->type=doc_e->de_flags=0;
|
||||
doc_e->type_u8=DOCT_ERROR;
|
||||
}
|
||||
}
|
||||
doc_e=doc_e2;
|
||||
}
|
||||
|
||||
b=doc->bin_head.next;
|
||||
doc->cur_bin_num=1;
|
||||
while (b!=&doc->bin_head) {
|
||||
b1=b->next;
|
||||
if (!b->use_cnt) {
|
||||
QueRem(b);
|
||||
Free(b->data);
|
||||
Free(b);
|
||||
} else {
|
||||
b->num=b->renum_num;
|
||||
if (b->num>=doc->cur_bin_num)
|
||||
doc->cur_bin_num=b->num+1;
|
||||
}
|
||||
b=b1;
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
U0 DocBinDel(CDoc *doc,CDocBin *b)
|
||||
{
|
||||
if (doc && b && b->use_cnt) {
|
||||
b->use_cnt--;
|
||||
if (!b->use_cnt) {
|
||||
QueRem(b);
|
||||
Free(b->tag);
|
||||
Free(b->data);
|
||||
Free(b);
|
||||
}
|
||||
} else
|
||||
RawPrint(3000,"DocBinDel");
|
||||
}
|
||||
|
||||
I64 DocBinPtrRst(CDoc *doc,CDocEntry *doc_e)
|
||||
{
|
||||
U8 *st,*st2;
|
||||
CDoc *doc2;
|
||||
CDocBin *tmpb,*tmpb2;
|
||||
I64 i,bin_num=0;
|
||||
if (doc_e->de_flags&DOCEF_HAS_BIN &&
|
||||
doc_e->bin_ptr_link && StrLen(doc_e->bin_ptr_link)) {
|
||||
bin_num=doc_e->bin_num;
|
||||
st=StrNew(doc_e->bin_ptr_link);
|
||||
st2=StrNew(st);
|
||||
StrLastRem(st,",",st2);
|
||||
i=Str2I64(st2);
|
||||
if (i>0||*st2) {
|
||||
doc2=DocRead(st);
|
||||
if (i>0 && (tmpb2=DocBinFindNum(doc2,i)) ||
|
||||
i==0 && (tmpb2=DocBinFindTag(doc2,st2))) {
|
||||
i=1;
|
||||
if (bin_num>0) {
|
||||
if (tmpb=DocBinFindNum(doc,bin_num)) {
|
||||
i=tmpb->use_cnt;
|
||||
DocBinDel(doc,tmpb);
|
||||
}
|
||||
} else
|
||||
bin_num=doc->cur_bin_num++;
|
||||
tmpb=MAllocIdent(tmpb2,doc->mem_task);
|
||||
tmpb->use_cnt=i;
|
||||
tmpb->data=MAllocIdent(tmpb2->data,doc->mem_task);
|
||||
tmpb->num=bin_num;
|
||||
doc_e->bin_data=tmpb;
|
||||
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
|
||||
tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
|
||||
else
|
||||
tmpb->tag=NULL;
|
||||
QueIns(tmpb,doc->bin_head.last);
|
||||
} else
|
||||
bin_num=0;
|
||||
DocDel(doc2);
|
||||
} else
|
||||
bin_num=0;
|
||||
Free(st2);
|
||||
Free(st);
|
||||
doc_e->bin_num=bin_num;
|
||||
}
|
||||
return bin_num;
|
||||
}
|
||||
652
temple-src/Adam/DolDoc/DocChar.HC
Executable file
652
temple-src/Adam/DolDoc/DocChar.HC
Executable file
@ -0,0 +1,652 @@
|
||||
#help_index "DolDoc/Editor"
|
||||
|
||||
public I64 EdCurU8(CDoc *doc)
|
||||
{//Return cur U8. See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
I64 res=-1;
|
||||
if (doc_ce->type_u8==DOCT_TEXT &&
|
||||
doc_ce->min_col<=doc->cur_col<doc_ce->max_col)
|
||||
res=doc_ce->tag[doc->cur_col];
|
||||
else if (doc_ce->type_u8==DOCT_TAB)
|
||||
res='\t';
|
||||
else if (doc_ce->type_u8==DOCT_NEW_LINE ||
|
||||
doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
|
||||
res='\n';
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 EdCursorLeft(CDoc *doc,I64 sc=I64_MIN)
|
||||
{//Move cursor left. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
|
||||
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
|
||||
U8 *dst;
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
|
||||
I64 cc=doc->cur_col,y=doc_ce->y;
|
||||
if (sc!=I64_MIN) sc=sc.u32[0];
|
||||
if (sc>=0 && sc&SCF_CTRL) {
|
||||
while (doc_ce->last!=doc && (doc_ce->last->y==y ||
|
||||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)))
|
||||
doc_ce=doc_ce->last; //TODO: sel? recurse?
|
||||
cc=doc_ce->min_col;
|
||||
} else {
|
||||
if (cc>doc_ce->min_col) {
|
||||
if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
|
||||
dst=doc_ce->tag+cc;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ce->max_col=cc;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
}
|
||||
cc--;
|
||||
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
|
||||
dst=doc_ce->tag+cc;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ce->max_col=cc;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc_ce=doc_ne;
|
||||
cc=doc_ce->min_col;
|
||||
}
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
} else {
|
||||
cc=doc_ce->min_col;
|
||||
while (doc_ce->last!=doc &&
|
||||
(doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE ||
|
||||
doc_ce->last->type_u8==DOCT_INDENT ||
|
||||
doc_ce->last->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
|
||||
doc_ce=doc_ce->last;
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
}
|
||||
if (doc_ce->last!=doc) {
|
||||
doc_ce=doc_ce->last;
|
||||
if (doc_ce->max_col>doc_ce->min_col) {
|
||||
cc=doc_ce->max_col-1;
|
||||
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
|
||||
dst=doc_ce->tag+cc;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ce->max_col=cc;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc_ce=doc_ne;
|
||||
cc=doc_ce->min_col;
|
||||
}
|
||||
} else
|
||||
cc=doc_ce->max_col;
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
}
|
||||
}
|
||||
}
|
||||
doc->cur_col=cc;
|
||||
doc->cur_entry=doc_ce;
|
||||
if (doc_ce!=original_ce)
|
||||
DocFormBwd(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 EdCursorRight(CDoc *doc,I64 sc=I64_MIN)
|
||||
{//Move cursor right. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
|
||||
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
|
||||
Bool unlock=DocLock(doc);
|
||||
U8 *dst;
|
||||
CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
|
||||
I64 cc=doc->cur_col,y=doc_ce->y,old_de_flags,old_color;
|
||||
if (sc!=I64_MIN) sc=sc.u32[0];
|
||||
if (sc>=0 && sc&SCF_CTRL) {
|
||||
while (doc_ce!=doc && doc_ce->next->y==y &&
|
||||
doc_ce->next->type_u8!=DOCT_SOFT_NEW_LINE && doc_ce->next!=doc &&
|
||||
(doc_ce->next->type_u8!=DOCT_NEW_LINE || !(doc->flags & DOCF_FORM)) ||
|
||||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))
|
||||
doc_ce=doc_ce->next;
|
||||
if (doc_ce->max_col>doc_ce->min_col)
|
||||
cc=doc_ce->max_col-1;
|
||||
else
|
||||
cc=doc_ce->min_col;
|
||||
} else {
|
||||
if (cc<doc_ce->max_col) {
|
||||
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
|
||||
dst=doc_ce->tag+cc;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ce->max_col=cc;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc_ce=doc_ne;
|
||||
cc=doc_ce->min_col;
|
||||
}
|
||||
cc++;
|
||||
old_de_flags=doc_ce->de_flags;
|
||||
old_color=doc_ce->type;
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
|
||||
dst=doc_ce->tag+cc;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ne->type=DOCT_TEXT | old_color & -0x100;
|
||||
doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
|
||||
doc_ce->max_col=cc;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc_ce=doc_ne;
|
||||
cc=doc_ce->min_col;
|
||||
} else if (cc>=doc_ce->max_col) {
|
||||
doc_ce=doc_ce->next;
|
||||
cc=doc_ce->min_col;
|
||||
}
|
||||
} else {
|
||||
if (doc_ce!=doc) {
|
||||
if (cc<=doc_ce->min_col && sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
doc_ce=doc_ce->next;
|
||||
while (doc_ce!=doc && doc_ce->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP)) {
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
doc_ce=doc_ce->next;
|
||||
}
|
||||
cc=doc_ce->min_col;
|
||||
if (doc_ce->type_u8==DOCT_SOFT_NEW_LINE) {
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
doc_ce=doc_ce->next;
|
||||
cc=doc_ce->min_col;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
doc->cur_col=cc;
|
||||
doc->cur_entry=doc_ce;
|
||||
if (doc_ce!=original_ce)
|
||||
DocFormFwd(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 EdLineUp(CDoc *doc,I64 sc=I64_MIN)
|
||||
{//Move cursor up. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
|
||||
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
|
||||
Bool unlock=DocLock(doc);
|
||||
U8 *dst;
|
||||
I64 y,x;
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
|
||||
|
||||
if (sc!=I64_MIN) sc=sc.u32[0];
|
||||
if (doc_ce->type_u8==DOCT_HEX_ED) {
|
||||
doc->cur_col=doc->cur_col-doc_ce->hex_ed_width*3;
|
||||
if (doc->cur_col>=0) {
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return;
|
||||
} else
|
||||
doc->cur_col=0;
|
||||
}
|
||||
x=doc->x; y=doc->y;
|
||||
if (IsEditableText(doc_ce)) {
|
||||
if (doc_ce->min_col<doc->cur_col<doc_ce->max_col-1) {
|
||||
dst=doc_ce->tag+doc->cur_col;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ne->x=doc_ce->x+doc->cur_col;
|
||||
doc_ce->max_col=doc->cur_col;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
} else if (doc->cur_col==doc_ce->min_col && doc_ce->last!=doc)
|
||||
doc_ce=doc_ce->last;
|
||||
} else if (doc_ce->last!=doc)
|
||||
doc_ce=doc_ce->last;
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
doc->cur_entry=doc_ce;
|
||||
DocFormBwd(doc);
|
||||
doc_ce=doc->cur_entry;
|
||||
while (doc_ce->last!=doc && (doc_ce->y>=y ||
|
||||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
|
||||
doc_ce=doc_ce->last;
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
}
|
||||
y=doc_ce->y;
|
||||
doc->y=y;
|
||||
while (doc_ce!=doc && (doc_ce->y>=y && doc_ce->x>=x ||
|
||||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
doc_ce=doc_ce->last;
|
||||
}
|
||||
|
||||
if (doc_ce==doc || doc_ce->y<y)
|
||||
doc_ce=doc_ce->next;
|
||||
else {
|
||||
if (!IsEditableText(doc_ce)) {
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
} else {
|
||||
if (doc_ce->next->x==x) {
|
||||
doc_ce=doc_ce->next;
|
||||
if (doc->flags & DOCF_FORM)
|
||||
while (doc_ce->next->x==x &&
|
||||
(!Bt(doldoc.type_flags_form,doc_ce->type_u8) &&
|
||||
!(doc_ce->de_flags&DOCEF_LINK)||
|
||||
doc_ce->de_flags&DOCEF_SKIP_IN_FORM))
|
||||
doc_ce=doc_ce->next;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doc_ce->de_flags&DOCEF_TAG) {
|
||||
doc->cur_col=x-doc_ce->x;
|
||||
if (IsEditableText(doc_ce)) {
|
||||
if (doc->cur_col>doc_ce->max_col)
|
||||
doc->cur_col=doc_ce->max_col;
|
||||
} else if (doc->cur_col>=doc_ce->max_col)
|
||||
doc->cur_col=doc_ce->max_col-1;
|
||||
if (doc->cur_col<doc_ce->min_col)
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
} else {
|
||||
if (doc_ce->type_u8==DOCT_HEX_ED) {
|
||||
doc->cur_col=RoundI64((doc_ce->len-1)*3,doc_ce->hex_ed_width*3);
|
||||
if (doc->cur_col<0)
|
||||
doc->cur_col=0;
|
||||
} else
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
}
|
||||
if (IsEditableText(doc_ce) && doc_ce->x<x) {
|
||||
if (doc->cur_col<doc_ce->max_col-1) {
|
||||
dst=doc_ce->tag+doc->cur_col;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
if (sc>=0) {
|
||||
if (sc&SCF_SHIFT)
|
||||
doc_ne->type=doc_ce->type | DOCET_SEL;
|
||||
else
|
||||
doc_ne->type=doc_ce->type & ~DOCET_SEL;
|
||||
}
|
||||
doc_ne->x=doc_ce->x+doc->cur_col;
|
||||
doc_ce->max_col=doc->cur_col;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc_ce=doc_ne;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
}
|
||||
}
|
||||
doc->cur_entry=doc_ce;
|
||||
DocFormFwd(doc);
|
||||
doc->x=doc->cur_entry->x+doc->cur_col;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 EdLineDown(CDoc *doc,I64 sc=I64_MIN)
|
||||
{//Move cursor down. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
|
||||
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
|
||||
Bool unlock=DocLock(doc);
|
||||
U8 *dst;
|
||||
I64 y,x,old_de_flags=0,old_color;
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_ne,*doc_ce2;
|
||||
if (sc!=I64_MIN) sc=sc.u32[0];
|
||||
if (doc_ce->type_u8==DOCT_HEX_ED) {
|
||||
doc->cur_col=doc->cur_col+doc_ce->hex_ed_width*3;
|
||||
if (doc->cur_col>=doc_ce->len*3) {
|
||||
doc->cur_entry=doc_ce=doc_ce->next;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
doc->x=doc_ce->x+doc->cur_col;
|
||||
doc->y=doc_ce->y;
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return;
|
||||
}
|
||||
x=doc->x; y=doc->y;
|
||||
if (IsEditableText(doc_ce)) {
|
||||
if (doc->cur_col>doc_ce->min_col && doc->cur_col<doc_ce->max_col-1) {
|
||||
dst=doc_ce->tag+doc->cur_col;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
if (sc>=0) {
|
||||
if (sc&SCF_SHIFT)
|
||||
doc_ne->type=doc_ce->type | DOCET_SEL;
|
||||
else
|
||||
doc_ne->type=doc_ce->type & ~DOCET_SEL;
|
||||
}
|
||||
doc_ne->x=doc_ce->x+doc->cur_col;
|
||||
doc_ce->max_col=doc->cur_col;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc_ce=doc_ne;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
}
|
||||
}
|
||||
doc_ce2=doc_ce;
|
||||
while (doc_ce!=doc && (doc_ce->y<=y ||
|
||||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)))
|
||||
doc_ce=doc_ce->next;
|
||||
y=doc_ce->y;
|
||||
doc->y=y;
|
||||
while (doc_ce!=doc && (doc_ce->y<=y && doc_ce->x<=x ||
|
||||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
|
||||
old_de_flags=doc_ce->de_flags;
|
||||
old_color=doc_ce->type;
|
||||
doc_ce=doc_ce->next;
|
||||
}
|
||||
if (doc_ce->last!=doc && (doc_ce->x>x && doc_ce->last->y>=y || doc_ce->y>y)) {
|
||||
doc_ce=doc_ce->last;
|
||||
doc->cur_entry=doc_ce;
|
||||
if (!((doc_ce->type_u8==DOCT_NEW_LINE ||
|
||||
doc_ce->type_u8==DOCT_SOFT_NEW_LINE ||
|
||||
doc_ce->type_u8==DOCT_INDENT) &&
|
||||
(doc_ce->last->type_u8==DOCT_NEW_LINE ||
|
||||
doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE ||
|
||||
doc_ce->last->type_u8==DOCT_INDENT)))
|
||||
DocFormBwd(doc);
|
||||
doc_ce=doc->cur_entry;
|
||||
}
|
||||
while (doc_ce2!=doc && (doc_ce2!=doc_ce || IsEditableText(doc_ce))) {
|
||||
if ((doc_ce2->y<y || doc_ce2->x<x ||
|
||||
doc_ce2->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP) ||
|
||||
doc_ce2->x==x && !doc_ce2->max_col &&
|
||||
Bt(doldoc.type_flags_nontag_invis,doc_ce2->type_u8)) && sc>=0)
|
||||
BEqu(&doc_ce2->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
if (doc_ce2==doc_ce) break;
|
||||
doc_ce2=doc_ce2->next;
|
||||
}
|
||||
if (doc_ce->de_flags&DOCEF_TAG) {
|
||||
doc->cur_col=x-doc_ce->x;
|
||||
if (IsEditableText(doc_ce)) {
|
||||
if (doc->cur_col>doc_ce->max_col)
|
||||
doc->cur_col=doc_ce->max_col;
|
||||
} else if (doc->cur_col>=doc_ce->max_col)
|
||||
doc->cur_col=doc_ce->max_col-1;
|
||||
if (doc->cur_col<doc_ce->min_col)
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
} else
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
if (IsEditableText(doc_ce)&&doc_ce->min_col<doc->cur_col<doc_ce->max_col-1) {
|
||||
dst=doc_ce->tag+doc->cur_col;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ne->type=DOCT_TEXT | old_color & -0x100;
|
||||
doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
|
||||
doc_ce->max_col=doc->cur_col;
|
||||
doc_ne->x=doc_ce->x+doc->cur_col;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc_ce=doc_ne;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
}
|
||||
doc->cur_entry=doc_ce;
|
||||
DocFormFwd(doc);
|
||||
if (!(doc->flags & DOCF_FORM))
|
||||
while (doc_ce!=doc && doc_ce!=doc->cur_entry) {
|
||||
if (sc>=0)
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
doc_ce=doc_ce->next;
|
||||
}
|
||||
doc->x=doc->cur_entry->x+doc->cur_col;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
U0 EdCharDel(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
|
||||
if (doc_ce==doc) {
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return;
|
||||
}
|
||||
if (doc_ce->max_col!=0 &&
|
||||
(IsEditableText(doc_ce)||doc_ce->type_u8==DOCT_DATA)) {
|
||||
if (doc_ce->type_u8==DOCT_DATA && doc_ce->de_flags & DOCEF_HAS_TERMINATOR &&
|
||||
doc->cur_col==doc_ce->max_col-1) {
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return;
|
||||
}
|
||||
if (doc->cur_col<doc_ce->max_col)
|
||||
StrCpy(doc_ce->tag+doc->cur_col,doc_ce->tag+doc->cur_col+1);
|
||||
if (doc->cur_col>=doc_ce->max_col-1) {
|
||||
doc->cur_entry=doc_ce->next;
|
||||
doc->cur_col=doc->cur_entry->min_col;
|
||||
}
|
||||
DocRemSoftNewLines(doc,doc->cur_entry);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return;
|
||||
}
|
||||
doc->cur_entry=doc_ce->next;
|
||||
doc->cur_col=doc->cur_entry->min_col;
|
||||
if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
|
||||
DocEntryDel(doc,doc_ce);
|
||||
DocRemSoftNewLines(doc,doc->cur_entry);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
U0 ChkDollarBufSize(CDoc *doc)
|
||||
{
|
||||
U8 *b;
|
||||
if (doc->dollar_buf_ptr>=doc->dollar_buf_size-2) {
|
||||
doc->dollar_buf_size<<=1;
|
||||
b=MAlloc(doc->dollar_buf_size,doc->mem_task);
|
||||
MemCpy(b,doc->dollar_buf,doc->dollar_buf_ptr);
|
||||
Free(doc->dollar_buf);
|
||||
doc->dollar_buf=b;
|
||||
}
|
||||
}
|
||||
|
||||
U0 EdCharIns(I64 ch,I64 sc,CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
U8 *st,*src,*dst;
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
|
||||
I64 i,j,m,y=doc_ce->y;
|
||||
|
||||
if (doc->flags & DOCF_IN_DOLLAR) {
|
||||
if (!Bt(char_bmp_printable,ch))
|
||||
goto ic_done;
|
||||
ChkDollarBufSize(doc);
|
||||
doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
|
||||
if (ch=='$$') {
|
||||
if (doc->dollar_buf_ptr==2) {
|
||||
doc->flags&=~DOCF_IN_DOLLAR;
|
||||
doc->dollar_buf_ptr=0;
|
||||
goto ic_cont;
|
||||
} else {
|
||||
doc->dollar_buf[doc->dollar_buf_ptr]=0;
|
||||
doc->flags&=~DOCF_IN_DOLLAR;
|
||||
DocPrint(doc,"%s",doc->dollar_buf);
|
||||
doc->dollar_buf_ptr=0;
|
||||
goto ic_done;
|
||||
}
|
||||
} else
|
||||
goto ic_done;
|
||||
}
|
||||
if (ch=='$$' && !(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
|
||||
doc->flags|=DOCF_IN_DOLLAR;
|
||||
doc->dollar_buf_ptr=0;
|
||||
doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
|
||||
goto ic_done;
|
||||
}
|
||||
if (ch=='\r') goto ic_done;
|
||||
|
||||
ic_cont:
|
||||
if ((ch==CH_SPACE || ch=='\n') &&
|
||||
!(sc & (SCF_CTRL|SCF_SHIFT)) &&
|
||||
doc_ce->de_flags &
|
||||
(DOCEF_LINK|DOCEF_TREE|DOCEF_LST|DOCEF_CHECK_COLLAPSABLE|
|
||||
DOCEF_LEFT_MACRO|DOCEF_LEFT_EXP|DOCEF_LEFT_CB|DOCEF_LEFT_IN_STR |
|
||||
DOCEF_RIGHT_MACRO|DOCEF_RIGHT_EXP|DOCEF_RIGHT_CB|DOCEF_RIGHT_IN_STR)) {
|
||||
doc->cmd_U8=ch;
|
||||
DocEntryRun(doc,doc_ce,FALSE);
|
||||
DocLock(doc);
|
||||
goto ic_done;
|
||||
}
|
||||
if (doc_ce->type_u8==DOCT_HEX_ED) {
|
||||
if (doc_ce->de_flags&DOCEF_DEREF_DATA &&
|
||||
!(doc_ce->de_flags&DOCEF_REMALLOC_DATA))
|
||||
st=doc_ce->data;
|
||||
else
|
||||
st=&doc_ce->data;
|
||||
i=doc->cur_col;
|
||||
j=i%(doc_ce->hex_ed_width*3);
|
||||
m=i/(doc_ce->hex_ed_width*3)*doc_ce->hex_ed_width;
|
||||
if (j>=doc_ce->hex_ed_width<<1)
|
||||
st[j-doc_ce->hex_ed_width<<1+m]=ch;
|
||||
else {
|
||||
ch=ToUpper(ch)-'0';
|
||||
if (ch>9) {
|
||||
ch+='0'-'A'+10;
|
||||
if (!(10<=ch<=15))
|
||||
goto ic_done;
|
||||
}
|
||||
m=j>>1+m;
|
||||
if (j & 1)
|
||||
st[m]=st[m] & 0xF0| ch;
|
||||
else
|
||||
st[m]=st[m] & 0xF | ch<<4;
|
||||
}
|
||||
doc->cur_col++;
|
||||
goto ic_done;
|
||||
}
|
||||
if (doc->flags & DOCF_OVERSTRIKE) {
|
||||
if (Bt(char_bmp_displayable,ch)) {
|
||||
ic_overstrike:
|
||||
if (IsEditableText(doc_ce)) {
|
||||
if (doc->cur_col<doc_ce->max_col) {
|
||||
if (doc_ce->tag[doc->cur_col]) {
|
||||
doc_ce->tag[doc->cur_col++]=ch;
|
||||
goto ic_done;
|
||||
}
|
||||
} else {
|
||||
doc_ce=doc_ce->next;
|
||||
doc->cur_entry=doc_ce;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
goto ic_overstrike;
|
||||
}
|
||||
} else if (doc_ce->type_u8==DOCT_DATA) {
|
||||
if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR) {
|
||||
if (doc_ce->tag[doc->cur_col] &&
|
||||
doc->cur_col<doc_ce->min_col+doc_ce->len) {
|
||||
doc_ce->tag[doc->cur_col++]=ch;
|
||||
if ( ! doc_ce->tag[doc->cur_col]) {
|
||||
doc_ce->tag[doc->cur_col]='_';
|
||||
doc_ce->tag[doc->cur_col+1]=0;
|
||||
}
|
||||
} else if (doc_ce->de_flags & DOCEF_REMALLOC_DATA)
|
||||
goto ic_not_overstrike;
|
||||
} else if (doc_ce->tag[doc->cur_col])
|
||||
doc_ce->tag[doc->cur_col++]=ch;
|
||||
goto ic_done;
|
||||
}
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,&ch);
|
||||
doc_ne->type=DOCT_TEXT | doc->settings_head.dft_text_attr<<8;
|
||||
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
|
||||
QueIns(doc_ne,doc_ce->last);
|
||||
} else if (ch=='\n') {
|
||||
while (doc->cur_entry->next!=doc && doc->cur_entry->y==y)
|
||||
doc->cur_entry=doc->cur_entry->next;
|
||||
doc->cur_col=doc->cur_entry->min_col;
|
||||
} else if (ch=='\t') {
|
||||
if (doc->flags&DOCF_FORM)
|
||||
goto ic_form_tab;
|
||||
}
|
||||
goto ic_done;
|
||||
}
|
||||
ic_not_overstrike:
|
||||
if (ch=='\n') {
|
||||
if (sc&SCF_CTRL && !(sc&SCF_SHIFT)) {
|
||||
doc_ne=DocEntryNewBase(doc,
|
||||
DOCT_PAGE_BREAK|doc->settings_head.dft_text_attr<<8);
|
||||
} else {
|
||||
doc_ne=DocEntryNewBase(doc,
|
||||
DOCT_NEW_LINE|doc->settings_head.dft_text_attr<<8);
|
||||
}
|
||||
DocInsEntry(doc,doc_ne);
|
||||
} else if (ch=='\t') {
|
||||
if (doc->flags&DOCF_FORM &&
|
||||
(Bt(doldoc.type_flags_form,doc->cur_entry->type_u8) ||
|
||||
doc->cur_entry->de_flags&DOCEF_LINK) &&
|
||||
!(doc->cur_entry->de_flags&DOCEF_SKIP_IN_FORM)) {
|
||||
ic_form_tab:
|
||||
doc->cur_entry=doc->cur_entry->next;
|
||||
doc->cur_col=doc->cur_entry->min_col;
|
||||
DocFormFwd(doc);
|
||||
goto ic_done;
|
||||
} else {
|
||||
doc_ne=DocEntryNewBase(doc,DOCT_TAB|doc->settings_head.dft_text_attr<<8);
|
||||
DocInsEntry(doc,doc_ne);
|
||||
}
|
||||
} else {
|
||||
if (Bt(char_bmp_displayable,ch)) {
|
||||
if (doc_ce->type_u8==DOCT_DATA) {
|
||||
while (TRUE) {
|
||||
i=doc_ce->len+doc_ce->min_col;
|
||||
if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR)
|
||||
i++;
|
||||
if (doc_ce->max_col<i) {
|
||||
st=doc_ce->tag;
|
||||
doc_ce->max_col++;
|
||||
for (i=doc_ce->max_col;i>doc->cur_col;i--)
|
||||
st[i]=st[i-1];
|
||||
st[doc->cur_col++]=ch;
|
||||
break;
|
||||
} else if (doc_ce->de_flags & DOCEF_REMALLOC_DATA) {
|
||||
st=MAlloc(doc_ce->max_col+8,doc->mem_task);
|
||||
MemCpy(st,doc_ce->tag,doc_ce->max_col+1);
|
||||
Free(doc_ce->tag);
|
||||
doc_ce->tag=st;
|
||||
doc_ce->len=MSize(st)-doc_ce->min_col-2; //See $LK,"DataTagWidth",A="FA:::/Adam/DolDoc/DocPlain.HC,DataTagWidth"$
|
||||
Free(doc_ce->data);
|
||||
doc_ce->data=MAlloc(doc_ce->len+2,doc->mem_task);
|
||||
} else
|
||||
break;
|
||||
}
|
||||
} else if (IsEditableText(doc_ce)) {
|
||||
dst=st=MAlloc(doc_ce->max_col+2,doc->mem_task);
|
||||
src=doc_ce->tag;
|
||||
i=doc->cur_col;
|
||||
while (i-->0)
|
||||
*dst++=*src++;
|
||||
*dst++=ch;
|
||||
while (*dst++=*src++);
|
||||
Free(doc_ce->tag);
|
||||
doc_ce->tag=st;
|
||||
doc_ce->max_col++;
|
||||
doc->cur_col++;
|
||||
} else {
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,&ch);
|
||||
doc_ne->type=DOCT_TEXT | doc->settings_head.dft_text_attr<<8;
|
||||
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
|
||||
doc_ne->x=doc_ce->x+1;
|
||||
QueIns(doc_ne,doc_ce->last);
|
||||
}
|
||||