Initial (manual) import
This commit is contained in:
1 parent
f39611c506
commit
895fe109de
661 files changed
+245862
No files matched your search
Binary file not shown.
@@ -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);
|
||||
|
||||
RBlks(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";
|
||||
WBlks(Fs->cur_dv,buf,blk,1);
|
||||
}
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
|
||||
public U8 *DCluster(I64 c,Bool write=FALSE,I64 num=0)
|
||||
{//Dump disk cluster. Optionally, write.
|
||||
//If you set write to TRUE, the cluster will
|
||||
//be written when you press <ESC>.
|
||||
//See $LK,"::/Demo/Dsk/DskRaw.HC"$.
|
||||
//Do $LK,"Dir",A="MN:Dir"$("*",TRUE); to get cluster numbers of files.
|
||||
U8 *buf=MAlloc(Fs->cur_dv->spc<<BLK_SIZE_BITS);
|
||||
c=ClusterNumNext(Fs->cur_dv,c,num);
|
||||
RClusters(Fs->cur_dv,buf,c,1);
|
||||
"Cluster:%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";
|
||||
WClusters(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_CLUSTER_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) {
|
||||
MkDir(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=CurDir;
|
||||
DirContextDel(dirc);
|
||||
i1=StrLen(st1);
|
||||
if (i1==3) i1--;
|
||||
if (dirc=DirContextNew(dst_files_find_mask,TRUE,TRUE)) {
|
||||
st2=CurDir;
|
||||
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.\n");
|
||||
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);
|
||||
}
|
||||
@@ -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);
|
||||
RBlks(dv,buf,Cluster2Blk(dv,tmpde->cluster),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;
|
||||
}
|
||||
@@ -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->cluster-dv->data_area>size) {
|
||||
PrintErr("Invalid Cluster:%s Cluster:%X\n",tmpde1->full_name,
|
||||
i+tmpde1->cluster);
|
||||
errs++;
|
||||
break;
|
||||
}
|
||||
if (LBts(bits,i+tmpde1->cluster-dv->data_area)) {
|
||||
PrintErr("Dbl Alloc:%s Cluster:%X\n",tmpde1->full_name,
|
||||
i+tmpde1->cluster);
|
||||
errs++;
|
||||
}
|
||||
if (!LBtr(bits2,i+tmpde1->cluster-dv->data_area)) {
|
||||
PrintErr("UnAlloc:%s Cluster:%X\n",tmpde1->full_name,
|
||||
i+tmpde1->cluster);
|
||||
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);
|
||||
RBlks(dv,bits2,dv->fat1,((size+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS);
|
||||
|
||||
//Get Root Dir size
|
||||
ptr2=MAlloc(bpc);
|
||||
RBlks(dv,ptr2,dv->root_cluster,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_cluster-dv->data_area>size) {
|
||||
PrintErr("Invalid Cluster: RootDir Cluster:%X\n",i+dv->root_cluster);
|
||||
errs++;
|
||||
break;
|
||||
}
|
||||
if (LBts(bits,i+dv->root_cluster-dv->data_area)) {
|
||||
PrintErr("Dbl Alloc: RootDir Cluster:%X\n",i+dv->root_cluster);
|
||||
errs++;
|
||||
}
|
||||
if (!LBtr(bits2,i+dv->root_cluster-dv->data_area)) {
|
||||
PrintErr("UnAlloc: RootDir Cluster:%X\n",i+dv->root_cluster);
|
||||
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 Cluster:%0X\n",i+dv->data_area);
|
||||
errs++;
|
||||
if (ChkDskConfirm(_fix,_confirm))
|
||||
RedSeaFreeClusters(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->cluster;
|
||||
while (0<c<0x0FFFFFF8) {
|
||||
if (c>size) {
|
||||
PrintErr("Invalid Cluster:%s Cluster:%X\n",tmpde1->full_name,c);
|
||||
errs++;
|
||||
break;
|
||||
}
|
||||
if (LBts(bits,c)) {
|
||||
PrintErr("Dbl Alloc:%s Cluster:%X\n",tmpde1->full_name,c);
|
||||
errs++;
|
||||
}
|
||||
if (!bits2[c]) {
|
||||
PrintErr("UnAlloc:%s Cluster:%X\n",tmpde1->full_name,c);
|
||||
errs++;
|
||||
} else
|
||||
bits2[c]=0;
|
||||
c=ClusterNumNext(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);
|
||||
RBlks(dv,bits2,dv->fat1,(size*4+BLK_SIZE-1)>>BLK_SIZE_BITS);
|
||||
|
||||
c=dv->root_cluster;
|
||||
while (0<c<0x0FFFFFF8) {
|
||||
if (c>size) {
|
||||
PrintErr("Invalid Cluster: RootDir Cluster:%X\n",c);
|
||||
errs++;
|
||||
break;
|
||||
}
|
||||
if (LBts(bits,c)) {
|
||||
PrintErr("Dbl Alloc: RootDir Cluster:%X\n",c);
|
||||
errs++;
|
||||
}
|
||||
if (!bits2[c]) {
|
||||
PrintErr("UnAlloc: RootDir Cluster:%X\n",c);
|
||||
errs++;
|
||||
} else
|
||||
bits2[c]=0;
|
||||
c=ClusterNumNext(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 Cluster:%0X\n",i);
|
||||
errs++;
|
||||
if (ChkDskConfirm(_fix,_confirm))
|
||||
FAT32FreeClusters(dv,i);
|
||||
}
|
||||
Free(files_find_mask);
|
||||
Free(bits);
|
||||
Free(bits2);
|
||||
Drv(Drv2Let(old_dv));
|
||||
Cd(old_dir);
|
||||
Free(old_dir);
|
||||
return errs;
|
||||
}
|
||||
|
||||
public I64 ChkDsk(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);
|
||||
RBlks(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);
|
||||
RBlks(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);
|
||||
RBlks(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);
|
||||
RBlks(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 UnusedDrvSpace(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;
|
||||
}
|
||||
@@ -0,0 +1,809 @@
|
||||
#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;
|
||||
}
|
||||
|
||||
U0 FMRebuildDoc(CDoc **_doc,CDirEntry **_head,I64 mode)
|
||||
{
|
||||
CDrv *dv;
|
||||
I64 i;
|
||||
CDoc *doc=*_doc,*doc2=sys_clipboard_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->flags|=DEF_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;
|
||||
MkDir(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;
|
||||
MkDir(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;
|
||||
ChgDsk(*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,I64 type)
|
||||
{
|
||||
CDocEntry *doc_ce=doc->cur_entry;
|
||||
CDirEntry *tmpde;
|
||||
U8 *st;
|
||||
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;
|
||||
switch (type) {
|
||||
case FSt_REDSEA:
|
||||
RedSeaISO(,tmpde->full_name);
|
||||
break;
|
||||
case FSt_ISO9660:
|
||||
if (tmpde->full_name[StrLen(tmpde->full_name)-1]=='/')
|
||||
st=MStrPrint("%s*",tmpde->full_name);
|
||||
else
|
||||
st=MStrPrint("%s/*",tmpde->full_name);
|
||||
ISO9660ISO(,st);
|
||||
Free(st);
|
||||
break;
|
||||
}
|
||||
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_clipboard_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->flags|=DEF_PROCESSED;
|
||||
tmpde2=tmpde->parent;
|
||||
if (!tmpde2 || !(tmpde2->flags&DEF_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->flags|=DEF_PROCESSED;
|
||||
tmpde2=tmpde->parent;
|
||||
if (!tmpde2 || !(tmpde2->flags&DEF_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_MAKE_ISO9660 12
|
||||
#define FMR_BURN_ISO 13
|
||||
#define FMR_HELP 14
|
||||
|
||||
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,\"ADAM INCLUDE \",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,\"MAKE DIRECTORY \",LE=FMR_MKDIR$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"PLAIN-TEXT EDIT \",LE=FMR_PLAIN$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"PASTE CLIPBOARD FILES \",LE=FMR_PASTE$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"CHANGE DISK(MOUNT IT) \",LE=FMR_CHG_DSK$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"FORMAT \",LE=FMR_FORMAT$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"MOUNT ISO.C FILE \","
|
||||
"LE=FMR_MOUNT_REDSEA_ISO_C$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"UNMOUNT \",LE=FMR_UNMOUNT$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"MAKE ISO.C (CD/DVD) FILE\",LE=FMR_MAKE_REDSEA_ISO_C$$"
|
||||
"$$CM+LX,29,0$$$$BT,\"MAKE ISO (CD/DVD) FILE \",LE=FMR_MAKE_ISO9660$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"BURN ISO (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_MAKE_ISO9660:
|
||||
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=CurDir;
|
||||
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,FSt_ISO9660);
|
||||
break;
|
||||
case 'm':
|
||||
FMMakeISO(doc,FSt_REDSEA);
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
Cd(__DIR__);;
|
||||
#include "ADskA"
|
||||
#include "ADskB"
|
||||
#include "PrtDsk"
|
||||
#include "Mount"
|
||||
#include "ChkDsk"
|
||||
#include "FileMgr"
|
||||
Cd("..");;
|
||||
@@ -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;
|
||||
PrtDsk(drv_let,1.0); //First mount whole drive.
|
||||
} else
|
||||
PrtDsk(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,"PrtDsk(Mount)",A="FF:::/Adam/ABlkDev/PrtDsk.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=DftExt(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;
|
||||
}
|
||||
@@ -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 PrtDsk(U8 drv_let=0,...)
|
||||
{/*Partition the disk containing partition drv_let.
|
||||
|
||||
drv_let=0 means add new drive that is not already mounted.
|
||||
|
||||
>PrtDsk('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;
|
||||
}
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
#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);
|
||||
|
||||
//This is cut and replaced when I generate a distro.
|
||||
//See $LK,"DD_TEMPLEOS_LOC",A="FF:::/Demo/AcctExample/TOS/TOSDistro.HC,DD_TEMPLEOS_LOC"$.
|
||||
$TR-C,"LineRep"$
|
||||
$ID,4$DefinePrint("DD_TEMPLEOS_LOC","119,749");
|
||||
DefinePrint("DD_TEMPLEOS_LOC_OFFICIAL","81,933");
|
||||
$ID,-4$
|
||||
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"$
|
||||
|
||||
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;
|
||||
@@ -0,0 +1,101 @@
|
||||
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 U0 ACMisspelledFind(CDoc *doc);
|
||||
extern I64 AdamFile(U8 *filename,Bool warn_ext=TRUE);
|
||||
extern Bool AutoComplete(Bool val=OFF);
|
||||
extern I64 BMPWrite(U8 *filename,CDC *dc,I64 bits=4);
|
||||
extern U0 ClipboardDel();
|
||||
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 DocBMP(CDoc *doc=NULL,U8 *filename,
|
||||
Bool dither_probability=FALSE,Bool use_ms_paint_palette=FALSE);
|
||||
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 I64 ISO9660ISO(U8 *_filename=NULL,U8 *src_files_find_mask,
|
||||
U8 *fu_flags=NULL,U8 *_stage2_filename=NULL);
|
||||
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;
|
||||
@@ -0,0 +1,433 @@
|
||||
#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],*st,*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) {
|
||||
st=MStrUtil(ptr(CHashDefineStr *)->data,SUF_SAFE_DOLLAR);
|
||||
j=ptr(CHashDefineStr *)->cnt;
|
||||
if (j==-1)
|
||||
StrPrint(buf,"%-10tQ ",st);
|
||||
else
|
||||
StrPrint(buf,"%-10tQ %02X",st,j);
|
||||
Free(st);
|
||||
} 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:%d Count:%d Longest:%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=DftExt(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);
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -0,0 +1,609 @@
|
||||
#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=MAlloc(sizeof(CMathODE));
|
||||
|
||||
ode->t=0;
|
||||
ode->t_scale=1.0;
|
||||
ode->base_t=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;
|
||||
ode->derivative=NULL;
|
||||
QueInit(&ode->next_mass);
|
||||
QueInit(&ode->next_spring);
|
||||
ode->acceleration_limit=ode->drag_v=ode->drag_v2=ode->drag_v3=0;
|
||||
|
||||
ode->state=CAlloc(s);
|
||||
ode->array_base=MAlloc(12*s);
|
||||
ODERstPtrs(ode);
|
||||
return ode;
|
||||
}
|
||||
|
||||
public U0 ODEDel(CMathODE *ode)
|
||||
{//Free ODE node, but not masses or springs.
|
||||
if (!ode) return;
|
||||
Free(ode->state);
|
||||
Free(ode->array_base);
|
||||
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 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);
|
||||
(*ode->derivative)(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
|
||||
(*ode->derivative)(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 if (ode->derivative) {
|
||||
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);
|
||||
}
|
||||
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->derivative) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,229 @@
|
||||
#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 DocTreeBranchExe(sys_registry_doc,path);
|
||||
}
|
||||
|
||||
public Bool RegWrite(U8 *path,U8 *fmt,...)
|
||||
{//Rewrite doc tree branch in registry.
|
||||
Bool res,unlock_doc;
|
||||
CDocEntry *tree_branch,*start_indent,*end_indent;
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
RegCache;
|
||||
unlock_doc=DocLock(sys_registry_doc);
|
||||
if (res=DocTreeFind(sys_registry_doc,path,
|
||||
&tree_branch,&start_indent,&end_indent))
|
||||
DocCut(sys_registry_doc,tree_branch,end_indent);
|
||||
DocTreeMake(sys_registry_doc,path);
|
||||
DocPrint(sys_registry_doc,"%s",buf);
|
||||
if (DrvIsWritable(*sys_registry_doc->filename.name))
|
||||
DocWrite(sys_registry_doc);
|
||||
if (unlock_doc)
|
||||
DocUnlock(sys_registry_doc);
|
||||
Free(buf);
|
||||
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,...)
|
||||
{//Rewrite doc tree branch in registry.
|
||||
Bool res,unlock_doc;
|
||||
CDocEntry *tree_branch,*start_indent,*end_indent;
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
RegCache;
|
||||
unlock_doc=DocLock(sys_registry_doc);
|
||||
if (res=DocTreeFind(sys_registry_doc,path,
|
||||
&tree_branch,&start_indent,&end_indent)) {
|
||||
sys_registry_doc->cur_entry=end_indent;
|
||||
sys_registry_doc->cur_col=sys_registry_doc->cur_entry->min_col;
|
||||
} else
|
||||
DocTreeMake(sys_registry_doc,path);
|
||||
DocPrint(sys_registry_doc,"%s",buf);
|
||||
if (DrvIsWritable(*sys_registry_doc->filename.name))
|
||||
DocWrite(sys_registry_doc);
|
||||
if (unlock_doc)
|
||||
DocUnlock(sys_registry_doc);
|
||||
Free(buf);
|
||||
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);
|
||||
}
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,263 @@
|
||||
/*
|
||||
This file is a stand-alone program
|
||||
which will regenerate processed dictionary
|
||||
files from a raw Project Gutenberg
|
||||
dictionary file.
|
||||
|
||||
$TX,"http://www.templeos.org/files/DICTIONARY.DD",HTML="http://www.templeos.org/files/DICTIONARY.DD"$
|
||||
|
||||
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");
|
||||
@@ -0,0 +1,261 @@
|
||||
#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
|
||||
FRBlks(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
|
||||
FRBlks(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);
|
||||
}
|
||||
|
||||
U0 ACMisspelledFind(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocEntry *doc_e=doc->cur_entry;
|
||||
I64 col=doc->cur_col,col2,ch;
|
||||
do {
|
||||
if (doc_e!=doc && doc_e->de_flags&DOCEF_TAG) {
|
||||
while (col<doc_e->max_col) {
|
||||
while (col<doc_e->max_col && !Bt(char_bmp_word,doc_e->tag[col]))
|
||||
col++;
|
||||
if (col<doc_e->max_col) {
|
||||
col2=col;
|
||||
while (col2<doc_e->max_col && Bt(char_bmp_word,doc_e->tag[col2]))
|
||||
col2++;
|
||||
ch=doc_e->tag[col2];
|
||||
doc_e->tag[col2]=0;
|
||||
if (StrICmp(&doc_e->tag[col],ACDWordPtAt(&doc_e->tag[col])+1)) {
|
||||
doc_e->tag[col2]=ch;
|
||||
doc->cur_entry=doc_e;
|
||||
doc->cur_col=col;
|
||||
goto fm_done;
|
||||
}
|
||||
doc_e->tag[col2]=ch;
|
||||
col=col2;
|
||||
}
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
col=doc_e->min_col;
|
||||
} while (doc_e!=doc->cur_entry);
|
||||
fm_done:
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
#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);
|
||||
}
|
||||
@@ -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_CLUSTER_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;
|
||||
}
|
||||
@@ -0,0 +1,284 @@
|
||||
#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_TASK_DFT-WIF_SELF_BORDER
|
||||
-WIF_SELF_MS_L-WIF_SELF_MS_R-WIG_DBL_CLICK;
|
||||
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_autocomplete=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_autocomplete=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_autocomplete=TRUE;
|
||||
Kill(ac.task);
|
||||
DeathWait(&ac.task);
|
||||
}
|
||||
}
|
||||
return old_autocomplete;
|
||||
}
|
||||
Binary file not shown.
@@ -0,0 +1,6 @@
|
||||
//See $LK,"::/Doc/AutoComplete.DD"$
|
||||
Cd(__DIR__);;
|
||||
#include "ACFill"
|
||||
#include "ACTask"
|
||||
#include "ACInit"
|
||||
Cd("..");;
|
||||
@@ -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);
|
||||
"\n Context\n"
|
||||
"CPU Swaps/s Cycles\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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
Cd(__DIR__);;
|
||||
|
||||
#help_index "Ctrls"
|
||||
#help_file "::/Doc/Ctrls"
|
||||
#include "CtrlsA"
|
||||
#include "CtrlsBttn"
|
||||
#include "CtrlsSlider"
|
||||
Cd("..");;
|
||||
@@ -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 :%010X with ",mem_mapped_space;
|
||||
if (Bt(&mem_page_size,30))
|
||||
"$$RED$$1GIG$$FG$$ pages\n";
|
||||
else
|
||||
"$$RED$$2MEG$$FG$$ pages\n";
|
||||
"PML2\t :%010X 2MEG :%08X\n",
|
||||
*MEM_PML2(U64 *),*MEM_2MEG_NUM(U64 *);
|
||||
"PML3\t :%010X 1GIG :%08X\n",
|
||||
*MEM_PML3(U64 *),*MEM_1GIG_NUM(U64 *);
|
||||
"PML4\t :%010X 512GIG:%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;
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
ic_done:
|
||||
DocRemSoftNewLines(doc,doc->cur_entry);
|
||||
if (doc->cur_entry->de_flags & DOCEF_UPDATE_DATA &&
|
||||
(doc->cur_entry->type_u8==DOCT_DATA ||
|
||||
doc->cur_entry->type_u8==DOCT_CHECK_BOX))
|
||||
DocDataScan(doc,doc->cur_entry);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
U0 EdLineDel(CDoc *doc)
|
||||
{
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_ce2;
|
||||
I64 y;
|
||||
y=doc->y;
|
||||
while (doc_ce!=doc && doc_ce->y==y)
|
||||
doc_ce=doc_ce->next;
|
||||
doc->cur_entry=doc_ce;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
doc_ce=doc_ce->last;
|
||||
while (doc_ce!=doc && doc_ce->y==y) {
|
||||
doc_ce2=doc_ce->last;
|
||||
if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
|
||||
DocEntryDel(doc,doc_ce);
|
||||
doc_ce=doc_ce2;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
#help_index "DolDoc/Clipboard"
|
||||
|
||||
sys_clipboard_doc=DocNew;
|
||||
|
||||
public U0 ClipboardDel()
|
||||
{//Delete everything on clipboard.
|
||||
DocRst(sys_clipboard_doc,TRUE);
|
||||
}
|
||||
|
||||
public U0 EdCopyToClipboard(CDoc *doc)
|
||||
{//Copy $LK,"DOCET_SEL",A="MN:DOCET_SEL"$ flagged entries to clipboard.
|
||||
CDoc *doc2=sys_clipboard_doc;
|
||||
Bool unlock_doc=DocLock(doc),
|
||||
unlock_doc2=DocLock(doc2);
|
||||
CDocEntry *doc_e=doc->head.next,*doc_ne;
|
||||
ClipboardDel;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->type & DOCET_SEL) {
|
||||
doc_e->type&=~DOCET_SEL;
|
||||
if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
|
||||
doc_ne=DocEntryCopy(doc2,doc_e);
|
||||
QueIns(doc_ne,doc2->head.last);
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
if (unlock_doc2)
|
||||
DocUnlock(doc2);
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 EdCutToClipboard(CDoc *doc)
|
||||
{//Remove sel entries and place on clipboard.
|
||||
CDoc *doc2=sys_clipboard_doc;
|
||||
Bool unlock_doc=DocLock(doc),
|
||||
unlock_doc2=DocLock(doc2);
|
||||
CDocEntry *doc_e=doc->head.next,*doc_e1,*doc_ne,*doc_e2=NULL;
|
||||
ClipboardDel;
|
||||
while (doc_e!=doc) {
|
||||
doc_e1=doc_e->next;
|
||||
if (doc_e->type & DOCET_SEL) {
|
||||
doc_e->type&=~DOCET_SEL;
|
||||
if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
|
||||
doc_ne=DocEntryCopy(doc2,doc_e);
|
||||
QueIns(doc_ne,doc2->head.last);
|
||||
}
|
||||
if (doc_e==doc->cur_entry || doc_e==doc_e2)
|
||||
doc_e2=doc_e->next;
|
||||
DocEntryDel(doc,doc_e);
|
||||
}
|
||||
doc_e=doc_e1;
|
||||
}
|
||||
if (doc_e2) {
|
||||
doc->cur_entry=doc_e2;
|
||||
doc->cur_col=doc_e2->min_col;
|
||||
}
|
||||
DocRemSoftNewLines(doc,NULL);
|
||||
if (unlock_doc2)
|
||||
DocUnlock(doc2);
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 EdPasteClipboard(CDoc *doc)
|
||||
{//Insert copy of clipboard at insert pt, cur_entry.
|
||||
CDoc *doc2=sys_clipboard_doc;
|
||||
Bool unlock_doc=DocLock(doc),
|
||||
unlock_doc2=DocLock(doc2);
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_e;
|
||||
if (doc_ce->type_u8==DOCT_DATA) {
|
||||
doc_e=doc2->head.next;
|
||||
while (doc_e!=doc2) {
|
||||
if (doc_e->de_flags&DOCEF_TAG)
|
||||
DocPrintPartial(doc,"%s",doc_e->tag);
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
} else
|
||||
DocInsDoc(doc,doc2);
|
||||
if (unlock_doc2)
|
||||
DocUnlock(doc2);
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 DocCut(CDoc *doc,CDocEntry *start,CDocEntry *end)
|
||||
{//Del start to end entry, including end points.
|
||||
Bool unlock_doc=DocLock(doc);
|
||||
CDocEntry *doc_e1;
|
||||
while (start!=doc) {
|
||||
doc_e1=start->next;
|
||||
if (start==doc->cur_entry) {
|
||||
doc->cur_entry=start->next;
|
||||
doc->cur_col=doc->cur_entry->min_col;
|
||||
}
|
||||
DocEntryDel(doc,start);
|
||||
if (start==end)
|
||||
break;
|
||||
start=doc_e1;
|
||||
}
|
||||
DocRemSoftNewLines(doc,NULL);
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public CDoc *DocCopy(CDoc *doc,CDocEntry *start,CDocEntry *end)
|
||||
{//Copies start to end entry, including end points.
|
||||
CDoc *doc2=DocNew;
|
||||
Bool unlock_doc=DocLock(doc);
|
||||
CDocEntry *doc_ne;
|
||||
while (start!=doc) {
|
||||
if (!Bt(doldoc.type_flags_data,start->type_u8)) {
|
||||
doc_ne=DocEntryCopy(doc2,start);
|
||||
QueIns(doc_ne,doc2->head.last);
|
||||
}
|
||||
if (start==end)
|
||||
break;
|
||||
start=start->next;
|
||||
}
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
return doc2;
|
||||
}
|
||||
@@ -0,0 +1,658 @@
|
||||
#help_index "DolDoc/Misc"
|
||||
|
||||
U0 EdReplaceTroubleOne(CDoc *doc,U8 *st_original,U8 *st_safe,I64 num,
|
||||
Bool to_safe,Bool sel)
|
||||
{
|
||||
U8 buf[STR_LEN];
|
||||
StrPrint(buf,st_safe,num);
|
||||
if (to_safe)
|
||||
EdReplace(doc,st_original,buf,sel);
|
||||
else
|
||||
EdReplace(doc,buf,st_original,sel);
|
||||
}
|
||||
|
||||
U0 EdReplaceTroubleAll(CDoc *doc,Bool to_safe,Bool sel)
|
||||
{
|
||||
I64 i=0;
|
||||
EdReplaceTroubleOne(doc,"#assert" ,"//<@%d@>" ,i++,to_safe,sel);
|
||||
EdReplaceTroubleOne(doc,"#define" ,"//<@%d@>" ,i++,to_safe,sel);
|
||||
EdReplaceTroubleOne(doc,"#include","//<@%d@>" ,i++,to_safe,sel);
|
||||
//#if will match #if,#ifdef,#ifndef,#ifaot and #ifjit
|
||||
EdReplaceTroubleOne(doc,"#if" ,"//<@%d@>" ,i++,to_safe,sel);
|
||||
EdReplaceTroubleOne(doc,"#endif" ,"//<@%d@>" ,i++,to_safe,sel);
|
||||
//Convert #exe to union because we want that indent pattern.
|
||||
EdReplaceTroubleOne(doc,"#exe" ,"union @%d@",i++,to_safe,sel);
|
||||
EdReplaceTroubleOne(doc,"'{'" ,"'<@%d@>'" ,i++,to_safe,sel);
|
||||
EdReplaceTroubleOne(doc,"'}'" ,"'<@%d@>'" ,i++,to_safe,sel);
|
||||
}
|
||||
|
||||
#define C_INDENT_SPACES 2
|
||||
#define ASM_RENUM_SPACING 5
|
||||
|
||||
#define EF_REINDENT 0
|
||||
#define EF_CMP_CHK 1
|
||||
#define EF_RENUM_ASM 2
|
||||
#define EF_CTRL_SLIDER 3
|
||||
#define EF_CH_SC 4
|
||||
|
||||
I64 PopUpEdFmt()
|
||||
{
|
||||
I64 i;
|
||||
CDoc *doc=DocNew;
|
||||
DocPrint(doc,"$$LTBLUE$$$$MU,\"Compile Check\",LE=EF_CMP_CHK$$\n"
|
||||
"$$MU,\"Reindent HolyC Fun (Beware braces in strings.)\","
|
||||
"LE=EF_REINDENT$$\n"
|
||||
"$$MU,\"Renum Asm Local @@ Labels for Fun\",LE=EF_RENUM_ASM$$\n"
|
||||
"$$MU,\"Insert Template Code: Ctrl Slider\",LE=EF_CTRL_SLIDER$$\n"
|
||||
"$$MU,\"Insert ASCII/Scan Code Hex Codes for key pressed\","
|
||||
"LE=EF_CH_SC$$\n\n"
|
||||
"$$MU,\"CANCEL\",LE=DOCM_CANCEL$$\n\n"
|
||||
"$$GREEN$$<ALT-BACKSPACE>$$FG$$ to undo if not happy\n"
|
||||
"with the ress.\n");
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
class CRILex
|
||||
{
|
||||
CCmpCtrl *cc1,*cc2;
|
||||
CQueVectU8 *indent;
|
||||
I64 depth,exp_depth,one_shot;
|
||||
Bool was_new_line,is_not_cont;
|
||||
};
|
||||
|
||||
I64 EdRILex(CRILex *rx)
|
||||
{
|
||||
rx->is_not_cont=FALSE;
|
||||
I64 i;
|
||||
CLexFile *tmpf;
|
||||
do {
|
||||
Lex(rx->cc1);
|
||||
Lex(rx->cc2);
|
||||
i=PrsKeyWord(rx->cc2);
|
||||
if (rx->cc1->token=='\n' && rx->cc2->token==';' || rx->cc2->token=='{' ||
|
||||
rx->cc2->token=='}' || rx->cc2->token==':' || rx->cc2->token==')' &&
|
||||
!rx->exp_depth || i==KW_ELSE || i==KW_CATCH || i==KW_DO)
|
||||
rx->is_not_cont=TRUE;
|
||||
if (rx->was_new_line && (rx->cc1->token!=':' || i==KW_CASE ||
|
||||
i==KW_DFT || i==KW_START || i==KW_END)) {
|
||||
tmpf=rx->cc2->lex_include_stk;
|
||||
while (tmpf->next)
|
||||
tmpf=tmpf->next;
|
||||
QueVectU8Put(rx->indent,tmpf->cur_entry->y,rx->depth+rx->one_shot);
|
||||
rx->one_shot=0;
|
||||
}
|
||||
if (rx->cc2->token=='\n')
|
||||
rx->was_new_line=TRUE;
|
||||
else
|
||||
rx->was_new_line=FALSE;
|
||||
} while (rx->cc1->token=='\n');
|
||||
return rx->cc1->token;
|
||||
}
|
||||
|
||||
U0 EdRIExp(CRILex *rx)
|
||||
{
|
||||
if (rx->cc1->token=='(') {
|
||||
if (!rx->exp_depth++)
|
||||
rx->depth+=3;
|
||||
EdRILex(rx);
|
||||
while (rx->cc1->token && rx->cc1->token!=')')
|
||||
EdRIExp(rx);
|
||||
if (!--rx->exp_depth) {
|
||||
rx->depth-=3;
|
||||
if (rx->depth<0) rx->depth=0;
|
||||
}
|
||||
} else if (rx->cc1->token=='[') {
|
||||
if (!rx->exp_depth++)
|
||||
rx->depth+=3;
|
||||
EdRILex(rx);
|
||||
while (rx->cc1->token && rx->cc1->token!=']')
|
||||
EdRIExp(rx);
|
||||
if (!--rx->exp_depth) {
|
||||
rx->depth-=3;
|
||||
if (rx->depth<0) rx->depth=0;
|
||||
}
|
||||
}
|
||||
EdRILex(rx);
|
||||
}
|
||||
|
||||
U0 EdRIStmt(CRILex *rx,Bool indent)
|
||||
{
|
||||
I64 i;
|
||||
Bool cont;
|
||||
if (rx->cc1->token=='{') {
|
||||
rx->depth++;
|
||||
EdRILex(rx);
|
||||
while (rx->cc1->token && rx->cc1->token!='}')
|
||||
EdRIStmt(rx,FALSE);
|
||||
if (--rx->depth<0) rx->depth=0;
|
||||
EdRILex(rx);
|
||||
} else {
|
||||
if (indent) rx->depth++;
|
||||
do {
|
||||
cont=FALSE;
|
||||
switch (PrsKeyWord(rx->cc1)) {
|
||||
case KW_IF:
|
||||
EdRILex(rx);
|
||||
EdRIExp(rx);
|
||||
EdRIStmt(rx,TRUE);
|
||||
if (PrsKeyWord(rx->cc1)==KW_ELSE) {
|
||||
EdRILex(rx);
|
||||
if (PrsKeyWord(rx->cc1)==KW_IF && rx->cc2->token!='\n')
|
||||
EdRIStmt(rx,FALSE);
|
||||
else
|
||||
EdRIStmt(rx,TRUE);
|
||||
}
|
||||
break;
|
||||
case KW_TRY:
|
||||
EdRILex(rx);
|
||||
EdRIStmt(rx,TRUE);
|
||||
if (PrsKeyWord(rx->cc1)==KW_CATCH) {
|
||||
EdRILex(rx);
|
||||
EdRIStmt(rx,TRUE);
|
||||
}
|
||||
break;
|
||||
case KW_LOCK:
|
||||
EdRILex(rx);
|
||||
EdRIStmt(rx,TRUE);
|
||||
break;
|
||||
case KW_FOR:
|
||||
case KW_WHILE:
|
||||
EdRILex(rx);
|
||||
EdRIExp(rx);
|
||||
EdRIStmt(rx,TRUE);
|
||||
break;
|
||||
case KW_ASM:
|
||||
case KW_CLASS:
|
||||
case KW_UNION:
|
||||
if (EdRILex(rx)==TK_IDENT)
|
||||
EdRILex(rx);
|
||||
EdRIStmt(rx,TRUE);
|
||||
break;
|
||||
case KW_DO:
|
||||
EdRILex(rx);
|
||||
EdRIStmt(rx,TRUE);
|
||||
if (PrsKeyWord(rx->cc1)==KW_WHILE) {
|
||||
EdRILex(rx);
|
||||
EdRIExp(rx);
|
||||
}
|
||||
if (rx->cc1->token==';')
|
||||
EdRILex(rx);
|
||||
break;
|
||||
case KW_SWITCH:
|
||||
EdRILex(rx);
|
||||
EdRIExp(rx);
|
||||
if (rx->cc1->token=='{') {
|
||||
rx->depth++;
|
||||
EdRILex(rx);
|
||||
i=0;
|
||||
while (rx->cc1->token && rx->cc1->token!='}') {
|
||||
switch (PrsKeyWord(rx->cc1)) {
|
||||
case KW_START:
|
||||
rx->depth+=i; i=0;
|
||||
while (EdRILex(rx) && rx->cc1->token!=':');
|
||||
EdRILex(rx);
|
||||
i++;
|
||||
break;
|
||||
case KW_END:
|
||||
rx->depth+=i; i=0;
|
||||
if (--rx->depth<0) rx->depth=0;
|
||||
while (EdRILex(rx) && rx->cc1->token!=':');
|
||||
EdRILex(rx);
|
||||
break;
|
||||
case KW_CASE:
|
||||
case KW_DFT:
|
||||
rx->depth+=i; i=0;
|
||||
while (EdRILex(rx) && rx->cc1->token!=':');
|
||||
EdRILex(rx);
|
||||
break;
|
||||
default:
|
||||
if (rx->cc1->token)
|
||||
EdRIStmt(rx,TRUE);
|
||||
}
|
||||
}
|
||||
if (--rx->depth<0) rx->depth=0;
|
||||
EdRILex(rx);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
if (rx->cc1->token==TK_IDENT && rx->cc1->hash_entry &&
|
||||
rx->cc1->hash_entry->type&(HTT_OPCODE|HTT_ASM_KEYWORD)) {
|
||||
// rx->one_shot=4-rx->depth;
|
||||
do EdRILex(rx);
|
||||
while (rx->cc2->token && rx->cc2->token!='\n');
|
||||
rx->is_not_cont=TRUE;
|
||||
} else {
|
||||
while (rx->cc1->token && rx->cc1->token!=';' &&
|
||||
rx->cc1->token!=':') {
|
||||
if (rx->cc2->token=='\n' && !rx->is_not_cont)
|
||||
rx->one_shot=3;
|
||||
EdRILex(rx);
|
||||
}
|
||||
if (rx->cc1->token==':')
|
||||
cont=TRUE;
|
||||
EdRILex(rx);
|
||||
}
|
||||
}
|
||||
} while (cont && rx->cc1->token!='}');
|
||||
if (indent && --rx->depth<0)
|
||||
rx->depth=0;
|
||||
}
|
||||
}
|
||||
|
||||
CQueVectU8 *EdRICode(CDoc *doc)
|
||||
{
|
||||
CQueVectU8 *res;
|
||||
CRILex *rx=CAlloc(sizeof(CRILex));
|
||||
|
||||
rx->cc1=CmpCtrlNew(,CCF_KEEP_NEW_LINES|CCF_DONT_FREE_BUF,doc->filename.name);
|
||||
Free(rx->cc1->lex_include_stk->full_name);
|
||||
LexAttachDoc(rx->cc1,rx->cc1->lex_include_stk,doc,,
|
||||
doc->cur_entry,doc->cur_col);
|
||||
|
||||
rx->cc2=CmpCtrlNew(,CCF_KEEP_NEW_LINES|CCF_DONT_FREE_BUF,doc->filename.name);
|
||||
Free(rx->cc2->lex_include_stk->full_name);
|
||||
LexAttachDoc(rx->cc2,rx->cc2->lex_include_stk,doc,,
|
||||
doc->cur_entry,doc->cur_col);
|
||||
|
||||
rx->indent=QueVectU8New(doc->cur_entry->y);
|
||||
|
||||
Lex(rx->cc1);
|
||||
EdRIStmt(rx,FALSE);
|
||||
|
||||
CmpCtrlDel(rx->cc1);
|
||||
CmpCtrlDel(rx->cc2);
|
||||
res=rx->indent;
|
||||
Free(rx);
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 EdRemFunLeadingSpace(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc),
|
||||
start_of_line=TRUE;
|
||||
U8 *ptr;
|
||||
I64 ch,levels=1;
|
||||
CDocEntry *doc_e,*doc_e2;
|
||||
|
||||
EdGoToFun(doc,FALSE,FALSE);
|
||||
doc_e=doc->cur_entry->next;
|
||||
do {
|
||||
doc_e2=doc_e->next;
|
||||
if (doc_e!=doc && doc_e!=doc->cur_entry &&
|
||||
!(doc_e->de_flags&(DOCEG_DONT_EDIT-DOCEF_SCROLLING_X)))
|
||||
switch (doc_e->type_u8) {
|
||||
case DOCT_TEXT:
|
||||
ptr=doc_e->tag;
|
||||
if (start_of_line) {
|
||||
while (*ptr==CH_SPACE)
|
||||
ptr++;
|
||||
if (*ptr)
|
||||
start_of_line=FALSE;
|
||||
ptr=StrNew(ptr,doc->mem_task);
|
||||
Free(doc_e->tag);
|
||||
doc_e->tag=ptr;
|
||||
}
|
||||
if (!*ptr)
|
||||
DocEntryDel(doc,doc_e);
|
||||
else {
|
||||
while (ch=*ptr++)
|
||||
if (ch=='{')
|
||||
levels++;
|
||||
else if (ch=='}') {
|
||||
if (!--levels)
|
||||
break;
|
||||
}
|
||||
if (!levels) goto ls_done;
|
||||
}
|
||||
break;
|
||||
case DOCT_TAB:
|
||||
if (start_of_line)
|
||||
DocEntryDel(doc,doc_e);
|
||||
break;
|
||||
case DOCT_NEW_LINE:
|
||||
start_of_line=TRUE;
|
||||
break;
|
||||
default:
|
||||
start_of_line=FALSE;
|
||||
}
|
||||
doc_e=doc_e2;
|
||||
} while (doc_e!=doc->cur_entry);
|
||||
ls_done:
|
||||
DocRecalc(doc);
|
||||
DocCenter(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
class CRenum
|
||||
{
|
||||
CRenum *next,*last;
|
||||
U8 label[sizeof(CEdFindText.find_text)];
|
||||
};
|
||||
|
||||
I64 EdRAGetU8(CDoc *doc)
|
||||
{
|
||||
I64 res=-1;
|
||||
while (doc->cur_entry!=doc &&
|
||||
doc->cur_entry->type&DOCET_SEL && res<0) {
|
||||
res=EdCurU8(doc);
|
||||
EdCursorRight(doc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 EdRACollect(CDoc *doc,CRenum *head)
|
||||
{
|
||||
I64 ch,i;
|
||||
CRenum *tmpr;
|
||||
U8 buf[sizeof(CEdFindText.find_text)];
|
||||
ch=EdRAGetU8(doc);
|
||||
while (ch>=0) {
|
||||
if (ch!='@')
|
||||
ch=EdRAGetU8(doc);
|
||||
else {
|
||||
ch=EdRAGetU8(doc);
|
||||
if (ch=='@') {
|
||||
ch=EdRAGetU8(doc);
|
||||
StrCpy(buf,"@@");
|
||||
i=2;
|
||||
while (ch>=0 && i<sizeof(CEdFindText.find_text)) {
|
||||
if (Bt(char_bmp_alpha_numeric,ch))
|
||||
buf[i++]=ch;
|
||||
else
|
||||
break;
|
||||
ch=EdRAGetU8(doc);
|
||||
}
|
||||
if (i<sizeof(CEdFindText.find_text)) {
|
||||
buf[i++]=0;
|
||||
while (ch>=0 && Bt(char_bmp_white_space,ch))
|
||||
ch=EdRAGetU8(doc);
|
||||
if (ch==':') {
|
||||
ch=EdRAGetU8(doc);
|
||||
tmpr=MAlloc(sizeof(CRenum));
|
||||
StrCpy(tmpr->label,buf);
|
||||
QueIns(tmpr,head->last);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//This is needed because we moved the
|
||||
//cursor and it didn't recalc.
|
||||
DocRecalc(doc);
|
||||
}
|
||||
|
||||
U0 EdRenumAsm(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
I64 num=0;
|
||||
CRenum head,*tmpr,*tmpr1;
|
||||
U8 buf[sizeof(CEdFindText.find_text)],
|
||||
buf2[sizeof(CEdFindText.find_text)];
|
||||
|
||||
QueInit(&head);
|
||||
EdSelFun(doc,TRUE);
|
||||
EdRACollect(doc,&head);
|
||||
|
||||
tmpr=head.next;
|
||||
while (tmpr!=&head) {
|
||||
tmpr1=tmpr->next;
|
||||
num+=ASM_RENUM_SPACING;
|
||||
StrPrint(buf,"@#%02d",num);
|
||||
EdReplace(doc,tmpr->label,buf,TRUE,TRUE,TRUE);
|
||||
Free(tmpr);
|
||||
tmpr=tmpr1;
|
||||
}
|
||||
|
||||
while (num) {
|
||||
StrPrint(buf, "@#%02d",num);
|
||||
StrPrint(buf2,"@@%02d",num);
|
||||
EdReplace(doc,buf,buf2,TRUE,TRUE,TRUE);
|
||||
num-=ASM_RENUM_SPACING;
|
||||
}
|
||||
EdSelAll(doc,FALSE);
|
||||
DocRecalc(doc);
|
||||
DocCenter(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
U0 EdCodeTools2(CDoc *doc,I64 tool_action,Bool beep=TRUE)
|
||||
{
|
||||
Bool okay,unlock=DocLock(doc),start_of_line=TRUE;
|
||||
CDocEntry *doc_e,*doc_ne;
|
||||
I64 i,start_y,end_y,x,r,goto_line_num;
|
||||
U8 *b,*st,*st2,*prj_file;
|
||||
CTask *task=NULL;
|
||||
CJob *tmpc;
|
||||
CQueVectU8 *indent;
|
||||
|
||||
DocRecalc(doc);
|
||||
goto_line_num=doc->cur_entry->y+1;
|
||||
|
||||
DocCaptureUndo(doc,TRUE);
|
||||
switch (tool_action) {
|
||||
case EF_CMP_CHK:
|
||||
okay=FALSE;
|
||||
if (doc->flags&DOCF_PLAIN_TEXT)
|
||||
DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
|
||||
DocWrite(doc);
|
||||
task=Spawn(&SrvCmdLine,NULL,"Srv",,Fs);
|
||||
st2=CurDir;
|
||||
st=MStrPrint("Cd(\"%s\");",st2);
|
||||
tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
|
||||
Free(st2);
|
||||
Free(st);
|
||||
WinHorz(Fs->win_left,Fs->win_right, task);
|
||||
WinVert(Fs->win_top, Fs->win_bottom,task);
|
||||
if (JobResScan(tmpc,&r)) {
|
||||
st=DirFile(doc->filename.name,,"PRJ.Z");
|
||||
prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
|
||||
Free(st);
|
||||
if (FileFind(prj_file)) {
|
||||
st2=DirFile(prj_file),
|
||||
st=MStrPrint("Cd(\"%s\");",st2);
|
||||
Free(st2);
|
||||
tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|
|
||||
1<<JOBf_FOCUS_MASTER|1<<JOBf_FREE_ON_COMPLETE);
|
||||
Free(st);
|
||||
st=MStrPrint("\"$$WW,1$$\";Cmp(\"%s\",\"SysTmp\",\"SysTmp\");",
|
||||
prj_file);
|
||||
tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
|
||||
Free(st);
|
||||
if (JobResScan(tmpc,&r))
|
||||
if (!r) {
|
||||
tmpc=TaskExe(task,Fs,
|
||||
"Load(\"SysTmp\",LDF_JUST_LOAD);",
|
||||
1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
|
||||
if (JobResScan(tmpc,&r))
|
||||
okay=TRUE;
|
||||
}
|
||||
tmpc=TaskExe(task,Fs,"Del(\"SysTmp.*\");",
|
||||
1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
|
||||
JobResScan(tmpc,&r);
|
||||
} else {
|
||||
Free(prj_file);
|
||||
st=DirFile(doc->filename.name,"Load","HC.Z");
|
||||
prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
|
||||
Free(st);
|
||||
if (FileFind(prj_file))
|
||||
st=MStrPrint("\"$$WW,1$$\";ExeFile(\"%s\",CCF_JUST_LOAD);",prj_file);
|
||||
else
|
||||
st=MStrPrint("\"$$WW,1$$\";ExeFile(\"%s\",CCF_JUST_LOAD);",
|
||||
doc->filename.name);
|
||||
tmpc=TaskExe(task,Fs,st,1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
|
||||
Free(st);
|
||||
if (JobResScan(tmpc,&r) && r)
|
||||
okay=TRUE;
|
||||
}
|
||||
Free(prj_file);
|
||||
}
|
||||
if (!okay) {
|
||||
PopUpOk("Has Errors");
|
||||
while (LBts(&sys_semas[SEMA_FIX],0))
|
||||
Yield;
|
||||
ToFileLine(dbg.fix_file_line,&st,&i);
|
||||
LBtr(&sys_semas[SEMA_FIX],0);
|
||||
if (!StrCmp(st,doc->filename.name))
|
||||
goto_line_num=i;
|
||||
Free(st);
|
||||
}
|
||||
break;
|
||||
case EF_REINDENT:
|
||||
start_y=doc->cur_entry->y;
|
||||
EdReplaceTroubleAll(doc,TRUE,FALSE);
|
||||
DocLineNumGoTo(doc,start_y+1);
|
||||
if (EdGoToFun(doc,FALSE,FALSE)) {
|
||||
start_y=doc->cur_entry->y;
|
||||
indent=EdRICode(doc);
|
||||
DocUnlock(doc);
|
||||
if (beep) {
|
||||
Snd(86); Sleep(150); Snd;
|
||||
Sleep(100);
|
||||
Snd(86); Sleep(150); Snd;
|
||||
}
|
||||
DocLock(doc);
|
||||
EdRemFunLeadingSpace(doc);
|
||||
DocLineNumGoTo(doc,start_y+1);
|
||||
doc_e=doc->cur_entry;
|
||||
end_y=start_y+indent->total_cnt;
|
||||
while (start_y<=doc_e->y<end_y) {
|
||||
if (doc_e!=doc && doc_e!=doc->cur_entry &&
|
||||
!(doc_e->de_flags&(DOCEG_DONT_EDIT-DOCEF_SCROLLING_X))) {
|
||||
if (doc_e->type_u8==DOCT_NEW_LINE||
|
||||
doc_e->type_u8==DOCT_SOFT_NEW_LINE)
|
||||
start_of_line=TRUE;
|
||||
else {
|
||||
if (start_of_line) {
|
||||
i=QueVectU8Get(indent,doc_e->y)*C_INDENT_SPACES;
|
||||
x=doc_e->x+1;
|
||||
while (i>8) {
|
||||
doc_ne=DocEntryNewBase(doc,
|
||||
DOCT_TAB|doc->settings_head.dft_text_attr<<8,,
|
||||
x,doc_e->y,doc_e->page_line_num);
|
||||
MemCpy(&doc_ne->settings,
|
||||
&doc_e->settings,sizeof(CDocSettings));
|
||||
QueIns(doc_ne,doc_e->last);
|
||||
i-=8;
|
||||
x+=8;
|
||||
}
|
||||
if (i>0) {
|
||||
b=MAlloc(i+1,doc->mem_task);
|
||||
MemSet(b,CH_SPACE,i);
|
||||
b[i]=0;
|
||||
doc_ne=DocEntryNewBase(doc,
|
||||
DOCT_TEXT|doc->settings_head.dft_text_attr<<8,,
|
||||
x,doc_e->y,doc_e->page_line_num);
|
||||
doc_ne->tag=b;
|
||||
doc_ne->max_col=1;
|
||||
MemCpy(&doc_ne->settings,
|
||||
&doc_e->settings,sizeof(CDocSettings));
|
||||
QueIns(doc_ne,doc_e->last);
|
||||
}
|
||||
}
|
||||
start_of_line=FALSE;
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
QueVectU8Del(indent);
|
||||
}
|
||||
start_y=doc->cur_entry->y;
|
||||
EdReplaceTroubleAll(doc,FALSE,FALSE);
|
||||
DocLineNumGoTo(doc,start_y+1);
|
||||
break;
|
||||
case EF_RENUM_ASM:
|
||||
if (EdGoToFun(doc,FALSE,TRUE)) {
|
||||
if (EdCurU8(doc)=='{') {
|
||||
EdCursorRight(doc);
|
||||
DocRecalc(doc);
|
||||
} else if (EdCurU8(doc)==':') {
|
||||
EdCursorRight(doc);
|
||||
if (EdCurU8(doc)==':')
|
||||
EdCursorRight(doc);
|
||||
DocRecalc(doc);
|
||||
}
|
||||
DocUnlock(doc);
|
||||
if (beep) {
|
||||
Snd(86); Sleep(150); Snd;
|
||||
Sleep(100);
|
||||
Snd(86); Sleep(150); Snd;
|
||||
}
|
||||
DocLock(doc);
|
||||
EdRenumAsm(doc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
DocRecalc(doc);
|
||||
DocLineNumGoTo(doc,goto_line_num);
|
||||
|
||||
DocUnlock(doc);
|
||||
if (!unlock)
|
||||
DocLock(doc);
|
||||
if (task)
|
||||
Kill(task,FALSE);
|
||||
}
|
||||
|
||||
U0 EdPopUpChSC(I64 *_ch,I64 *_sc)
|
||||
{
|
||||
I64 sc;
|
||||
"Press A Key\n";
|
||||
DocPut->flags|=DOCF_SIZE_MIN;
|
||||
do GetMsg(_ch,&sc,1<<MSG_KEY_DOWN);
|
||||
while (sc.u8[0]==SC_SHIFT || sc.u8[0]==SC_CTRL || sc.u8[0]==SC_ALT);
|
||||
*_sc=sc;
|
||||
}
|
||||
|
||||
U0 EdChSC(CDoc *doc)
|
||||
{
|
||||
I64 ch,sc;
|
||||
U8 buf[STR_LEN];
|
||||
StrPrint(buf,"EdPopUpChSC(%d,%d);",&ch,&sc);
|
||||
PopUp(buf,Fs);
|
||||
if (ch==CH_BACKSPACE)
|
||||
DocPrint(doc,"CH_BACKSPACE,0x%X",sc);
|
||||
else if (ch=='\n')
|
||||
DocPrint(doc,"'\n',0x%X",sc);
|
||||
else if (CH_CTRLA<=ch<=CH_CTRLZ)
|
||||
DocPrint(doc,"CH_CTRL%C,0x%X",ch+'@',sc);
|
||||
else if (ch=='$$')
|
||||
DocPrint(doc,"'$$$$',0x%X",sc);
|
||||
else if (ch=='\\')
|
||||
DocPrint(doc,"'\\\\',0x%X",sc);
|
||||
else if (ch=='\'')
|
||||
DocPrint(doc,"'\\\'',0x%X",sc);
|
||||
else if (ch==CH_ESC)
|
||||
DocPrint(doc,"CH_ESC,0x%X",sc);
|
||||
else if (ch==CH_SHIFT_ESC)
|
||||
DocPrint(doc,"CH_SHIFT_ESC,0x%X",sc);
|
||||
else if (ch==CH_SPACE)
|
||||
DocPrint(doc,"CH_SPACE,0x%X",sc);
|
||||
else if (ch==CH_SHIFT_SPACE)
|
||||
DocPrint(doc,"CH_SHIFT_SPACE,0x%X",sc);
|
||||
else if (Bt(char_bmp_displayable,ch))
|
||||
DocPrint(doc,"'%c',0x%X",ch,sc);
|
||||
else
|
||||
DocPrint(doc,"0x%X,0x%X",ch,sc);
|
||||
}
|
||||
|
||||
U0 EdCodeTools(CDoc *doc)
|
||||
{
|
||||
I64 tool_action=PopUpEdFmt;
|
||||
switch (tool_action) {
|
||||
case EF_CMP_CHK:
|
||||
case EF_REINDENT:
|
||||
case EF_RENUM_ASM:
|
||||
EdCodeTools2(doc,tool_action);
|
||||
break;
|
||||
case EF_CTRL_SLIDER:
|
||||
TemplateCtrlSlider(doc);
|
||||
break;
|
||||
case EF_CH_SC:
|
||||
EdChSC(doc);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,110 @@
|
||||
#help_index "DolDoc/Task;StdOut/Task"
|
||||
public CDoc *DocPut(CTask *task=NULL)
|
||||
{//Current document that StdOut Put() goes to.
|
||||
//Basically, StdOut unless double buffering.
|
||||
CDoc *res;
|
||||
if (!task) task=Fs;
|
||||
if (Bt(&task->task_flags,TASKf_INPUT_FILTER_TASK))
|
||||
task=task->parent_task;
|
||||
if ((res=task->put_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
|
||||
return res;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public CDoc *DocDisplay(CTask *task=NULL)
|
||||
{//StdOut displayed unless double buffering.
|
||||
CDoc *res;
|
||||
if (!task) task=Fs;
|
||||
if ((res=task->display_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
|
||||
return res;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public CDoc *DocBorder(CTask *task=NULL)
|
||||
{//Doc holding border of window text.
|
||||
CDoc *res;
|
||||
if (!task) task=Fs;
|
||||
if ((res=task->border_doc) && res->doc_signature==DOC_SIGNATURE_VAL)
|
||||
return res;
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public CDoc *DocDblBufStart(CTask *task=NULL)
|
||||
{//See $LK,"::/Demo/Spy.HC"$
|
||||
Bool unlock_ddoc;
|
||||
CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task),*res;
|
||||
if (!pdoc || !ddoc || pdoc!=ddoc)
|
||||
res=NULL; //Already Double buffering
|
||||
else {
|
||||
if (!task) task=Fs;
|
||||
unlock_ddoc=DocLock(ddoc); //dont change during winupdate, so lock DocPut$WW,0$
|
||||
res=DocNew(,task);
|
||||
res->win_task =ddoc->win_task;
|
||||
res->max_entries =ddoc->max_entries;
|
||||
MemCpy(res->find_replace,ddoc->find_replace,sizeof(CEdFindText));
|
||||
MemCpy(&res->filename,&ddoc->filename,sizeof(CEdFileName));
|
||||
res->left_click_link =ddoc->left_click_link;
|
||||
res->right_click_link =ddoc->right_click_link;
|
||||
res->user_put_data =ddoc->user_put_data;
|
||||
res->user_put_key =ddoc->user_put_key;
|
||||
res->user_put_s =ddoc->user_put_s;
|
||||
res->parent_doc =ddoc->parent_doc;
|
||||
res->desc =ddoc->desc;
|
||||
res->user_data =ddoc->user_data;
|
||||
res->flags|=ddoc->flags&DOCG_DBL_BUF_FLAGS | DOCF_DONT_SHOW;
|
||||
task->put_doc=res;
|
||||
if (unlock_ddoc)
|
||||
DocUnlock(ddoc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool DocDblBufEnd(CTask *task=NULL)
|
||||
{//See $LK,"::/Demo/Spy.HC"$
|
||||
Bool res=FALSE;
|
||||
CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task);
|
||||
if (pdoc && ddoc && pdoc!=ddoc) {//Double buffering?
|
||||
if (!task) task=Fs;
|
||||
ddoc->flags|=DOCF_DONT_SHOW;
|
||||
pdoc->flags&=~DOCF_DONT_SHOW;
|
||||
DocLock(ddoc);
|
||||
task->display_doc=pdoc;
|
||||
DocUnlock(ddoc);
|
||||
DocDel(ddoc);
|
||||
res=TRUE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool DocDblBufSwap(CTask *task=NULL)
|
||||
{//See $LK,"::/Demo/Spy.HC"$
|
||||
Bool res=FALSE;
|
||||
CDoc *pdoc=DocPut(task),*ddoc=DocDisplay(task);
|
||||
if (pdoc && ddoc && pdoc!=ddoc) {//Double buffering?
|
||||
if (!task) task=Fs;
|
||||
ddoc->flags|=DOCF_DONT_SHOW;
|
||||
pdoc->flags&=~DOCF_DONT_SHOW;
|
||||
DocLock(ddoc);
|
||||
task->display_doc=pdoc;
|
||||
DocUnlock(ddoc);
|
||||
DocRst(ddoc,TRUE);
|
||||
MemCpy(ddoc->find_replace,pdoc->find_replace,sizeof(CEdFindText));
|
||||
MemCpy(&ddoc->filename,&pdoc->filename,sizeof(CEdFileName));
|
||||
ddoc->max_entries =pdoc->max_entries;
|
||||
ddoc->flags =pdoc->flags&DOCG_DBL_BUF_FLAGS |
|
||||
ddoc->flags&~DOCG_DBL_BUF_FLAGS;
|
||||
ddoc->left_click_link =pdoc->left_click_link;
|
||||
ddoc->right_click_link =pdoc->right_click_link;
|
||||
ddoc->user_put_data =pdoc->user_put_data;
|
||||
ddoc->user_put_key =pdoc->user_put_key;
|
||||
ddoc->user_put_s =pdoc->user_put_s;
|
||||
ddoc->desc =pdoc->desc;
|
||||
ddoc->user_data =pdoc->user_data;
|
||||
task->put_doc=ddoc;
|
||||
res=TRUE;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,250 @@
|
||||
#help_index "DolDoc/Output;StdOut/DolDoc"
|
||||
|
||||
public Bool View()
|
||||
{//Go live for user interaction until <ESC> or <SHIFT-ESC>.
|
||||
I64 ch;
|
||||
do ch=DocGetKey;
|
||||
while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
|
||||
return ch==CH_ESC;
|
||||
}
|
||||
|
||||
#help_index "DolDoc"
|
||||
U8 *EdOverStrikeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
|
||||
{
|
||||
CDoc *doc=doc_e->user_data;
|
||||
U8 *st=MAlloc(8,mem_task);
|
||||
if (doc->flags & DOCF_OVERSTRIKE)
|
||||
*st='O';
|
||||
else
|
||||
*st='Ä';
|
||||
st[1]=0;
|
||||
return st;
|
||||
}
|
||||
|
||||
U8 *EdFilterCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
|
||||
{
|
||||
CDoc *doc=doc_e->user_data;
|
||||
U8 *st=MAlloc(8,mem_task);
|
||||
if (doc->find_replace->filter_lines)
|
||||
*st='F';
|
||||
else
|
||||
*st='Ä';
|
||||
st[1]=0;
|
||||
return st;
|
||||
}
|
||||
|
||||
U8 *EdDollarCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
|
||||
{
|
||||
CDoc *doc=doc_e->user_data;
|
||||
U8 *st=MAlloc(8,mem_task);
|
||||
if (doc->flags & DOCF_IN_DOLLAR)
|
||||
*st='$$';
|
||||
else
|
||||
*st='Ä';
|
||||
st[1]=0;
|
||||
return st;
|
||||
}
|
||||
|
||||
U8 *EdMoreCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
|
||||
{
|
||||
CDoc *doc=doc_e->user_data;
|
||||
U8 *st=MAlloc(8,mem_task);
|
||||
if (doc->flags&DOCF_MORE)
|
||||
StrCpy(st,"MoreÄ");
|
||||
else
|
||||
StrCpy(st,"ÄÄÄÄÄ");
|
||||
return st;
|
||||
}
|
||||
|
||||
U8 *EdDollarTypeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
|
||||
{
|
||||
CDoc *doc=doc_e->user_data;
|
||||
U8 *src=DefineSub(doc->cur_entry->type_u8,"ST_DOC_CMDS"),
|
||||
*st=CAlloc(8,mem_task);
|
||||
if (doc->cur_entry==doc)
|
||||
src="EOF";
|
||||
else if (!src)
|
||||
src="ERR";
|
||||
StrPrint(st,"%-3ts",src);
|
||||
return st;
|
||||
}
|
||||
|
||||
public Bool DocEd(CDoc *doc,I64 dof_flags=0)
|
||||
{//Live for user interaction. End on <ESC> or <SHIFT-ESC>.
|
||||
CDoc *old_put_doc =DocPut,
|
||||
*old_display_doc=DocDisplay,
|
||||
*old_border_doc =DocBorder,*bdoc;
|
||||
CDocEntry *doc_e;
|
||||
I64 old_attr=Fs->text_attr,
|
||||
old_top =Fs->win_top, old_bottom=Fs->win_bottom,
|
||||
old_left=Fs->win_left,old_right =Fs->win_right,
|
||||
old_title_src=Fs->title_src;
|
||||
Bool res,unlock;
|
||||
U8 *old_task_title;
|
||||
if (dof_flags&DOF_WIN_MAX)
|
||||
WinMax;
|
||||
|
||||
unlock=DocLock(doc);
|
||||
doc->win_task=Fs;
|
||||
bdoc=DocNew;
|
||||
bdoc->flags|=DOCF_BORDER_DOC;
|
||||
DocPrint(bdoc,"$$CM+TY+LX+NC,0,-1$$");
|
||||
DocPrint(bdoc,"$$TX+RX+BD,\"[X]\"$$");
|
||||
DocPrint(bdoc,"$$BK,1$$$$TX+LX+BD,\"MENU\"$$$$BK,0$$");
|
||||
|
||||
old_task_title=StrNew(Fs->task_title);
|
||||
if (Fs->title_src!=TTS_LOCKED_CONST) {
|
||||
Fs->title_src=TTS_ED_FILENAME;
|
||||
MemCpy(Fs->task_title,doc->filename.name,STR_LEN-1);
|
||||
}
|
||||
doc_e=DocPrint(bdoc,"$$DA-TRM-P+BD+RD+CX+IV,LEN=STR_LEN-1,"
|
||||
"A=\"%%s...\",SCX=16$$");
|
||||
doc_e->data=&Fs->task_title;
|
||||
DocDataFmt(bdoc,doc_e);
|
||||
|
||||
if (doc->flags & DOCF_ALLOW_UNDO) {
|
||||
DocPrint(bdoc,"$$CM+BY+LX+NC,1,1$$");
|
||||
doc_e=DocPrint(bdoc,"$$DA+BD+RD-TRM,RT=U32,A=\"Undo:%%03d\"$$\n");
|
||||
doc_e->data=&doc->undo_cnt;
|
||||
DocDataFmt(bdoc,doc_e);
|
||||
}
|
||||
|
||||
DocPrint(bdoc,"$$CM+BY+RX+NC,-30,1$$");
|
||||
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
|
||||
doc_e->user_data=doc;
|
||||
doc_e->tag_cb=&EdMoreCB;
|
||||
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
|
||||
doc_e->user_data=doc;
|
||||
doc_e->tag_cb=&EdDollarTypeCB;
|
||||
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
|
||||
doc_e->user_data=doc;
|
||||
doc_e->tag_cb=&EdFilterCB;
|
||||
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
|
||||
doc_e->user_data=doc;
|
||||
doc_e->tag_cb=&EdOverStrikeCB;
|
||||
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
|
||||
doc_e->user_data=doc;
|
||||
doc_e->tag_cb=&EdDollarCB;
|
||||
doc_e=DocPrint(bdoc,"$$DA+BD+RD-TRM,A=\"Line:%%04d \"$$");
|
||||
doc_e->data=&doc->line;
|
||||
DocDataFmt(bdoc,doc_e);
|
||||
doc_e=DocPrint(bdoc,"$$DA+BD+RD-TRM,A=\"Col:%%04d\"$$\n");
|
||||
doc_e->data=&doc->col;
|
||||
DocDataFmt(bdoc,doc_e);
|
||||
|
||||
DocRecalc(bdoc);
|
||||
DocRecalc(doc);
|
||||
if (!(dof_flags&DOF_DONT_HOME))
|
||||
DocTop(doc);
|
||||
Fs->border_doc=bdoc;
|
||||
if (doc!=old_display_doc)
|
||||
doc->parent_doc=old_display_doc;
|
||||
Fs->put_doc=Fs->display_doc=doc;
|
||||
if (!(dof_flags&DOF_DONT_TEXT_ATTR))
|
||||
Fs->text_attr=DOC_ATTR_DFT_TEXT;
|
||||
if (!(dof_flags&DOF_DONT_SHOW)) {
|
||||
LBts(&Fs->display_flags,DISPLAYf_SHOW);
|
||||
WinZBufUpdate;
|
||||
}
|
||||
if (dof_flags&DOF_SIZE_MIN)
|
||||
doc->flags|=DOCF_SIZE_MIN;
|
||||
|
||||
DocUnlock(doc);
|
||||
if (!(dof_flags&DOF_DONT_WINMGR_SYNC)) {
|
||||
Refresh(2,TRUE);
|
||||
if (doc->flags&DOCF_SIZE_MIN)
|
||||
Refresh(2,TRUE);
|
||||
}
|
||||
res=View;
|
||||
|
||||
DocLock(doc);
|
||||
if (res) {
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX)
|
||||
DocDataScan(doc,doc_e);
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
Fs->border_doc =old_border_doc;
|
||||
Fs->display_doc=old_display_doc;
|
||||
Fs->put_doc =old_put_doc;
|
||||
Fs->text_attr =old_attr;
|
||||
if (Fs->title_src!=TTS_LOCKED_CONST) {
|
||||
Fs->title_src =old_title_src;
|
||||
StrCpy(Fs->task_title,old_task_title);
|
||||
}
|
||||
Free(old_task_title);
|
||||
DocDel(bdoc);
|
||||
if (dof_flags&DOF_SIZE_MIN) {
|
||||
WinHorz(old_left,old_right);
|
||||
WinVert(old_top,old_bottom);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
|
||||
public Bool Ed(U8 *link_st,I64 edf_dof_flags=0)
|
||||
{//Invoke document editor.
|
||||
U8 *filename,*needle_str;
|
||||
I64 i,num;
|
||||
Bool cont,res=FALSE;
|
||||
CDoc *doc;
|
||||
|
||||
switch (i=EdLinkCvt(link_st,&filename,&needle_str,&num,edf_dof_flags)) {
|
||||
case -1:
|
||||
break;
|
||||
case LK_DEF:
|
||||
doc=DocNew;
|
||||
doc->desc='DictDef';
|
||||
ACDDefsPut(doc,filename,num);
|
||||
goto ej_doc;
|
||||
case LK_HELP_INDEX:
|
||||
doc=DocNew;
|
||||
doc->desc='HelpIndx';
|
||||
DocHelpIdx(doc,filename);
|
||||
ej_doc:
|
||||
if (!(edf_dof_flags&EDF_BAIL)) {
|
||||
DocEd(doc);
|
||||
DocDel(doc);
|
||||
}
|
||||
if (!(edf_dof_flags&EDF_WAS_WRITE))
|
||||
res=TRUE;
|
||||
break;
|
||||
default:
|
||||
if (IsRaw)
|
||||
res=EdLite(filename,num,edf_dof_flags);
|
||||
else {
|
||||
cont=TRUE;
|
||||
if (!(edf_dof_flags&EDF_BAIL) && !(LK_DOC<=i<=LK_DOC_LINE) &&
|
||||
!FilesFindMatch(filename,FILEMASK_TXT) &&
|
||||
!PopUpCancelOk(ST_WARN_ST "Not Text File\n\n"))
|
||||
cont=FALSE;
|
||||
if (cont)
|
||||
res=DocFileEd(i,filename,needle_str,&num,edf_dof_flags);
|
||||
}
|
||||
}
|
||||
Free(filename);
|
||||
Free(needle_str);
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool Plain(U8 *filename,I64 edf_dof_flags=0)
|
||||
{//Edit document in plain text mode, so dollar signs are not special.
|
||||
Bool res;
|
||||
U8 *st=MStrPrint("PI:%s",filename);
|
||||
res=Ed(st,edf_dof_flags);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "DolDoc;Job/Exe;Task/Job/Exe"
|
||||
public I64 PopUpEd(U8 *filename,CTask *parent=NULL,CTask **_pu_task=NULL)
|
||||
{//Create PopUp win task and edit a doc.
|
||||
U8 *st=MStrPrint("Ed(\"%Q\");",filename);
|
||||
I64 res=PopUp(st,parent,_pu_task);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
#help_index "DolDoc"
|
||||
extern Bool DocEd(CDoc *doc,I64 dof_flags=0);
|
||||
extern I64 DocEntryRun(CDoc *doc,CDocEntry *doc_e,
|
||||
Bool exited,I64 *_has_action=NULL);
|
||||
extern U0 DocFormBwd(CDoc *doc,Bool giveup=FALSE);
|
||||
extern U0 DocLoad(CDoc *doc,U8 *src2,I64 size);
|
||||
extern U0 DocPrintAtomic(CDoc *doc=NULL,U8 *fmt,...);
|
||||
extern U0 DocPrintPartial(CDoc *doc=NULL,U8 *fmt,...);
|
||||
extern CDocEntry *DocPutS(CDoc *doc,U8 *st);
|
||||
extern U8 *DocSave(CDoc *doc,I64 *_size=NULL);
|
||||
extern I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e);
|
||||
extern U8 *PopUpPickLst(U8 *lst);
|
||||
extern I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e);
|
||||
@@ -0,0 +1,333 @@
|
||||
#help_index "DolDoc/File"
|
||||
|
||||
public U0 DocLoad(CDoc *doc,U8 *src2,I64 size)
|
||||
{//Fetch doc from raw mem buf.
|
||||
I64 i;
|
||||
U8 *src;
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocBin *tmpb;
|
||||
doc->find_replace->filter_lines=0;
|
||||
if (src2) {
|
||||
DocPutS(doc,src2); //Too big $LK,"DocPrint",A="MN:DocPrint"$() is wasteful.
|
||||
src=src2+StrLen(src2)+1;
|
||||
i=size-(offset(CDocBin.end)-offset(CDocBin.start));
|
||||
while (src<=src2+i) {
|
||||
tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
|
||||
MemCpy(&tmpb->start,src,offset(CDocBin.end)-offset(CDocBin.start));
|
||||
src+=offset(CDocBin.end)-offset(CDocBin.start);
|
||||
tmpb->data=MAlloc(tmpb->size,doc->mem_task);
|
||||
if (tmpb->size) {
|
||||
MemCpy(tmpb->data,src,tmpb->size);
|
||||
src+=tmpb->size;
|
||||
}
|
||||
QueIns(tmpb,doc->bin_head.last);
|
||||
if (tmpb->num>=doc->cur_bin_num)
|
||||
doc->cur_bin_num=tmpb->num+1;
|
||||
}
|
||||
}
|
||||
if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))
|
||||
DocBinsValidate(doc);
|
||||
DocTop(doc); //Calls $LK,"DocRecalc",A="MN:DocRecalc"$(). DOCT_CURSOR will be set.
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public CDoc *DocRead(U8 *name=NULL,I64 flags=0)
|
||||
{//Fetch doc from disk. See $LK,"flags",A="MN:DOCF_PLAIN_TEXT"$.
|
||||
CDoc *doc=DocNew;
|
||||
U8 *src,*name2;
|
||||
I64 size=0;
|
||||
CDirContext *dirc;
|
||||
if (!name) name=blkdev.tmp_filename;
|
||||
doc->flags|=flags;
|
||||
name2=FileNameAbs(name);
|
||||
StrCpy(doc->filename.name,name2);
|
||||
if (src=FileRead(name2,&size,&doc->file_attr)) {
|
||||
if (dirc=DirContextNew(name2)) {
|
||||
DocLoad(doc,src,size);
|
||||
DirContextDel(dirc);
|
||||
}
|
||||
Free(src);
|
||||
}
|
||||
Free(name2);
|
||||
return doc;
|
||||
}
|
||||
|
||||
public U8 *DocSave(CDoc *doc,I64 *_size=NULL)
|
||||
{//Store doc to raw mem buf.
|
||||
CDocEntry *doc_e,*doc_e1;
|
||||
CDocBin *b;
|
||||
Bool unlock=DocLock(doc);
|
||||
I64 ch,cnt=1;//terminator
|
||||
U8 *st,*res,*dst,*src;
|
||||
|
||||
if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)))
|
||||
DocBinsValidate(doc);
|
||||
if (doc->flags&DOCF_NO_CURSOR)
|
||||
DocRecalc(doc);
|
||||
else {
|
||||
DocRecalc(doc,RECALCF_ADD_CURSOR);
|
||||
if (doc->head.next->type_u8==DOCT_CURSOR)
|
||||
DocEntryDel(doc,doc->head.next); //If no cursor, $LK,"DocLoad",A="MN:DocLoad"$() puts at top.
|
||||
}
|
||||
for (doc_e=doc->head.next;doc_e!=doc;doc_e=doc_e->next) {
|
||||
if (!Bt(doldoc.type_flags_data,doc_e->type_u8)) {
|
||||
switch (doc_e->type_u8) {
|
||||
case DOCT_TAB:
|
||||
case DOCT_PAGE_BREAK:
|
||||
case DOCT_CURSOR:
|
||||
cnt++;
|
||||
break;
|
||||
case DOCT_NEW_LINE:
|
||||
if (doc->flags&DOCF_CARRIAGE_RETURN)
|
||||
cnt+=2;
|
||||
else
|
||||
cnt++;
|
||||
break;
|
||||
case DOCT_SOFT_NEW_LINE:
|
||||
break;
|
||||
case DOCT_TEXT:
|
||||
if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|
|
||||
DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP))&&
|
||||
!(doc_e->type&DOCG_BL_IV_UL)) {
|
||||
cnt+=StrLen(doc_e->tag);
|
||||
if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS)) ||
|
||||
doc->flags&DOCF_DBL_DOLLARS)
|
||||
cnt+=StrOcc(doc_e->tag,'$$');
|
||||
break;
|
||||
}
|
||||
default:
|
||||
st=Doc2PlainText(doc,doc_e);
|
||||
cnt+=StrLen(st)+2;
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
}
|
||||
for (b=doc->bin_head.next;b!=&doc->bin_head;b=b->next)
|
||||
if (b->use_cnt>b->tmp_use_cnt)
|
||||
cnt+=offset(CDocBin.end)-offset(CDocBin.start)+b->size;
|
||||
res=MAlloc(cnt);
|
||||
dst=res;
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
doc_e1=doc_e->next;
|
||||
if (!Bt(doldoc.type_flags_data,doc_e->type_u8))
|
||||
switch (doc_e->type_u8) {
|
||||
case DOCT_CURSOR:
|
||||
DocEntryDel(doc,doc_e);
|
||||
*dst++=CH_CURSOR;
|
||||
break;
|
||||
case DOCT_TAB:
|
||||
*dst++='\t';
|
||||
break;
|
||||
case DOCT_NEW_LINE:
|
||||
if (doc->flags&DOCF_CARRIAGE_RETURN)
|
||||
*dst++='\r';
|
||||
*dst++='\n';
|
||||
break;
|
||||
case DOCT_SOFT_NEW_LINE:
|
||||
break;
|
||||
case DOCT_TEXT:
|
||||
if (!(doc_e->de_flags & ~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|
|
||||
DOCEF_HIGHLIGHT|DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&
|
||||
!(doc_e->type&DOCG_BL_IV_UL)) {
|
||||
src=doc_e->tag;
|
||||
while (ch=*src++) {
|
||||
*dst++=ch;
|
||||
if (ch=='$$' && (!(doc->flags & (DOCF_PLAIN_TEXT|
|
||||
DOCF_PLAIN_TEXT_TABS)) || doc->flags&DOCF_DBL_DOLLARS))
|
||||
*dst++=ch;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
*dst++='$$';
|
||||
st=Doc2PlainText(doc,doc_e);
|
||||
StrCpy(dst,st);
|
||||
dst+=StrLen(st);
|
||||
*dst++='$$';
|
||||
Free(st);
|
||||
}
|
||||
doc_e=doc_e1;
|
||||
}
|
||||
*dst++=0;
|
||||
b=doc->bin_head.next;
|
||||
if (b!=&doc->bin_head) {
|
||||
do {
|
||||
if (b->use_cnt>b->tmp_use_cnt) {
|
||||
MemCpy(dst,&b->start,offset(CDocBin.end)-offset(CDocBin.start));
|
||||
dst+=offset(CDocBin.end)-offset(CDocBin.start);
|
||||
MemCpy(dst,b->data,b->size);
|
||||
dst+=b->size;
|
||||
}
|
||||
b=b->next;
|
||||
} while (b!=&doc->bin_head);
|
||||
} else
|
||||
cnt--; //No terminator
|
||||
if (_size) *_size=cnt;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool DocWrite(CDoc *doc,Bool prompt=FALSE)
|
||||
{//Store doc to disk.
|
||||
I64 size;
|
||||
U8 *buf;
|
||||
if (prompt && !DocForm(&doc->filename) ||
|
||||
doc->filename.name[0]=='A' && doc->filename.name[2]==':')
|
||||
return FALSE; //CANCEL || LK_DOC,LK_DOC_ANCHOR,LK_DOC_FIND,LK_DOC_LINE?
|
||||
buf=DocSave(doc,&size);
|
||||
FileWrite(doc->filename.name,buf,size,0,doc->file_attr);
|
||||
Free(buf);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#help_index "DolDoc"
|
||||
public U0 DocInsDoc(CDoc *doc=NULL,CDoc *doc2)
|
||||
{//Insert copy of doc2 into doc at insert pt, cur_entry.
|
||||
//TODO: $LK,"DocRst",A="MN:DocRst"$
|
||||
U8 *dst;
|
||||
Bool unlock_doc,unlock_doc2=DocLock(doc2);
|
||||
CDocEntry *doc_ne,*doc_e=doc2->head.next,*doc_ce;
|
||||
if (!doc) doc=DocPut;
|
||||
unlock_doc=DocLock(doc),
|
||||
DocRemSoftNewLines(doc,NULL);
|
||||
doc_ce=doc->cur_entry;
|
||||
if (doc_ce->type_u8==DOCT_TEXT && doc->cur_col>doc_ce->min_col) {
|
||||
if (doc->cur_col<doc_ce->max_col) {
|
||||
dst=doc_ce->tag+doc->cur_col;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ne->type=DOCT_TEXT | doc_ce->type & 0xFFFFFF00;
|
||||
doc_ce->max_col=doc->cur_col;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc->cur_entry=doc_ne;
|
||||
doc->cur_col=doc_ne->min_col;
|
||||
} else
|
||||
if (doc_ce!=doc)
|
||||
doc->cur_entry=doc_ce->next;
|
||||
}
|
||||
while (doc_e!=doc2) {
|
||||
if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE) {
|
||||
doc_ne=DocEntryCopy(doc,doc_e);
|
||||
QueIns(doc_ne,doc->cur_entry->last);
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
DocRecalc(doc);
|
||||
if (unlock_doc2)
|
||||
DocUnlock(doc2);
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Compiler;Compiler/Directive"
|
||||
public U0 StreamDoc(CDoc *doc)
|
||||
{//Inject doc into compile stream. Use inside #exe{}.
|
||||
//TODO: $LK,"DocRst",A="MN:DocRst"$
|
||||
Bool unlock_doc=DocLock(doc);
|
||||
CDocEntry *doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->type_u8==DOCT_TEXT)
|
||||
StreamPrint("%s",doc_e->tag);
|
||||
else if (doc_e->type_u8==DOCT_NEW_LINE)
|
||||
StreamPrint("\n");
|
||||
else if (doc_e->type_u8==DOCT_TAB)
|
||||
StreamPrint("\t");
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
#help_index "DolDoc"
|
||||
Bool DocCaptureUndo(CDoc *doc,Bool force=FALSE)
|
||||
{
|
||||
Bool res=FALSE,unlock;
|
||||
I64 time_stamp,flags;
|
||||
CDocUndo *u;
|
||||
if (doc->flags&DOCF_ALLOW_UNDO) {
|
||||
unlock=DocLock(doc);
|
||||
time_stamp=GetTSC;
|
||||
if (doc->flags&DOCF_UNDO_DIRTY &&
|
||||
time_stamp>doc->undo_head.last->time_stamp+cnts.time_stamp_freq<<4 ||
|
||||
force) {
|
||||
u=CAlloc(sizeof(CDocUndo),doc->mem_task);
|
||||
u->time_stamp=time_stamp;
|
||||
flags=doc->flags;
|
||||
doc->flags&=~DOCF_NO_CURSOR;
|
||||
u->body=DocSave(doc,&u->size);
|
||||
doc->flags=flags;
|
||||
QueIns(u,doc->undo_head.last);
|
||||
doc->flags&=~DOCF_UNDO_DIRTY;
|
||||
doc->undo_cnt++;
|
||||
u->doc_flags=doc->flags;
|
||||
res=TRUE;
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 DocUndoRestore(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocUndo *u=doc->undo_head.last,*u_next,*u_last;
|
||||
if (u!=&doc->undo_head) {
|
||||
QueRem(u);
|
||||
u_next=doc->undo_head.next;
|
||||
u_last=doc->undo_head.last;
|
||||
QueInit(&doc->undo_head);
|
||||
DocRst(doc,TRUE);
|
||||
doc->flags=u->doc_flags&~DOCF_NO_CURSOR;
|
||||
DocLoad(doc,u->body,u->size);
|
||||
doc->flags=u->doc_flags;
|
||||
DocUndoDel(doc,u);
|
||||
doc->undo_head.next=u_next;
|
||||
doc->undo_head.last=u_last;
|
||||
}
|
||||
DocUndoCntSet(doc);
|
||||
doc->flags&=~DOCF_UNDO_DIRTY;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
#help_index "Graphics/Windows BMP Files;Graphics/GR Files;"\
|
||||
"DolDoc/Output;StdOut/DolDoc"
|
||||
public Bool DocType(CDoc *doc=NULL,U8 *filename,I64 trailing_new_lines=1)
|
||||
{//Output txt or graphic file to document.
|
||||
Bool res=FALSE;
|
||||
CDoc *doc2;
|
||||
if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
|
||||
return FALSE;
|
||||
if (FilesFindMatch(filename,FILEMASK_TXT)) {
|
||||
doc2=DocRead(filename);
|
||||
DocInsDoc(doc,doc2);
|
||||
if (IsRaw)
|
||||
DocDump(doc2,100000);
|
||||
DocDel(doc2);
|
||||
res=TRUE;
|
||||
} else if (FilesFindMatch(filename,"*.BMP.Z")) {
|
||||
DocBMP(doc,filename,,FALSE);
|
||||
res=TRUE;
|
||||
} else if (FilesFindMatch(filename,"*.BMP;*.bmp")) {
|
||||
DocBMP(doc,filename,,TRUE);
|
||||
res=TRUE;
|
||||
} else if (FilesFindMatch(filename,"*.GR*")) {
|
||||
DocGR(doc,filename);
|
||||
res=TRUE;
|
||||
}
|
||||
if (res)
|
||||
DocPrint(doc,"%h*c",trailing_new_lines,'\n');
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "Graphics/Windows BMP Files;Graphics/GR Files;"\
|
||||
"File/Cmd Line (Typically);DolDoc/Cmd Line (Typically);"\
|
||||
"StdOut;Cmd Line (Typically)"
|
||||
public Bool Type(U8 *filename,I64 trailing_new_lines=1)
|
||||
{//Output txt or graphic file to command line.
|
||||
return DocType(,filename,trailing_new_lines);
|
||||
}
|
||||
@@ -0,0 +1,584 @@
|
||||
#help_index "DolDoc/Editor"
|
||||
|
||||
public Bool DocLineNumGoTo(CDoc *doc,I64 line_num) //one based
|
||||
{//Nearest to specified line num. Move cur_entry & center.
|
||||
Bool res=FALSE,unlock;
|
||||
if (doc) {
|
||||
unlock=DocLock(doc);
|
||||
doc->x=0;
|
||||
doc->y=line_num-1;
|
||||
DocRecalc(doc,RECALCt_FIND_CURSOR);
|
||||
DocCenter(doc);
|
||||
if (doc->cur_entry->y==line_num-1)
|
||||
res=TRUE;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool DocFind(CDoc *haystack_doc,I64 start_line_num=I64_MIN,
|
||||
U8 *needle,I64 match=1)
|
||||
{//Find str by searching tags. Move cur_entry & center.
|
||||
Bool res=FALSE,unlock;
|
||||
CDocEntry *doc_e;
|
||||
U8 *ptr;
|
||||
I64 i;
|
||||
if (haystack_doc) {
|
||||
unlock=DocLock(haystack_doc);
|
||||
if (start_line_num==I64_MIN) {
|
||||
res=TRUE;
|
||||
doc_e=haystack_doc->head.next;
|
||||
} else {
|
||||
res=DocLineNumGoTo(haystack_doc,start_line_num);
|
||||
doc_e=haystack_doc->cur_entry;
|
||||
}
|
||||
if (res) {
|
||||
if (needle) {
|
||||
res=FALSE;
|
||||
while (doc_e!=haystack_doc) {
|
||||
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
|
||||
//TODO: handle multi-DocEntry strs
|
||||
(ptr=StrIMatch(needle,doc_e->tag))) {
|
||||
i=ptr-doc_e->tag;
|
||||
if (!--match) {
|
||||
haystack_doc->cur_entry=doc_e;
|
||||
if (i<doc_e->min_col) i=doc_e->min_col;
|
||||
if (i>doc_e->max_col) i=doc_e->max_col;
|
||||
haystack_doc->cur_col=i;
|
||||
res=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
} else
|
||||
res=FALSE;
|
||||
}
|
||||
if (!res) DocBottom(haystack_doc);
|
||||
DocCenter(haystack_doc);
|
||||
if (unlock)
|
||||
DocUnlock(haystack_doc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool DocAnchorFind(CDoc *haystack_doc,U8 *needle_str)
|
||||
{//Find named anchor. Move cur_entry & center.
|
||||
Bool res=FALSE,unlock;
|
||||
CDocEntry *doc_e;
|
||||
if (haystack_doc) {
|
||||
unlock=DocLock(haystack_doc);
|
||||
doc_e=haystack_doc->head.next;
|
||||
if (needle_str)
|
||||
while (doc_e!=haystack_doc) {
|
||||
if (doc_e->type_u8==DOCT_ANCHOR && doc_e->de_flags & DOCEF_AUX_STR) {
|
||||
if (!StrCmp(needle_str,doc_e->aux_str)) {
|
||||
haystack_doc->cur_entry=doc_e;
|
||||
haystack_doc->cur_col=doc_e->min_col;
|
||||
res=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
if (!res) DocBottom(haystack_doc);
|
||||
DocCenter(haystack_doc);
|
||||
if (unlock)
|
||||
DocUnlock(haystack_doc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 EdFindNext(CDoc *doc)
|
||||
{//Editor F3 find next, possibly doing replaces.
|
||||
Bool unlock=DocLock(doc);
|
||||
U8 *ptr,*ptr2,*ptr3;
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce;
|
||||
I64 sf_flags;
|
||||
if (doc->find_replace->match_case)
|
||||
sf_flags=0;
|
||||
else
|
||||
sf_flags=SFF_IGNORE_CASE;
|
||||
if (doc->find_replace->whole_labels)
|
||||
sf_flags|=SFG_WHOLE_LABELS;
|
||||
do {
|
||||
if (doc_e!=doc) {
|
||||
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
|
||||
!(doc_e->de_flags&(DOCEG_DONT_EDIT|DOCEF_FILTER_SKIP))) {
|
||||
if (doc_e->type & DOCET_SEL ||
|
||||
!doc->find_replace->scan_sel_text) {
|
||||
if (doc->find_replace->scan_fwd) {
|
||||
if (doc_e==doc_ce) {
|
||||
ptr=doc_ce->tag+doc->cur_col+1;
|
||||
if (ptr-doc_ce->tag>=doc_ce->max_col)
|
||||
goto fn_skip;
|
||||
if (ptr-doc_ce->tag<doc_ce->min_col)
|
||||
ptr=doc_ce->tag+doc_ce->min_col;
|
||||
} else
|
||||
ptr=doc_e->tag;
|
||||
if (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) {
|
||||
doc->cur_entry=doc_e;
|
||||
doc->cur_col=ptr-doc_e->tag;
|
||||
if (doc->cur_col>=doc_e->max_col)
|
||||
doc->cur_col=doc_e->max_col-1;
|
||||
if (doc->cur_col<doc_e->min_col)
|
||||
doc->cur_col=doc_e->min_col;
|
||||
DocCenter(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
ptr2=NULL;
|
||||
ptr=doc_e->tag+doc_e->min_col;
|
||||
if (doc_e==doc_ce)
|
||||
ptr3=doc_ce->tag+doc->cur_col;
|
||||
else
|
||||
ptr3=doc_e->tag+doc_e->max_col;
|
||||
while (ptr=StrFind(doc->find_replace->find_text,ptr,sf_flags)) {
|
||||
if (ptr>=ptr3)
|
||||
break;
|
||||
ptr2=ptr++;
|
||||
}
|
||||
if (ptr2 && ptr2<ptr3) {
|
||||
doc->cur_entry=doc_e;
|
||||
doc->cur_col=ptr2-doc_e->tag;
|
||||
if (doc->cur_col>=doc_e->max_col)
|
||||
doc->cur_col=doc_e->max_col-1;
|
||||
if (doc->cur_col<doc_e->min_col)
|
||||
doc->cur_col=doc_e->min_col;
|
||||
DocCenter(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
fn_skip:
|
||||
if (doc->find_replace->scan_fwd)
|
||||
doc_e=doc_e->next;
|
||||
else
|
||||
doc_e=doc_e->last;
|
||||
} while (doc_e!=doc_ce);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 EdSelAll(CDoc *doc,Bool sel)
|
||||
{//Set state of $LK,"DOCET_SEL",A="MN:DOCET_SEL"$ on all entries.
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocEntry *doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
BEqu(&doc_e->type,DOCEt_SEL,sel);
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public Bool EdFindPaired(CDoc *doc,U8 plus,U8 minus,
|
||||
Bool fwd,Bool abort_on_dbl_colon=FALSE)
|
||||
{//Find { } or ( ) pair. Move cur_entry & center.
|
||||
Bool unlock=DocLock(doc),res=FALSE;
|
||||
U8 *ptr;
|
||||
I64 ch,levels=0,colons=0,original_col=doc->cur_col;
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_e=doc_ce,*original_ce=doc_ce;
|
||||
if (abort_on_dbl_colon && EdCurU8(doc)==':')
|
||||
colons=1;
|
||||
else
|
||||
colons=0;
|
||||
do {
|
||||
if (doc_e!=doc) {
|
||||
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag &&
|
||||
!(doc_e->de_flags&DOCEF_FILTER_SKIP)) {
|
||||
if (fwd) {
|
||||
if (doc_e==doc_ce)
|
||||
ptr=doc_e->tag+doc->cur_col+1;
|
||||
else
|
||||
ptr=doc_e->tag;
|
||||
if (ptr-doc_e->tag<doc_e->min_col)
|
||||
ptr=doc_e->tag+doc_e->min_col;
|
||||
if (ptr-doc_e->tag>=doc_e->max_col)
|
||||
goto pa_skip;
|
||||
while (ch=*ptr++)
|
||||
if (abort_on_dbl_colon && ch==':') {
|
||||
if (++colons==2) {
|
||||
doc->cur_entry=doc_e;
|
||||
doc->cur_col=ptr-doc_e->tag-1;
|
||||
EdCursorLeft(doc);
|
||||
res=FALSE;
|
||||
goto pa_done;
|
||||
}
|
||||
} else {
|
||||
colons=0;
|
||||
if (ch==plus)
|
||||
levels++;
|
||||
else if (ch==minus) {
|
||||
if (!levels--) {
|
||||
doc->cur_entry=doc_e;
|
||||
doc->cur_col=ptr-doc_e->tag-1;
|
||||
res=doc->cur_entry!=original_ce ||
|
||||
doc->cur_col!=original_col;
|
||||
goto pa_done;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (doc_e==doc_ce) {
|
||||
ptr=doc_e->tag+doc->cur_col-1;
|
||||
if (ptr-doc_e->tag>=doc_e->max_col)
|
||||
ptr=doc_e->tag+doc_e->max_col-1;
|
||||
} else
|
||||
ptr=doc_e->tag+doc_e->max_col-1;
|
||||
if (ptr-doc_e->tag<doc_e->min_col)
|
||||
goto pa_skip;
|
||||
while (ptr>=doc_e->tag+doc_e->min_col) {
|
||||
ch=*ptr--;
|
||||
if (abort_on_dbl_colon && ch==':') {
|
||||
if (++colons==2) {
|
||||
doc->cur_entry=doc_e;
|
||||
doc->cur_col=ptr-doc_e->tag+1;
|
||||
res=FALSE;
|
||||
goto pa_done;
|
||||
}
|
||||
} else {
|
||||
colons=0;
|
||||
if (ch==plus)
|
||||
levels++;
|
||||
else if (ch==minus) {
|
||||
if (!levels--) {
|
||||
doc->cur_entry=doc_e;
|
||||
doc->cur_col=ptr-doc_e->tag+1;
|
||||
res=doc->cur_entry!=original_ce ||
|
||||
doc->cur_col!=original_col;
|
||||
goto pa_done;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
pa_skip:
|
||||
if (fwd)
|
||||
doc_e=doc_e->next;
|
||||
else
|
||||
doc_e=doc_e->last;
|
||||
} while (doc_e!=doc_ce);
|
||||
pa_done:
|
||||
DocRecalc(doc);
|
||||
DocCenter(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool EdGoToFun(CDoc *doc,Bool fwd,Bool abort_on_dbl_colon)
|
||||
{//Move cur_entry to start of cur fun and center.(Shoddy)
|
||||
Bool unlock=DocLock(doc),res=FALSE;
|
||||
I64 ch,levels,colons;
|
||||
if (fwd) {
|
||||
levels=0;
|
||||
colons=0;
|
||||
while (doc->cur_entry!=doc) {
|
||||
ch=EdCurU8(doc);
|
||||
if (abort_on_dbl_colon && ch==':') {
|
||||
if (++colons==2) {
|
||||
EdCursorLeft(doc);
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
colons=0;
|
||||
if (ch=='{')
|
||||
levels++;
|
||||
else if (ch=='}' && !levels--)
|
||||
break;
|
||||
}
|
||||
EdCursorRight(doc);
|
||||
}
|
||||
DocRecalc(doc);
|
||||
if (doc->cur_entry!=doc)
|
||||
res=TRUE;
|
||||
} else {
|
||||
while (EdFindPaired(doc,'}','{',FALSE,abort_on_dbl_colon));
|
||||
if (doc->cur_entry!=doc) {
|
||||
ch=EdCurU8(doc);
|
||||
if (abort_on_dbl_colon && ch==':')
|
||||
res=TRUE;
|
||||
else {
|
||||
if (ch=='{')
|
||||
res=TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 EdSelFun(CDoc *doc,Bool abort_on_dbl_colon=FALSE)
|
||||
{//Set $LK,"DOCET_SEL",A="MN:DOCET_SEL"$ on all entries in cur fun.
|
||||
Bool unlock=DocLock(doc);
|
||||
U8 *ptr;
|
||||
I64 ch,levels=0,colons=0;
|
||||
CDocEntry *doc_e;
|
||||
EdSelAll(doc,FALSE);
|
||||
EdGoToFun(doc,FALSE,abort_on_dbl_colon);
|
||||
if (EdCurU8(doc)=='{')
|
||||
levels--;
|
||||
else if (abort_on_dbl_colon && EdCurU8(doc)==':') {
|
||||
EdCursorRight(doc);
|
||||
if (EdCurU8(doc)==':')
|
||||
EdCursorRight(doc);
|
||||
}
|
||||
doc_e=doc->cur_entry;
|
||||
while (doc_e!=doc) {
|
||||
doc_e->type|=DOCET_SEL;
|
||||
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
|
||||
ptr=doc_e->tag;
|
||||
if (doc_e==doc->cur_entry)
|
||||
ptr+=doc->cur_col;
|
||||
while (ch=*ptr++)
|
||||
if (abort_on_dbl_colon && ch==':') {
|
||||
if (++colons==2)
|
||||
goto sf_done;
|
||||
} else {
|
||||
colons=0;
|
||||
if (ch=='{')
|
||||
levels++;
|
||||
else if (ch=='}' && !levels--)
|
||||
goto sf_done;
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
sf_done:
|
||||
DocRecalc(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
#define RSAC_REPLACE 0
|
||||
#define RSAC_SKIP 1
|
||||
#define RSAC_ALL 2
|
||||
|
||||
I64 PopUpReplaceSkipAllCancel(U8 *header=NULL,U8 *footer=NULL)
|
||||
{
|
||||
I64 i;
|
||||
CDoc *doc=DocNew;
|
||||
if (header) DocPrint(doc,"%s",header);
|
||||
DocPrint(doc,"$$CM+LX,1,4$$$$BT,\"REPLACE\",LE=RSAC_REPLACE$$"
|
||||
"$$CM+LX,17,0$$$$BT,\"SKIP\",LE=RSAC_SKIP$$"
|
||||
"$$CM+LX,1,3$$$$BT,\"ALL\",LE=RSAC_ALL$$"
|
||||
"$$CM+LX,17,0$$$$BT,\"CANCEL\",LE=DOCM_CANCEL$$\n");
|
||||
if (footer) DocPrint(doc,"%s",footer);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
I64 EdFindReplace(CDoc *doc)
|
||||
{
|
||||
Bool found,unlock;
|
||||
I64 cmd,i,j,plen,rlen,dlen,res=-1,sf_flags;
|
||||
U8 *src,*dst,*dst2;
|
||||
CDocEntry *doc_ce,*doc_e,*doc_marker=NULL;
|
||||
if (doc->find_replace->pmt)
|
||||
cmd=RSAC_REPLACE;
|
||||
else
|
||||
cmd=RSAC_ALL;
|
||||
if (!doc->find_replace->pmt || DocForm(doc->find_replace)) {
|
||||
res=0;
|
||||
unlock=DocLock(doc);
|
||||
if (doc->find_replace->match_case || doc->find_replace->local_var)
|
||||
sf_flags=0;
|
||||
else
|
||||
sf_flags=SFF_IGNORE_CASE;
|
||||
if (doc->find_replace->whole_labels || doc->find_replace->local_var)
|
||||
sf_flags|=SFG_WHOLE_LABELS;
|
||||
|
||||
if (i=doc->find_replace->filter_lines) {
|
||||
doc_ce=doc->head.next;
|
||||
while (doc_ce!=doc) {
|
||||
if (doc_ce->de_flags&DOCEF_TAG && doc_ce->tag &&
|
||||
!(doc_ce->de_flags&DOCEF_FILTER_SKIP) &&
|
||||
StrFind(doc->find_replace->find_text,doc_ce->tag,sf_flags)) {
|
||||
doc_ce->type|=DOCET_SEL;
|
||||
res++;
|
||||
} else
|
||||
doc_ce->type&=~DOCET_SEL;
|
||||
doc_ce=doc_ce->next;
|
||||
}
|
||||
|
||||
doc_ce=doc->head.next;
|
||||
while (doc_ce!=doc) {
|
||||
if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP)) {
|
||||
found=FALSE;
|
||||
|
||||
doc_e=doc_ce;
|
||||
while (doc_e!=doc && doc_e->y>doc_ce->y-i) {
|
||||
if (doc_e->type&DOCET_SEL) {
|
||||
found=TRUE;
|
||||
break;
|
||||
} else
|
||||
doc_e=doc_e->last;
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
doc_e=doc_ce;
|
||||
while (doc_e!=doc && doc_e->y<doc_ce->y+i) {
|
||||
if (doc_e->type&DOCET_SEL) {
|
||||
found=TRUE;
|
||||
break;
|
||||
} else
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
}
|
||||
|
||||
if (!found)
|
||||
doc_ce->de_flags|=DOCEF_FILTER_SKIP;
|
||||
}
|
||||
|
||||
doc_ce=doc_ce->next;
|
||||
}
|
||||
EdSelAll(doc,FALSE);
|
||||
goto fr_unlock_done;
|
||||
}
|
||||
|
||||
if (doc->find_replace->local_var)
|
||||
EdSelFun(doc);
|
||||
|
||||
if (!doc->find_replace->replace && !doc->find_replace->local_var) {
|
||||
EdFindNext(doc);
|
||||
goto fr_unlock_done;
|
||||
}
|
||||
plen=StrLen(doc->find_replace->find_text);
|
||||
if (!plen)
|
||||
goto fr_unlock_done;
|
||||
rlen=StrLen(doc->find_replace->replace_text);
|
||||
if (doc->head.next!=doc) {
|
||||
doc_e=doc_marker=DocSplitTag(doc,doc->cur_entry,doc->cur_col,
|
||||
doc->cur_entry->x+doc->cur_col,doc->cur_entry->y,DOCT_MARKER);
|
||||
do {
|
||||
if (doc_e==doc) {
|
||||
if (doc->find_replace->scan_fwd)
|
||||
doc_e=doc_e->next;
|
||||
else
|
||||
doc_e=doc_e->last;
|
||||
if (doc_e==doc_marker)
|
||||
break;
|
||||
}
|
||||
if (doc_e->type_u8==DOCT_TEXT &&
|
||||
!(doc_e->de_flags&(DOCEG_DONT_EDIT|DOCEF_FILTER_SKIP)) &&
|
||||
(doc_e->type & DOCET_SEL ||
|
||||
!doc->find_replace->scan_sel_text&&
|
||||
!doc->find_replace->local_var)) {
|
||||
src=doc_e->tag;
|
||||
while (src) {
|
||||
src=StrFind(doc->find_replace->find_text,src,sf_flags);
|
||||
if (src) {
|
||||
doc->cur_col=src-doc_e->tag;
|
||||
doc->cur_entry=doc_e;
|
||||
if (cmd!=RSAC_ALL)
|
||||
DocCenter(doc);
|
||||
if (cmd!=RSAC_ALL) {
|
||||
DocUnlock(doc);
|
||||
cmd=PopUpReplaceSkipAllCancel("");
|
||||
DocLock(doc);
|
||||
if (cmd<0)
|
||||
goto fr_unlock_done;
|
||||
}
|
||||
doc_e=doc->cur_entry;
|
||||
src=doc->cur_col+doc_e->tag;
|
||||
if (cmd==RSAC_REPLACE || cmd==RSAC_ALL) {
|
||||
dlen=StrLen(doc_e->tag);
|
||||
doc_e->max_col=dlen+rlen-plen;
|
||||
dst=MAlloc(doc_e->max_col+1,doc->mem_task);
|
||||
dst2=dst;
|
||||
j=src-doc_e->tag;
|
||||
for (i=0;i<j;i++)
|
||||
*dst++=doc_e->tag[i];
|
||||
for (i=0;i<rlen;i++)
|
||||
*dst++=doc->find_replace->replace_text[i];
|
||||
src=dst;
|
||||
for (i=j+plen;i<=dlen;i++)
|
||||
*dst++=doc_e->tag[i];
|
||||
Free(doc_e->tag);
|
||||
doc_e->tag=dst2;
|
||||
doc->cur_col=src-doc_e->tag;
|
||||
doc->cur_entry=doc_e;
|
||||
if (cmd!=RSAC_ALL) {
|
||||
DocRemSoftNewLines(doc,doc->cur_entry);
|
||||
DocRecalc(doc);
|
||||
}
|
||||
doc_e=doc->cur_entry;
|
||||
src=doc->cur_col+doc_e->tag;
|
||||
res++;
|
||||
} else
|
||||
src++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (doc->find_replace->scan_fwd)
|
||||
doc_e=doc_e->next;
|
||||
else
|
||||
doc_e=doc_e->last;
|
||||
} while (doc_e!=doc_marker);
|
||||
}
|
||||
fr_unlock_done:
|
||||
if (doc_marker)
|
||||
DocEntryDel(doc,doc_marker);
|
||||
DocRemSoftNewLines(doc,NULL);
|
||||
DocRecalc(doc);
|
||||
DocCenter(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 EdReplace(CDoc *doc,U8 *find,U8 *replace,
|
||||
Bool sel=TRUE,Bool match_case=TRUE,Bool whole_labels=FALSE)
|
||||
{//Find & replace using editor's cmd.
|
||||
CEdFindText old_find_replace;
|
||||
Bool unlock;
|
||||
I64 i,res=-1;
|
||||
if (!doc) return -1;
|
||||
unlock=DocLock(doc);
|
||||
MemCpy(&old_find_replace,doc->find_replace,sizeof(CEdFindText));
|
||||
MemSet(doc->find_replace,0,sizeof(CEdFindText));
|
||||
i=StrLen(find);
|
||||
if (i<sizeof(CEdFindText.find_text)) {
|
||||
MemCpy(doc->find_replace->find_text,find,i+1);
|
||||
i=StrLen(replace);
|
||||
if (i<sizeof(CEdFindText.replace_text)) {
|
||||
MemCpy(doc->find_replace->replace_text,replace,i+1);
|
||||
doc->find_replace->replace=TRUE;
|
||||
doc->find_replace->scan_sel_text=sel;
|
||||
doc->find_replace->match_case=match_case;
|
||||
doc->find_replace->whole_labels=whole_labels;
|
||||
doc->find_replace->pmt=FALSE;
|
||||
res=EdFindReplace(doc);
|
||||
}
|
||||
}
|
||||
MemCpy(doc->find_replace,&old_find_replace,sizeof(CEdFindText));
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
class CEdLineGoTo
|
||||
{
|
||||
I64 line fmtstr "$$DA,A=\"Go to Line:%d\"$$";
|
||||
};
|
||||
|
||||
U0 EdGoToLine(CDoc *doc)
|
||||
{//Prompt with form and go to line num.
|
||||
CEdLineGoTo gtl;
|
||||
gtl.line=1;
|
||||
if (DocForm(>l))
|
||||
DocLineNumGoTo(doc,gtl.line);
|
||||
}
|
||||
@@ -0,0 +1,344 @@
|
||||
#help_index "DolDoc/Form"
|
||||
|
||||
U0 DocFormFwd(CDoc *doc,Bool giveup=FALSE)
|
||||
{
|
||||
CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
|
||||
if (doc->flags & DOCF_FORM) {
|
||||
if (doc_e==doc) goto ff_recover;
|
||||
while (!Bt(doldoc.type_flags_form,doc_e->type_u8) &&
|
||||
!(doc_e->de_flags&DOCEF_LINK) ||
|
||||
doc_e->de_flags&DOCEF_SKIP_IN_FORM) {
|
||||
doc_e=doc_e->next;
|
||||
if (doc_e==doc) {
|
||||
ff_recover:
|
||||
doc->cur_col=0;
|
||||
if (!giveup) {
|
||||
doc->cur_entry=doc_e->last;
|
||||
DocFormBwd(doc,TRUE);
|
||||
} else
|
||||
doc->cur_entry=doc;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (doc_e->type_u8==DOCT_INDENT)
|
||||
doc_e=doc_e->next;
|
||||
if (doc_e!=doc_e2) {
|
||||
doc->cur_col=doc_e->min_col;
|
||||
doc->cur_entry=doc_e;
|
||||
}
|
||||
}
|
||||
|
||||
U0 DocFormBwd(CDoc *doc,Bool giveup=FALSE)
|
||||
{
|
||||
CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
|
||||
if (doc->flags & DOCF_FORM) {
|
||||
while (!Bt(doldoc.type_flags_form,doc_e->type_u8) &&
|
||||
!(doc_e->de_flags&DOCEF_LINK) ||
|
||||
doc_e->de_flags&DOCEF_SKIP_IN_FORM) {
|
||||
doc_e=doc_e->last;
|
||||
if (doc_e==doc) {
|
||||
doc->cur_col=0;
|
||||
if (!giveup) {
|
||||
doc->cur_entry=doc_e->next;
|
||||
DocFormFwd(doc,TRUE);
|
||||
} else
|
||||
doc->cur_entry=doc;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
while (doc_e->type_u8==DOCT_INDENT)
|
||||
doc_e=doc_e->next;
|
||||
if (doc_e!=doc_e2) {
|
||||
doc->cur_col=doc_e->min_col;
|
||||
doc->cur_entry=doc_e;
|
||||
}
|
||||
}
|
||||
|
||||
U0 DocDataFmt(CDoc *doc,CDocEntry *doc_e,I64 d=DOCM_CANCEL)
|
||||
{
|
||||
I64 i;
|
||||
U8 *ptr,*ptr2;
|
||||
CHashDefineStr *tmph;
|
||||
if (doc_e->type_u8==DOCT_DATA && doc_e->de_flags&DOCEF_AUX_STR ||
|
||||
doc_e->type_u8==DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LST) {
|
||||
if (d==DOCM_CANCEL) {
|
||||
if (doc_e->de_flags&DOCEF_DEREF_DATA &&
|
||||
!(doc_e->de_flags&DOCEF_REMALLOC_DATA)) {
|
||||
if (!(ptr=doc_e->data)) return;
|
||||
} else
|
||||
ptr=&doc_e->data;
|
||||
switch (doc_e->raw_type) {
|
||||
case RT_I0:
|
||||
case RT_U0: d=0; break;
|
||||
case RT_I8: d=*ptr(I8 *); break;
|
||||
case RT_U8: d=*ptr(U8 *); break;
|
||||
case RT_I16: d=*ptr(I16 *); break;
|
||||
case RT_U16: d=*ptr(U16 *); break;
|
||||
case RT_I32: d=*ptr(I32 *); break;
|
||||
case RT_U32: d=*ptr(U32 *); break;
|
||||
default: d=*ptr(I64 *);
|
||||
}
|
||||
}
|
||||
if (doc_e->type_u8==DOCT_DATA) {
|
||||
if (doc_e->de_flags & DOCEF_REMALLOC_DATA) {
|
||||
ptr=MStrPrint(doc_e->aux_str,d,doc_e->my_fmt_data);
|
||||
i=StrLen(ptr);
|
||||
if (!doc_e->data) {
|
||||
doc_e->data=CAlloc(2,doc->mem_task);
|
||||
doc_e->len=MSize(doc_e->data)-2;
|
||||
}
|
||||
if (doc_e->len+doc_e->min_col>i)
|
||||
MemCpy(doc_e->tag,ptr,i+1);
|
||||
else {
|
||||
ptr2=MAlloc(i+8,doc->mem_task);
|
||||
doc_e->len=MSize(ptr2)-doc_e->min_col-2; //See $LK,"DataTagWidth",A="FA:::/Adam/DolDoc/DocPlain.HC,DataTagWidth"$
|
||||
MemCpy(ptr2,ptr,i+1);
|
||||
Free(doc_e->tag);
|
||||
doc_e->tag=ptr2;
|
||||
}
|
||||
Free(ptr);
|
||||
} else {
|
||||
StrPrint(doc_e->tag,doc_e->aux_str,d,doc_e->my_fmt_data);
|
||||
i=StrLen(doc_e->tag);
|
||||
}
|
||||
if (doc_e->de_flags & DOCEF_HAS_TERMINATOR) {
|
||||
doc_e->tag[i++]='_';
|
||||
doc_e->tag[i]=0;
|
||||
}
|
||||
doc_e->max_col=i;
|
||||
} else if (doc_e->de_flags & DOCEF_LST) {
|
||||
if (doc_e->de_flags & DOCEF_DEFINE && (tmph=HashFind(doc_e->define_str,
|
||||
doc->win_task->hash_table,HTT_DEFINE_STR)) && 0<=d<tmph->cnt) {
|
||||
ptr=MStrPrint("[%s]",tmph->sub_idx[d]);
|
||||
Free(doc_e->tag);
|
||||
doc_e->tag=StrNew(ptr,doc->mem_task);
|
||||
Free(ptr);
|
||||
} else {
|
||||
Free(doc_e->tag);
|
||||
doc_e->tag=StrNew("[]",doc->mem_task);
|
||||
}
|
||||
} else {
|
||||
if (d)
|
||||
doc_e->de_flags|=DOCEF_CHECKED_COLLAPSED;
|
||||
else
|
||||
doc_e->de_flags&=~DOCEF_CHECKED_COLLAPSED;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 DocDataScan(CDoc *doc,CDocEntry *doc_e)
|
||||
{
|
||||
I64 i,d;
|
||||
U8 *ptr,*ptr1,*ptr2;
|
||||
CHashDefineStr *tmph;
|
||||
if (doc_e->type_u8==DOCT_DATA && doc_e->de_flags&DOCEF_AUX_STR ||
|
||||
doc_e->type_u8==DOCT_CHECK_BOX || doc_e->de_flags & DOCEF_LST) {
|
||||
if (doc_e->de_flags&DOCEF_DEREF_DATA &&
|
||||
!(doc_e->de_flags&DOCEF_REMALLOC_DATA)) {
|
||||
if (!(ptr=doc_e->data)) return;
|
||||
} else
|
||||
ptr=&doc_e->data;
|
||||
if (doc_e->type_u8==DOCT_DATA) {
|
||||
i=StrLen(doc_e->tag);
|
||||
if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
|
||||
doc_e->tag[--i]=0;
|
||||
if (i>doc_e->len+doc_e->min_col)
|
||||
doc_e->tag[doc_e->len+doc_e->min_col]=0;
|
||||
if (RT_I8<=doc_e->raw_type<=RT_U32) {
|
||||
StrScan(doc_e->tag,doc_e->aux_str,&d,doc_e->my_fmt_data);
|
||||
if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
|
||||
doc_e->tag[i]='_';
|
||||
} else if (RT_I64<=doc_e->raw_type<=RT_UF64) {
|
||||
if (doc_e->de_flags & DOCEF_REMALLOC_DATA) {
|
||||
ptr=MAlloc(i-doc_e->min_col+8,doc->mem_task);
|
||||
MemCpy(ptr,doc_e->tag+doc_e->min_col,i-doc_e->min_col+1);
|
||||
Free(doc_e->data);
|
||||
doc_e->data=ptr;
|
||||
doc_e->len=MSize(ptr)-1;
|
||||
} else
|
||||
StrScan(doc_e->tag,doc_e->aux_str,ptr,doc_e->my_fmt_data);
|
||||
if (doc_e->de_flags & DOCEF_HAS_TERMINATOR)
|
||||
doc_e->tag[i]='_';
|
||||
return;
|
||||
}
|
||||
} else if (doc_e->de_flags & DOCEF_LST) {
|
||||
d=0;
|
||||
if (doc_e->tag && doc_e->de_flags & DOCEF_DEFINE &&
|
||||
(tmph=HashFind(doc_e->define_str,
|
||||
doc->win_task->hash_table,HTT_DEFINE_STR))) {
|
||||
ptr1=ptr2=StrNew(doc_e->tag);
|
||||
if (*ptr2=='[') {
|
||||
ptr2++;
|
||||
i=StrLen(ptr2);
|
||||
if (ptr2[i-1]==']')
|
||||
ptr2[i-1]=0;
|
||||
}
|
||||
d=LstMatch(ptr2,tmph->data);
|
||||
Free(ptr1);
|
||||
}
|
||||
} else {
|
||||
if (doc_e->de_flags & DOCEF_CHECKED_COLLAPSED)
|
||||
d=TRUE;
|
||||
else
|
||||
d=FALSE;
|
||||
}
|
||||
switch (doc_e->raw_type) {
|
||||
case RT_I8:
|
||||
case RT_U8:
|
||||
*ptr(U8 *)=d;
|
||||
case RT_I0:
|
||||
case RT_U0:
|
||||
break;
|
||||
case RT_I16:
|
||||
case RT_U16:
|
||||
*ptr(U16 *)=d;
|
||||
break;
|
||||
case RT_I32:
|
||||
case RT_U32:
|
||||
*ptr(U32 *)=d;
|
||||
break;
|
||||
default:
|
||||
*ptr(I64 *)=d;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Input;StdIn/DolDoc"
|
||||
public Bool DocForm(U8 *_d,U8 *class_name=lastclass,
|
||||
I64 dof_flags=0,U8 *header=NULL,U8 *footer=NULL)
|
||||
{//User input. Supply a class name that has fmtstr definitions.
|
||||
//See $LK,"::/Demo/DolDoc/Form.HC"$ and $LK,"::/Demo/LastClass.HC"$.
|
||||
CMemberLst *ml;
|
||||
CDocEntry *doc_e;
|
||||
U8 *fmtstr;
|
||||
CHashClass *tmpc,*tmpc2;
|
||||
CDoc *doc;
|
||||
Bool res=FALSE;
|
||||
I64 old_border_src=Fs->border_src,has_action;
|
||||
if (!(tmpc=HashFind(class_name,Fs->hash_table,HTT_CLASS)))
|
||||
return FALSE;
|
||||
doc=DocNew;
|
||||
doc->desc='Form';
|
||||
if (header) DocPrint(doc,"%s",header);
|
||||
doc->flags|=DOCF_OVERSTRIKE|DOCF_FORM;
|
||||
if (dof_flags&DOF_SIZE_MIN)
|
||||
doc->flags|=DOCF_SIZE_MIN;
|
||||
ml=tmpc->member_lst_and_root;
|
||||
while (ml) {
|
||||
if ((fmtstr=MemberMetaData("fmtstr",ml)) &&
|
||||
(doc_e=DocPrint(doc,"%s",fmtstr))) {
|
||||
tmpc2=ml->member_class;
|
||||
if ((doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_LST ||
|
||||
doc_e->type_u8==DOCT_CHECK_BOX) && !tmpc2->ptr_stars_cnt) {
|
||||
tmpc2=OptClassFwd(tmpc2);
|
||||
tmpc2-=tmpc2->ptr_stars_cnt;
|
||||
if (tmpc2->type & HTT_INTERNAL_TYPE) {
|
||||
if (ml->dim.next) { //Array
|
||||
if (tmpc2->raw_type==RT_U8 &&
|
||||
LBtr(&doc_e->de_flags,&DOCEf_DFT_LEN)) {
|
||||
doc_e->len=ml->dim.total_cnt;
|
||||
if (doc_e->de_flags&DOCEF_HAS_TERMINATOR)
|
||||
doc_e->len--;
|
||||
Free(doc_e->tag); //See $LK,"DataTagWidth",A="FA:::/Adam/DolDoc/DocPlain.HC,DataTagWidth"$
|
||||
doc_e->tag=MAlloc(doc_e->len+doc_e->min_col+2,
|
||||
doc->mem_task); //+2 because "_\0"
|
||||
}
|
||||
} else if (LBtr(&doc_e->de_flags,DOCEf_DFT_RAW_TYPE))
|
||||
doc_e->raw_type=tmpc2->raw_type;
|
||||
}
|
||||
}
|
||||
if (doc_e->de_flags&DOCEF_REMALLOC_DATA) {
|
||||
doc_e->user_data=_d+ml->offset;
|
||||
doc_e->data=*doc_e->user_data(U8 **);
|
||||
} else
|
||||
doc_e->data=_d+ml->offset;
|
||||
doc_e->my_fmt_data=MemberMetaData("fmtdata",ml);
|
||||
DocDataFmt(doc,doc_e);
|
||||
}
|
||||
ml=ml->next;
|
||||
}
|
||||
if (footer) DocPrint(doc,"%s",footer);
|
||||
if (doc->head.next!=doc) {
|
||||
Fs->border_src=BDS_CONST;
|
||||
DocRecalc(doc);
|
||||
if (DocEd(doc,dof_flags)) {
|
||||
doc_e=doc->cur_entry;
|
||||
res=TRUE;
|
||||
if (doc_e!=doc) {
|
||||
if (DocEntryRun(doc,doc_e,TRUE,&has_action)==DOCM_CANCEL && has_action)
|
||||
res=FALSE;
|
||||
DocUnlock(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->de_flags&DOCEF_REMALLOC_DATA) {
|
||||
*doc_e->user_data(U8 **)=doc_e->data;
|
||||
doc_e->data=NULL;
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
DocDel(doc);
|
||||
Fs->border_src=old_border_src;
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 DocMenuEndTaskCB()
|
||||
{
|
||||
WinToTop;
|
||||
throw;
|
||||
}
|
||||
|
||||
public I64 DocMenu(CDoc *m,I64 dof_flags=0)
|
||||
{//Run menu chooser doc. Returns menu doc unlocked.
|
||||
U8 *old_end_cb=Fs->task_end_cb;
|
||||
Bool old_break_shift_esc=LBts(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC);
|
||||
CDocEntry *doc_e;
|
||||
I64 old_border_src=Fs->border_src,res=DOCM_CANCEL,has_action;
|
||||
Fs->task_end_cb=&DocMenuEndTaskCB;
|
||||
try {
|
||||
if (m) {
|
||||
m->desc='Menu';
|
||||
Fs->border_src=BDS_CONST;
|
||||
dm_restart:
|
||||
if (DocEd(m,dof_flags)) {
|
||||
doc_e=m->cur_entry;
|
||||
if (doc_e!=m) {
|
||||
res=DocEntryRun(m,doc_e,TRUE,&has_action);
|
||||
DocUnlock(m);
|
||||
if (!has_action) {
|
||||
res=DOCM_CANCEL;
|
||||
dof_flags|=DOF_DONT_HOME;
|
||||
goto dm_restart;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
if (!Fs->except_ch) {
|
||||
if (!(dof_flags & DOF_INTERCEPT_TASK_END))
|
||||
Exit;
|
||||
Fs->catch_except=TRUE;
|
||||
}
|
||||
}
|
||||
LBEqu(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC,old_break_shift_esc);
|
||||
Fs->border_src=old_border_src;
|
||||
Fs->task_end_cb=old_end_cb;
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 PopUpMenu(CDoc *doc,I64 dof_flags=0)
|
||||
{//Run menu chooser doc in PopUp win task.
|
||||
doc->flags|=DOCF_SIZE_MIN | DOCF_FORM;
|
||||
return PopUpPrint("DocMenu(0x%X,0x%X);",doc,dof_flags);
|
||||
}
|
||||
|
||||
public Bool PopUpForm(U8 *_d,U8 *class_name=lastclass,
|
||||
I64 dof_flags=DOF_SIZE_MIN,U8 *header=NULL,U8 *footer=NULL)
|
||||
{//See $LK,"::/Demo/DolDoc/Form.HC"$ and $LK,"::/Demo/LastClass.HC"$.
|
||||
return PopUpPrint("DocForm(0x%X,0x%X,0x%X,0x%X,0x%X);",_d,class_name,
|
||||
dof_flags,header,footer);
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
#help_index "DolDoc"
|
||||
|
||||
U0 EdUndoFilter(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocEntry *doc_ce=doc->head.next;
|
||||
while (doc_ce!=doc) {
|
||||
doc_ce->de_flags&=~DOCEF_FILTER_SKIP;
|
||||
doc_ce=doc_ce->next;
|
||||
}
|
||||
doc->find_replace->filter_lines=0;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public I64 DocGetKey(I64 *_sc=NULL)
|
||||
{//Called by $LK,"View",A="MN:View"$. You probably don't need this.
|
||||
I64 ch,sc;
|
||||
Bool cont,old_key_desc;
|
||||
do {
|
||||
old_key_desc=LBtr(&Fs->win_inhibit,WIf_SELF_KEY_DESC);
|
||||
do ch=GetKey(&sc,TRUE);
|
||||
while (sc&SCF_KEY_DESC);
|
||||
LBEqu(&Fs->win_inhibit,WIf_SELF_KEY_DESC,old_key_desc);
|
||||
|
||||
DocRecalc(DocPut);
|
||||
cont=FALSE;
|
||||
if ((ch==CH_ESC || ch==CH_SHIFT_ESC) && //Check for exit filter mode
|
||||
DocPut && DocPut->find_replace->filter_lines) {
|
||||
EdUndoFilter(DocPut);
|
||||
cont=TRUE;
|
||||
}
|
||||
} while (cont);
|
||||
if (_sc) *_sc=sc;
|
||||
return ch;
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Input;StdIn/DolDoc"
|
||||
public U8 *DocScanLine(CDoc *doc,CDocEntry *doc_e,
|
||||
I64 *cur_col=NULL,CDocEntry **_do_e_end=NULL)
|
||||
{//Start at entry in doc,make and return one line as str.
|
||||
CDocEntry *doc_e2=doc_e;
|
||||
Bool unlock=DocLock(doc);
|
||||
U8 *dst,*src,*start,*res;
|
||||
I64 i=0;
|
||||
if (cur_col)
|
||||
*cur_col=-1;
|
||||
while (doc_e2!=doc && doc_e2->type_u8!=DOCT_NEW_LINE) {
|
||||
if (doc_e2->de_flags&DOCEF_TAG && doc_e2->tag) {
|
||||
src=doc_e2->tag;
|
||||
i+=StrLen(src);
|
||||
} else if (doc_e2->type_u8==DOCT_TAB)
|
||||
i++;
|
||||
doc_e2=doc_e2->next;
|
||||
}
|
||||
res=MAlloc(i+1);
|
||||
dst=res;
|
||||
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
|
||||
start=dst;
|
||||
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag) {
|
||||
src=doc_e->tag;
|
||||
while (*src)
|
||||
*dst++=*src++;
|
||||
} else if (doc_e->type_u8==DOCT_TAB)
|
||||
*dst++='\t';
|
||||
if (doc_e==doc->cur_entry && cur_col)
|
||||
*cur_col=start-res+doc->cur_col;
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
if (_do_e_end) *_do_e_end=doc_e;
|
||||
*dst=0;
|
||||
if (doc_e==doc->cur_entry && cur_col && !doc->cur_col)
|
||||
*cur_col=dst-res;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
U8 *DocGetStr2(I64 flags=0)
|
||||
{//$LK,"Flags",A="MN:GSF_SHIFT_ESC_EXIT"$
|
||||
CDoc *doc;
|
||||
CDocEntry *doc_e,*doc_e_end;
|
||||
U8 *st,*st2,*res;
|
||||
I64 ch,sc;
|
||||
"$$PT$$";
|
||||
do {
|
||||
ch=DocGetKey(&sc);
|
||||
if (ch==CH_ESC) {
|
||||
if (doc=DocPut) {
|
||||
DocLock(doc);
|
||||
if (doc->doc_signature==DOC_SIGNATURE_VAL && doc->cur_entry!=doc) {
|
||||
doc_e=DocEntryCopy(doc,doc->cur_entry);
|
||||
DocBottom(doc);
|
||||
DocEntryRun(doc,doc_e,TRUE);
|
||||
DocEntryDel(doc,doc_e);
|
||||
}
|
||||
DocUnlock(doc);
|
||||
}
|
||||
if (flags&GSF_WITH_NEW_LINE)
|
||||
break;
|
||||
} if (ch==CH_SHIFT_ESC) {
|
||||
if (flags&GSF_SHIFT_ESC_EXIT)
|
||||
Exit;
|
||||
else {
|
||||
res=StrNew("");
|
||||
goto gs_done;
|
||||
}
|
||||
}
|
||||
//<CTRL-SHIFT-ENTER> is a blank line without entry
|
||||
} while (flags&GSF_WITH_NEW_LINE || ch!='\n' ||
|
||||
sc&SCF_CTRL && sc&SCF_SHIFT);
|
||||
|
||||
doc=DocPut;
|
||||
DocLock(doc);
|
||||
if (flags&GSF_WITH_NEW_LINE) {
|
||||
doc_e=doc->cur_entry;
|
||||
do doc_e=doc_e->last;
|
||||
while (doc_e!=doc && doc_e->type_u8!=DOCT_PMT);
|
||||
doc_e=doc_e->next;
|
||||
if (res=DocScanLine(doc,doc_e,NULL,&doc_e_end)) {
|
||||
while (doc_e_end!=doc && doc_e_end->type_u8==DOCT_NEW_LINE) {
|
||||
st2=MStrPrint("%s\n",res);
|
||||
Free(res);
|
||||
res=st2;
|
||||
if (st=DocScanLine(doc,doc_e_end->next,NULL,&doc_e_end)) {
|
||||
st2=MStrPrint("%s%s",res,st);
|
||||
Free(st);
|
||||
Free(res);
|
||||
res=st2;
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
doc_e=doc->cur_entry;
|
||||
do doc_e=doc_e->last;
|
||||
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
|
||||
doc_e->type_u8!=DOCT_PMT);
|
||||
if (doc_e!=doc && doc_e->type_u8!=DOCT_PMT) {
|
||||
do doc_e=doc_e->last;
|
||||
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
|
||||
doc_e->type_u8!=DOCT_PMT);
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
res=DocScanLine(doc,doc_e,NULL);
|
||||
}
|
||||
DocUnlock(doc);
|
||||
gs_done:
|
||||
"$$PT$$$$FG$$$$BG$$";
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "Keyboard Devices;Char/Input;StdIn"
|
||||
public I64 GetI64(U8 *msg=NULL,I64 dft=0,I64 lo=I64_MIN,I64 hi=I64_MAX)
|
||||
{//Prompt user for I64 expression.
|
||||
Bool okay;
|
||||
U8 *st;
|
||||
I64 res;
|
||||
while (TRUE) {
|
||||
if (msg)
|
||||
"" msg,dft;
|
||||
st=GetStr;
|
||||
if (!*st) {
|
||||
Free(st);
|
||||
return dft;
|
||||
}
|
||||
try {
|
||||
res=ExePrint2("ToI64(%s);",st);
|
||||
okay=TRUE;
|
||||
} catch {
|
||||
Fs->catch_except=TRUE;
|
||||
okay=FALSE;
|
||||
}
|
||||
Free(st);
|
||||
if (okay && lo<=res<=hi)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public F64 GetF64(U8 *msg=NULL,F64 dft=0,F64 lo=F64_MIN,F64 hi=F64_MAX)
|
||||
{//Prompt user for F64 expression.
|
||||
Bool okay;
|
||||
U8 *st;
|
||||
F64 res;
|
||||
while (TRUE) {
|
||||
if (msg)
|
||||
"" msg,dft;
|
||||
st=GetStr;
|
||||
if (!*st) {
|
||||
Free(st);
|
||||
return dft;
|
||||
}
|
||||
try {
|
||||
res=ExePrint2("ToF64(%s);",st)(F64);
|
||||
okay=TRUE;
|
||||
} catch {
|
||||
Fs->catch_except=TRUE;
|
||||
okay=FALSE;
|
||||
}
|
||||
Free(st);
|
||||
if (okay && lo<=res<=hi)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
public CDate GetDate(U8 *msg=NULL,CDate dft=I64_MIN,
|
||||
CDate lo=I64_MIN,CDate hi=I64_MAX)
|
||||
{//Prompt user for date expression. (Use $LK,"Now",A="MN:Now"$() if you want current time.)
|
||||
U8 *st;
|
||||
CDate res;
|
||||
if (dft==I64_MIN) dft=Now;
|
||||
while (TRUE) {
|
||||
if (msg)
|
||||
"" msg,dft,dft;
|
||||
st=GetStr;
|
||||
if (!*st) {
|
||||
Free(st);
|
||||
return dft;
|
||||
}
|
||||
res=Str2Date(st);
|
||||
Free(st);
|
||||
if (res>=lo && res<=hi)
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,163 @@
|
||||
#help_index "Graphics/Input"
|
||||
|
||||
public I64 PopUpColor(U8 *header=NULL,
|
||||
Bool allow_transparent=TRUE,Bool allow_dft=TRUE)
|
||||
{//Chooser for 16-color, default or transparent.
|
||||
I64 i;
|
||||
CDoc *doc=DocNew;
|
||||
if (header)
|
||||
DocPrint(doc,"%s",header);
|
||||
if (allow_transparent)
|
||||
DocPrint(doc,"$$MU,\"TRANSPARENT\",LE=TRANSPARENT$$\n");
|
||||
for (i=0;i<COLORS_NUM;i++)
|
||||
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-8Z__\",LE=%d$$$$BG$$\n",i,i,"ST_COLORS",i);
|
||||
if (allow_dft)
|
||||
DocPrint(doc,"$$BG,WHITE$$$$MU,\"DEFAULT\",LE=DOC_DFT$$$$BG$$");
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
public I64 PopUpColorLighting(U8 *header=NULL)
|
||||
{//Chooser for std TempleOS $LK,"DCLighting",A="MN:DCLighting"$() color.
|
||||
I64 i;
|
||||
CDoc *doc=DocNew;
|
||||
if (header)
|
||||
DocPrint(doc,"%s",header);
|
||||
DocPrint(doc,"\nSingle-Sided means front and back different."
|
||||
"\nDouble-Sided means front and back same."
|
||||
"\n"
|
||||
"\nHalf-Range means 0 to [0,7]"
|
||||
"\n [8,15]-8 to [8,15]"
|
||||
"\nFull-Range means 0 to [0,7] to [0,7]+8"
|
||||
"\n");
|
||||
DocPrint(doc,
|
||||
"\n$$LTPURPLE$$Single-Sided Full-Range Double-Sided Full-Range\n$$BLACK$$");
|
||||
for (i=0;i<COLORS_NUM/2;i++) {
|
||||
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",LE=%d$$$$BG$$ ",i,i,"ST_COLORS",i);
|
||||
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",LE=%d$$$$BG$$\n",i,i,"ST_COLORS",
|
||||
ROPF_TWO_SIDED+i);
|
||||
}
|
||||
DocPrint(doc,
|
||||
"\n$$LTPURPLE$$Single-Sided Half-Range Double-Sided Half-Range\n$$BLACK$$");
|
||||
for (i=0;i<COLORS_NUM;i++) {
|
||||
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",LE=%d$$$$BG$$ ",
|
||||
i,i,"ST_COLORS",ROPF_HALF_RANGE_COLOR+i);
|
||||
DocPrint(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",LE=%d$$$$BG$$\n",
|
||||
i,i,"ST_COLORS",ROPF_TWO_SIDED+ROPF_HALF_RANGE_COLOR+i);
|
||||
}
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
class CTransformForm
|
||||
{
|
||||
F64 x_scale fmtstr "$$DA-TRM,A=\"X Scale :%12.6f\"$$\n";
|
||||
F64 y_scale fmtstr "$$DA-TRM,A=\"Y Scale :%12.6f\"$$\n";
|
||||
F64 z_scale fmtstr "$$DA-TRM,A=\"Z Scale :%12.6f\"$$\n";
|
||||
F64 é_z fmtstr "\nAngles are in degrees\n"
|
||||
"$$DA-TRM,A=\"Z-Axis :%12.6f\"$$\n";
|
||||
F64 é_y fmtstr "$$DA-TRM,A=\"Y-Axis :%12.6f\"$$\n";
|
||||
F64 é_x fmtstr "$$DA-TRM,A=\"X-Axis :%12.6f\"$$\n";
|
||||
F64 x_offset fmtstr "\n$$DA-TRM,A=\"X Offset:%12.6f\"$$\n";
|
||||
F64 y_offset fmtstr "$$DA-TRM,A=\"Y Offset:%12.6f\"$$\n";
|
||||
F64 z_offset fmtstr "$$DA-TRM,A=\"Z Offset:%12.6f\"$$\n";
|
||||
};
|
||||
|
||||
#help_index "Graphics/Input;Graphics/Math/3D Transformation"
|
||||
public Bool PopUpTransform(I64 *r)
|
||||
{//Prompt for Mat4x4 transform.
|
||||
CTransformForm *tf=MAlloc(sizeof(CTransformForm));
|
||||
tf->x_scale=1.0;
|
||||
tf->y_scale=1.0;
|
||||
tf->z_scale=1.0;
|
||||
tf->é_x=0.0;
|
||||
tf->é_y=0.0;
|
||||
tf->é_z=0.0;
|
||||
tf->x_offset=0.0;
|
||||
tf->y_offset=0.0;
|
||||
tf->z_offset=0.0;
|
||||
if (PopUpForm(tf)) {
|
||||
MemSet(r,0,16*sizeof(I64));
|
||||
r[0] =tf->x_scale*GR_SCALE;
|
||||
r[5] =tf->y_scale*GR_SCALE;
|
||||
r[10]=tf->z_scale*GR_SCALE;
|
||||
r[15]=GR_SCALE;
|
||||
|
||||
Mat4x4RotZ(r,tf->é_z*ã/180.0);
|
||||
Mat4x4RotY(r,tf->é_y*ã/180.0);
|
||||
Mat4x4RotX(r,tf->é_x*ã/180.0);
|
||||
|
||||
r[3] =tf->x_offset*GR_SCALE;
|
||||
r[7] =tf->y_offset*GR_SCALE;
|
||||
r[11]=tf->z_offset*GR_SCALE;
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#help_index "Graphics/Input"
|
||||
#define PU_SPACING 10
|
||||
U0 DrawIt(CTask *task,CDC *dc)
|
||||
{
|
||||
I64 i,j,i1,j1;
|
||||
CDoc *doc=DocPut(task);
|
||||
for (j=0;j<17;j++)
|
||||
for (i=0;i<17;i++) {
|
||||
if (j<16)
|
||||
j1=j;
|
||||
else
|
||||
j1=TRANSPARENT;
|
||||
if (i<16)
|
||||
i1=i;
|
||||
else
|
||||
i1=TRANSPARENT;
|
||||
dc->color=j1+i1<<16+ROPF_DITHER;
|
||||
GrRect(dc,i*PU_SPACING,j*PU_SPACING+FramePtr("DitherFrame",task),
|
||||
PU_SPACING,PU_SPACING);
|
||||
}
|
||||
i=(17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH;
|
||||
if (doc->max_x>i) i=doc->max_x;
|
||||
WinHorz(task->win_left,task->win_left+i,task);
|
||||
WinVert(task->win_top,task->win_top+doc->max_y+
|
||||
(17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH,task);
|
||||
}
|
||||
|
||||
I64 DitherColor2(U8 *header=NULL)
|
||||
{
|
||||
I64 msg_code,arg1,arg2,res=-1,i,j;
|
||||
DocClear;
|
||||
"%s",header;
|
||||
DocRecalc(DocPut);
|
||||
FramePtrAdd("DitherFrame",(DocPut->max_y+1)*FONT_HEIGHT);
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
Fs->draw_it=&DrawIt;
|
||||
do {
|
||||
msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_KEY_DOWN);
|
||||
if (msg_code==MSG_MS_L_DOWN) {
|
||||
msg_code=GetMsg(&arg1,&arg2,1<<MSG_MS_L_UP);
|
||||
i=arg1/PU_SPACING;
|
||||
j=(arg2-FramePtr("DitherFrame"))/PU_SPACING;
|
||||
if (arg1>=0 && arg2>=0 && 0<=j<17 && 0<=i<17) {
|
||||
if (j==16) j=TRANSPARENT;
|
||||
if (i==16) i=TRANSPARENT;
|
||||
res=j+i<<16+ROPF_DITHER;
|
||||
goto dc_done;
|
||||
}
|
||||
}
|
||||
} while (!(msg_code==MSG_KEY_DOWN && (arg1==CH_ESC || arg1==CH_SHIFT_ESC)));
|
||||
do GetMsg(&arg1,&arg2,1<<MSG_KEY_UP);
|
||||
while (!arg1);
|
||||
dc_done:
|
||||
SettingsPop;
|
||||
FramePtrDel("DitherFrame");
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 PopUpColorDither(U8 *header=NULL)
|
||||
{//Chooser for 2 x 16 colors or transparent.
|
||||
U8 buf[STR_LEN];
|
||||
StrPrint(buf,"DitherColor2(0x%X);",header);
|
||||
return PopUp(buf,Fs);
|
||||
}
|
||||
@@ -0,0 +1,160 @@
|
||||
#help_index "DolDoc/Misc"
|
||||
|
||||
CColorROPU32 highlight_hash_type_colors[HTt_TYPES_NUM]=
|
||||
DOC_COLOR_EXPORT_SYS_SYM,0,DOC_COLOR_DEFINE_STR,DOC_COLOR_GLBL_VAR,
|
||||
DOC_COLOR_CLASS,DOC_COLOR_KEYWORD,DOC_COLOR_FUN,0,0,DOC_COLOR_KEYWORD,
|
||||
DOC_COLOR_KEYWORD,DOC_COLOR_KEYWORD,DOC_COLOR_REG,0,0,0,0};
|
||||
|
||||
U32 *DocHighlight(CDocEntry *doc_e,U8 *src,I64 len,I64 _tmp_u32_attr)
|
||||
{//Be aware of $LK,"::/Demo/ToHtmlToTXTDemo/ToHtml.HC"$.
|
||||
U32 *res=MAlloc((len+1)*sizeof(U32)),*dst=res;
|
||||
U8 *ptr;
|
||||
CDocSettings *s=&doc_e->settings;
|
||||
I64 ch,ch1,last_ch,tmp_u32_attr,mask_tmp_u32_attr=_tmp_u32_attr&0xFFFFF000,
|
||||
comment_depth,brace_depth=s->brace_depth,paren_depth=s->paren_depth;
|
||||
CHash *tmph;
|
||||
switch [s->state] {
|
||||
case DOCSS_NORMAL:
|
||||
hl_normal:
|
||||
while (len) {
|
||||
while (len && !Bt(char_bmp_alpha_numeric,*src)) {
|
||||
tmp_u32_attr=_tmp_u32_attr;
|
||||
ch1=*src++;
|
||||
switch (ch1) {
|
||||
case '/':
|
||||
if (len>=2) {
|
||||
if (*src=='/') {
|
||||
tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
*dst++=*src++ +tmp_u32_attr;
|
||||
len-=2;
|
||||
goto hl_cpp_comment;
|
||||
} else if (*src=='*') {
|
||||
tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
*dst++=*src++ +tmp_u32_attr;
|
||||
len-=2;
|
||||
comment_depth=1;
|
||||
goto hl_comment;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\'':
|
||||
tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
len--;
|
||||
goto hl_single_quote;
|
||||
case '\"':
|
||||
tmp_u32_attr=DOC_COLOR_STR<<8|mask_tmp_u32_attr;
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
len--;
|
||||
goto hl_dbl_quote;
|
||||
case '(':
|
||||
if (paren_depth++&1)
|
||||
tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
|
||||
break;
|
||||
case ')':
|
||||
if (--paren_depth&1)
|
||||
tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
|
||||
break;
|
||||
case '{':
|
||||
if (brace_depth++&1)
|
||||
tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
|
||||
break;
|
||||
case '}':
|
||||
if (--brace_depth&1)
|
||||
tmp_u32_attr=DOC_COLOR_ALT_TEXT<<8|mask_tmp_u32_attr;
|
||||
break;
|
||||
}
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
if (!--len) goto hl_normal_done;
|
||||
}
|
||||
ptr=src;
|
||||
while (len && Bt(char_bmp_alpha_numeric,*src)) {
|
||||
src++;
|
||||
len--;
|
||||
}
|
||||
ch=*src;
|
||||
*src=0;
|
||||
if (tmph=HashFind(ptr,adam_task->hash_table,
|
||||
HTT_EXPORT_SYS_SYM|HTT_DEFINE_STR|HTT_GLBL_VAR|HTT_CLASS|
|
||||
HTT_INTERNAL_TYPE|HTT_FUN|HTT_KEYWORD|HTT_ASM_KEYWORD|
|
||||
HTT_OPCODE|HTT_REG))
|
||||
tmp_u32_attr=highlight_hash_type_colors[HashTypeNum(tmph)]<<8|
|
||||
mask_tmp_u32_attr;
|
||||
else
|
||||
tmp_u32_attr=_tmp_u32_attr;
|
||||
while (ch1=*ptr++)
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
*src=ch;
|
||||
}
|
||||
hl_normal_done:
|
||||
s->state=DOCSS_NORMAL;
|
||||
s->comment_depth=0;
|
||||
break;
|
||||
case DOCSS_SINGLE_QUOTE:
|
||||
tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
|
||||
hl_single_quote:
|
||||
last_ch=0;
|
||||
while (len--) {
|
||||
ch1=*src++;
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
if (last_ch!='\\' && ch1=='\'')
|
||||
goto hl_normal;
|
||||
if (last_ch=='\\' && ch1=='\\')
|
||||
last_ch=0;
|
||||
else
|
||||
last_ch=ch1;
|
||||
}
|
||||
s->state=DOCSS_SINGLE_QUOTE;
|
||||
s->comment_depth=0;
|
||||
break;
|
||||
case DOCSS_DBL_QUOTE:
|
||||
tmp_u32_attr=DOC_COLOR_CHAR_CONST<<8|mask_tmp_u32_attr;
|
||||
hl_dbl_quote:
|
||||
last_ch=0;
|
||||
while (len--) {
|
||||
ch1=*src++;
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
if (last_ch!='\\' && ch1=='\"')
|
||||
goto hl_normal;
|
||||
if (last_ch=='\\' && ch1=='\\')
|
||||
last_ch=0;
|
||||
else
|
||||
last_ch=ch1;
|
||||
}
|
||||
s->state=DOCSS_DBL_QUOTE;
|
||||
s->comment_depth=0;
|
||||
break;
|
||||
case DOCSS_COMMENT:
|
||||
tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
|
||||
comment_depth=s->comment_depth;
|
||||
hl_comment:
|
||||
last_ch=0;
|
||||
while (len--) {
|
||||
ch1=*src++;
|
||||
*dst++=ch1+tmp_u32_attr;
|
||||
if (last_ch=='*' && ch1=='/') {
|
||||
if (!--comment_depth)
|
||||
goto hl_normal;
|
||||
} else if (last_ch=='/' && ch1=='*')
|
||||
comment_depth++;
|
||||
last_ch=ch1;
|
||||
}
|
||||
s->state=DOCSS_COMMENT;
|
||||
s->comment_depth=comment_depth;
|
||||
break;
|
||||
case DOCSS_CPP_Z_COMMENT:
|
||||
tmp_u32_attr=DOC_COLOR_COMMENT<<8|mask_tmp_u32_attr;
|
||||
hl_cpp_comment:
|
||||
while (len--)
|
||||
*dst++=*src++ +tmp_u32_attr;
|
||||
s->state=DOCSS_CPP_Z_COMMENT;
|
||||
s->comment_depth=0;
|
||||
break;
|
||||
}
|
||||
s->paren_depth=paren_depth;
|
||||
s->brace_depth=brace_depth;
|
||||
*dst=0;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
#help_index "DolDoc"
|
||||
|
||||
U0 DocInit()
|
||||
{//$LK-UL,"CMD Defines",A="MN:DOCT_TEXT"$
|
||||
CCmpCtrl *cc;
|
||||
I64 i;
|
||||
CHashGeneric *tmph;
|
||||
|
||||
DefineLstLoad("ST_DOC_CMDS",
|
||||
"TX\0CR\0SR\0TB\0PB\0CU\0MK\0PT\0CL\0PL\0LM\0RM\0HD\0FO\0ID\0FG\0"
|
||||
"BG\0FD\0BD\0WW\0HL\0BK\0IV\0UL\0SX\0SY\0CM\0AN\0LK\0BT\0"
|
||||
"DA\0CB\0LS\0MA\0MU\0HX\0TR\0SP\0IB\0IS\0SO\0HC\0ER\0");
|
||||
DefineLstLoad("ST_DOC_FLAGS",
|
||||
"T\0LEN\0A\0D\0HTML\0LE\0LM\0RE\0RM\0BI\0BP\0RT\0SX\0SY\0SCX\0U\0"
|
||||
"LC\0LIS\0RC\0RIS\0LX\0CX\0RX\0TY\0CY\0BY\0"
|
||||
"HL\0WW\0BK\0IV\0SEL\0UL\0"
|
||||
"TC\0PRY\0MRX\0WR\0L\0X\0Q\0FST\0B\0S\0BD\0C\0CA\0RD\0UD\0P\0M\0"
|
||||
"TRM\0Z\0H\0TR\0LS\0SK\0PU\0SIF\0FS\0NC\0DD\0DL\0DRT\0");
|
||||
DefineLstLoad("ST_LINK_TYPES",
|
||||
"FI\0FA\0FF\0FL\0MN\0PI\0PF\0PL\0BF\0DN\0HI\0AD\0AI\0AA\0AF\0AL\0");
|
||||
|
||||
doldoc.hash=HashTableNew(512);
|
||||
HashDefineLstAdd("ST_DOC_CMDS",DHT_DOC_CMD,doldoc.hash);
|
||||
HashDefineLstAdd("ST_DOC_FLAGS",DHT_DOC_FLAG,doldoc.hash);
|
||||
HashDefineLstAdd("ST_COLORS",DHT_COLOR,doldoc.hash);
|
||||
|
||||
MemSet(doldoc.dft_de_flags, 0,sizeof(doldoc.dft_de_flags));
|
||||
MemSet(doldoc.dft_type_flags, 0,sizeof(doldoc.dft_type_flags));
|
||||
cc=CmpCtrlNew("TX+T;DA+P+TRM+T+DL+DRT;CM+LE+RE;AN+T;LK+L+UL+T;MA+X+UL+T;"
|
||||
"MU+X+UL+T;BT+X+B+T;CB+CA+P+T+DRT;LS+LS+P+T+DRT;HX+P+Z;TR+TR+C+CA+UL+T;"
|
||||
"SP+T;IB+T;IS+T;SO+T;HC+T;",CCF_DONT_FREE_BUF);
|
||||
cc->htc.hash_table_lst=NULL;
|
||||
Lex(cc);
|
||||
while (cc->token==TK_IDENT) {
|
||||
if (tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_CMD)) {
|
||||
i=tmph->user_data0;
|
||||
Lex(cc);
|
||||
PrsDocFlags(cc,&doldoc.dft_de_flags[i],&doldoc.dft_type_flags[i]);
|
||||
}
|
||||
if (cc->token==';')
|
||||
Lex(cc);
|
||||
}
|
||||
CmpCtrlDel(cc);
|
||||
|
||||
for (i=0;i<DOCT_TYPES_NUM;i++)
|
||||
doldoc.dft_de_flags[i]&=~DOCG_BL_IV_UL;
|
||||
|
||||
doldoc.type_flags_form[0]=0;
|
||||
for (i=0;i<DOCT_TYPES_NUM;i++)
|
||||
if (Bt(&doldoc.dft_de_flags[i],DOCEf_TAG) && i!=DOCT_TEXT || i==DOCT_HEX_ED)
|
||||
Bts(doldoc.type_flags_form,i);
|
||||
|
||||
//Don't forget $LK,"cmp_type_flags_src_code",A="MN:cmp_type_flags_src_code"$.
|
||||
doldoc.type_flags_nontag_invis[0]=
|
||||
1<<DOCT_PMT|
|
||||
1<<DOCT_PAGE_LEN|
|
||||
1<<DOCT_LEFT_MARGIN|
|
||||
1<<DOCT_RIGHT_MARGIN|
|
||||
1<<DOCT_HEADER|
|
||||
1<<DOCT_FOOTER|
|
||||
1<<DOCT_INDENT|
|
||||
1<<DOCT_FOREGROUND|
|
||||
1<<DOCT_BACKGROUND|
|
||||
1<<DOCT_DFT_FOREGROUND|
|
||||
1<<DOCT_DFT_BACKGROUND|
|
||||
1<<DOCT_WORD_WRAP|
|
||||
1<<DOCT_HIGHLIGHT|
|
||||
1<<DOCT_BLINK|
|
||||
1<<DOCT_INVERT|
|
||||
1<<DOCT_UNDERLINE|
|
||||
1<<DOCT_SHIFTED_X|
|
||||
1<<DOCT_SHIFTED_Y|
|
||||
1<<DOCT_SPRITE;
|
||||
|
||||
doldoc.type_flags_data[0]=1<<DOCT_DATA|1<<DOCT_HEX_ED|1<<DOCT_CHECK_BOX;
|
||||
|
||||
doldoc.type_flags_chk_dup[0]=
|
||||
1<<DOCT_LEFT_MARGIN|
|
||||
1<<DOCT_RIGHT_MARGIN|
|
||||
1<<DOCT_HEADER|
|
||||
1<<DOCT_FOOTER|
|
||||
1<<DOCT_FOREGROUND|
|
||||
1<<DOCT_BACKGROUND|
|
||||
1<<DOCT_DFT_FOREGROUND|
|
||||
1<<DOCT_DFT_BACKGROUND|
|
||||
1<<DOCT_WORD_WRAP|
|
||||
1<<DOCT_HIGHLIGHT|
|
||||
1<<DOCT_BLINK|
|
||||
1<<DOCT_INVERT|
|
||||
1<<DOCT_UNDERLINE|
|
||||
1<<DOCT_SHIFTED_X|
|
||||
1<<DOCT_SHIFTED_Y;
|
||||
|
||||
Bts(doldoc.clean_scan_codes,SC_CURSOR_RIGHT);
|
||||
Bts(doldoc.clean_scan_codes,SC_CURSOR_LEFT);
|
||||
Bts(doldoc.clean_scan_codes,SC_CURSOR_UP);
|
||||
Bts(doldoc.clean_scan_codes,SC_CURSOR_DOWN);
|
||||
Bts(doldoc.clean_scan_codes,SC_PAGE_UP);
|
||||
Bts(doldoc.clean_scan_codes,SC_PAGE_DOWN);
|
||||
Bts(doldoc.clean_scan_codes,SC_ALT);
|
||||
Bts(doldoc.clean_scan_codes,SC_CTRL);
|
||||
Bts(doldoc.clean_scan_codes,SC_SHIFT);
|
||||
Bts(doldoc.clean_scan_codes,SC_CAPS);
|
||||
Bts(doldoc.clean_scan_codes,SC_NUM);
|
||||
Bts(doldoc.clean_scan_codes,SC_SCROLL);
|
||||
Bts(doldoc.clean_scan_codes,SC_HOME);
|
||||
Bts(doldoc.clean_scan_codes,SC_END);
|
||||
Bts(doldoc.clean_scan_codes,SC_GUI);
|
||||
Bts(doldoc.clean_scan_codes,SC_BACKSPACE); //Handled specially
|
||||
}
|
||||
|
||||
DocInit;
|
||||
@@ -0,0 +1,358 @@
|
||||
#help_index "DolDoc/Link"
|
||||
|
||||
/* See $LK,"TempleOS Link Types",A="MN:ST_LINK_TYPES"$.
|
||||
"filename"
|
||||
"FI:filename"
|
||||
"FA:haystack_filename,needle_anchor_str"
|
||||
"FF:haystack_filename,needle_str"
|
||||
"FF:haystack_filename,needle_str:occurnum"
|
||||
"FL:filename,linenum"
|
||||
"MN:SymName"
|
||||
"PI:filename"
|
||||
"PF:haystack_filename,needle_str"
|
||||
"PF:haystack_filename,needle_str:occurnum"
|
||||
"PL:filename,linenum"
|
||||
"BF:haystack_bible_book,needle_str"
|
||||
"DN:word"
|
||||
"DN:word,defnum"
|
||||
"HI:index"
|
||||
"AD:code_address_number"
|
||||
|
||||
To edit a doc structure already in memory. See $LK,"SpriteEdText",A="MN:SpriteEdText"$().
|
||||
"AI:doc_address"
|
||||
"AA:haystack_doc_address,needle_anchor_str"
|
||||
"AF:haystack_doc_address,needle_str"
|
||||
"AF:haystack_doc_address,needle_str:occurnum"
|
||||
"AL:doc_address,linenum"
|
||||
*/
|
||||
|
||||
#define LK_FILE 0
|
||||
#define LK_FILE_ANCHOR 1
|
||||
#define LK_FILE_FIND 2
|
||||
#define LK_FILE_LINE 3
|
||||
#define LK_MAN_PAGE 4
|
||||
#define LK_PLAIN 5
|
||||
#define LK_PLAIN_FIND 6
|
||||
#define LK_PLAIN_LINE 7
|
||||
#define LK_BIBLE_FIND 8
|
||||
#define LK_DEF 9
|
||||
#define LK_HELP_INDEX 10
|
||||
#define LK_ADDR 11
|
||||
#define LK_DOC 12 //See $LK,"SpriteEdText",A="MN:SpriteEdText"$()
|
||||
#define LK_DOC_ANCHOR 13
|
||||
#define LK_DOC_FIND 14
|
||||
#define LK_DOC_LINE 15
|
||||
#define LK_PLACE_ANCHOR 16
|
||||
|
||||
public U8 *DocEntryLink(CDoc *doc,CDocEntry *doc_e)
|
||||
{//MAlloc new str, either tag or aux_str if link.
|
||||
if (doc_e->de_flags&DOCEF_LINK) {
|
||||
if (doc_e->de_flags & DOCEF_AUX_STR)
|
||||
return StrNew(doc_e->aux_str,doc->mem_task);
|
||||
else if (doc_e->de_flags & DOCEF_TAG)
|
||||
return StrNew(doc_e->tag,doc->mem_task);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Bool DocFileEd(I64 _type,U8 *filename,
|
||||
U8 *needle_str,I64 *_num,I64 edf_dof_flags)
|
||||
{
|
||||
I64 type=_type,flags=0,old_border_src=Fs->border_src;
|
||||
CDocEntry *doc_e;
|
||||
CDoc *doc;
|
||||
Bool old_silent=Bt(&Fs->display_flags,DISPLAYf_SILENT),
|
||||
res=FALSE,other_found=FALSE;
|
||||
U8 *st1,*st2;
|
||||
try {
|
||||
switch (type) {
|
||||
case LK_PLAIN:
|
||||
flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
|
||||
case LK_DOC:
|
||||
type=LK_FILE;
|
||||
break;
|
||||
case LK_DOC_ANCHOR:
|
||||
type=LK_FILE_ANCHOR;
|
||||
break;
|
||||
case LK_PLAIN_FIND:
|
||||
flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
|
||||
case LK_DOC_FIND:
|
||||
type=LK_FILE_FIND;
|
||||
break;
|
||||
case LK_PLAIN_LINE:
|
||||
flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
|
||||
case LK_DOC_LINE:
|
||||
type=LK_FILE_LINE;
|
||||
break;
|
||||
case LK_BIBLE_FIND:
|
||||
flags=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
|
||||
break;
|
||||
}
|
||||
|
||||
flags|=DOCF_ALLOW_UNDO;
|
||||
|
||||
if (LK_DOC<=_type<=LK_DOC_LINE) {
|
||||
doc=Str2I64(filename);//See $LK,"SpriteEdText",A="MN:SpriteEdText"$()
|
||||
res=TRUE;
|
||||
} else {
|
||||
st1=StrNew(filename);
|
||||
st2=StrNew(filename);
|
||||
StrLastRem(st1,"/",st2); //st2 is name without dir
|
||||
if (!FileNameChk(st2))
|
||||
doc=NULL;
|
||||
else {
|
||||
Silent;
|
||||
if (Bt(&edf_dof_flags,EDf_BAIL)) //if bail, scan parents
|
||||
res=FileFind(filename,,
|
||||
FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
|
||||
else if (!(res=FileFind(filename,,FUF_JUST_FILES)))
|
||||
other_found=FileFind(filename,,
|
||||
FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
|
||||
doc=DocRead(filename,flags);
|
||||
doc->desc='Edit';
|
||||
Silent(old_silent);
|
||||
Fs->border_src=BDS_ED_FILENAME_DRV;
|
||||
}
|
||||
Free(st1);
|
||||
Free(st2);
|
||||
}
|
||||
if (!doc||doc->doc_signature!=DOC_SIGNATURE_VAL)
|
||||
res=FALSE;
|
||||
else {
|
||||
if (Bt(&edf_dof_flags,EDf_COLLAPSE))
|
||||
DocCollapse(TRUE,doc);
|
||||
else if (Bt(&edf_dof_flags,EDf_UNCOLLAPSE))
|
||||
DocCollapse(FALSE,doc);
|
||||
|
||||
if (res || other_found)
|
||||
switch (type) {
|
||||
case LK_FILE_LINE:
|
||||
res=DocLineNumGoTo(doc,*_num);
|
||||
break;
|
||||
case LK_FILE_ANCHOR:
|
||||
res=DocAnchorFind(doc,needle_str);
|
||||
break;
|
||||
case LK_FILE_FIND:
|
||||
res=DocFind(doc,,needle_str,*_num);
|
||||
break;
|
||||
case LK_BIBLE_FIND:
|
||||
res=DocFind(doc,*_num,needle_str);
|
||||
break;
|
||||
default:
|
||||
DocCenter(doc);
|
||||
}
|
||||
*_num=doc->cur_entry->y+1;
|
||||
|
||||
if (edf_dof_flags&EDF_WAS_WRITE)
|
||||
res=FALSE;
|
||||
if (!(edf_dof_flags&EDF_BAIL)) {
|
||||
if (*doc->filename.name)
|
||||
doc->filename.dirc=DirContextNew(doc->filename.name);
|
||||
else
|
||||
doc->filename.dirc=NULL;
|
||||
if (DocEd(doc,edf_dof_flags|DOF_DONT_HOME)) {
|
||||
DocLock(doc);
|
||||
doc_e=doc->cur_entry;
|
||||
if (doc_e!=doc)
|
||||
DocEntryRun(doc,doc_e,TRUE);
|
||||
DocUnlock(doc);
|
||||
if (!(LK_DOC<=_type<=LK_DOC_LINE)) {
|
||||
DocWrite(doc);
|
||||
if (edf_dof_flags&EDF_WAS_WRITE)
|
||||
res=TRUE;
|
||||
}
|
||||
}
|
||||
DirContextDel(doc->filename.dirc);
|
||||
}
|
||||
if (!(LK_DOC<=_type<=LK_DOC_LINE))
|
||||
DocDel(doc);
|
||||
}
|
||||
} catch {
|
||||
Silent(old_silent);
|
||||
res=FALSE;
|
||||
}
|
||||
Fs->border_src=old_border_src;
|
||||
return res;
|
||||
}
|
||||
|
||||
#define DFT_ADDR_LINK_BIN_SIZE 64
|
||||
|
||||
public I64 EdLinkCvt(U8 *link_st,U8 **_filename=NULL,U8 **_needle_str=NULL,
|
||||
I64 *_num=NULL,I64 edf_dof_flags=0)
|
||||
{//$LK,"Editor Link",A="MN:LK_FILE"$--> filename, needle_str and line number.
|
||||
U8 *st,*ptr,*src,*filename=NULL,*needle_str=NULL,*filename2;
|
||||
I64 res,i,num=1;
|
||||
CHashSrcSym *tmph;
|
||||
if (!link_st||!*link_st) {
|
||||
if (edf_dof_flags&EDF_BAIL)
|
||||
return -1;
|
||||
link_st=blkdev.tmp_filename;
|
||||
}
|
||||
st=StrNew(link_st);
|
||||
res=LK_FILE;
|
||||
if (StrLen(st)>3 && st[2]==':') {
|
||||
st[2]=0;
|
||||
filename2=st+3;
|
||||
switch (res=DefineMatch(st,"ST_LINK_TYPES",LMF_IGNORE_CASE)) {
|
||||
case LK_MAN_PAGE:
|
||||
if (tmph=HashFind(filename2,Fs->hash_table,HTG_SRC_SYM))
|
||||
res=EdLinkCvt(tmph->src_link,&filename,
|
||||
&needle_str,&num,edf_dof_flags);
|
||||
else
|
||||
res=-1;
|
||||
goto lc_done;
|
||||
case LK_ADDR:
|
||||
if (ptr=StrLastOcc(filename2,",")) {
|
||||
*ptr=0;
|
||||
i=Str2I64(ptr+1);
|
||||
} else
|
||||
i=DFT_ADDR_LINK_BIN_SIZE;
|
||||
if (ptr=SrcEdLink(ExePrint("%s;",filename2),i)) {
|
||||
res=EdLinkCvt(ptr,&filename,&needle_str,&num,edf_dof_flags);
|
||||
Free(ptr);
|
||||
} else
|
||||
res=-1;
|
||||
goto lc_done;
|
||||
case LK_DEF:
|
||||
if (ptr=StrLastOcc(filename2,",")) {
|
||||
*ptr=0;
|
||||
i=Str2I64(ptr+1);
|
||||
} else
|
||||
i=-1;
|
||||
filename=StrNew(filename2);
|
||||
num=i;
|
||||
goto lc_done;
|
||||
case LK_HELP_INDEX:
|
||||
filename=StrNew(filename2);
|
||||
goto lc_done;
|
||||
case LK_BIBLE_FIND:
|
||||
if (ptr=StrLastOcc(filename2,",")) {
|
||||
*ptr=0;
|
||||
src=ptr+1;
|
||||
while (*src) { //We do not allow ending verse
|
||||
if (*src=='-')
|
||||
*src=0;
|
||||
src++;
|
||||
}
|
||||
needle_str=StrNew(ptr+1);
|
||||
}
|
||||
i=DefineMatch(filename2,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE);
|
||||
if (i<0)
|
||||
res=-1;
|
||||
else {
|
||||
num=Str2I64(DefineSub(i,"ST_BIBLE_BOOK_LINES"));
|
||||
filename2=BIBLE_FILENAME;
|
||||
}
|
||||
break;
|
||||
case LK_FILE_LINE:
|
||||
case LK_PLAIN_LINE:
|
||||
case LK_DOC_LINE:
|
||||
if (ptr=StrLastOcc(filename2,",")) {
|
||||
*ptr=0;
|
||||
num=Str2I64(ptr+1);
|
||||
}
|
||||
break;
|
||||
case LK_FILE_ANCHOR:
|
||||
case LK_DOC_ANCHOR:
|
||||
if (ptr=StrLastOcc(filename2,",")) {
|
||||
*ptr=0;
|
||||
needle_str=StrNew(ptr+1);
|
||||
}
|
||||
break;
|
||||
case LK_FILE_FIND:
|
||||
case LK_PLAIN_FIND:
|
||||
case LK_DOC_FIND:
|
||||
if (ptr=StrLastOcc(filename2,",")) {
|
||||
*ptr=0;
|
||||
needle_str=StrNew(ptr+1);
|
||||
if (ptr=StrLastOcc(needle_str,":")) {
|
||||
*ptr=0;
|
||||
num=Str2I64(ptr+1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
} else
|
||||
filename2=st;
|
||||
if (res>=0) {
|
||||
if (LK_DOC<=res<=LK_DOC_LINE)
|
||||
filename=StrNew(filename2); //Holds document address as number.
|
||||
else
|
||||
filename=FileNameAbs(filename2,FUF_Z_OR_NOT_Z);
|
||||
}
|
||||
lc_done:
|
||||
Free(st);
|
||||
if (_filename)
|
||||
*_filename=filename;
|
||||
else
|
||||
Free(filename);
|
||||
if (_needle_str)
|
||||
*_needle_str=needle_str;
|
||||
else
|
||||
Free(needle_str);
|
||||
if (_num)
|
||||
*_num=num;
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool DocLinkChk(CDoc *doc,U8 *link_st)
|
||||
{//Check for bad $LK,"Editor Link",A="MN:LK_FILE"$.
|
||||
U8 *filename,*st;
|
||||
Bool res=FALSE;
|
||||
CDirContext *dirc;
|
||||
if (link_st) {
|
||||
st=FileNameAbs(doc->filename.name);
|
||||
dirc=DirContextNew(st);
|
||||
Free(st);
|
||||
switch (EdLinkCvt(link_st,&filename)) {
|
||||
case -1:
|
||||
break;
|
||||
case LK_FILE_LINE:
|
||||
case LK_PLAIN_LINE:
|
||||
case LK_FILE:
|
||||
//We don't check line number
|
||||
res=FileFind(filename,,
|
||||
FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
|
||||
break;
|
||||
case LK_BIBLE_FIND:
|
||||
st=StrNew(link_st+3);
|
||||
if (StrOcc(st,','))
|
||||
StrLastRem(st,",");
|
||||
if (DefineMatch(st,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE)>=0)
|
||||
res=TRUE;
|
||||
Free(st);
|
||||
break;
|
||||
default://TODO: Need to validate HI: and DN:
|
||||
if (Ed(link_st,EDF_BAIL))
|
||||
res=TRUE;
|
||||
}
|
||||
Free(filename);
|
||||
DirContextDel(dirc);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *DocLinkFile(U8 *link_st,CTask *mem_task=NULL)
|
||||
{//Return the file for an $LK,"Editor Link Types",A="MN:LK_FILE"$.
|
||||
U8 *filename=NULL,*st,*res=NULL;
|
||||
if (link_st) {
|
||||
switch (EdLinkCvt(link_st,&filename)) {
|
||||
case LK_FILE:
|
||||
case LK_FILE_ANCHOR:
|
||||
case LK_FILE_FIND:
|
||||
case LK_FILE_LINE:
|
||||
case LK_PLAIN:
|
||||
case LK_PLAIN_FIND:
|
||||
case LK_PLAIN_LINE:
|
||||
st=FileNameAbs(filename,FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
|
||||
res=StrNew(st);
|
||||
Free(st);
|
||||
break;
|
||||
case LK_BIBLE_FIND:
|
||||
res=StrNew(BIBLE_FILENAME,mem_task);
|
||||
break;
|
||||
}
|
||||
Free(filename);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
#help_index "DolDoc/Misc"
|
||||
|
||||
U8 captured_macro_name[STR_LEN];
|
||||
StrCpy(captured_macro_name,"Test");
|
||||
|
||||
I64 sys_macro_repeat_n=1;
|
||||
|
||||
U0 SysMacroStripKey(CJob *macro_head,I64 arg1,I64 arg2)
|
||||
{
|
||||
CJob *tmpc,*tmpc1;
|
||||
tmpc=macro_head->next;
|
||||
while (tmpc!=macro_head) {
|
||||
tmpc1=tmpc->next;
|
||||
if (tmpc->job_code==JOBT_MSG &&
|
||||
(tmpc->msg_code==MSG_KEY_DOWN || tmpc->msg_code==MSG_KEY_UP ||
|
||||
tmpc->msg_code==MSG_KEY_DOWN_UP) &&
|
||||
arg1 && tmpc->aux1==arg1 || !arg1 && tmpc->aux2==arg2) {
|
||||
QueRem(tmpc);
|
||||
JobDel(tmpc);
|
||||
}
|
||||
tmpc=tmpc1;
|
||||
}
|
||||
}
|
||||
|
||||
#define MT_NULL 0
|
||||
#define MT_MSG 1
|
||||
#define MT_CHAR 2
|
||||
|
||||
class CMacroTmp
|
||||
{
|
||||
CMacroTmp *next,*last;
|
||||
I64 type;
|
||||
U8 buf[STR_LEN];
|
||||
};
|
||||
|
||||
CMacroTmp *Cmd2MT(CJob *tmpc)
|
||||
{
|
||||
U8 buf[8];
|
||||
CMacroTmp *tmpmt=CAlloc(sizeof(CMacroTmp));
|
||||
if (Bt(char_bmp_macro,tmpc->aux1) && tmpc->msg_code==MSG_KEY_DOWN) {
|
||||
tmpmt->type=MT_CHAR;
|
||||
buf[0]=tmpc->aux1;
|
||||
buf[1]=0;
|
||||
StrPrint(tmpmt->buf,"%Q",buf);
|
||||
} else {
|
||||
tmpmt->type=MT_MSG;
|
||||
StrPrint(tmpmt->buf,"Msg(0x%X,0x%X,0x%X);",
|
||||
tmpc->msg_code,tmpc->aux1,tmpc->aux2);
|
||||
}
|
||||
return tmpmt;
|
||||
}
|
||||
|
||||
U8 *SysMacro2Str(CJob *macro_head)
|
||||
{
|
||||
CJob *tmpc;
|
||||
I64 cnt=1; //terminating zero
|
||||
U8 *ptr,*m;
|
||||
CMacroTmp *tmpmt,*tmpmt1,head;
|
||||
LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
|
||||
|
||||
QueInit(&head);
|
||||
head.type=MT_NULL;
|
||||
tmpc=macro_head->next;
|
||||
while (tmpc!=macro_head) {
|
||||
tmpmt=Cmd2MT(tmpc);
|
||||
QueIns(tmpmt,head.last);
|
||||
cnt+=StrLen(tmpmt->buf);
|
||||
if (tmpmt->type==MT_CHAR) {
|
||||
if (tmpmt->last->type!=MT_CHAR)
|
||||
cnt+=StrLen("\"");
|
||||
if (tmpmt->next->type!=MT_CHAR)
|
||||
cnt+=StrLen("\";");
|
||||
}
|
||||
tmpc=tmpc->next;
|
||||
}
|
||||
|
||||
m=MAlloc(cnt);
|
||||
ptr=m;
|
||||
|
||||
tmpmt=head.next;
|
||||
while (tmpmt!=&head) {
|
||||
tmpmt1=tmpmt->next;
|
||||
if (tmpmt->type==MT_MSG) {
|
||||
StrCpy(ptr, tmpmt->buf);
|
||||
ptr+=StrLen(tmpmt->buf);
|
||||
} else {
|
||||
if (tmpmt->last->type!=MT_CHAR) {
|
||||
StrCpy(ptr, "\"");
|
||||
ptr+=StrLen("\"");
|
||||
}
|
||||
StrCpy(ptr,tmpmt->buf);
|
||||
ptr+=StrLen(tmpmt->buf);
|
||||
if (tmpmt->next->type!=MT_CHAR) {
|
||||
StrCpy(ptr, "\";");
|
||||
ptr+=StrLen("\";");
|
||||
}
|
||||
}
|
||||
Free(tmpmt);
|
||||
tmpmt=tmpmt1;
|
||||
}
|
||||
*ptr=0;
|
||||
return m;
|
||||
}
|
||||
|
||||
U0 PlaySysMacro(I64 n=1)
|
||||
{
|
||||
CTask *task=sys_focus_task;
|
||||
U8 *m;
|
||||
if (TaskValidate(task)) {
|
||||
LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
|
||||
m=SysMacro2Str(&sys_macro_head);
|
||||
while (n-- && TaskValidate(task)) {
|
||||
if (task==Fs)
|
||||
InStr("%s",m);
|
||||
else
|
||||
XTalkStrWait(task,"%s",m);
|
||||
}
|
||||
Free(m);
|
||||
}
|
||||
}
|
||||
|
||||
U0 EdInsCapturedMacro()
|
||||
{
|
||||
U8 *st=SysMacro2Str(&sys_macro_head);
|
||||
if (sys_focus_task) {
|
||||
XTalk(sys_focus_task,"$$MA+LIS,T=\"%s\",LM=\"%$$Q\"$$",
|
||||
captured_macro_name,st);
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
|
||||
#define SM_RECORD 0
|
||||
#define SM_INS 1
|
||||
#define SM_PLAY 2
|
||||
#define SM_REPEAT_N 3
|
||||
#define SM_STOP 4
|
||||
|
||||
I64 PopUpMacroMenu()
|
||||
{
|
||||
I64 res=0;
|
||||
U8 buf[STR_LEN];
|
||||
CJob *tmpc;
|
||||
CDoc *doc=DocNew;
|
||||
CDocEntry *doc_e=DocPrint(doc,"$$DA-P,LEN=STR_LEN-1,A=\"Name:%%s\"$$");
|
||||
doc_e->data=captured_macro_name;
|
||||
DocDataFmt(doc,doc_e);
|
||||
|
||||
doc_e=DocPrint(doc,"\n$$DA,A=\"Repeat N:%%d\"$$");
|
||||
doc_e->data=&sys_macro_repeat_n;
|
||||
DocDataFmt(doc,doc_e);
|
||||
|
||||
DocPrint(doc,"\n"
|
||||
"$$CM+LX,1,3$$$$BT,\"RECORD\",LE=SM_RECORD$$"
|
||||
"$$CM+LX,17,0$$$$BT,\"INSERT\",LE=SM_INS$$"
|
||||
"$$CM+LX,1,3$$$$BT,\"PLAY\",LE=SM_PLAY$$"
|
||||
"$$CM+LX,17,0$$$$BT,\"REPEAT N\",LE=SM_REPEAT_N$$"
|
||||
"$$CM+LX,1,3$$$$BT,\"STOP\",LE=SM_STOP$$"
|
||||
"$$CM+LX,17,0$$$$BT,\"CANCEL\",LE=DOCM_CANCEL$$"
|
||||
"\n\n\n$$GREEN$$SHIFT-F2$$FG$$ will play macro.\n");
|
||||
doc->flags|=DOCF_SIZE_MIN | DOCF_FORM;
|
||||
StrPrint(buf,"DocMenu(%d);",doc);
|
||||
sys_macro_task=Spawn(&SrvCmdLine,NULL,"Macro Popup",,Fs);
|
||||
Fs->popup_task=sys_macro_task;
|
||||
LBts(&sys_macro_task->display_flags,DISPLAYf_WIN_ON_TOP);
|
||||
tmpc=TaskExe(sys_macro_task,Fs,buf,
|
||||
1<<JOBf_WAKE_MASTER|1<<JOBf_FOCUS_MASTER);
|
||||
JobResScan(tmpc,&res);
|
||||
Fs->popup_task=NULL;
|
||||
Kill(sys_macro_task);
|
||||
sys_macro_task=NULL;
|
||||
DocDataScan(doc,doc_e);
|
||||
DocDel(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 MacroTask(I64)
|
||||
{
|
||||
I64 i;
|
||||
StrCpy(captured_macro_name,"Click Here");
|
||||
sys_macro_repeat_n=1;
|
||||
do {
|
||||
i=PopUpMacroMenu;
|
||||
WinRefocus(sys_focus_task);
|
||||
switch (i) {
|
||||
case SM_RECORD:
|
||||
LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
|
||||
QueDel(&sys_macro_head,TRUE);
|
||||
LBts(&sys_semas[SEMA_RECORD_MACRO],0);
|
||||
break;
|
||||
case SM_PLAY:
|
||||
PlaySysMacro;
|
||||
break;
|
||||
case SM_REPEAT_N:
|
||||
PlaySysMacro(sys_macro_repeat_n);
|
||||
break;
|
||||
case SM_STOP:
|
||||
LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
|
||||
break;
|
||||
case SM_INS:
|
||||
LBtr(&sys_semas[SEMA_RECORD_MACRO],0);
|
||||
EdInsCapturedMacro;
|
||||
break;
|
||||
}
|
||||
} while (i>=0);
|
||||
}
|
||||
|
||||
U0 EdMacroUtil()
|
||||
{
|
||||
if (!sys_macro_task)
|
||||
Spawn(&MacroTask,NULL,"Macro");
|
||||
}
|
||||
@@ -0,0 +1,385 @@
|
||||
#help_index "DolDoc"
|
||||
|
||||
public Bool DocLock(CDoc *doc)
|
||||
{//Make this task have exclusive access to this doc.
|
||||
if (!Bt(&doc->locked_flags,DOClf_LOCKED) || doc->owning_task!=Fs) {
|
||||
while (LBts(&doc->locked_flags,DOClf_LOCKED))
|
||||
Yield;
|
||||
if (doc->owning_task!=Fs)
|
||||
LBEqu(&doc->flags,DOCf_BREAK_UNLOCKED,BreakLock(Fs));
|
||||
doc->owning_task=Fs;
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public Bool DocUnlock(CDoc *doc)
|
||||
{//Release exclusive lock on access to doc.
|
||||
Bool unlock_break;
|
||||
if (Bt(&doc->locked_flags,DOClf_LOCKED) && doc->owning_task==Fs) {
|
||||
doc->owning_task=0;
|
||||
unlock_break=Bt(&doc->flags,DOCf_BREAK_UNLOCKED);
|
||||
LBtr(&doc->locked_flags,DOClf_LOCKED);
|
||||
if (unlock_break)
|
||||
BreakUnlock(Fs);
|
||||
return TRUE;
|
||||
} else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
Bool IsEditableText(CDocEntry *doc_e)
|
||||
{
|
||||
if (doc_e->type_u8==DOCT_TEXT&&!(doc_e->de_flags&DOCEG_DONT_EDIT))
|
||||
return TRUE;
|
||||
else
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
CDocEntry *DocEntryNewBase(CDoc *doc,I64 type,I64 de_flags=0,
|
||||
I64 x=0,I64 y=0,I64 page_line_num=0)
|
||||
{//See also $LK,"MAllocIdent",A="FF:::/Adam/DolDoc/DocRecalc.HC,MAllocIdent"$ and $MA-X+PU,"CDocEntry",LM="F(\"sizeof(CDocEntry)\");View;"$.
|
||||
CDocEntry *res=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
|
||||
res->type=type;
|
||||
res->de_flags=de_flags|doldoc.dft_de_flags[type.u8[0]];
|
||||
res->x=x;
|
||||
res->y=y;
|
||||
res->page_line_num=page_line_num;
|
||||
return res;
|
||||
}
|
||||
|
||||
CDocEntry *DocEntryNewTag(CDoc *doc,CDocEntry *doc_ce,U8 *tag)
|
||||
{
|
||||
I64 l=StrLen(tag);
|
||||
CDocEntry *res=DocEntryNewBase(doc,doc_ce->type,doc_ce->de_flags,
|
||||
doc_ce->x,doc_ce->y,doc_ce->page_line_num);
|
||||
res->de_flags=doc_ce->de_flags; //Override
|
||||
res->max_col=l;
|
||||
res->tag=MAlloc(l+1,doc->mem_task);
|
||||
MemCpy(res->tag,tag,l+1);
|
||||
MemCpy(&res->settings,&doc_ce->settings,sizeof(CDocSettings));
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 DocEntryDel(CDoc *doc,CDocEntry *doc_e)
|
||||
{//Free entry and all parts of entry.
|
||||
if (!doc || doc==doc_e)
|
||||
RawPrint(3000,"DocEntryDel");
|
||||
else {
|
||||
if (doc->cur_entry==doc_e)
|
||||
doc->cur_entry=doc_e->next;
|
||||
QueRem(doc_e);
|
||||
if (doc_e->de_flags & DOCEF_TAG)
|
||||
Free(doc_e->tag);
|
||||
if (doc_e->de_flags & DOCEF_AUX_STR)
|
||||
Free(doc_e->aux_str);
|
||||
if (doc_e->de_flags & DOCEF_DEFINE)
|
||||
Free(doc_e->define_str);
|
||||
if (doc_e->de_flags & DOCEF_HTML_LINK)
|
||||
Free(doc_e->html_link);
|
||||
if (doc_e->de_flags & DOCEF_LEFT_MACRO)
|
||||
Free(doc_e->left_macro);
|
||||
if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
|
||||
Free(doc_e->right_macro);
|
||||
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
|
||||
Free(doc_e->bin_ptr_link);
|
||||
if (doc_e->de_flags & DOCEF_HAS_BIN)
|
||||
DocBinDel(doc,doc_e->bin_data);
|
||||
if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
|
||||
Free(doc_e->data);
|
||||
Free(doc_e);
|
||||
}
|
||||
}
|
||||
|
||||
public I64 DocEntrySize(CDoc *,CDocEntry *doc_e)
|
||||
{//Mem size of entry and all parts.
|
||||
I64 res;
|
||||
if (!doc_e) return 0;
|
||||
res=MSize2(doc_e);
|
||||
if (doc_e->de_flags & DOCEF_TAG)
|
||||
res+=MSize2(doc_e->tag);
|
||||
if (doc_e->de_flags & DOCEF_AUX_STR)
|
||||
res+=MSize2(doc_e->aux_str);
|
||||
if (doc_e->de_flags & DOCEF_DEFINE)
|
||||
res+=MSize2(doc_e->define_str);
|
||||
if (doc_e->de_flags & DOCEF_HTML_LINK)
|
||||
res+=MSize2(doc_e->html_link);
|
||||
if (doc_e->de_flags & DOCEF_LEFT_MACRO)
|
||||
res+=MSize2(doc_e->left_macro);
|
||||
if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
|
||||
res+=MSize2(doc_e->right_macro);
|
||||
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
|
||||
res+=MSize2(doc_e->bin_ptr_link);
|
||||
if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
|
||||
res+=MSize2(doc_e->data);
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 DocUndoDel(CDoc *,CDocUndo *u)
|
||||
{
|
||||
Free(u->body);
|
||||
Free(u);
|
||||
}
|
||||
|
||||
U0 DocUndoCntSet(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocUndo *u=doc->undo_head.next;
|
||||
doc->undo_cnt=0;
|
||||
while (u!=&doc->undo_head) {
|
||||
doc->undo_cnt++;
|
||||
u=u->next;
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e)
|
||||
{//Make copy of entry and all parts of entry.
|
||||
CDocEntry *doc_ne;
|
||||
CDocBin *tmpb;
|
||||
CTask *task=doc->mem_task;
|
||||
doc_ne=MAllocIdent(doc_e,task);
|
||||
doc_ne->next=doc_ne;
|
||||
doc_ne->last=doc_ne;
|
||||
if (doc_e->de_flags & DOCEF_TAG)
|
||||
doc_ne->tag=MAllocIdent(doc_e->tag,task);
|
||||
if (doc_e->de_flags & DOCEF_AUX_STR)
|
||||
doc_ne->aux_str=MAllocIdent(doc_e->aux_str,task);
|
||||
if (doc_e->de_flags & DOCEF_DEFINE)
|
||||
doc_ne->define_str=MAllocIdent(doc_e->define_str,task);
|
||||
if (doc_e->de_flags & DOCEF_HTML_LINK)
|
||||
doc_ne->html_link=MAllocIdent(doc_e->html_link,task);
|
||||
if (doc_e->de_flags & DOCEF_LEFT_MACRO)
|
||||
doc_ne->left_macro=MAllocIdent(doc_e->left_macro,task);
|
||||
if (doc_e->de_flags & DOCEF_RIGHT_MACRO)
|
||||
doc_ne->right_macro=MAllocIdent(doc_e->right_macro,task);
|
||||
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
|
||||
doc_ne->bin_ptr_link=MAllocIdent(doc_e->bin_ptr_link,task);
|
||||
if (doc_e->de_flags & DOCEF_HAS_BIN) {
|
||||
tmpb=MAllocIdent(doc_e->bin_data,task);
|
||||
tmpb->data=MAllocIdent(doc_e->bin_data->data,task);
|
||||
doc_ne->bin_num=doc->cur_bin_num;
|
||||
tmpb->num=doc->cur_bin_num++;
|
||||
doc_ne->bin_data=tmpb;
|
||||
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
|
||||
tmpb->tag=StrNew(doc_e->tag,task);
|
||||
else
|
||||
tmpb->tag=NULL;
|
||||
QueIns(tmpb,doc->bin_head.last);
|
||||
}
|
||||
if (doc_e->de_flags & DOCEF_REMALLOC_DATA)
|
||||
doc_ne->data=MAllocIdent(doc_e->data,task);
|
||||
return doc_ne;
|
||||
}
|
||||
|
||||
U0 DocRemSoftNewLines(CDoc *doc=NULL,CDocEntry *doc_e=NULL)
|
||||
{
|
||||
CDocEntry *doc_e2,*saved_ll=doc_e;
|
||||
Bool unlock;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
unlock=DocLock(doc);
|
||||
if (!doc_e) doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
doc_e2=doc_e->next;
|
||||
if (doc_e->type_u8==DOCT_SOFT_NEW_LINE) {
|
||||
if (doc->cur_entry==doc_e) {
|
||||
doc->cur_entry=doc_e2;
|
||||
doc->cur_col=doc->cur_entry->min_col;
|
||||
}
|
||||
DocEntryDel(doc,doc_e);
|
||||
} else if (saved_ll && doc_e->type_u8==DOCT_NEW_LINE)
|
||||
break;
|
||||
doc_e=doc_e2;
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 DocInsEntry(CDoc *doc,CDocEntry *doc_e)
|
||||
{//Insert entry into doc, updating its vals.
|
||||
U8 *dst;
|
||||
Bool unlock=DocLock(doc);
|
||||
CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
|
||||
|
||||
doc_e->x=doc_ce->x;
|
||||
doc_e->y=doc_ce->y;
|
||||
doc_e->page_line_num=doc_ce->page_line_num;
|
||||
MemCpy(&doc_e->settings,&doc_ce->settings,sizeof(CDocSettings));
|
||||
if (doc->cur_col>0 &&
|
||||
doc_ce->type_u8==DOCT_TEXT &&
|
||||
!(doc_ce->de_flags&(DOCEF_TAG_CB|DOCEF_DEFINE|DOCEF_AUX_STR|
|
||||
DOCEF_HTML_LINK|DOCEF_BIN_PTR_LINK)) &&
|
||||
doc->cur_col<doc_ce->max_col) {
|
||||
dst=doc_ce->tag+doc->cur_col;
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
|
||||
*dst=0;
|
||||
doc_ne->type=DOCT_TEXT|doc_ce->type&0xFFFFFF00;
|
||||
doc_ce->max_col=doc->cur_col;
|
||||
QueIns(doc_ne,doc_ce);
|
||||
doc->cur_col=0;
|
||||
doc_ce=doc_ne;
|
||||
}
|
||||
if (doc_ce->type_u8==DOCT_TEXT && doc->cur_col>=doc_ce->max_col) {
|
||||
QueIns(doc_e,doc_ce);
|
||||
doc->cur_entry=doc_e->next;
|
||||
} else {
|
||||
QueIns(doc_e,doc_ce->last);
|
||||
doc->cur_entry=doc_ce;
|
||||
}
|
||||
doc->cur_col=doc->cur_entry->min_col;
|
||||
DocRemSoftNewLines(doc,doc->cur_entry);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 DocRst(CDoc *doc,Bool is_old)
|
||||
{//Del all entries and set doc to dfts.
|
||||
Bool unlock;
|
||||
CDocEntry *doc_e,*doc_e2;
|
||||
CDocUndo *u,*u8;
|
||||
CDocSettings *s;
|
||||
CDocBin *b,*b1;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
unlock=DocLock(doc);
|
||||
if (is_old) {
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
doc_e2=doc_e->next;
|
||||
DocEntryDel(doc,doc_e);
|
||||
doc_e=doc_e2;
|
||||
}
|
||||
u=doc->undo_head.next;
|
||||
while (u!=&doc->undo_head) {
|
||||
u8=u->next;
|
||||
DocUndoDel(doc,u);
|
||||
u=u8;
|
||||
}
|
||||
b=doc->bin_head.next;
|
||||
while (b!=&doc->bin_head) {
|
||||
b1=b->next;
|
||||
QueRem(b);
|
||||
Free(b->data);
|
||||
Free(b);
|
||||
b=b1;
|
||||
}
|
||||
}
|
||||
//Check $LK,"DocInsDoc",A="MN:DocInsDoc"$
|
||||
doc->flags&=DOCF_BREAK_UNLOCKED;
|
||||
doc->head.next=doc->head.last=doc;
|
||||
QueInit(&doc->bin_head);
|
||||
QueInit(&doc->undo_head);
|
||||
doc->undo_head.time_stamp=0;
|
||||
doc->undo_cnt=0;
|
||||
doc->cur_bin_num=1;
|
||||
doc->dollar_buf_ptr=0;
|
||||
doc->cmd_U8=CH_SPACE;
|
||||
doc->page_line_num=0;
|
||||
doc->best_d=I64_MAX;
|
||||
|
||||
s=&doc->settings_head;
|
||||
s->left_margin=DOC_DFT;
|
||||
s->right_margin=DOC_DFT;
|
||||
s->indent=0;
|
||||
s->page_len=66;
|
||||
s->header=DOC_DFT;
|
||||
s->footer=DOC_DFT;
|
||||
s->state=DOCSS_NORMAL;
|
||||
s->comment_depth=0;
|
||||
s->paren_depth=0;
|
||||
s->brace_depth=0;
|
||||
s->shifted_x=0;
|
||||
s->shifted_y=0;
|
||||
s->cur_text_attr=s->dft_text_attr=DOC_ATTR_DFT_TEXT;
|
||||
|
||||
doc_e=&doc->head;
|
||||
doc_e->type=DOCT_ERROR;
|
||||
doc_e->de_flags=0;
|
||||
doc_e->x=0;
|
||||
doc_e->y=0;
|
||||
doc_e->min_col=0;
|
||||
doc_e->max_col=0;
|
||||
doc_e->page_line_num=doc->page_line_num;
|
||||
MemCpy(&doc_e->settings,s,sizeof(CDocSettings));
|
||||
|
||||
DocTop(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 DocDel(CDoc *doc)
|
||||
{//Free entire doc and entries.
|
||||
if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return;
|
||||
DocLock(doc);
|
||||
doc->doc_signature=0;
|
||||
DocRst(doc,TRUE);
|
||||
Free(doc->find_replace);
|
||||
Free(doc->dollar_buf);
|
||||
DocUnlock(doc);
|
||||
Free(doc);
|
||||
}
|
||||
|
||||
public I64 DocSize(CDoc *doc)
|
||||
{//Mem size of doc and all its entries.
|
||||
Bool unlock;
|
||||
CDocEntry *doc_e;
|
||||
CDocUndo *u;
|
||||
CDocBin *b;
|
||||
I64 res=0;
|
||||
|
||||
if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return 0;
|
||||
unlock=DocLock(doc);
|
||||
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
res+=DocEntrySize(doc,doc_e);
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
|
||||
u=doc->undo_head.next;
|
||||
while (u!=&doc->undo_head) {
|
||||
res+=MSize2(u->body);
|
||||
res+=MSize2(u);
|
||||
u=u->next;
|
||||
}
|
||||
|
||||
b=doc->bin_head.next;
|
||||
while (b!=&doc->bin_head) {
|
||||
res+=MSize2(b->data);
|
||||
res+=MSize2(b);
|
||||
b=b->next;
|
||||
}
|
||||
|
||||
res+=MSize2(doc->find_replace);
|
||||
res+=MSize2(doc->dollar_buf);
|
||||
res+=MSize2(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "DolDoc"
|
||||
public CDoc *DocNew(U8 *filename=NULL,CTask *task=NULL)
|
||||
{//MAlloc new $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.DD"$. (Begin a new doc.)
|
||||
CDoc *doc;
|
||||
if (!task) task=Fs;
|
||||
doc=CAlloc(sizeof(CDoc),task);
|
||||
if (filename)
|
||||
StrCpy(doc->filename.name,filename);
|
||||
else
|
||||
StrCpy(doc->filename.name,blkdev.tmp_filename);
|
||||
doc->find_replace=CAlloc(sizeof(CEdFindText),task);
|
||||
doc->find_replace->scan_fwd=TRUE;
|
||||
doc->find_replace->match_case=TRUE;
|
||||
doc->find_replace->pmt=TRUE;
|
||||
doc->left_click_link=&EdLeftClickLink;
|
||||
doc->dollar_buf_size=84;
|
||||
doc->dollar_buf=MAlloc(doc->dollar_buf_size,task);
|
||||
doc->max_entries=I64_MAX;
|
||||
doc->win_task=task;
|
||||
doc->mem_task=task;
|
||||
DocRst(doc,FALSE);
|
||||
doc->doc_signature=DOC_SIGNATURE_VAL;
|
||||
return doc;
|
||||
}
|
||||
@@ -0,0 +1,611 @@
|
||||
#help_index "DolDoc"
|
||||
|
||||
I64 PrsDocFlagSingle(CCmpCtrl *cc,I64 *_de_flags,U32 *_type,Bool turn_on)
|
||||
{
|
||||
I64 res=-1;
|
||||
CHashGeneric *tmph;
|
||||
if (cc->token==TK_IDENT &&
|
||||
(tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_FLAG))) {
|
||||
res=tmph->user_data0;
|
||||
if (res<64) {
|
||||
BEqu(_de_flags,res,turn_on);
|
||||
switch (res) {
|
||||
case DOCEf_BLINK:
|
||||
case DOCEf_INVERT:
|
||||
case DOCEf_UNDERLINE:
|
||||
case DOCEf_SEL:
|
||||
BEqu(_type,res,turn_on);
|
||||
break;
|
||||
}
|
||||
}
|
||||
Lex(cc); //skip flag
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
I64 PrsDocFlags(CCmpCtrl *cc,I64 *_de_flags,U32 *_type)
|
||||
{
|
||||
I64 res=-1;
|
||||
Bool turn_on;
|
||||
while (TRUE) {
|
||||
if (cc->token=='+')
|
||||
turn_on=TRUE;
|
||||
else if (cc->token=='-')
|
||||
turn_on=FALSE;
|
||||
else
|
||||
break;
|
||||
Lex(cc);
|
||||
res=PrsDocFlagSingle(cc,_de_flags,_type,turn_on);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U8 *Doc2PlainText(CDoc *doc,CDocEntry *doc_e)
|
||||
{//TODO: break strs
|
||||
I64 i,j,attr=doc_e->attr,
|
||||
t1,f1,de_flags,type;
|
||||
U8 *buf,*buf2;
|
||||
|
||||
if (doc_e->type_u8==DOCT_FOREGROUND &&
|
||||
doc->flags&DOCF_COLOR_NAMES && 0<=attr<COLORS_NUM) {
|
||||
buf=StrNew(DefineSub(attr,"ST_COLORS"));
|
||||
attr=DOC_DFT;
|
||||
} else
|
||||
buf=StrNew(DefineSub(doc_e->type_u8,"ST_DOC_CMDS"));
|
||||
if (doc_e->type_u8!=DOCT_ERROR) {
|
||||
f1=doldoc.dft_de_flags[doc_e->type_u8];
|
||||
t1=doc_e->type_u8|doldoc.dft_type_flags[doc_e->type_u8];
|
||||
|
||||
de_flags=doc_e->de_flags&~(DOCG_BL_IV_UL|DOCEF_SEL|
|
||||
DOCEF_HIGHLIGHT|DOCEF_WORD_WRAP|DOCEF_SKIP|DOCEF_FILTER_SKIP);
|
||||
for (i=0;i<DOCEf_FLAGS_NUM;i++)
|
||||
if (Bt(&f1,i)!=Bt(&de_flags,i)) {
|
||||
if (Bt(&de_flags,i)) {
|
||||
if (!(1<<i&DOCEG_HAS_ARG)) {
|
||||
buf2=MStrPrint("%s+%Z",buf,i,"ST_DOC_FLAGS");
|
||||
Free(buf); buf=buf2;
|
||||
}
|
||||
} else {
|
||||
buf2=MStrPrint("%s-%Z",buf,i,"ST_DOC_FLAGS");
|
||||
Free(buf); buf=buf2;
|
||||
}
|
||||
}
|
||||
type=doc_e->type&~DOCET_SEL;
|
||||
for (i=DOCEt_BLINK;i<=DOCEt_UNDERLINE;i++)
|
||||
if (Bt(&t1,i)!=Bt(&type,i)) {
|
||||
if (Bt(&type,i))
|
||||
buf2=MStrPrint("%s+%Z",buf,i,"ST_DOC_FLAGS");
|
||||
else
|
||||
buf2=MStrPrint("%s-%Z",buf,i,"ST_DOC_FLAGS");
|
||||
Free(buf); buf=buf2;
|
||||
}
|
||||
buf2=MStrPrint("%s,",buf);
|
||||
Free(buf); buf=buf2;
|
||||
switch [doc_e->type_u8] {
|
||||
case DOCT_HEX_ED:
|
||||
buf2=MStrPrint("%s%d,",buf,doc_e->len);
|
||||
Free(buf); buf=buf2;
|
||||
buf2=MStrPrint("%s%d,",buf,doc_e->hex_ed_width);
|
||||
Free(buf); buf=buf2;
|
||||
break;
|
||||
case DOCT_FOREGROUND:
|
||||
case DOCT_BACKGROUND:
|
||||
case DOCT_DFT_FOREGROUND:
|
||||
case DOCT_DFT_BACKGROUND:
|
||||
if (doc->flags&DOCF_COLOR_NAMES && 0<=attr<COLORS_NUM) {
|
||||
buf2=MStrPrint("%s%Z,",buf,doc_e->attr,"ST_COLORS");
|
||||
Free(buf); buf=buf2;
|
||||
break;
|
||||
}
|
||||
case DOCT_PAGE_LEN:
|
||||
case DOCT_LEFT_MARGIN:
|
||||
case DOCT_RIGHT_MARGIN:
|
||||
case DOCT_HEADER:
|
||||
case DOCT_FOOTER:
|
||||
case DOCT_INDENT:
|
||||
case DOCT_WORD_WRAP:
|
||||
case DOCT_HIGHLIGHT:
|
||||
case DOCT_BLINK:
|
||||
case DOCT_INVERT:
|
||||
case DOCT_UNDERLINE:
|
||||
case DOCT_SHIFTED_X:
|
||||
case DOCT_SHIFTED_Y:
|
||||
if (attr!=DOC_DFT) {
|
||||
buf2=MStrPrint("%s%d,",buf,doc_e->attr);
|
||||
Free(buf); buf=buf2;
|
||||
}
|
||||
case DOCT_TYPES_NUM-1: //nobound switch
|
||||
break;
|
||||
}
|
||||
de_flags=doc_e->de_flags & DOCEG_HAS_ARG;
|
||||
while (de_flags) {
|
||||
j=Bsf(de_flags);
|
||||
Btr(&de_flags,j);
|
||||
switch [j] {
|
||||
case DOCEf_TAG:
|
||||
if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_MACRO &&
|
||||
(doc_e->de_flags&DOCEF_LEFT_MACRO &&
|
||||
!StrCmp(doc_e->tag,doc_e->left_macro) ||
|
||||
doc_e->de_flags&DOCEF_RIGHT_MACRO &&
|
||||
!StrCmp(doc_e->tag,doc_e->right_macro)) ||
|
||||
doc_e->de_flags&DOCEF_LST && !StrCmp(doc_e->tag,"[]") &&
|
||||
doc_e->de_flags&DOCEF_DEFINE) {
|
||||
buf2=buf;
|
||||
buf=NULL;
|
||||
} else {
|
||||
if (doc_e->type_u8==DOCT_CHECK_BOX) {
|
||||
if (StrLen(doc_e->tag)>=4)
|
||||
buf2=doc_e->tag+4;
|
||||
else
|
||||
buf2="";
|
||||
} else if (doc_e->de_flags & DOCEF_TREE) {
|
||||
if (StrLen(doc_e->tag)>=3)
|
||||
buf2=doc_e->tag+3;
|
||||
else
|
||||
buf2="";
|
||||
} else
|
||||
buf2=doc_e->tag;
|
||||
if (Bt(&doldoc.dft_de_flags[doc_e->type_u8],DOCEf_TAG))
|
||||
buf2=MStrPrint("%s\"%$$Q\",",buf,buf2);
|
||||
else
|
||||
buf2=MStrPrint("%sT=\"%$$Q\",",buf,buf2);
|
||||
}
|
||||
break;
|
||||
case DOCEf_LEN:
|
||||
buf2=MStrPrint("%sLEN=%d,",buf,doc_e->len);
|
||||
break;
|
||||
case DOCEf_AUX_STR:
|
||||
buf2=MStrPrint("%sA=\"%$$Q\",",buf,doc_e->aux_str);
|
||||
break;
|
||||
case DOCEf_DEFINE:
|
||||
buf2=MStrPrint("%sD=\"%$$Q\",",buf,doc_e->define_str);
|
||||
break;
|
||||
case DOCEf_HTML_LINK:
|
||||
buf2=MStrPrint("%sHTML=\"%$$Q\",",buf,doc_e->html_link);
|
||||
break;
|
||||
case DOCEf_LEFT_EXP:
|
||||
buf2=MStrPrint("%sLE=%d,",buf,doc_e->left_exp);
|
||||
break;
|
||||
case DOCEf_LEFT_MACRO:
|
||||
buf2=MStrPrint("%sLM=\"%$$Q\",",buf,doc_e->left_macro);
|
||||
break;
|
||||
case DOCEf_RIGHT_EXP:
|
||||
buf2=MStrPrint("%sRE=%d,",buf,doc_e->right_exp);
|
||||
break;
|
||||
case DOCEf_RIGHT_MACRO:
|
||||
buf2=MStrPrint("%sRM=\"%$$Q\",",buf,doc_e->right_macro);
|
||||
break;
|
||||
case DOCEf_HAS_BIN:
|
||||
buf2=MStrPrint("%sBI=%d,",buf,doc_e->bin_num);
|
||||
break;
|
||||
case DOCEf_BIN_PTR_LINK:
|
||||
buf2=MStrPrint("%sBP=\"%$$Q\",",buf,doc_e->bin_ptr_link);
|
||||
break;
|
||||
case DOCEf_RAW_TYPE:
|
||||
if (doc_e->type_u8==DOCT_CHECK_BOX&&doc_e->raw_type!=RT_I8 ||
|
||||
doc_e->type_u8!=DOCT_CHECK_BOX&&doc_e->raw_type!=RT_I64)
|
||||
buf2=MStrPrint("%sRT=%Z,",buf,doc_e->raw_type,"ST_RAW_TYPES");
|
||||
break;
|
||||
case DOCEf_SHIFTED_X:
|
||||
j=doc_e->type.u16[1]&0x1F;
|
||||
if (j&0x10) j|=0xFFFFFFF0;
|
||||
buf2=MStrPrint("%sSX=%d,",buf,j);
|
||||
break;
|
||||
case DOCEf_SHIFTED_Y:
|
||||
j=doc_e->type>>21 &0x1F;
|
||||
if (j&0x10) j|=0xFFFFFFF0;
|
||||
buf2=MStrPrint("%sSY=%d,",buf,j);
|
||||
break;
|
||||
case DOCEf_SCROLLING_X:
|
||||
buf2=MStrPrint("%sSCX=%d,",buf,doc_e->scroll_len);
|
||||
break;
|
||||
case DOCEf_USER_DATA:
|
||||
buf2=MStrPrint("%sU=0x%X,",buf,doc_e->user_data);
|
||||
break;
|
||||
case DOCEf_FLAGS_NUM-1: //nobound switch
|
||||
break;
|
||||
}
|
||||
Free(buf); buf=buf2;
|
||||
}
|
||||
buf[StrLen(buf)-1]=0; //Kill last comma
|
||||
}
|
||||
buf2=StrNew(buf,doc->mem_task); //exact allocation
|
||||
Free(buf);
|
||||
return buf2;
|
||||
}
|
||||
|
||||
CDocEntry *PrsDollarCmd(CDoc *doc,U8 *st)
|
||||
{//Uses $LK-UL,"Lex",A="MN:Lex"$() to parse a string and make Doc entries.
|
||||
I64 i,j,de_flags,processed_flags,attr=DOC_DFT;
|
||||
U8 *ptr,*st2;
|
||||
CDocEntry *doc_e=NULL;
|
||||
CHashGeneric *tmph;
|
||||
CCmpCtrl *cc=CmpCtrlNew(st,CCF_DONT_FREE_BUF);
|
||||
CHashTable *old_hash_table_lst=cc->htc.hash_table_lst;
|
||||
try {
|
||||
cc->htc.hash_table_lst=NULL;
|
||||
if (Lex(cc)==TK_IDENT) {
|
||||
if (tmph=HashFind(cc->cur_str,doldoc.hash,DHT_DOC_CMD|DHT_COLOR)) {
|
||||
if (tmph->type&DHT_DOC_CMD)
|
||||
i=tmph->user_data0;
|
||||
else {//DHT_COLOR
|
||||
i=DOCT_FOREGROUND;
|
||||
attr=tmph->user_data0;
|
||||
}
|
||||
} else
|
||||
goto pd_err;
|
||||
Lex(cc); //skip cmd code
|
||||
doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
|
||||
doc_e->type=i;
|
||||
doc_e->de_flags=doldoc.dft_de_flags[i];
|
||||
doc_e->type|=doldoc.dft_type_flags[i];
|
||||
doc_e->raw_type=RT_I64;
|
||||
doc_e->len=DOCE_LEN_DFT;
|
||||
j=PrsDocFlags(cc,&doc_e->de_flags,&doc_e->type);
|
||||
cc->htc.hash_table_lst=old_hash_table_lst;
|
||||
switch [i] {
|
||||
case DOCT_CHECK_BOX:
|
||||
doc_e->raw_type=RT_I8;
|
||||
break;
|
||||
case DOCT_HEX_ED:
|
||||
while (cc->token==',')
|
||||
Lex(cc);
|
||||
if (cc->token)
|
||||
doc_e->len=LexExpressionI64(cc);
|
||||
else
|
||||
goto pd_err;
|
||||
while (cc->token==',')
|
||||
Lex(cc);
|
||||
if (cc->token)
|
||||
doc_e->hex_ed_width=LexExpressionI64(cc);
|
||||
else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCT_PAGE_LEN:
|
||||
case DOCT_LEFT_MARGIN:
|
||||
case DOCT_RIGHT_MARGIN:
|
||||
case DOCT_HEADER:
|
||||
case DOCT_FOOTER:
|
||||
case DOCT_INDENT:
|
||||
case DOCT_FOREGROUND:
|
||||
case DOCT_BACKGROUND:
|
||||
case DOCT_DFT_FOREGROUND:
|
||||
case DOCT_DFT_BACKGROUND:
|
||||
case DOCT_WORD_WRAP:
|
||||
case DOCT_HIGHLIGHT:
|
||||
case DOCT_BLINK:
|
||||
case DOCT_INVERT:
|
||||
case DOCT_UNDERLINE:
|
||||
case DOCT_SHIFTED_X:
|
||||
case DOCT_SHIFTED_Y:
|
||||
while (cc->token==',')
|
||||
Lex(cc);
|
||||
if (cc->token)
|
||||
doc_e->attr=LexExpressionI64(cc);
|
||||
else
|
||||
doc_e->attr=attr;
|
||||
break;
|
||||
#assert DOCT_ERROR==DOCT_TYPES_NUM-1
|
||||
case DOCT_ERROR:
|
||||
goto pd_err;
|
||||
}
|
||||
|
||||
processed_flags=0;
|
||||
while (TRUE) {
|
||||
cc->htc.hash_table_lst=NULL;
|
||||
while (cc->token==',')
|
||||
Lex(cc);
|
||||
cc->htc.hash_table_lst=old_hash_table_lst;
|
||||
j=PrsDocFlagSingle(cc,&doc_e->de_flags,&doc_e->type,TRUE);
|
||||
if (!(de_flags=~processed_flags & doc_e->de_flags & DOCEG_HAS_ARG))
|
||||
break;
|
||||
if (cc->token=='=')
|
||||
Lex(cc);
|
||||
else
|
||||
j=Bsf(de_flags);
|
||||
if (j<0 || Bts(&processed_flags,j))
|
||||
goto pd_err;
|
||||
switch [j] {//TODO: Might check for expression errors
|
||||
case DOCEf_TAG:
|
||||
if (!doc_e->tag) {
|
||||
//If a $$MA,LM=""$$, Tag is filled when the LM is processed.
|
||||
//if doc_e->df_flags&DOCEF_LST,
|
||||
// Tag is filled when the Define is processed.
|
||||
//(The dft_flag1.tag calls this after.)
|
||||
if (cc->token==TK_STR) {
|
||||
st2=LexExtStr(cc);
|
||||
if (i==DOCT_CHECK_BOX) {
|
||||
st=MStrPrint("[X] %s",st2);
|
||||
Free(st2);
|
||||
doc_e->min_col=1;
|
||||
} else if (doc_e->de_flags & DOCEF_LST) {
|
||||
if (*st2!='[') {
|
||||
st=MStrPrint("[%s]",st2);
|
||||
Free(st2);
|
||||
} else
|
||||
st=st2;
|
||||
doc_e->min_col=1;
|
||||
} else if (doc_e->de_flags & DOCEF_TREE) {
|
||||
st=MStrPrint("+] %s",st2);
|
||||
Free(st2);
|
||||
doc_e->min_col=1;
|
||||
} else
|
||||
st=st2;
|
||||
doc_e->tag=StrNew(st,doc->mem_task);
|
||||
Free(st);
|
||||
} else
|
||||
goto pd_err;
|
||||
}
|
||||
break;
|
||||
case DOCEf_LEN:
|
||||
if (cc->token) {
|
||||
doc_e->len=LexExpression(cc);
|
||||
doc_e->de_flags&=~DOCEF_DFT_LEN;
|
||||
} else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_AUX_STR:
|
||||
if (cc->token==TK_STR) {
|
||||
st2=LexExtStr(cc);
|
||||
doc_e->aux_str=StrNew(st2,doc->mem_task);
|
||||
Free(st2);
|
||||
//$AN,"Anchor",A="DataTagWidth"$
|
||||
if (i==DOCT_DATA) { //See $LK,"DocForm",A="MN:DocForm"$()
|
||||
if (ptr=StrMatch(":",doc_e->aux_str))
|
||||
doc_e->min_col=ptr-doc_e->aux_str+1;
|
||||
doc_e->tag=MAlloc(doc_e->len+doc_e->min_col+2,
|
||||
doc->mem_task); //+2 because "_\0"
|
||||
}
|
||||
} else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_DEFINE:
|
||||
if (cc->token==TK_STR) {
|
||||
st2=LexExtStr(cc);
|
||||
doc_e->define_str=StrNew(st2,doc->mem_task);
|
||||
Free(st2);
|
||||
if (doc_e->de_flags&DOCEF_LST && !doc_e->tag)
|
||||
doc_e->tag=StrNew("[]",doc->mem_task);
|
||||
} else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_HTML_LINK:
|
||||
if (cc->token==TK_STR) {
|
||||
st2=LexExtStr(cc);
|
||||
doc_e->html_link=StrNew(st2,doc->mem_task);
|
||||
Free(st2);
|
||||
} else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_LEFT_EXP:
|
||||
if (cc->token)
|
||||
doc_e->left_exp=LexExpression(cc);
|
||||
else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_LEFT_MACRO:
|
||||
if (cc->token==TK_STR) {
|
||||
st2=LexExtStr(cc);
|
||||
doc_e->left_macro=StrNew(st2,doc->mem_task);
|
||||
Free(st2);
|
||||
if (i==DOCT_MACRO && !doc_e->tag)
|
||||
doc_e->tag=StrNew(doc_e->left_macro,doc->mem_task);
|
||||
} else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_RIGHT_EXP:
|
||||
if (cc->token)
|
||||
doc_e->right_exp=LexExpression(cc);
|
||||
else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_RIGHT_MACRO:
|
||||
if (cc->token==TK_STR) {
|
||||
st2=LexExtStr(cc);
|
||||
doc_e->right_macro=StrNew(st2,doc->mem_task);
|
||||
Free(st2);
|
||||
if (i==DOCT_MACRO && !doc_e->tag)
|
||||
doc_e->tag=StrNew(doc_e->right_macro,doc->mem_task);
|
||||
} else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_HAS_BIN:
|
||||
if (cc->token)
|
||||
doc_e->bin_num=LexExpressionI64(cc);
|
||||
else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_BIN_PTR_LINK:
|
||||
if (cc->token==TK_STR) {
|
||||
st2=LexExtStr(cc);
|
||||
doc_e->bin_ptr_link=StrNew(st2,doc->mem_task);
|
||||
Free(st2);
|
||||
if (!DocBinPtrRst(doc,doc_e))
|
||||
doc_e->type=DOCT_ERROR;
|
||||
} else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_RAW_TYPE:
|
||||
if (cc->token==TK_IDENT) {
|
||||
j=DefineMatch(cc->cur_str,"ST_RAW_TYPES");
|
||||
if (j<0)
|
||||
goto pd_err;
|
||||
doc_e->raw_type=j;
|
||||
doc_e->de_flags&=~DOCEF_DFT_RAW_TYPE;
|
||||
Lex(cc);
|
||||
} else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_SHIFTED_X:
|
||||
if (cc->token)
|
||||
doc_e->type|=(LexExpressionI64(cc) & 0x1F)<<16;
|
||||
else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_SHIFTED_Y:
|
||||
if (cc->token)
|
||||
doc_e->type|=(LexExpressionI64(cc) & 0x1F)<<21;
|
||||
else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_SCROLLING_X:
|
||||
if (cc->token)
|
||||
doc_e->scroll_len=LexExpressionI64(cc);
|
||||
else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_USER_DATA:
|
||||
if (cc->token)
|
||||
doc_e->user_data=LexExpression(cc);
|
||||
else
|
||||
goto pd_err;
|
||||
break;
|
||||
case DOCEf_FLAGS_NUM-1: //nobound switch
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
pd_err:
|
||||
if (!doc_e)
|
||||
doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
|
||||
doc_e->type=DOCT_ERROR;
|
||||
doc_e->de_flags=0;
|
||||
}
|
||||
if (doc_e->de_flags&DOCEF_LST && (doc_e->de_flags&DOCEF_REMALLOC_DATA ||
|
||||
!(doc_e->de_flags&DOCEF_DEREF_DATA))) {
|
||||
DocDataScan(doc,doc_e);
|
||||
DocDataFmt(doc,doc_e);
|
||||
}
|
||||
CmpCtrlDel(cc);
|
||||
} catch {
|
||||
Fs->catch_except=TRUE;
|
||||
if (!doc_e)
|
||||
doc_e=CAlloc(sizeof(CDocEntry),doc->mem_task);
|
||||
doc_e->type=DOCT_ERROR;
|
||||
doc_e->de_flags=0;
|
||||
}
|
||||
return doc_e;
|
||||
}
|
||||
|
||||
U0 DocEntryToggle(CDoc *doc)
|
||||
{
|
||||
Bool unlock=DocLock(doc),old_color_names;
|
||||
CDocEntry *doc_ce=doc->cur_entry,*cl1,*doc_ce2;
|
||||
U8 ch,*st,*st2;
|
||||
I64 i,j,k;
|
||||
if (doc_ce!=doc &&
|
||||
!(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
|
||||
if (doc_ce->type_u8==DOCT_TEXT && !(doc_ce->de_flags &
|
||||
~(DOCEF_TAG|DOCG_BL_IV_UL|DOCEF_WORD_WRAP|DOCEF_HIGHLIGHT|
|
||||
DOCEF_SKIP|DOCEF_FILTER_SKIP)) &&
|
||||
!(doc_ce->type&DOCG_BL_IV_UL)) {
|
||||
doc_ce2=doc_ce->last;
|
||||
for (k=0;k<20;k++) {
|
||||
if (doc_ce2!=doc) {
|
||||
cl1=doc_ce2->last;
|
||||
if (doc_ce2->type_u8==DOCT_TEXT &&
|
||||
doc_ce->de_flags==doc_ce2->de_flags &&
|
||||
doc_ce->type==doc_ce2->type) {
|
||||
i=StrLen(doc_ce2->tag);
|
||||
j=StrLen(doc_ce->tag);
|
||||
st=MAlloc(i+j+1,doc->mem_task);
|
||||
MemCpy(st,doc_ce2->tag,i);
|
||||
MemCpy(st+i,doc_ce->tag,j+1);
|
||||
Free(doc_ce->tag);
|
||||
doc_ce->tag=st;
|
||||
doc_ce->max_col=i+j;
|
||||
doc->cur_col+=i;
|
||||
DocEntryDel(doc,doc_ce2);
|
||||
} else if (doc_ce2->type_u8==DOCT_SOFT_NEW_LINE)
|
||||
DocEntryDel(doc,doc_ce2);
|
||||
else
|
||||
break;
|
||||
doc_ce2=cl1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
doc_ce2=doc_ce->next;
|
||||
for (k=0;k<20;k++) {
|
||||
if (doc_ce2!=doc) {
|
||||
cl1=doc_ce2->next;
|
||||
if (doc_ce2->type_u8==DOCT_TEXT &&
|
||||
doc_ce->de_flags==doc_ce2->de_flags &&
|
||||
doc_ce->type==doc_ce2->type) {
|
||||
i=StrLen(doc_ce->tag);
|
||||
j=StrLen(doc_ce2->tag);
|
||||
st=MAlloc(i+j+1,doc->mem_task);
|
||||
MemCpy(st,doc_ce->tag,i);
|
||||
MemCpy(st+i,doc_ce2->tag,j+1);
|
||||
Free(doc_ce->tag);
|
||||
doc_ce->tag=st;
|
||||
doc_ce->max_col=i+j;
|
||||
DocEntryDel(doc,doc_ce2);
|
||||
} else if (doc_ce2->type_u8==DOCT_SOFT_NEW_LINE)
|
||||
DocEntryDel(doc,doc_ce2);
|
||||
else
|
||||
break;
|
||||
doc_ce2=cl1;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
i=doc->cur_col;
|
||||
while (i>doc_ce->min_col && doc_ce->tag[i]!='$$')
|
||||
i--;
|
||||
j=doc->cur_col+1;
|
||||
while (j<doc_ce->max_col && doc_ce->tag[j]!='$$')
|
||||
j++;
|
||||
if (i<j-1 && doc_ce->min_col<=i<j<doc_ce->max_col &&
|
||||
doc_ce->tag[i]=='$$' && doc_ce->tag[j]=='$$') {
|
||||
ch=doc_ce->tag[j+1];
|
||||
doc_ce->tag[j+1]=0;
|
||||
st=StrNew(doc_ce->tag+i);
|
||||
doc_ce->tag[j+1]=ch;
|
||||
StrCpy(doc_ce->tag+i,doc_ce->tag+j+1);
|
||||
doc->cur_col=i;
|
||||
st2=MStrPrint("%q",st);
|
||||
if (doc_ce=DocPrint(doc,st2)) {
|
||||
doc->cur_entry=doc_ce;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
}
|
||||
Free(st);
|
||||
Free(st2);
|
||||
}
|
||||
} else {
|
||||
old_color_names=LBts(&doc->flags,DOCf_COLOR_NAMES);
|
||||
st=Doc2PlainText(doc,doc_ce);
|
||||
LBEqu(&doc->flags,DOCf_COLOR_NAMES,old_color_names);
|
||||
DocEntryDel(doc,doc_ce);
|
||||
DocPrint(doc,"$$$$%$$Q$$$$",st);
|
||||
}
|
||||
DocRecalc(doc);
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
U0 DocFlagsToggle(CDoc *doc,I64 tog_flags)
|
||||
{
|
||||
Bool unlock=DocLock(doc);
|
||||
I64 size,flags=doc->flags^tog_flags;
|
||||
U8 *st;
|
||||
CDocUndo *u_next,*u_last;
|
||||
|
||||
doc->flags=doc->flags&~DOCF_NO_CURSOR|DOCF_COLOR_NAMES;
|
||||
st=DocSave(doc,&size);
|
||||
|
||||
u_next=doc->undo_head.next;
|
||||
u_last=doc->undo_head.last;
|
||||
doc->undo_head.next=doc->undo_head.last=&doc->undo_head;
|
||||
|
||||
DocRst(doc,TRUE);
|
||||
doc->undo_head.next=u_next;
|
||||
doc->undo_head.last=u_last;
|
||||
DocUndoCntSet(doc);
|
||||
doc->flags=flags&~(DOCF_NO_CURSOR|DOCG_BL_IV_UL|DOCF_WORD_WRAP);
|
||||
DocLoad(doc,st,size);
|
||||
doc->flags|=flags&DOCF_NO_CURSOR;
|
||||
DocCenter(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
Free(st);
|
||||
}
|
||||
@@ -0,0 +1,323 @@
|
||||
#help_index "DolDoc/Output;StdOut/DolDoc"
|
||||
public CTask *PopUpViewDoc(CDoc *doc,I64 dof_flags=0)
|
||||
{//Pass doc to PopUp win task for viewing.
|
||||
U8 *buf=MStrPrint("DocEd(0x%X,0x%X);",doc,dof_flags);
|
||||
CTask *task=Spawn(&SrvCmdLine,NULL,"View",,Fs);
|
||||
TaskExe(task,NULL,buf,1<<JOBf_EXIT_ON_COMPLETE|1<<JOBf_FREE_ON_COMPLETE);
|
||||
Free(buf);
|
||||
return task;
|
||||
}
|
||||
|
||||
U0 PopUpViewPrintEndCB()
|
||||
{
|
||||
DocDel(FramePtr("ViewStrFrame"));
|
||||
Exit;
|
||||
}
|
||||
|
||||
public CTask *PopUpViewPrint(U8 *fmt,...)
|
||||
{//View Print stmt in PopUp win task.
|
||||
CTask *task;
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
CDoc *doc=DocNew;
|
||||
DocPrint(doc,buf);
|
||||
Free(buf);
|
||||
task=PopUpViewDoc(doc);
|
||||
FramePtrAdd("ViewStrFrame",doc,task);
|
||||
task->task_end_cb=&PopUpViewPrintEndCB;
|
||||
return task;
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Input;File/FileNames;StdIn/DolDoc"
|
||||
public U8 *PopUpPickFile(U8 *dir=NULL)
|
||||
{//Filename chooser. Uses $LK,"FileMgr",A="MN:FileMgr"$().
|
||||
U8 *res,*st,*st2;
|
||||
if (dir)
|
||||
st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",dir);
|
||||
else {
|
||||
st2=CurDir;
|
||||
st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",st2);
|
||||
Free(st2);
|
||||
}
|
||||
res=PopUp(st,Fs);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *PopUpPickDir(U8 *dir=NULL)
|
||||
{//File dir name chooser. Uses $LK,"FileMgr",A="MN:FileMgr"$().
|
||||
U8 *res,*st,*st2;
|
||||
if (dir)
|
||||
st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",dir);
|
||||
else {
|
||||
st2=CurDir;
|
||||
st=MStrPrint("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",st2);
|
||||
Free(st2);
|
||||
}
|
||||
res=PopUp(st,Fs);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *FileNameForm(U8 *dft=NULL,I64 dof_flags=0,CTask *mem_task=NULL)
|
||||
{//Text filename form in cur win, not PopUp.
|
||||
CEdFileName fn;
|
||||
if (dft)
|
||||
StrCpy(fn.name,dft);
|
||||
else
|
||||
*fn.name=0;
|
||||
if (DocForm(&fn,,dof_flags))
|
||||
return StrNew(fn.name,mem_task);
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public U8 *PopUpFileName(U8 *dft=NULL,I64 dof_flags=0)
|
||||
{//Filename chooser. Uses form, not $LK,"FileMgr",A="MN:FileMgr"$().
|
||||
U8 *st=MStrPrint("FileNameForm(\"%Q\",0x%X,Fs->parent_task);",
|
||||
dft,dof_flags|DOF_SIZE_MIN),*res=PopUp(st,Fs);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "DolDoc"
|
||||
Bool PopUpCd()
|
||||
{
|
||||
Bool res;
|
||||
U8 *st=PopUpPickDir;
|
||||
if (st) {
|
||||
res=Cd(st);
|
||||
Free(st);
|
||||
} else
|
||||
res=FALSE;
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Input;Char/Lists;StdIn/DolDoc"
|
||||
public U8 *PopUpPickLst(U8 *lst)
|
||||
{//Prompt for lst entry in PopUp win task.
|
||||
I64 i=0;
|
||||
CDoc *doc=DocNew;
|
||||
DocPrint(doc,"$$LTBLUE$$");
|
||||
while (*lst) {
|
||||
if (*lst=='@') {//Check for '@' alias lst entry
|
||||
i--;
|
||||
lst++;
|
||||
}
|
||||
DocPrint(doc,"$$MU,\"%s\",LE=%d$$\n",lst,i++);
|
||||
lst+=StrLen(lst)+1;
|
||||
}
|
||||
DocPrint(doc,"\n$$MU,\"CANCEL\",LE=DOCM_CANCEL$$\n");
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Input;Char/Lists;Char/Define;StdIn/DolDoc"
|
||||
public U8 *PopUpPickDefineSub(U8 *dname)
|
||||
{//Prompt for $LK,"Define",A="HI:Define"$ lst entry in PopUp win task.
|
||||
return PopUpPickLst(Define(dname));
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Input;StdIn/DolDoc"
|
||||
public I64 PopUp1(U8 *b1,I64 n1,U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Make PopUp win task with one bttn.
|
||||
I64 i,l1=StrLen(b1);
|
||||
CDoc *doc=DocNew;
|
||||
if (header) DocPrint(doc,"%s",header);
|
||||
DocPrint(doc,"$$CM+CX,%d,4$$$$BT,\"%s\",LE=%d$$\n",-l1/2,b1,n1);
|
||||
if (footer) DocPrint(doc,"%s",footer);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
public I64 PopUp2(U8 *b1,I64 n1,U8 *b2,I64 n2,U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Make PopUp win task with two bttns.
|
||||
I64 i,l1=StrLen(b1),l2=StrLen(b2),y;
|
||||
CDoc *doc=DocNew;
|
||||
if (header) {
|
||||
DocPrint(doc,"%s",header);
|
||||
y=4;
|
||||
} else {
|
||||
DocPrint(doc,"%*s\n",l1+l2+10,"");
|
||||
y=3;
|
||||
}
|
||||
DocPrint(doc,"$$CM+CX,%d,%d$$$$BT,\"%s\",LE=%d$$",-(l1+l2+3)>>1,y,b1,n1);
|
||||
DocPrint(doc,"$$CM+CX,%d,0$$$$BT,\"%s\",LE=%d$$\n" ,-(l1+l2+3)>>1+l1+6,b2,n2);
|
||||
if (footer) DocPrint(doc,"%s",footer);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
public Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Make PopUp win task with OKAY bttn.
|
||||
return PopUp1("OKAY",1,header,footer)>0;
|
||||
}
|
||||
|
||||
public Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Make PopUp win task with NO/YES bttns.
|
||||
return $WW,0$PopUp2("YES",1,"NO",0,header,footer)>0;
|
||||
}
|
||||
|
||||
public Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Make PopUp win task CANCEL/OKAY bttns.
|
||||
return PopUp2("OKAY",1,"CANCEL",0,header,footer)>0;
|
||||
}
|
||||
|
||||
U8 *PopUpGetStr2(U8 *header,CTask *mem_task)
|
||||
{
|
||||
U8 *res,*st;
|
||||
if (header)
|
||||
"%s",header;
|
||||
st=GetStr(,,GSF_WITH_NEW_LINE);
|
||||
res=StrNew(st,mem_task);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *PopUpGetStr(U8 *header=NULL)
|
||||
{//Prompt for text str in PopUp win task.
|
||||
U8 *st=MStrPrint("PopUpGetStr2(0x%X,0x%X);",header,Fs),
|
||||
*res=PopUp(st,Fs);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 PopUpGetI64(U8 *msg,I64 dft,I64 lo=I64_MIN,I64 hi=I64_MAX)
|
||||
{//Prompt for I64 text expression in PopUp win task.
|
||||
U8 *st=MStrPrint("GetI64(0x%X,0x%X,0x%X,0x%X);",msg,dft,lo,hi);
|
||||
I64 res=PopUp(st,Fs);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
|
||||
public F64 PopUpGetF64(U8 *msg,F64 dft,F64 lo=F64_MIN,F64 hi=F64_MAX)
|
||||
{//Prompt for F64 text expression in PopUp win task.
|
||||
U8 *st=MStrPrint("GetF64(0x%X,0x%X(F64),0x%X(F64),0x%X(F64));",msg,dft,lo,hi);
|
||||
F64 res=PopUp(st,Fs)(F64);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 PopUpRangeI64(I64 lo,I64 hi,I64 step=1,
|
||||
U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Evenly-spaced I64 range chooser in PopUp win task.
|
||||
I64 i;
|
||||
CDoc *doc=DocNew;
|
||||
if (header)
|
||||
DocPrint(doc,"%s",header);
|
||||
DocPrint(doc,"$$LTBLUE$$");
|
||||
for (i=lo;i<=hi;i+=step)
|
||||
DocPrint(doc,"$$MU,\"%d\",LE=%d$$\n",i,i);
|
||||
if (footer)
|
||||
DocPrint(doc,"%s",footer);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
public F64 PopUpRangeF64(F64 lo,F64 hi,F64 step,
|
||||
U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Evenly-spaced F64 range chooser in PopUp win task.
|
||||
F64 d;
|
||||
I64 i;
|
||||
U8 buf[STR_LEN];
|
||||
CDoc *doc=DocNew;
|
||||
if (header)
|
||||
DocPrint(doc,"%s",header);
|
||||
DocPrint(doc,"$$LTBLUE$$");
|
||||
for (d=lo;d<=hi;d+=step) {
|
||||
StrPrint(buf,fmt,d);
|
||||
DocPrint(doc,"$$MU,\"%s\",LE=0x%X$$\n",buf,d);
|
||||
}
|
||||
if (footer)
|
||||
DocPrint(doc,"%s",footer);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i(F64);
|
||||
}
|
||||
|
||||
public F64 PopUpRangeF64Exp(F64 lo,F64 hi,F64 factor,
|
||||
U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Exp-spaced F64 range chooser in PopUp win task.
|
||||
F64 d;
|
||||
I64 i;
|
||||
U8 buf[STR_LEN];
|
||||
CDoc *doc=DocNew;
|
||||
if (header)
|
||||
DocPrint(doc,"%s",header);
|
||||
DocPrint(doc,"$$LTBLUE$$");
|
||||
for (d=lo;d<=hi;d*=factor) {
|
||||
StrPrint(buf,fmt,d);
|
||||
DocPrint(doc,"$$MU,\"%s\",LE=0x%X$$\n",buf,d);
|
||||
}
|
||||
if (footer)
|
||||
DocPrint(doc,"%s",footer);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i(F64);
|
||||
}
|
||||
|
||||
public F64 PopUpRangeF64Log(F64 lo,F64 hi,I64 steps,
|
||||
U8 *fmt="%9.4f",U8 *header=NULL,U8 *footer=NULL)
|
||||
{//Log-spaced F64 range chooser in PopUp win task.
|
||||
return PopUpRangeF64Exp(lo,hi,Exp(Ln(hi/lo)/(steps-1)),fmt,header,footer);
|
||||
}
|
||||
|
||||
#help_index "Job/Exe;Task/Job/Exe;Compiler"
|
||||
public I64 AdamFile(U8 *filename,Bool warn_ext=TRUE)
|
||||
{//Make adam_task execute file.
|
||||
Bool okay=TRUE;
|
||||
U8 *name=FileNameAbs(filename),
|
||||
*name2=DftExt(name,"HC.Z");
|
||||
I64 res=0;
|
||||
if (warn_ext &&
|
||||
!FilesFindMatch(name2,FILEMASK_JIT) &&
|
||||
!PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n"))
|
||||
okay=FALSE;
|
||||
if (okay)
|
||||
res=Adam("#include \"%s\";",name2);
|
||||
Free(name2);
|
||||
Free(name);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 PopUpFile(U8 *filename,Bool warn_ext=TRUE,
|
||||
CTask *parent=NULL,CTask **_pu_task=NULL)
|
||||
{//$LK,"ExeFile2",A="MN:ExeFile2"$() in $LK,"PopUp",A="MN:PopUp"$ task. Cont as User.
|
||||
Bool okay=TRUE;
|
||||
U8 *st,*name=FileNameAbs(filename),
|
||||
*name2=DftExt(name,"HC.Z");
|
||||
I64 res=0;
|
||||
if (warn_ext &&
|
||||
!FilesFindMatch(name2,FILEMASK_JIT) &&
|
||||
!PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n"))
|
||||
okay=FALSE;
|
||||
if (okay) {
|
||||
st=MStrPrint(
|
||||
"\"$$$$WW+H,1$$$$\";In(\"ExeFile2(\\\"%s\\\",CCF_CMD_LINE);\\n\");"
|
||||
"UserTaskCont;",
|
||||
name2);
|
||||
res=PopUp(st,parent,_pu_task);
|
||||
Free(st);
|
||||
}
|
||||
Free(name2);
|
||||
Free(name);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 PopUpRunFile(U8 *filename,I64 ccf_flags=0,...)
|
||||
{//$LK,"ExeFile",A="MN:ExeFile"$() with args using $LK,"LastFun",A="MN:LastFun"$() in $LK,"PopUp",A="MN:PopUp"$ task.
|
||||
U8 *st,*name=FileNameAbs(filename),
|
||||
*name2=DftExt(name,"HC.Z");
|
||||
I64 res=0;
|
||||
st=MStrPrint(
|
||||
"\"$$$$WW+H,1$$$$\";ExeFile2(\"%s\",0x%X);LastFun(0x%X,0x%X);",
|
||||
name2,ccf_flags,argc,argv);
|
||||
res=PopUp(st,Fs);
|
||||
Free(st);
|
||||
Free(name2);
|
||||
Free(name);
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,729 @@
|
||||
#help_index "DolDoc/Output;StdOut/DolDoc"
|
||||
|
||||
public U0 DocPutKey(CDoc *doc,I64 ch=0,I64 sc=0)
|
||||
{//$LK,"PutKey",A="MN:PutKey"$(ch,sc) at doc insert pt, cur_entry.
|
||||
I64 i,x,y;
|
||||
CDoc *m;
|
||||
CDocEntry *doc_ce;
|
||||
U8 *st,*st2;
|
||||
Bool unlock;
|
||||
|
||||
if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
|
||||
return;
|
||||
if (doc->user_put_key && (*doc->user_put_key)(doc,doc->user_put_data,ch,sc))
|
||||
return;
|
||||
unlock=DocLock(doc);
|
||||
if (!Bt(doldoc.clean_scan_codes,sc.u8[0]))
|
||||
doc->flags|=DOCF_UNDO_DIRTY;
|
||||
DocCaptureUndo(doc);
|
||||
if (Bt(char_bmp_printable,ch) && !(sc&(SCF_CTRL|SCF_ALT))) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
st=Char2KeyName(ch,FALSE);
|
||||
KeyDescSet("Char /'%s'",st);
|
||||
Free(st);
|
||||
} else
|
||||
EdCharIns(ch,sc,doc);
|
||||
} else {
|
||||
doc_ce=doc->cur_entry;
|
||||
x=doc->x; y=doc->y;
|
||||
if (sc&SCF_ALT)
|
||||
switch (ch) {
|
||||
case CH_BACKSPACE: //<CTRL-H>
|
||||
if (!(sc&(SCF_SHIFT|SCF_CTRL))) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Undo");
|
||||
else
|
||||
DocUndoRestore(doc);
|
||||
}
|
||||
break;
|
||||
}
|
||||
else
|
||||
switch (ch) {
|
||||
case 0:
|
||||
switch (sc.u8[0]) {
|
||||
case SC_CURSOR_DOWN:
|
||||
if (!(sc&SCF_CTRL)) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Cursor Down, Sel");
|
||||
else
|
||||
KeyDescSet("Edit/Cursor Down");
|
||||
} else
|
||||
EdLineDown(doc,sc);
|
||||
break;
|
||||
} else
|
||||
sc&=~SCF_CTRL;
|
||||
//Fall Through to SC_END
|
||||
case SC_END:
|
||||
if (!(sc&SCF_CTRL)) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/GoTo Doc End, Sel");
|
||||
else
|
||||
KeyDescSet("Edit/GoTo Doc End");
|
||||
} else {
|
||||
while (doc_ce!=doc) {
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
doc_ce=doc->cur_entry=doc_ce->next;
|
||||
}
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
DocFormBwd(doc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_CURSOR_UP:
|
||||
if (!(sc&SCF_CTRL)) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Cursor Up, Sel");
|
||||
else
|
||||
KeyDescSet("Edit/Cursor Up");
|
||||
} else
|
||||
EdLineUp(doc,sc);
|
||||
break;
|
||||
} else
|
||||
sc&=~SCF_CTRL;
|
||||
//Fall Through to SC_HOME
|
||||
case SC_HOME:
|
||||
if (!(sc&SCF_CTRL)) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/GoTo Top of Doc, Sel");
|
||||
else
|
||||
KeyDescSet("Edit/GoTo Top of Doc");
|
||||
} else {
|
||||
if (doc_ce==doc) doc_ce=doc_ce->last;
|
||||
while (doc_ce!=doc) {
|
||||
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
|
||||
doc_ce=doc->cur_entry=doc_ce->last;
|
||||
}
|
||||
doc_ce=doc->cur_entry=doc->head.next;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
DocFormFwd(doc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_PAGE_DOWN:
|
||||
if (!(sc&SCF_CTRL)) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Page Down, Sel");
|
||||
else
|
||||
KeyDescSet("Edit/Page Down");
|
||||
} else {
|
||||
i=doc_ce->y+doc->win_task->win_height-1;
|
||||
if (doc_ce->type_u8==DOCT_HEX_ED)
|
||||
i+=doc->cur_col/3/doc_ce->hex_ed_width;
|
||||
while (doc_ce!=doc &&
|
||||
(doc_ce->type_u8!=DOCT_HEX_ED && doc_ce->y<i ||
|
||||
doc_ce->type_u8==DOCT_HEX_ED &&
|
||||
doc_ce->y+doc->cur_col/3/doc_ce->hex_ed_width<i)) {
|
||||
EdLineDown(doc,sc);
|
||||
//paranoid check for stuck on same node
|
||||
if (doc->cur_entry==doc_ce && doc_ce->type_u8!=DOCT_HEX_ED)
|
||||
break;
|
||||
doc_ce=doc->cur_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_PAGE_UP:
|
||||
if (!(sc&SCF_CTRL)) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Page Up, Sel");
|
||||
else
|
||||
KeyDescSet("Edit/Page Up");
|
||||
}else {
|
||||
i=doc_ce->y-(doc->win_task->win_height-1);
|
||||
if (doc_ce->type_u8==DOCT_HEX_ED)
|
||||
i+=doc->cur_col/3/doc_ce->hex_ed_width;
|
||||
while (doc_ce->last!=doc &&
|
||||
(doc_ce->type_u8!=DOCT_HEX_ED && doc_ce->y>i ||
|
||||
doc_ce->type_u8==DOCT_HEX_ED &&
|
||||
doc_ce->y+doc->cur_col/3/doc_ce->hex_ed_width>i) &&
|
||||
doc_ce->y!=doc->head.next->y) {
|
||||
EdLineUp(doc,sc);
|
||||
//paranoid check for stuck on same node
|
||||
if (doc->cur_entry==doc_ce && doc_ce->type_u8!=DOCT_HEX_ED)
|
||||
break;
|
||||
doc_ce=doc->cur_entry;
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_CURSOR_LEFT:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_CTRL)
|
||||
KeyDescSet("Edit/GoTo Start of Line");
|
||||
else {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Cursor Left, Sel");
|
||||
else
|
||||
KeyDescSet("Edit/Cursor Left");
|
||||
}
|
||||
} else
|
||||
EdCursorLeft(doc,sc);
|
||||
break;
|
||||
case SC_CURSOR_RIGHT:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_CTRL)
|
||||
KeyDescSet("Edit/GoTo End of Line");
|
||||
else {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Cursor Right, Sel");
|
||||
else
|
||||
KeyDescSet("Edit/Cursor Right");
|
||||
}
|
||||
} else
|
||||
EdCursorRight(doc,sc);
|
||||
break;
|
||||
case SC_DELETE:
|
||||
if (!(sc&SCF_CTRL)) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Cut To Clipboard");
|
||||
else
|
||||
KeyDescSet("Char /Delete");
|
||||
} else {
|
||||
if (sc&SCF_SHIFT)
|
||||
EdCutToClipboard(doc);
|
||||
else
|
||||
EdCharDel(doc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_INS:
|
||||
if (sc&(SCF_SHIFT|SCF_CTRL)!=(SCF_SHIFT|SCF_CTRL)) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Paste Clipboard");
|
||||
else if (sc&SCF_CTRL)
|
||||
KeyDescSet("Edit/Copy to Clipboard");
|
||||
else
|
||||
KeyDescSet("Edit/Toggle Overstrike");
|
||||
} else {
|
||||
if (sc&SCF_SHIFT)
|
||||
EdPasteClipboard(doc);
|
||||
else if (sc&SCF_CTRL)
|
||||
EdCopyToClipboard(doc);
|
||||
else
|
||||
doc->flags^=DOCF_OVERSTRIKE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_F1...SC_F10:
|
||||
if (sc&SCF_CTRL) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Cmd /Src Code of Sym");
|
||||
else
|
||||
KeyDescSet("Edit/Autocomplete Sym");
|
||||
} else {
|
||||
DocUnlock(doc);
|
||||
if (AutoComplete(ON)) {
|
||||
if (sc&SCF_SHIFT)
|
||||
ACMan(sc.u8[0]-SC_F1+1,Fs);
|
||||
else
|
||||
ACFillIn(sc.u8[0]-SC_F1+1);
|
||||
}
|
||||
DocLock(doc);
|
||||
}
|
||||
} else {
|
||||
switch (sc.u8[0]) {
|
||||
case SC_F1:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Cmd /About");
|
||||
else
|
||||
KeyDescSet("Cmd /Help");
|
||||
} else {
|
||||
if (sc&SCF_SHIFT)
|
||||
Ed("::/Doc/AboutTempleOS.DD.Z");
|
||||
else
|
||||
Ed("::/Doc/HelpIndex.DD.Z");
|
||||
}
|
||||
break;
|
||||
case SC_F2:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Play Macro");
|
||||
else
|
||||
KeyDescSet("Edit/Macro");
|
||||
} else {
|
||||
DocUnlock(doc);
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (TaskValidate(sys_macro_task))
|
||||
PostMsgWait(sys_macro_task,
|
||||
MSG_KEY_DOWN_UP,CH_SHIFT_ESC,0);
|
||||
SysMacroStripKey(&sys_macro_head,ch,sc);
|
||||
PlaySysMacro;
|
||||
} else
|
||||
EdMacroUtil;
|
||||
DocLock(doc);
|
||||
}
|
||||
break;
|
||||
case SC_F3:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Edit/Find Last");
|
||||
else
|
||||
KeyDescSet("Edit/Find Next");
|
||||
}else {
|
||||
doc->find_replace->scan_fwd=!(sc&SCF_SHIFT);
|
||||
EdFindNext(doc);
|
||||
}
|
||||
break;
|
||||
case SC_F4:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Cmd /Insert Directory Name");
|
||||
else
|
||||
KeyDescSet("Cmd /Insert FileName");
|
||||
} else {
|
||||
DocUnlock(doc);
|
||||
if (sc&SCF_SHIFT)
|
||||
st=PopUpPickDir;
|
||||
else
|
||||
st=PopUpPickFile;
|
||||
DocLock(doc);
|
||||
if (st) {
|
||||
DocPrintPartial(doc,"%s",st);
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_F5:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Cmd /Adam Include");
|
||||
else
|
||||
KeyDescSet("Cmd /Run (Execute)");
|
||||
} else {
|
||||
if (st2=DocEntryLink(doc,doc_ce)) {
|
||||
st=DocLinkFile(st2);
|
||||
Free(st2);
|
||||
} else {
|
||||
DocWrite(doc);
|
||||
st=StrNew(doc->filename.name);
|
||||
}
|
||||
if (st2=DirFile(st,"Run","HC.Z")) {
|
||||
if (FileFind(st2)) {
|
||||
Free(st);
|
||||
st=st2;
|
||||
} else
|
||||
Free(st2);
|
||||
}
|
||||
if (st) {
|
||||
if (sc&SCF_SHIFT)
|
||||
AdamFile(st);
|
||||
else
|
||||
PopUpFile(st);
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SC_F6:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Cmd /God Doodle");
|
||||
else
|
||||
KeyDescSet("Cmd /God Song");
|
||||
} else {
|
||||
//$LK,"::/Adam/God/HSNotes.DD"$
|
||||
if (sc&SCF_SHIFT) {
|
||||
DocUnlock(doc);
|
||||
GodDoodle;
|
||||
DocLock(doc);
|
||||
} else
|
||||
GodSong;
|
||||
}
|
||||
break;
|
||||
case SC_F7:
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Cmd /God Passage");
|
||||
else
|
||||
KeyDescSet("Cmd /God Word");
|
||||
} else {
|
||||
//$LK,"::/Adam/God/HSNotes.DD"$
|
||||
FifoU8Flush(god.fifo);
|
||||
GodBitsIns(GOD_GOOD_BITS,KbdMsEvtTime>>GOD_BAD_BITS);
|
||||
if (sc&SCF_SHIFT)
|
||||
GodBiblePassage;
|
||||
else
|
||||
GodWord;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case CH_CTRLA:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Save As");
|
||||
else if (DocWrite(doc,TRUE)&&(st=FileNameAbs(doc->filename.name))) {
|
||||
DirContextDel(doc->filename.dirc);
|
||||
doc->filename.dirc=DirContextNew(st);
|
||||
Free(st);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CH_CTRLB:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Cmd /Toggle Border");
|
||||
else
|
||||
WinBorder(Bt(&doc->win_task->display_flags,
|
||||
DISPLAYf_NO_BORDER),doc->win_task);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLC:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Copy to Clipboard");
|
||||
else
|
||||
EdCopyToClipboard(doc);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLD:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Cmd /File Manager");
|
||||
else {
|
||||
DocUnlock(doc);
|
||||
FileMgr;
|
||||
DocLock(doc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CH_CTRLF:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Cmd /Search Files");
|
||||
else
|
||||
FindWiz;
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Find & Replace");
|
||||
else
|
||||
EdFindReplace(doc);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLG:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/GoTo Line Num");
|
||||
else
|
||||
EdGoToLine(doc);
|
||||
}
|
||||
break;
|
||||
case CH_BACKSPACE: //<CTRL-H>
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Char /Back Space");
|
||||
else {
|
||||
DocCaptureUndo(doc);
|
||||
doc_ce=doc->cur_entry;
|
||||
if (doc->cur_col<=doc_ce->min_col) {
|
||||
doc_ce=doc->cur_entry=doc_ce->last;
|
||||
if (doc_ce!=doc && doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
|
||||
doc_ce=doc->cur_entry=doc_ce->last;
|
||||
if (doc_ce==doc || doc_ce->type_u8==DOCT_PMT) {
|
||||
doc_ce=doc->cur_entry=doc_ce->next;
|
||||
doc->cur_col=doc_ce->min_col;
|
||||
} else {
|
||||
doc->cur_col=doc_ce->max_col;
|
||||
if (doc->cur_col>doc_ce->min_col)
|
||||
doc->cur_col--;
|
||||
EdCharDel(doc);
|
||||
}
|
||||
} else {
|
||||
doc->cur_col--;
|
||||
EdCharDel(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CH_CTRLI:
|
||||
if (sc.u8[0]!=SC_TAB) {
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Unindent 2");
|
||||
else
|
||||
DocPrint(doc,"$$ID,-2$$");
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Indent 2");
|
||||
else
|
||||
DocPrint(doc,"$$ID,2$$");
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '\n':
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Char /Return");
|
||||
else
|
||||
KeyDescSet("Char /Page Break");
|
||||
} else
|
||||
EdCharIns(ch,sc,doc);
|
||||
break;
|
||||
case CH_CTRLK:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Blinking Text Off");
|
||||
else
|
||||
DocPrint(doc,"$$BK,0$$");
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Blinking Text On");
|
||||
else
|
||||
DocPrint(doc,"$$BK,1$$");
|
||||
}
|
||||
break;
|
||||
case CH_CTRLL:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Cmd /Code Tools");
|
||||
else {
|
||||
DocUnlock(doc);
|
||||
EdCodeTools(doc);
|
||||
DocLock(doc);
|
||||
}
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Cmd /Insert Text Widgets Wizard");
|
||||
else {
|
||||
DocUnlock(doc);
|
||||
EdInsWidgetWiz;
|
||||
DocLock(doc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CH_CTRLM:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Cmd /Personal Notes");
|
||||
else
|
||||
Ed("~/PersonalNotes.DD.Z");
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Cmd /Personal Menu");
|
||||
else {
|
||||
m=DocRead("~/PersonalMenu.DD.Z");
|
||||
DocMenu(m);
|
||||
DocDel(m);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CH_CTRLO:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Collapse");
|
||||
else
|
||||
DocCollapse(TRUE,doc);
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Uncolapse");
|
||||
else
|
||||
DocCollapse(FALSE,doc);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLP:
|
||||
if (doc->flags & (DOCF_SUPERSCRIPT_MODE | DOCF_SUBSCRIPT_MODE)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Toggle Super or Sub script");
|
||||
else {
|
||||
DocPrint(doc,"$$SY,0$$");
|
||||
doc->flags&=~(DOCF_SUPERSCRIPT_MODE | DOCF_SUBSCRIPT_MODE);
|
||||
}
|
||||
} else if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Toggle Subscript");
|
||||
else {
|
||||
DocPrint(doc,"$$SY,3$$");
|
||||
doc->flags|=DOCF_SUBSCRIPT_MODE;
|
||||
}
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Toggle Superscript");
|
||||
else {
|
||||
DocPrint(doc,"$$SY,-3$$");
|
||||
doc->flags|=DOCF_SUPERSCRIPT_MODE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CH_CTRLQ:
|
||||
break;
|
||||
case CH_CTRLR:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Cmd /Sprite Graphic Resource");
|
||||
else
|
||||
if (!(doc->flags&DOCF_FORM) &&
|
||||
!(doc->flags&(DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
|
||||
DocUnlock(doc);
|
||||
if (doc_ce->type_u8==DOCT_SPRITE)
|
||||
EdSpriteEd(doc);
|
||||
else
|
||||
EdSpriteIns(doc);
|
||||
DocLock(doc);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case CH_CTRLS:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Find Misspelled");
|
||||
else
|
||||
ACMisspelledFind(doc);
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Save");
|
||||
else
|
||||
DocWrite(doc);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLT:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Single Entry Toggle Plain Text");
|
||||
else if (!(doc->flags&DOCF_FORM))
|
||||
DocEntryToggle(doc);
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Toggle Plain Text Display");
|
||||
else if (!(doc->flags&DOCF_FORM))
|
||||
DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLU:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Underline Off");
|
||||
else
|
||||
DocPrint(doc,"$$UL,0$$");
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Underline On");
|
||||
else
|
||||
DocPrint(doc,"$$UL,1$$");
|
||||
}
|
||||
break;
|
||||
case CH_CTRLV:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Paste Clipboard");
|
||||
else
|
||||
EdPasteClipboard(doc);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLW:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Word Wrap Off");
|
||||
else
|
||||
DocPrint(doc,"$$WW,0$$");
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Word Wrap On");
|
||||
else
|
||||
DocPrint(doc,"$$WW,1$$");
|
||||
}
|
||||
break;
|
||||
case CH_CTRLX:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Cut To Clipboard");
|
||||
else
|
||||
EdCutToClipboard(doc);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLY:
|
||||
if (!(sc&SCF_SHIFT)) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/Delete Line");
|
||||
else
|
||||
EdLineDel(doc);
|
||||
}
|
||||
break;
|
||||
case CH_CTRLZ:
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Inverted Text Off");
|
||||
else
|
||||
DocPrint(doc,"$$IV,0$$");
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Dol /Inverted Text On");
|
||||
else
|
||||
DocPrint(doc,"$$IV,1$$");
|
||||
}
|
||||
break;
|
||||
case '0'...'9':
|
||||
if (sc&SCF_CTRL) {
|
||||
if (sc&SCF_KEY_DESC) {
|
||||
if (sc&SCF_SHIFT)
|
||||
KeyDescSet("Cmd /Word Definition");
|
||||
else
|
||||
KeyDescSet("Edit/Autocomplete Word");
|
||||
} else {
|
||||
if (AutoComplete(ON)) {
|
||||
DocUnlock(doc);
|
||||
if (sc&SCF_SHIFT)
|
||||
ACDDef(ch-'0',Fs);
|
||||
else
|
||||
ACDFillin(ch-'0');
|
||||
DocLock(doc);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case '[':
|
||||
if (sc&SCF_CTRL) {
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/GoTo matching brace");
|
||||
else
|
||||
EdFindPaired(doc,'}','{',FALSE);
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/GoTo matching bracket");
|
||||
else
|
||||
EdFindPaired(doc,']','[',FALSE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case ']':
|
||||
if (sc&SCF_CTRL) {
|
||||
if (sc&SCF_SHIFT) {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/GoTo matching brace");
|
||||
else
|
||||
EdFindPaired(doc,'{','}',TRUE);
|
||||
} else {
|
||||
if (sc&SCF_KEY_DESC)
|
||||
KeyDescSet("Edit/GoTo matching bracket");
|
||||
else
|
||||
EdFindPaired(doc,'[',']',TRUE);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
if (!(doc->flags&DOCF_DONT_SWAP_OUT))
|
||||
Yield;
|
||||
}
|
||||
|
||||
Bool KDDocPutKey(I64 ch,I64 scan_code)
|
||||
{
|
||||
CDoc *doc;
|
||||
if (doc=DocPut)
|
||||
DocPutKey(doc,ch,scan_code);
|
||||
return FALSE;
|
||||
}
|
||||
@@ -0,0 +1,336 @@
|
||||
#help_index "DolDoc/Output;StdOut/DolDoc"
|
||||
|
||||
CDocEntry *DocPutS(CDoc *doc,U8 *st)
|
||||
{//Don't use this. Use $LK-UL,"DocPrint",A="MN:DocPrint"$().
|
||||
//Does not handle partial Doc entries.
|
||||
//Returns last newly created dollar-sign CDocEntry or NULL.
|
||||
U8 *ptr=st,*ptr2,*st2,*ptr3,*ptr4,*src,
|
||||
*char_bmp;
|
||||
Bool unlock;
|
||||
I64 ch,j;
|
||||
CDocEntry *doc_e=NULL,*res=NULL,*doc_ce;
|
||||
if (!st || !doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
|
||||
return NULL;
|
||||
unlock=DocLock(doc);
|
||||
if (doc->flags & DOCF_PLAIN_TEXT_TABS)
|
||||
char_bmp=char_bmp_zero_cr_nl_cursor;
|
||||
else if (doc->flags & DOCF_PLAIN_TEXT)
|
||||
char_bmp=char_bmp_zero_tab_cr_nl_cursor;
|
||||
else
|
||||
char_bmp=char_bmp_zero_tab_cr_nl_cursor_dollar;
|
||||
doc_ce=doc->cur_entry;
|
||||
while (*ptr) {
|
||||
ptr2=ptr;
|
||||
do ch=*ptr++;
|
||||
while (!Bt(char_bmp,ch) || ch==CH_CURSOR && doc->flags&DOCF_NO_CURSOR);
|
||||
ptr--;
|
||||
if (!ch) {
|
||||
if (j=ptr-ptr2) {
|
||||
doc_e=DocEntryNewBase(doc,
|
||||
DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
|
||||
if (doc->flags & DOCF_NO_CURSOR) {
|
||||
src=MAlloc(j+1);
|
||||
MemCpy(src,ptr2,j+1);
|
||||
StrUtil(src,SUF_REM_CTRL_CHARS);
|
||||
j=StrLen(src);
|
||||
} else
|
||||
src=ptr2;
|
||||
doc_e->tag=MAlloc(j+1,doc->mem_task);
|
||||
MemCpy(doc_e->tag,src,j+1);
|
||||
doc_e->max_col=j;
|
||||
DocInsEntry(doc,doc_e);
|
||||
if (doc->flags & DOCF_NO_CURSOR)
|
||||
Free(src);
|
||||
}
|
||||
} else {
|
||||
if (j=ptr-ptr2) {
|
||||
*ptr=0;
|
||||
doc_e=DocEntryNewBase(doc,
|
||||
DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
|
||||
if (doc->flags & DOCF_NO_CURSOR) {
|
||||
src=MAlloc(j+1);
|
||||
MemCpy(src,ptr2,j+1);
|
||||
ptr3=src;
|
||||
ptr4=src;
|
||||
while (*ptr3)
|
||||
if (*ptr3!=CH_CURSOR)
|
||||
*ptr4++=*ptr3++;
|
||||
else
|
||||
ptr3++;
|
||||
*ptr4=0;
|
||||
j=ptr4-src;
|
||||
} else
|
||||
src=ptr2;
|
||||
doc_e->tag=MAlloc(j+1,doc->mem_task);
|
||||
MemCpy(doc_e->tag,src,j+1);
|
||||
doc_e->max_col=j;
|
||||
DocInsEntry(doc,doc_e);
|
||||
if (doc->flags & DOCF_NO_CURSOR)
|
||||
Free(src);
|
||||
*ptr=ch;
|
||||
}
|
||||
switch (ch) {
|
||||
case CH_CURSOR:
|
||||
doc_e=DocEntryNewBase(doc,
|
||||
DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
|
||||
DocInsEntry(doc,doc_e);
|
||||
ptr++;
|
||||
break;
|
||||
case '\t':
|
||||
doc_e=DocEntryNewBase(doc,
|
||||
DOCT_TAB|doc->settings_head.dft_text_attr<<8);
|
||||
DocInsEntry(doc,doc_e);
|
||||
ptr++;
|
||||
break;
|
||||
case '$$':
|
||||
ptr++; //skip first dollar
|
||||
ptr2=ptr;
|
||||
while (*ptr && *ptr!='$$')
|
||||
ptr++;
|
||||
if (*ptr) {
|
||||
*ptr=0; //zero second dollar
|
||||
if (ptr-1==ptr2 && *ptr2==CH_CURSOR) {
|
||||
doc_e=DocEntryNewBase(doc,
|
||||
DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
|
||||
DocInsEntry(doc,doc_e);
|
||||
ptr2++;
|
||||
}
|
||||
if (ptr==ptr2) {
|
||||
doc_e=DocEntryNewBase(doc,
|
||||
DOCT_TEXT|doc->settings_head.dft_text_attr<<8);
|
||||
doc_e->max_col=1;
|
||||
if (doc->flags & DOCF_DBL_DOLLARS)
|
||||
doc_e->tag=StrNew("$$$$",doc->mem_task);
|
||||
else
|
||||
doc_e->tag=StrNew("$$",doc->mem_task);
|
||||
DocInsEntry(doc,doc_e);
|
||||
} else {
|
||||
st2=MAlloc(ptr-ptr2+1);
|
||||
ptr3=ptr2;
|
||||
ptr4=st2;
|
||||
while (ch=*ptr3++) {
|
||||
if (ch==CH_CURSOR) {
|
||||
doc_e=DocEntryNewBase(doc,
|
||||
DOCT_CURSOR|doc->settings_head.dft_text_attr<<8);
|
||||
DocInsEntry(doc,doc_e);
|
||||
} else
|
||||
*ptr4++=ch;
|
||||
}
|
||||
*ptr4=0;
|
||||
if (doc_e=PrsDollarCmd(doc,st2)) {
|
||||
res=doc_e;
|
||||
DocInsEntry(doc,doc_e);
|
||||
}
|
||||
Free(st2);
|
||||
}
|
||||
*ptr++='$$';
|
||||
}
|
||||
break;
|
||||
default:
|
||||
doc_e=DocEntryNewBase(doc,
|
||||
DOCT_NEW_LINE|doc->settings_head.dft_text_attr<<8);
|
||||
DocInsEntry(doc,doc_e);
|
||||
if (ch=='\r')
|
||||
while (*ptr=='\r')
|
||||
ptr++;
|
||||
if (*ptr=='\n')
|
||||
ptr++;
|
||||
while (*ptr=='\r')
|
||||
ptr++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public CDocEntry *DocPrint(CDoc *doc=NULL,U8 *fmt,...)
|
||||
{//You must not print partial doc cmds.
|
||||
//Returns last newly created dollar-sign CDocEntry or NULL.
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
CDocEntry *res=DocPutS(doc,buf);
|
||||
Free(buf);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 DocPrintPartial(CDoc *doc=NULL,U8 *fmt,...)
|
||||
{//Lets you print half a doc cmd, if you like.
|
||||
U8 *buf,*st,*src,*dst,*ptr,*ptr2;
|
||||
Bool unlock;
|
||||
CDocEntry *doc_ce,*doc_ne;
|
||||
I64 ch,i,j;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
ptr=buf;
|
||||
if (doc->user_put_s && (*doc->user_put_s)(doc,doc->user_put_data,buf)) {
|
||||
Free(buf);
|
||||
return;
|
||||
}
|
||||
unlock=DocLock(doc);
|
||||
if (doc->cur_entry->type_u8==DOCT_DATA)
|
||||
while (ch=*ptr++)
|
||||
DocPutKey(doc,ch,0);
|
||||
else
|
||||
while (ch=*ptr) {
|
||||
if (!Bt(char_bmp_safe_dollar,ch) ||
|
||||
doc->flags & (DOCF_OVERSTRIKE|DOCF_IN_DOLLAR)) {
|
||||
DocPutKey(doc,ch,0);
|
||||
ptr++;
|
||||
} else {
|
||||
ptr2=ptr++;
|
||||
while (TRUE) {
|
||||
ch=*ptr++;
|
||||
if (!Bt(char_bmp_safe_dollar,ch))
|
||||
break;
|
||||
}
|
||||
ptr--;
|
||||
*ptr=0;
|
||||
doc_ce=doc->cur_entry;
|
||||
j=ptr-ptr2;
|
||||
if (IsEditableText(doc_ce)) {
|
||||
dst=st=MAlloc(doc_ce->max_col+j+1,doc->mem_task);
|
||||
src=doc_ce->tag;
|
||||
i=doc->cur_col;
|
||||
doc->cur_col+=j;
|
||||
doc_ce->max_col+=j;
|
||||
while (i-->0)
|
||||
*dst++=*src++;
|
||||
while (j-->0)
|
||||
*dst++=*ptr2++;
|
||||
while (*dst++=*src++);
|
||||
Free(doc_ce->tag);
|
||||
doc_ce->tag=st;
|
||||
} else {
|
||||
doc_ne=DocEntryNewTag(doc,doc_ce,ptr2);
|
||||
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);
|
||||
doc->cur_entry=doc_ne;
|
||||
doc->cur_col=StrLen(ptr2);
|
||||
}
|
||||
*ptr=ch;
|
||||
DocRemSoftNewLines(doc,doc->cur_entry);
|
||||
}
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
if (!(doc->flags&DOCF_DONT_SWAP_OUT))
|
||||
Yield;
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
Bool KDDocPutS(U8 *st)
|
||||
{
|
||||
CDoc *doc;
|
||||
if (doc=DocPut)
|
||||
DocPrintPartial(doc,"%s",st);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public U0 DocPrintAtomic(CDoc *doc=NULL,U8 *fmt,...)
|
||||
{//Prints multiple whole cmds all-at-once. Might need this when printing trees.
|
||||
U8 *buf;
|
||||
Bool unlock;
|
||||
I64 old_flags;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
unlock=DocLock(doc);
|
||||
old_flags=doc->flags;
|
||||
doc->flags|=DOCF_NO_CURSOR;
|
||||
DocPrint(doc,"%s",buf);
|
||||
DocRecalc(doc);
|
||||
doc->flags=old_flags;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
U0 DocDump(CDoc *doc,I64 uS_delay=0)
|
||||
{
|
||||
U8 *st;
|
||||
CDocEntry *doc_e,*doc_e2;
|
||||
Bool unlock=DocLock(doc);
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
st=DocScanLine(doc,doc_e,NULL,&doc_e2);
|
||||
"%s",st;
|
||||
Free(st);
|
||||
doc_e=doc_e2;
|
||||
if (doc_e->type_u8==DOCT_NEW_LINE) {
|
||||
'\n';
|
||||
Busy(uS_delay);
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
}
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public CDocEntry *DocPutLine(CDoc *doc=NULL,CDocEntry *doc_e)
|
||||
{//Send line from other doc to StdOut $LK,"DocPut",A="MN:DocPut"$.
|
||||
I64 ch;
|
||||
U8 *ptr,*ptr2;
|
||||
Bool unlock;
|
||||
if (!doc && !(doc=DocPut) || doc->doc_signature!=DOC_SIGNATURE_VAL)
|
||||
return NULL;
|
||||
unlock=DocLock(doc);
|
||||
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
|
||||
if (doc_e->de_flags&DOCEF_TAG) {
|
||||
ptr=doc_e->tag;
|
||||
do {
|
||||
ptr2=ptr;
|
||||
while (ch=*ptr)
|
||||
if (ch=='$$')
|
||||
break;
|
||||
else
|
||||
ptr++;
|
||||
*ptr=0;
|
||||
"%s",ptr2;
|
||||
*ptr=ch;
|
||||
if (ch=='$$') {
|
||||
"$$$$";
|
||||
ptr++;
|
||||
}
|
||||
} while (ch);
|
||||
} else if (doc_e->type_u8==DOCT_TAB)
|
||||
'\t';
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
'\n';
|
||||
if (doc_e!=doc)
|
||||
doc_e=doc_e->next;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return doc_e;
|
||||
}
|
||||
|
||||
#help_index "Debugging/Dump;DolDoc/Cmd Line (Typically);"\
|
||||
"Cmd Line (Typically);DolDoc/Output;StdOut/DolDoc"
|
||||
public U0 DocDm(U8 *buf,I64 cnt=0x80)
|
||||
{//Dump live chunk of mem showing addresses. Can be edited.
|
||||
CDocEntry *doc_e;
|
||||
CDoc *doc=DocPut;
|
||||
Bool unlock=DocLock(doc);
|
||||
doc_e=DocPrint(doc,"$$HX-Z,%d,16$$",cnt);
|
||||
doc_e->data=buf;
|
||||
doc->cur_entry=doc_e->next;
|
||||
DocRecalc(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 DocD(U8 *buf,I64 cnt=0x80)
|
||||
{//Dump live chunk of mem showing offsets. Can be edited.
|
||||
CDocEntry *doc_e;
|
||||
CDoc *doc=DocPut;
|
||||
Bool unlock=DocLock(doc);
|
||||
doc_e=DocPrint(doc,"$$HX,%d,16$$",cnt);
|
||||
doc_e->data=buf;
|
||||
doc->cur_entry=doc_e->next;
|
||||
DocRecalc(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,213 @@
|
||||
#help_index "DolDoc"
|
||||
|
||||
I64 DocCharDist(CDoc *doc,I64 x,I64 y)
|
||||
{
|
||||
#assert FONT_WIDTH==FONT_HEIGHT
|
||||
return (SqrI64(doc->x-x)+SqrI64(doc->y-y))*FONT_WIDTH*FONT_WIDTH;
|
||||
}
|
||||
|
||||
U0 DocDelToNum(CDoc *doc,I64 num)
|
||||
{
|
||||
CDocEntry *doc_e=doc->head.next,*doc_e2;
|
||||
while (num-->0 && doc_e!=doc) {
|
||||
doc_e2=doc_e->next;
|
||||
if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))) {
|
||||
if (doc_e==doc->cur_entry) {
|
||||
doc->cur_entry=doc_e2;
|
||||
doc->cur_col=doc_e2->min_col;
|
||||
}
|
||||
DocEntryDel(doc,doc_e);
|
||||
}
|
||||
doc_e=doc_e2;
|
||||
}
|
||||
}
|
||||
|
||||
U0 DocDelToEntry(CDoc *doc,CDocEntry *clear_entry,Bool clear_holds)
|
||||
{
|
||||
CDocEntry *doc_e=doc->head.next,*doc_e2;
|
||||
while (doc_e!=doc) {
|
||||
doc_e2=doc_e->next;
|
||||
if (!(doc_e->de_flags & (DOCEF_HOLD|DOCEF_FILTER_SKIP))||clear_holds) {
|
||||
if (doc_e==doc->cur_entry) {
|
||||
doc->cur_entry=doc_e2;
|
||||
doc->cur_col=doc_e2->min_col;
|
||||
}
|
||||
DocEntryDel(doc,doc_e);
|
||||
}
|
||||
if (doc_e==clear_entry)
|
||||
break;
|
||||
doc_e=doc_e2;
|
||||
}
|
||||
}
|
||||
|
||||
U0 DocBorderLstDraw(CDoc *doc)
|
||||
{
|
||||
CTask *win_task=doc->win_task;
|
||||
I64 i,y=-1,attr=win_task->border_attr<<8;
|
||||
U64 ch;
|
||||
CDoc *tmpl=doc;
|
||||
CD3I64 saved_scroll;
|
||||
while (tmpl && tmpl->doc_signature==DOC_SIGNATURE_VAL) {
|
||||
y+=(Bsr(tmpl->desc)+7)>>3+1; //StrLen+1
|
||||
tmpl=tmpl->parent_doc;
|
||||
}
|
||||
tmpl=doc;
|
||||
if (y>win_task->win_height)
|
||||
y=win_task->win_height;
|
||||
WinScrollNull(win_task,&saved_scroll);
|
||||
while (tmpl && tmpl->doc_signature==DOC_SIGNATURE_VAL) {
|
||||
ch=tmpl->desc;
|
||||
i=(Bsr(ch)+7)>>3; //StrLen
|
||||
ch=EndianI64(ch<<((8-i)<<3));
|
||||
attr=win_task->border_attr<<8;
|
||||
while (i-- && y>0) {
|
||||
TextChar(win_task,TRUE,-1,--y,attr+ch&0xFF);
|
||||
ch>>=8;
|
||||
}
|
||||
y--;
|
||||
tmpl=tmpl->parent_doc;
|
||||
}
|
||||
WinScrollRestore(win_task,&saved_scroll);
|
||||
}
|
||||
|
||||
public U0 DocTop(CDoc *doc=NULL)
|
||||
{//Move cursor, cur_entry, to top.
|
||||
Bool unlock;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
unlock=DocLock(doc);
|
||||
doc->cur_entry=doc->head.next;
|
||||
doc->cur_col=doc->cur_entry->min_col;
|
||||
doc->x=0;
|
||||
doc->y=0;
|
||||
doc->line_start_col=0;
|
||||
doc->top_line_num=0;
|
||||
|
||||
DocFormFwd(doc);
|
||||
DocRecalc(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 DocCenter(CDoc *doc=NULL,I64 recalc_flags=RECALCt_NORMAL)
|
||||
{//Center win on doc cursor, cur_entry.
|
||||
Bool unlock;
|
||||
CTask *task;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
unlock=DocLock(doc);
|
||||
task=doc->win_task;
|
||||
DocRecalc(doc,recalc_flags);
|
||||
if (!(doc->flags&DOCF_BORDER_DOC))
|
||||
doc->top_line_num=doc->y-(task->win_height+1)>>1;
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 DocBottom(CDoc *doc=NULL)
|
||||
{//Move cursor, cur_entry, to bottom.
|
||||
Bool unlock;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
unlock=DocLock(doc);
|
||||
doc->cur_entry=doc;
|
||||
doc->cur_col=0;
|
||||
DocRecalc(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public U0 DocClear(CDoc *doc=NULL,Bool clear_holds=FALSE)
|
||||
{//Clear all doc entries, except +H, hold entries.
|
||||
Bool unlock;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
unlock=DocLock(doc);
|
||||
DocBottom(doc);
|
||||
if (clear_holds)
|
||||
DocPrint(doc,"$$CL+H$$");
|
||||
else
|
||||
DocPrint(doc,"$$CL$$");
|
||||
DocRecalc(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
public Bool DocCursor(Bool show=OFF,CDoc *doc=NULL)
|
||||
{//Show or hide cursor.
|
||||
if (!doc && !(doc=DocPut))
|
||||
return FALSE;
|
||||
return !LBEqu(&doc->flags,DOCf_HIDE_CURSOR,!show);
|
||||
}
|
||||
|
||||
public Bool DocHighlightCursor(Bool show=OFF,CDoc *doc=NULL)
|
||||
{//Highlight or Don't highlight cursor.
|
||||
if (!doc && !(doc=DocPut))
|
||||
return FALSE;
|
||||
return !LBEqu(&doc->flags,DOCf_DONT_HIGHLIGHT_CURSOR,!show);
|
||||
}
|
||||
|
||||
public Bool DocScroll(Bool val=OFF,CDoc *doc=NULL)
|
||||
{//Turn scroll bars OFF/ON.
|
||||
if (!doc && !(doc=DocPut))
|
||||
return FALSE;
|
||||
return !LBEqu(&doc->flags,DOCf_NO_SCROLL_BARS,!val);
|
||||
}
|
||||
|
||||
public U0 DocCollapse(Bool collapse=TRUE,CDoc *doc=NULL)
|
||||
{//Collapse or uncollapse all tree widgets.
|
||||
CDocEntry *doc_e;
|
||||
Bool unlock;
|
||||
if (!doc && !(doc=DocPut))
|
||||
return;
|
||||
unlock=DocLock(doc);
|
||||
doc_e=doc->head.next;
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->de_flags&DOCEF_TREE)
|
||||
BEqu(&doc_e->de_flags,DOCEf_CHECKED_COLLAPSED,collapse);
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
DocRecalc(doc);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Cmd Line (Typically);Cmd Line (Typically)"
|
||||
public I64 DocMax(I64 i=I64_MAX)
|
||||
{//Set max document entries. (Cmd line buffer size.)
|
||||
//Adjusts the size of the cmd line buf.
|
||||
//Normally, the cmd line deletes entries
|
||||
//when more are added and the old scroll up.
|
||||
//See $LK,"max_entries",A="FF:::/Adam/DolDoc/DocTerm.HC,max_entries"$.
|
||||
I64 res;
|
||||
CDoc *doc;
|
||||
if (doc=DocPut) {
|
||||
res=doc->max_entries;
|
||||
doc->max_entries=i;
|
||||
return res;
|
||||
} else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Task;StdOut/Task"
|
||||
U0 DocUpdateTaskDocs(CTask *task)
|
||||
{//This is called from $LK,"GrUpdateTaskWin",A="MN:GrUpdateTaskWin"$() by the winmgr at 30fps.
|
||||
CDoc *doc;
|
||||
CD3I64 saved_scroll;
|
||||
if (task->border_src==BDS_CUR_DRV && task->cur_dv)
|
||||
task->border_attr=DrvTextAttrGet(Drv2Let(task->cur_dv));
|
||||
if (task->title_src==TTS_TASK_NAME)
|
||||
StrCpy(task->task_title,task->task_name);
|
||||
if ((doc=DocDisplay(task)) && !(doc->flags&DOCF_DONT_SHOW)) {
|
||||
if (task->border_src==BDS_ED_FILENAME_DRV)
|
||||
task->border_attr=DrvTextAttrGet(*doc->filename.name);
|
||||
if (task->title_src==TTS_ED_FILENAME)
|
||||
MemCpy(task->task_title,doc->filename.name,STR_LEN-1);
|
||||
DocRecalc(doc,RECALCt_TO_SCRN|RECALCF_HAS_CURSOR);
|
||||
}
|
||||
if ((doc=DocBorder(task)) && !(doc->flags&DOCF_DONT_SHOW)) {
|
||||
WinScrollNull(task,&saved_scroll);
|
||||
DocRecalc(doc,RECALCt_TO_SCRN);
|
||||
WinScrollRestore(task,&saved_scroll);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,103 @@
|
||||
#help_index "DolDoc"
|
||||
|
||||
public I64 DocEntryRun(CDoc *doc,CDocEntry *doc_e,
|
||||
Bool exited,I64 *_has_action=NULL)
|
||||
{//Do action on final entry sel by user.
|
||||
//Sometimes returns locked, sometimes unlocked
|
||||
U8 ch=doc->cmd_U8,*st;
|
||||
I64 res=DOCM_CANCEL,has_action=FALSE;
|
||||
CHashDefineStr *tmph;
|
||||
DocLock(doc);
|
||||
if (!exited) {
|
||||
if (doc_e->de_flags & DOCEF_ESC) {
|
||||
Msg(MSG_KEY_DOWN,CH_ESC,0,1<<JOBf_DONT_FILTER);
|
||||
has_action=TRUE;
|
||||
goto er_done;
|
||||
} if (doc_e->de_flags & DOCEF_QUIT) {
|
||||
Msg(MSG_KEY_DOWN,CH_SHIFT_ESC,0,1<<JOBf_DONT_FILTER);
|
||||
has_action=TRUE;
|
||||
goto er_done;
|
||||
} else if (doc_e->de_flags & DOCEF_CHECK_COLLAPSABLE) {
|
||||
doc_e->de_flags^=DOCEF_CHECKED_COLLAPSED;
|
||||
has_action=TRUE;
|
||||
}
|
||||
}
|
||||
try {
|
||||
if (ch==CH_SPACE) {
|
||||
if (doc_e->de_flags & DOCEF_LINK && doc->left_click_link) {
|
||||
res=(*doc->left_click_link)(doc,doc_e);
|
||||
has_action=TRUE;
|
||||
}
|
||||
if (doc_e->de_flags & DOCEF_LEFT_EXP) {
|
||||
res=doc_e->left_exp;
|
||||
has_action=TRUE;
|
||||
Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
|
||||
}
|
||||
if (doc_e->de_flags & DOCEF_LEFT_CB && doc_e->left_cb) {
|
||||
DocUnlock(doc);
|
||||
res=(*doc_e->left_cb)(doc,doc_e);
|
||||
has_action=TRUE;
|
||||
Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
|
||||
}
|
||||
if (doc_e->de_flags & DOCEF_LEFT_MACRO) {
|
||||
if (doc_e->de_flags & DOCEF_POPUP) {
|
||||
st=StrNew(doc_e->left_macro);
|
||||
DocUnlock(doc);
|
||||
PopUp(st,Fs);
|
||||
Free(st);
|
||||
} else {
|
||||
if (doc_e->de_flags & DOCEF_LEFT_IN_STR)
|
||||
InStr("%s",doc_e->left_macro);
|
||||
else
|
||||
In("%s",doc_e->left_macro);
|
||||
}
|
||||
has_action=TRUE;
|
||||
}
|
||||
if (!exited && doc_e->de_flags & DOCEF_LST &&
|
||||
doc_e->de_flags & DOCEF_DEFINE &&
|
||||
(tmph=HashFind(doc_e->define_str,
|
||||
doc->win_task->hash_table,HTT_DEFINE_STR)) &&
|
||||
(res=PopUpPickLst(tmph->data))!=DOCM_CANCEL) {
|
||||
DocDataFmt(doc,doc_e,res);
|
||||
DocDataScan(doc,doc_e);
|
||||
has_action=TRUE;
|
||||
}
|
||||
} else if (ch=='\n') {
|
||||
if (doc_e->de_flags & DOCEF_LINK && doc->right_click_link) {
|
||||
res=(*doc->right_click_link)(doc,doc_e);
|
||||
has_action=TRUE;
|
||||
}
|
||||
if (doc_e->de_flags & DOCEF_RIGHT_EXP) {
|
||||
res=doc_e->right_exp;
|
||||
has_action=TRUE;
|
||||
Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
|
||||
}
|
||||
if (doc_e->de_flags & DOCEF_RIGHT_CB && doc_e->right_cb) {
|
||||
DocUnlock(doc);
|
||||
res=(*doc_e->right_cb)(doc,doc_e);
|
||||
has_action=TRUE;
|
||||
Msg(MSG_CMD,res,0,1<<JOBf_DONT_FILTER);
|
||||
}
|
||||
if (doc_e->de_flags & DOCEF_RIGHT_MACRO) {
|
||||
if (doc_e->de_flags & DOCEF_POPUP) {
|
||||
st=StrNew(doc_e->right_macro);
|
||||
DocUnlock(doc);
|
||||
PopUp(st,Fs);
|
||||
Free(st);
|
||||
} else {
|
||||
if (doc_e->de_flags & DOCEF_RIGHT_IN_STR)
|
||||
InStr("%s",doc_e->right_macro);
|
||||
else
|
||||
In("%s",doc_e->right_macro);
|
||||
}
|
||||
has_action=TRUE;
|
||||
}
|
||||
}
|
||||
}
|
||||
catch
|
||||
DocBottom(doc);
|
||||
doc->cmd_U8=CH_SPACE;
|
||||
er_done:
|
||||
if (_has_action) *_has_action=has_action;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,213 @@
|
||||
#help_index "DolDoc/Task;StdOut/Task"
|
||||
public CDoc *DocBorderNew(CDoc *pdoc)
|
||||
{//Make new std border doc.
|
||||
CDocEntry *doc_e;
|
||||
CDoc *bdoc;
|
||||
|
||||
bdoc=DocNew;
|
||||
bdoc->flags|=DOCF_BORDER_DOC;
|
||||
if (pdoc) {
|
||||
DocPrint(bdoc,"$$CM+H+BY+RX+NC,-7,1$$");
|
||||
doc_e=DocPrint(bdoc,"$$TX+H+BD+TC,\" \"$$");
|
||||
doc_e->user_data=pdoc;
|
||||
doc_e->tag_cb=&EdFilterCB;
|
||||
doc_e=DocPrint(bdoc,"$$TX+H+BD+TC,\" \"$$");
|
||||
doc_e->user_data=pdoc;
|
||||
doc_e->tag_cb=&EdOverStrikeCB;
|
||||
doc_e=DocPrint(bdoc,"$$TX+H+BD+TC,\" \"$$");
|
||||
doc_e->user_data=pdoc;
|
||||
doc_e->tag_cb=&EdDollarCB;
|
||||
DocPrint(bdoc,"$$CM+H+BY+RX+NC,-18,1$$");
|
||||
doc_e=DocPrint(bdoc,"$$TX+BD+TC,\" \"$$");
|
||||
doc_e->user_data=pdoc;
|
||||
doc_e->tag_cb=&EdMoreCB;
|
||||
doc_e=DocPrint(bdoc,"$$TX+H+BD+TC,\" \"$$");
|
||||
doc_e->user_data=pdoc;
|
||||
doc_e->tag_cb=&EdDollarTypeCB;
|
||||
}
|
||||
DocPrint(bdoc,"$$CM+H+TY+NC,0,-1$$");
|
||||
doc_e=DocPrint(bdoc,"$$DA+H-TRM-P+BD+RD+CX+IV,LEN=STR_LEN-1,"
|
||||
"A=\"%%s...\",SCX=15$$");
|
||||
doc_e->data=&Fs->task_title;
|
||||
DocDataFmt(bdoc,doc_e);
|
||||
DocPrint(bdoc,"$$CM+H+NC,1,0$$$$TX+H+BD+IV,\"%X\"$$",Fs);
|
||||
DocPrint(bdoc,"$$TX+H+RX+BD,\"[X]\"$$");
|
||||
DocPrint(bdoc,"$$BK,1$$$$TX+H+LX+BD,\"MENU\"$$$$BK,0$$");
|
||||
return bdoc;
|
||||
}
|
||||
|
||||
public U0 DocTermNew()
|
||||
{//Make into term win task with Put/Display/Border docs.
|
||||
CDoc *pdoc=DocNew;
|
||||
pdoc->right_click_link=&TermRightClickLink;
|
||||
pdoc->max_entries=4096;
|
||||
Fs->border_src=BDS_CUR_DRV;
|
||||
pdoc->desc='Term';
|
||||
Fs->put_doc=Fs->display_doc=pdoc;
|
||||
Fs->border_doc=DocBorderNew(pdoc);
|
||||
Fs->cur_menu=MenuFile("::/Doc/EdPullDown.DD");
|
||||
WinScrollsInit(Fs);
|
||||
Raw(OFF);
|
||||
}
|
||||
|
||||
#help_index "DolDoc"
|
||||
|
||||
#define RIGHT_INCLUDE 0
|
||||
#define RIGHT_AINCLUDE 1
|
||||
#define RIGHT_COPY 2
|
||||
#define RIGHT_MOVE 3
|
||||
#define RIGHT_DELETE 4
|
||||
#define RIGHT_TYPE 5
|
||||
#define RIGHT_ED 6
|
||||
#define RIGHT_MOUNT 7
|
||||
#define RIGHT_PLAIN 8
|
||||
#define RIGHT_INFILE 9
|
||||
|
||||
I64 PopUpTermRight(U8 *header)
|
||||
{
|
||||
I64 i;
|
||||
CDoc *doc=DocNew;
|
||||
if (header) DocPrint(doc,"%s",header);
|
||||
DocPrint(doc,"\n\n"
|
||||
"TXT=%s\nDD =%s\nJIT=%s\nGR =%s"
|
||||
"$$CM+LX,1,3 $$$$BT,\"INCLUDE JIT\",LE=RIGHT_INCLUDE$$"
|
||||
"$$CM+LX,25,0$$$$BT,\"ADAM_INCLUDE JIT\",LE=RIGHT_AINCLUDE$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"COPY \",LE=RIGHT_COPY$$"
|
||||
"$$CM+LX,25,0$$$$BT,\"MOVE OR RENAME \",LE=RIGHT_MOVE$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"DELETE \",LE=RIGHT_DELETE$$"
|
||||
"$$CM+LX,25,0$$$$BT,\"TYPE TXT;GR\",LE=RIGHT_TYPE$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"DOLDOC EDIT DD\",LE=RIGHT_ED$$"
|
||||
"$$CM+LX,25,0$$$$BT,\"MOUNT ISO.C\",LE=RIGHT_MOUNT$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"PLAIN TEXT EDIT TXT\",LE=RIGHT_PLAIN$$"
|
||||
"$$CM+LX,25,0$$$$BT,\"INFILE IN\",LE=RIGHT_INFILE$$"
|
||||
"$$CM+LX,1,3 $$$$BT,\"CANCEL \",LE=DOCM_CANCEL$$\n",
|
||||
FILEMASK_TXT,FILEMASK_DD,FILEMASK_JIT,FILEMASK_GR);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e)
|
||||
{//Called with doc locked, exit unlocked
|
||||
Bool res;
|
||||
U8 *st;
|
||||
if (st=DocEntryLink(doc,doc_e)) {
|
||||
DocUnlock(doc);
|
||||
if (doc_e->de_flags & DOCEF_POPUP)
|
||||
res=PopUpEd(st);
|
||||
else
|
||||
res=Ed(st);
|
||||
Free(st);
|
||||
return res;
|
||||
}
|
||||
}
|
||||
|
||||
I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e)
|
||||
{//Called with doc locked, exit unlocked
|
||||
Bool send_new_line=FALSE,res=FALSE;
|
||||
U8 *st,*st2;
|
||||
I64 i;
|
||||
CEdFileName fn;
|
||||
if (st2=DocEntryLink(doc,doc_e)) {
|
||||
if (st=DocLinkFile(st2)) {
|
||||
DocUnlock(doc);
|
||||
if ((i=PopUpTermRight(st))>=0) {
|
||||
DocBottom(doc);
|
||||
switch (i) {
|
||||
case RIGHT_INCLUDE:
|
||||
if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_JIT)) {
|
||||
if (!PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n")) {
|
||||
send_new_line=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
"#include \"%s\";\n$$PT$$$$FG$$$$BG$$",st;
|
||||
WinZBufUpdate;
|
||||
ExeFile(st,CCF_CMD_LINE);
|
||||
res=TRUE;
|
||||
break;
|
||||
case RIGHT_AINCLUDE:
|
||||
if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_JIT)) {
|
||||
if (!PopUpCancelOk(ST_WARN_ST "Not .HC File\n\n")) {
|
||||
send_new_line=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
"Adam(\"#include \\\"%s\\\"\" );\n$$PT$$$$FG$$$$BG$$",st;
|
||||
WinZBufUpdate;
|
||||
AdamFile(st,FALSE);
|
||||
res=TRUE;
|
||||
break;
|
||||
case RIGHT_COPY:
|
||||
StrCpy(fn.name,st);
|
||||
if (DocForm(&fn)) {
|
||||
res=ToBool(Copy(st,fn.name));
|
||||
} else
|
||||
send_new_line=TRUE;
|
||||
break;
|
||||
case RIGHT_MOVE:
|
||||
StrCpy(fn.name,st);
|
||||
if (DocForm(&fn))
|
||||
res=Move(st,fn.name);
|
||||
else
|
||||
send_new_line=TRUE;
|
||||
break;
|
||||
case RIGHT_DELETE:
|
||||
res=ToBool(Del(st));
|
||||
break;
|
||||
case RIGHT_TYPE:
|
||||
res=Type(st);
|
||||
break;
|
||||
case RIGHT_ED:
|
||||
if (FileExtDot(st) && !FilesFindMatch(st,FILEMASK_DD)) {
|
||||
if (!PopUpCancelOk(ST_WARN_ST "Not DolDoc File\n\n")) {
|
||||
send_new_line=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
"Ed(\"%s\");\n$$PT$$$$FG$$$$BG$$",st;
|
||||
res=Ed(st);
|
||||
break;
|
||||
case RIGHT_MOUNT:
|
||||
if (FileExtDot(st) && !FilesFindMatch(st,"*.ISO.C")) {
|
||||
if (!PopUpCancelOk(ST_WARN_ST "Not .ISO.C File\n\n")) {
|
||||
send_new_line=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
"MountFile(\"%s\");\n$$PT$$$$FG$$$$BG$$",st;
|
||||
WinZBufUpdate;
|
||||
MountFile(st);
|
||||
res=TRUE;
|
||||
break;
|
||||
case RIGHT_PLAIN:
|
||||
"Plain(\"%s\");\n$$PT$$$$FG$$$$BG$$",st;
|
||||
res=Plain(st);
|
||||
break;
|
||||
case RIGHT_INFILE:
|
||||
if (FileExtDot(st) && !FilesFindMatch(st,"*.IN*")) {
|
||||
if (!PopUpCancelOk(ST_WARN_ST "Not .IN File\n\n")) {
|
||||
send_new_line=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
"InFile(\"%s\");\n$$PT$$$$FG$$$$BG$$",st;
|
||||
WinZBufUpdate;
|
||||
InFile(st);
|
||||
res=TRUE;
|
||||
break;
|
||||
}
|
||||
} else
|
||||
send_new_line=TRUE;
|
||||
Free(st);
|
||||
} else
|
||||
send_new_line=TRUE;
|
||||
Free(st2);
|
||||
} else
|
||||
send_new_line=TRUE;
|
||||
DocBottom(doc);
|
||||
"$$PT$$$$FG$$$$BG$$";
|
||||
if (send_new_line)
|
||||
'\n';
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,167 @@
|
||||
#help_index "DolDoc"
|
||||
|
||||
public Bool DocTreeFind(CDoc *haystack_doc,U8 *needle_path,
|
||||
CDocEntry **_tree_entry=NULL,
|
||||
CDocEntry **_start_indent=NULL, CDocEntry **_end_indent=NULL)
|
||||
{//Find registry-like tree widget start and end.
|
||||
I64 i=0,k=0;
|
||||
U8 *st1=StrNew(needle_path),*st2=MAlloc(StrLen(needle_path)+1);
|
||||
Bool res=FALSE,unlock_doc=DocLock(haystack_doc);
|
||||
CDocEntry *doc_e=haystack_doc->head.next;
|
||||
if (_tree_entry) *_tree_entry=haystack_doc;
|
||||
if (_start_indent) *_start_indent=haystack_doc;
|
||||
if (_end_indent) *_end_indent=haystack_doc;
|
||||
while (*st1 && doc_e!=haystack_doc) {
|
||||
StrFirstRem(st1,"/",st2);
|
||||
if (*st2) {
|
||||
while (doc_e!=haystack_doc) {
|
||||
if (doc_e->type_u8==DOCT_INDENT)
|
||||
i+=doc_e->attr;
|
||||
else if (i==k && doc_e->de_flags&DOCEF_TREE &&
|
||||
!StrCmp(doc_e->tag+3,st2)) {
|
||||
if (*st1)
|
||||
break;
|
||||
else {
|
||||
if (_tree_entry) *_tree_entry=doc_e;
|
||||
i=0;
|
||||
while (doc_e!=haystack_doc && doc_e->type_u8!=DOCT_INDENT)
|
||||
doc_e=doc_e->next;
|
||||
if (doc_e!=haystack_doc) {
|
||||
i=doc_e->attr;
|
||||
if (_start_indent) *_start_indent=doc_e;
|
||||
doc_e=doc_e->next;
|
||||
while (doc_e!=haystack_doc && i>0) {
|
||||
if (doc_e->type_u8==DOCT_INDENT) {
|
||||
i+=doc_e->attr;
|
||||
if (i<=0) {
|
||||
if (_end_indent) *_end_indent=doc_e;
|
||||
res=TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
}
|
||||
goto ft_done;
|
||||
}
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
k+=2;
|
||||
}
|
||||
}
|
||||
ft_done:
|
||||
if (unlock_doc)
|
||||
DocUnlock(haystack_doc);
|
||||
Free(st1);
|
||||
Free(st2);
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool DocTreeMake(CDoc *doc,U8 *path)
|
||||
{//Make registry-like tree widget.
|
||||
I64 i=0,j=I64_MIN,k=0;
|
||||
U8 *st1=StrNew(path),
|
||||
*st2=MAlloc(StrLen(path)+1),
|
||||
*st3=StrNew(path);
|
||||
Bool res=TRUE,unlock_doc=DocLock(doc);
|
||||
CDocEntry *doc_e=doc->head.next;
|
||||
doc->cur_entry=doc;
|
||||
doc->cur_col=0;
|
||||
while (*st1 && doc_e!=doc) {
|
||||
StrFirstRem(st1,"/",st2);
|
||||
if (*st2) {
|
||||
while (doc_e!=doc) {
|
||||
if (doc_e->type_u8==DOCT_INDENT) {
|
||||
i+=doc_e->attr;
|
||||
if (i==j) {
|
||||
doc->cur_entry=doc_e;
|
||||
doc->cur_col=0;
|
||||
goto mt_done;
|
||||
}
|
||||
} else if (i==k && doc_e->de_flags&DOCEF_TREE &&
|
||||
!StrCmp(doc_e->tag+3,st2)) {
|
||||
Free(st3);
|
||||
st3=StrNew(st1);
|
||||
j=i;
|
||||
if (!*st1)
|
||||
res=FALSE;
|
||||
else
|
||||
break;
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
k+=2;
|
||||
}
|
||||
}
|
||||
mt_done:
|
||||
if (res) {
|
||||
while (*st3) {
|
||||
StrFirstRem(st3,"/",st2);
|
||||
if (*st2) {
|
||||
DocPrint(doc,"$$TR+C,\"%s\"$$\n$$ID,2$$",st2);
|
||||
doc->cur_entry=DocPrint(doc,"$$ID,-2$$");
|
||||
doc->cur_col=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
Free(st1);
|
||||
Free(st2);
|
||||
Free(st3);
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "DolDoc/Compiler;Compiler"
|
||||
public I64 ExeDoc(CDoc *doc,I64 ccf_flags=0)
|
||||
{//JIT Compile and execute a document.
|
||||
I64 res;
|
||||
Bool okay=TRUE,unlock_doc=DocLock(doc);
|
||||
CCmpCtrl *cc=CmpCtrlNew(,ccf_flags|CCF_DONT_FREE_BUF);
|
||||
if (Fs->last_cc!=&Fs->next_cc)
|
||||
cc->opts=Fs->last_cc->opts;
|
||||
QueIns(cc,Fs->last_cc);
|
||||
LexAttachDoc(cc,,doc);
|
||||
try {
|
||||
Lex(cc);
|
||||
res=ExeCmdLine(cc);
|
||||
} catch {
|
||||
if (Fs->except_ch=='Compiler' || Fs->except_ch=='Break') {
|
||||
Fs->catch_except=TRUE;
|
||||
okay=FALSE;
|
||||
res=0;
|
||||
}
|
||||
}
|
||||
QueRem(cc);
|
||||
if (okay)
|
||||
CmpCtrlDel(cc); //TODO: can crash
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 DocTreeBranchExe(CDoc *doc,U8 *path)
|
||||
{//JIT Compile and execute code in doc tree branch.
|
||||
CDoc *doc2;
|
||||
Bool unlock_doc=DocLock(doc);
|
||||
CDocEntry *tree_branch,*start_indent,*end_indent;
|
||||
I64 res=0;
|
||||
if (DocTreeFind(doc,path,&tree_branch,&start_indent,&end_indent)) {
|
||||
doc2=DocCopy(doc,tree_branch,end_indent);
|
||||
res=ExeDoc(doc2);
|
||||
DocDel(doc2);
|
||||
}
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 ExeTreeBranch(U8 *registry_file,U8 *path)
|
||||
{//JIT Compile and execute a specified branch in a specified file.
|
||||
I64 res;
|
||||
CDoc *doc=DocRead(registry_file);
|
||||
res=DocTreeBranchExe(doc,path);
|
||||
DocDel(doc);
|
||||
return res;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,69 @@
|
||||
Cd(__DIR__);;
|
||||
|
||||
#help_index "DolDoc"
|
||||
#help_file "::/Doc/DolDoc"
|
||||
|
||||
/*
|
||||
TempleOS DolDoc's can have "cursor movement" cmds which can move the cursor up
|
||||
the scrn and layer on existing text. It can also have callback funs which
|
||||
supply live, changing text. For these reasons, you can't assume you know
|
||||
where the vis portion of the document is and must process much
|
||||
of the document each time it is placed on the scrn, becoming CPU
|
||||
intensive on big documents.
|
||||
See $LK,"::/Doc/DolDocOverview.DD"$
|
||||
*/
|
||||
|
||||
//Hash Types
|
||||
#define DHT_DOC_CMD 1
|
||||
#define DHT_DOC_FLAG 2
|
||||
#define DHT_COLOR 4
|
||||
|
||||
public class CDolDocGlbls
|
||||
{
|
||||
CHashTable *hash;
|
||||
I64 dft_de_flags [DOCT_TYPES_NUM],
|
||||
type_flags_nontag_invis [(DOCT_TYPES_NUM+63)/64],
|
||||
type_flags_form [(DOCT_TYPES_NUM+63)/64],
|
||||
type_flags_data [(DOCT_TYPES_NUM+63)/64],
|
||||
type_flags_chk_dup [(DOCT_TYPES_NUM+63)/64],
|
||||
clean_scan_codes [4];
|
||||
I32 dft_type_flags [DOCT_TYPES_NUM];
|
||||
} doldoc;
|
||||
MemSet(&doldoc,0,sizeof(CDolDocGlbls));
|
||||
|
||||
#help_index "God"
|
||||
#define BIBLE_FILENAME "::/Misc/Bible.TXT.Z"
|
||||
|
||||
#include "DocExt"
|
||||
#include "DocBin"
|
||||
#include "DocNew"
|
||||
#include "DocForm"
|
||||
#include "DocDblBuf"
|
||||
#include "DocPlain"
|
||||
#include "DocInit"
|
||||
#include "DocHighlight"
|
||||
#include "DocRecalcLib"
|
||||
#include "DocRecalc"
|
||||
#include "DocFile"
|
||||
#include "DocClipBoard"
|
||||
#include "DocRun"
|
||||
#include "DocGet"
|
||||
#include "DocChar"
|
||||
#include "DocFind"
|
||||
#include "DocLink"
|
||||
#include "DocEd"
|
||||
#include "DocPopUp"
|
||||
#include "DocGr"
|
||||
#include "DocMacro"
|
||||
#include "DocWidgetWiz"
|
||||
#include "DocPutKey"
|
||||
#include "DocPutS"
|
||||
#include "DocCodeTools"
|
||||
#include "DocTree"
|
||||
#include "DocTerm"
|
||||
|
||||
KeyDevAdd(&KDDocPutKey,&KDDocPutS,0x80000000,TRUE);
|
||||
fp_getstr2=&DocGetStr2;
|
||||
fp_doc_put=&DocPut;
|
||||
|
||||
Cd("..");;
|
||||
@@ -0,0 +1,348 @@
|
||||
#help_index "God"
|
||||
U0 BibleInit()
|
||||
{
|
||||
DefineLstLoad("ST_BIBLE_BOOKS",
|
||||
"Genesis\0"
|
||||
"Exodus\0"
|
||||
"Leviticus\0"
|
||||
"Numbers\0"
|
||||
"Deuteronomy\0"
|
||||
"Joshua\0"
|
||||
"Judges\0"
|
||||
"Ruth\0"
|
||||
"1 Samuel\0"
|
||||
"2 Samuel\0"
|
||||
"1 Kings\0"
|
||||
"2 Kings\0"
|
||||
"1 Chronicles\0"
|
||||
"2 Chronicles\0"
|
||||
"Ezra\0"
|
||||
"Nehemiah\0"
|
||||
"Esther\0"
|
||||
"Job\0"
|
||||
"Psalms\0"
|
||||
"Proverbs\0"
|
||||
"Ecclesiastes\0"
|
||||
"Song of Songs\0"
|
||||
"Isaiah\0"
|
||||
"Jeremiah\0"
|
||||
"Lamentations\0"
|
||||
"Ezekiel\0"
|
||||
"Daniel\0"
|
||||
"Hosea\0"
|
||||
"Joel\0"
|
||||
"Amos\0"
|
||||
"Obadiah\0"
|
||||
"Jonah\0"
|
||||
"Micah\0"
|
||||
"Nahum\0"
|
||||
"Habakkuk\0"
|
||||
"Zephaniah\0"
|
||||
"Haggai\0"
|
||||
"Zechariah\0"
|
||||
"Malachi\0"
|
||||
"Matthew\0"
|
||||
"Mark\0"
|
||||
"Luke\0"
|
||||
"John\0"
|
||||
"Acts\0"
|
||||
"Romans\0"
|
||||
"1 Corinthians\0"
|
||||
"2 Corinthians\0"
|
||||
"Galatians\0"
|
||||
"Ephesians\0"
|
||||
"Philippians\0"
|
||||
"Colossians\0"
|
||||
"1 Thessalonians\0"
|
||||
"2 Thessalonians\0"
|
||||
"1 Timothy\0"
|
||||
"2 Timothy\0"
|
||||
"Titus\0"
|
||||
"Philemon\0"
|
||||
"Hebrews\0"
|
||||
"James\0"
|
||||
"1 Peter\0"
|
||||
"2 Peter\0"
|
||||
"1 John\0"
|
||||
"2 John\0"
|
||||
"3 John\0"
|
||||
"Jude\0"
|
||||
"Revelation\0");
|
||||
DefineLstLoad("ST_BIBLE_BOOK_LINES",
|
||||
"297\0"
|
||||
"5068\0"
|
||||
"9123\0"
|
||||
"12005\0"
|
||||
"15977\0"
|
||||
"19168\0"
|
||||
"21329\0"
|
||||
"23598\0"
|
||||
"23902\0"
|
||||
"26892\0"
|
||||
"29345\0"
|
||||
"32241\0"
|
||||
"34961\0"
|
||||
"37633\0"
|
||||
"40756\0"
|
||||
"41671\0"
|
||||
"42963\0"
|
||||
"43605\0"
|
||||
"46190\0"
|
||||
"53793\0"
|
||||
"56267\0"
|
||||
"56966\0"
|
||||
"57332\0"
|
||||
"61806\0"
|
||||
"66736\0"
|
||||
"67217\0"
|
||||
"71804\0"
|
||||
"73189\0"
|
||||
"73876\0"
|
||||
"74130\0"
|
||||
"74615\0"
|
||||
"74697\0"
|
||||
"74860\0"
|
||||
"75241\0"
|
||||
"75416\0"
|
||||
"75604\0"
|
||||
"75806\0"
|
||||
"75932\0"
|
||||
"76684\0"
|
||||
"76908\0"
|
||||
"79970\0"
|
||||
"81941\0"
|
||||
"85266\0"
|
||||
"87803\0"
|
||||
"90914\0"
|
||||
"92110\0"
|
||||
"93323\0"
|
||||
"94088\0"
|
||||
"94514\0"
|
||||
"94869\0"
|
||||
"95153\0"
|
||||
"95402\0"
|
||||
"95647\0"
|
||||
"95772\0"
|
||||
"96090\0"
|
||||
"96320\0"
|
||||
"96440\0"
|
||||
"96500\0"
|
||||
"97370\0"
|
||||
"97687\0"
|
||||
"97976\0"
|
||||
"98163\0"
|
||||
"98506\0"
|
||||
"98552\0"
|
||||
"98597\0"
|
||||
"98684\0"
|
||||
"100111\0");
|
||||
DefinePrint("ST_BIBLE_LINES","%d",
|
||||
Str2I64(DefineSub(DefineCnt("ST_BIBLE_BOOK_LINES")-1,
|
||||
"ST_BIBLE_BOOK_LINES"))-1);
|
||||
} BibleInit;
|
||||
|
||||
public U8 *BibleLine2Verse(I64 line,I64 separate_ch=CH_SPACE)
|
||||
{//Line number to verse str, Malloc()ed.
|
||||
//Separate with <SPACE> or ','. If you pass '%', it uses "%20".
|
||||
CDoc *doc;
|
||||
CDocEntry *doc_e;
|
||||
I64 i=0,cnt=DefineCnt("ST_BIBLE_BOOKS"),start=0,last_start=0;
|
||||
U8 *ptr=DefineSub(0,"ST_BIBLE_BOOK_LINES"),*ptr2;
|
||||
while (i<=cnt) {
|
||||
last_start=start;
|
||||
start=Str2I64(ptr);
|
||||
if (line<start)
|
||||
break;
|
||||
i++;
|
||||
ptr+=StrLen(ptr)+1;
|
||||
}
|
||||
if (0<=--i<cnt) {
|
||||
doc=DocRead(BIBLE_FILENAME,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
|
||||
DocLineNumGoTo(doc,line); //one based
|
||||
doc_e=doc->cur_entry;
|
||||
while (doc_e!=doc && (doc_e->type_u8!=DOCT_TEXT || !*doc_e->tag))
|
||||
doc_e=doc_e->next;
|
||||
if (doc_e->type_u8==DOCT_TEXT && '0'<=*doc_e->tag<='9') {
|
||||
ptr=ptr2=doc_e->tag;
|
||||
while ('0'<=*ptr2<='9' || *ptr2==':')
|
||||
ptr2++;
|
||||
*ptr2=0;
|
||||
if (separate_ch=='%')
|
||||
ptr=MStrPrint("%Z%%20%s",i,"ST_BIBLE_BOOKS",ptr);
|
||||
else
|
||||
ptr=MStrPrint("%Z%c%s",i,"ST_BIBLE_BOOKS",separate_ch,ptr);
|
||||
} else {
|
||||
while (TRUE) {
|
||||
doc_e=doc_e->last;
|
||||
if (doc_e==doc) {
|
||||
ptr=NULL;
|
||||
break;
|
||||
}
|
||||
if (doc_e->y+1<last_start) {
|
||||
ptr=MStrPrint("%Z",i,"ST_BIBLE_BOOKS");
|
||||
break;
|
||||
}
|
||||
if (doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=3) {
|
||||
ptr=doc_e->tag+StrLen(doc_e->tag)-1;
|
||||
while (ptr>doc_e->tag && (!('0'<=*(ptr-1)<='9') || *ptr!=':' ||
|
||||
!('0'<=*(ptr+1)<='9')))
|
||||
ptr--;
|
||||
ptr--;
|
||||
while (ptr>=doc_e->tag && '0'<=*ptr<='9')
|
||||
ptr--;
|
||||
ptr2=++ptr;
|
||||
if ('0'<=*ptr2++<='9') {
|
||||
while ('0'<=*ptr2<='9')
|
||||
ptr2++;
|
||||
if (*ptr2++==':' && '0'<=*ptr2++<='9') {
|
||||
while ('0'<=*ptr2<='9')
|
||||
ptr2++;
|
||||
*ptr2=0;
|
||||
if (separate_ch=='%')
|
||||
ptr=MStrPrint("%Z%%20%s",i,"ST_BIBLE_BOOKS",ptr);
|
||||
else
|
||||
ptr=MStrPrint("%Z%c%s",i,"ST_BIBLE_BOOKS",separate_ch,ptr);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
DocDel(doc);
|
||||
return ptr;
|
||||
} else
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public U0 BookLines(CDoc *doc_out=NULL,I64 start,I64 lines,
|
||||
U8 *book_filename=BIBLE_FILENAME)
|
||||
{//Put N line starting at line M into doc.
|
||||
CDoc *doc_in;
|
||||
CDocEntry *doc_e;
|
||||
if (!doc_out) doc_out=DocPut;
|
||||
if (doc_out && FileFind(book_filename)) {
|
||||
doc_in=DocRead(book_filename,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
|
||||
DocLineNumGoTo(doc_in,start); //one based
|
||||
doc_e=doc_in->cur_entry;
|
||||
while (lines>0 && doc_e!=doc_in) {
|
||||
if (doc_e->type_u8==DOCT_TEXT)
|
||||
DocPrint(doc_out,"%s",doc_e->tag);
|
||||
else if (doc_e->type_u8==DOCT_NEW_LINE) {
|
||||
DocPutKey(doc_out,'\n');
|
||||
lines--;
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
DocDel(doc_in);
|
||||
}
|
||||
}
|
||||
|
||||
public U0 BibleVerse(CDoc *doc_out=NULL,U8 *verse,I64 lines)
|
||||
{//Put N lines starting at verse str into doc.
|
||||
I64 i;
|
||||
CDoc *doc_in;
|
||||
CDocEntry *doc_e;
|
||||
U8 *st,*st2;
|
||||
if (!doc_out) doc_out=DocPut;
|
||||
if (doc_out && FileFind(BIBLE_FILENAME)) {
|
||||
st=StrNew(verse);
|
||||
st2=StrNew(verse);
|
||||
if (StrOcc(st,','))
|
||||
StrLastRem(st,",",st2);
|
||||
else
|
||||
*st2=0;
|
||||
i=DefineMatch(st,"ST_BIBLE_BOOKS",LMF_IGNORE_CASE);
|
||||
if (i>=0) {
|
||||
i=Str2I64(DefineSub(i,"ST_BIBLE_BOOK_LINES"));
|
||||
doc_in=DocRead(BIBLE_FILENAME,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
|
||||
DocLineNumGoTo(doc_in,i); //one based
|
||||
if (*st2) {
|
||||
StrCpy(doc_in->find_replace->find_text,st2);
|
||||
EdFindNext(doc_in);
|
||||
}
|
||||
doc_e=doc_in->cur_entry;
|
||||
while (lines>0 && doc_e!=doc_in) {
|
||||
if (doc_e->type_u8==DOCT_TEXT)
|
||||
DocPrint(doc_out,"%s",doc_e->tag);
|
||||
else if (doc_e->type_u8==DOCT_NEW_LINE) {
|
||||
DocPutKey(doc_out,'\n');
|
||||
lines--;
|
||||
}
|
||||
doc_e=doc_e->next;
|
||||
}
|
||||
DocDel(doc_in);
|
||||
}
|
||||
Free(st);
|
||||
Free(st2);
|
||||
}
|
||||
}
|
||||
|
||||
public CDoc *BibleDoc()
|
||||
{//Return Bible as DolDoc with trees.
|
||||
CDoc *res=DocRead(BIBLE_FILENAME);
|
||||
CDocEntry *doc_e=res->head.next,*doc_e1;
|
||||
Bool open_chapter=FALSE;
|
||||
U8 *ptr=Define("ST_BIBLE_BOOK_LINES");
|
||||
I64 book,book_cnt=DefineCnt("ST_BIBLE_BOOK_LINES")-1,
|
||||
chapter,
|
||||
line=Str2I64(ptr,,&ptr);
|
||||
ptr++;
|
||||
for (book=0;book<book_cnt;book++) {
|
||||
while (doc_e->y+1<line) {
|
||||
doc_e1=doc_e->next;
|
||||
DocEntryDel(res,doc_e);
|
||||
doc_e=doc_e1;
|
||||
}
|
||||
res->cur_entry=doc_e;
|
||||
res->cur_col=0;
|
||||
DocPrint(res,"$$TR,\"%Z\"$$\n$$ID,2$$",book,"ST_BIBLE_BOOKS");
|
||||
line=Str2I64(ptr,,&ptr);
|
||||
ptr++;
|
||||
chapter=1;
|
||||
while (doc_e->y+1<line) {
|
||||
doc_e1=doc_e->next;
|
||||
if (doc_e->type_u8==DOCT_TEXT && StrMatch(":1 ",doc_e->tag)) {
|
||||
res->cur_entry=doc_e;
|
||||
res->cur_col=0;
|
||||
if (open_chapter) {
|
||||
DocPrint(res,"$$ID,-2$$");
|
||||
open_chapter=FALSE;
|
||||
}
|
||||
DocPrint(res,"$$TR,\"%d\"$$\n$$ID,2$$",chapter++);
|
||||
open_chapter=TRUE;
|
||||
} else if (chapter==1) {
|
||||
doc_e1=doc_e->next;
|
||||
DocEntryDel(res,doc_e);
|
||||
doc_e=doc_e1;
|
||||
}
|
||||
doc_e=doc_e1;
|
||||
}
|
||||
res->cur_entry=doc_e;
|
||||
res->cur_col=0;
|
||||
if (open_chapter) {
|
||||
DocPrint(res,"$$ID,-2$$");
|
||||
open_chapter=FALSE;
|
||||
}
|
||||
DocPrint(res,"$$ID,-2$$");
|
||||
}
|
||||
while (doc_e!=res) {
|
||||
doc_e1=doc_e->next;
|
||||
DocEntryDel(res,doc_e);
|
||||
doc_e=doc_e1;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 BibleView()
|
||||
{//View Bible as DolDoc with trees.
|
||||
U8 buf[STR_LEN];
|
||||
CDoc *doc=BibleDoc;
|
||||
StrPrint(buf,"AL:%d,1",doc);
|
||||
Ed(buf);
|
||||
DocDel(doc);
|
||||
}
|
||||
U0 CtrlAltB(I64)
|
||||
{
|
||||
PopUp("BibleView;");
|
||||
}
|
||||
CtrlAltCBSet('B',&CtrlAltB,"Cmd /Bible");
|
||||
@@ -0,0 +1,192 @@
|
||||
#help_index "God;Graphics/Sprite;Sprites"
|
||||
|
||||
U0 GodDoodleDraw(CTask *task,CDC *dc)
|
||||
{
|
||||
GrBlot(dc,0,0,god.doodle_dc);
|
||||
if (Blink) {
|
||||
if (god.doodle_done) {
|
||||
dc->color=RED;
|
||||
GrPrint(dc,(task->pix_width-FONT_WIDTH*29)>>1,
|
||||
(task->pix_height-3*FONT_HEIGHT)>>1,
|
||||
"Press <ESC> to insert sprite.");
|
||||
GrPrint(dc,(task->pix_width-FONT_WIDTH*39)>>1,
|
||||
(task->pix_height-3*FONT_HEIGHT)>>1+2*FONT_HEIGHT,
|
||||
"Press <SHIFT-ESC> to throw-away sprite.");
|
||||
} else {
|
||||
dc->color=GREEN;
|
||||
GrPrint(dc,(task->pix_width-FONT_WIDTH*25)>>1,
|
||||
(task->pix_height-FONT_HEIGHT)>>1,
|
||||
"Press <SPACE> repeatedly.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 GodDoodleSmooth(I64 num)
|
||||
{
|
||||
CDC *dc=DCExt(god.doodle_dc,0,0,
|
||||
god.doodle_dc->width-1,god.doodle_dc->height-1);
|
||||
I64 i,x,y,x1,y1,c,histogram[16],best,best_cnt,c_old=god.doodle_dc->color;
|
||||
for (y=0;y<god.doodle_dc->height;y++)
|
||||
for (x=0;x<god.doodle_dc->width;x++) {
|
||||
MemSet(histogram,0,sizeof(histogram));
|
||||
for (y1=y-num;y1<=y+num;y1++)
|
||||
for (x1=x-num;x1<=x+num;x1++) {
|
||||
c=GrPeek(dc,x1,y1);
|
||||
if (0<=c<=15)
|
||||
histogram[c]++;
|
||||
}
|
||||
best=BLACK;
|
||||
best_cnt=-1;
|
||||
for (i=0;i<16;i++)
|
||||
if (histogram[i]>best_cnt) {
|
||||
best=i;
|
||||
best_cnt=histogram[i];
|
||||
}
|
||||
god.doodle_dc->color=best;
|
||||
GrPlot(god.doodle_dc,x,y);
|
||||
}
|
||||
god.doodle_dc->color=c_old;
|
||||
DCDel(dc);
|
||||
}
|
||||
|
||||
U0 GodDoodleBitsIns(I64 num_bits,I64 n)
|
||||
{//Insert bits into God doodle bit fifo.
|
||||
I64 i;
|
||||
for (i=0;i<num_bits;i++) {
|
||||
FifoU8Ins(god.doodle_fifo,n&1);
|
||||
n>>=1;
|
||||
}
|
||||
}
|
||||
|
||||
U0 GodDoodleHexIns(U8 *st)
|
||||
{//Insert hex record into God doodle bit fifo.
|
||||
U8 buf[2];
|
||||
if (st) {
|
||||
buf[1]=0;
|
||||
while (*buf=*st++)
|
||||
if (Bt(char_bmp_hex_numeric,*buf))
|
||||
GodDoodleBitsIns(4,rev_bits_table[Str2I64(buf,16)]>>4);
|
||||
}
|
||||
}
|
||||
|
||||
I64 GodDoodleBits(I64 num_bits)
|
||||
{
|
||||
U8 b;
|
||||
I64 res=0;
|
||||
while (num_bits) {
|
||||
if (FifoU8Rem(god.doodle_fifo,&b)) {
|
||||
res=res<<1+b;
|
||||
num_bits--;
|
||||
} else {
|
||||
god.doodle_ch=GetChar(,FALSE);
|
||||
if (god.doodle_ch==CH_ESC||god.doodle_ch==CH_SHIFT_ESC)
|
||||
throw;
|
||||
else if (god.doodle_ch=='\n') {
|
||||
DCFill(god.doodle_dc,WHITE);
|
||||
FifoU8Flush(god.doodle_fifo);
|
||||
} else if ('0'<=god.doodle_ch<='9')
|
||||
GodDoodleSmooth(god.doodle_ch-'0');
|
||||
else
|
||||
GodDoodleBitsIns(GOD_GOOD_BITS,KbdMsEvtTime>>GOD_BAD_BITS);
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *GodDoodleSprite(U8 *hex=NULL)
|
||||
{//Make God draw sprite. $LK+PU,"Holy Spirit Instructions",A="FI:::/Adam/God/HSNotes.DD"$
|
||||
I64 i,j,w,h,x,y,ch;
|
||||
U8 *elems;
|
||||
|
||||
if (god.doodle_dc) return NULL;
|
||||
god.doodle_done=FALSE;
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
AutoComplete;
|
||||
WinBorder;
|
||||
WinMax;
|
||||
|
||||
if (!hex)
|
||||
PopUpOk("The $LK+PU,"Holy Spirit",A="FI:::/Adam/God/HSNotes.DD"$ can puppet you.\n\n"
|
||||
"Press $$GREEN$$<SPACE>$$FG$$ until it finishes.");
|
||||
|
||||
god.doodle_ch=0;
|
||||
god.doodle_dc=DCNew(Fs->pix_width,Fs->pix_height);
|
||||
DCFill(god.doodle_dc,WHITE);
|
||||
w=god.doodle_dc->width;
|
||||
h=god.doodle_dc->height;
|
||||
|
||||
Fs->draw_it=&GodDoodleDraw;
|
||||
FifoU8Flush(god.doodle_fifo);
|
||||
GodDoodleHexIns(hex);
|
||||
try {
|
||||
for (i=0;i<3;i++) {
|
||||
god.doodle_dc->color=RED;
|
||||
for (j=0;j<29;j++)
|
||||
switch [GodDoodleBits(3)] {
|
||||
case 0:
|
||||
GrEllipse3(god.doodle_dc,
|
||||
(w-1)*GodDoodleBits(5)/15.5-w/2,
|
||||
(h-1)*GodDoodleBits(5)/15.5-h/2,0,
|
||||
(w-1)*GodDoodleBits(5)/15.5,(h-1)*GodDoodleBits(5)/15.5);
|
||||
break;
|
||||
case 1:
|
||||
GrCircle3(god.doodle_dc,
|
||||
(w-1)*GodDoodleBits(5)/15.5-w/2,
|
||||
(h-1)*GodDoodleBits(5)/15.5-h/2,0,
|
||||
(w-1)*GodDoodleBits(5)/15.5);
|
||||
break;
|
||||
case 2:
|
||||
GrBorder(god.doodle_dc,
|
||||
(w-1)*GodDoodleBits(5)/15.5-w/2,
|
||||
(h-1)*GodDoodleBits(5)/15.5-h/2,
|
||||
(w-1)*GodDoodleBits(5)/15.5,(h-1)*GodDoodleBits(5)/15.5);
|
||||
break;
|
||||
case 3...7:
|
||||
GrLine3(god.doodle_dc,
|
||||
(w-1)*GodDoodleBits(4)/15,(h-1)*GodDoodleBits(4)/15,0,
|
||||
(w-1)*GodDoodleBits(4)/15,(h-1)*GodDoodleBits(4)/15,0);
|
||||
break;
|
||||
}
|
||||
for (j=0;j<6;j++) {
|
||||
x=(w-1)*GodDoodleBits(5)/31+w/64;
|
||||
y=(h-1)*GodDoodleBits(5)/31+h/64;
|
||||
switch [GodDoodleBits(2)] {
|
||||
case 0: god.doodle_dc->color=BLACK; break;
|
||||
case 1: god.doodle_dc->color=DKGRAY; break;
|
||||
case 2: god.doodle_dc->color=LTGRAY; break;
|
||||
case 3: god.doodle_dc->color=WHITE; break;
|
||||
}
|
||||
GrFloodFill3(god.doodle_dc,x,y,0);
|
||||
}
|
||||
GodDoodleSmooth(3);
|
||||
}
|
||||
god.doodle_done=TRUE;
|
||||
if (!hex) {
|
||||
do ch=GetChar(,FALSE);
|
||||
while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
|
||||
} else
|
||||
ch=CH_ESC;
|
||||
} catch {
|
||||
Fs->catch_except=TRUE;
|
||||
ch=CH_SHIFT_ESC;
|
||||
}
|
||||
DCFill;
|
||||
SettingsPop;
|
||||
if (ch==CH_ESC)
|
||||
elems=DC2Sprite(god.doodle_dc);
|
||||
else
|
||||
elems=NULL;
|
||||
DCDel(god.doodle_dc);
|
||||
god.doodle_dc=NULL;
|
||||
return elems;
|
||||
}
|
||||
|
||||
#help_index "God"
|
||||
public U0 GodDoodle(U8 *hex=NULL)
|
||||
{//Make God draw sprite, insert in doc. $LK+PU,"Holy Spirit Instructions",A="FI:::/Adam/God/HSNotes.DD"$
|
||||
U8 *elems;
|
||||
if (elems=GodDoodleSprite(hex)) {
|
||||
Sprite(elems);
|
||||
Free(elems);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
#help_index "God"
|
||||
|
||||
#define GOD_BAD_BITS 4
|
||||
#define GOD_GOOD_BITS 24
|
||||
|
||||
public class CGodGlbls
|
||||
{
|
||||
U8 **words,
|
||||
*word_file_mask;
|
||||
I64 word_fuf_flags,
|
||||
num_words;
|
||||
CFifoU8 *fifo;
|
||||
CDC *doodle_dc;
|
||||
I64 doodle_ch;
|
||||
CFifoU8 *doodle_fifo;
|
||||
Bool doodle_done;
|
||||
} god;
|
||||
MemSet(&god,0,sizeof(CGodGlbls));
|
||||
god.doodle_fifo =FifoU8New(2048*8);
|
||||
god.fifo =FifoU8New(2048*8);
|
||||
|
||||
extern U0 GodBiblePassage(I64 num_lines=20);
|
||||
extern U0 GodBitsIns(I64 num_bits,I64 n);
|
||||
extern U0 GodDoodle(U8 *hex=NULL);
|
||||
extern U0 GodSong();
|
||||
extern U0 GodWord(I64 bits=17,Bool show_num=FALSE);
|
||||
@@ -0,0 +1,171 @@
|
||||
#help_index "God"
|
||||
|
||||
DefineLstLoad("ST_RHYTHM_COMPLEXITY","Simple\0Normal\0Complex\0");
|
||||
|
||||
class CMakeSongSettings
|
||||
{
|
||||
I64 complexity fmtstr "$$LS,D=\"ST_RHYTHM_COMPLEXITY\"$$\n";
|
||||
Bool rests fmtstr "$$CB,\"Rests\"$$\n";
|
||||
Bool six_eight fmtstr "$$CB,\"Six Eight\"$$\n";
|
||||
I64 octave fmtstr "$$DA-TRM,A=\"Octave:%d\"$$\n";
|
||||
I64 octave_state;
|
||||
};
|
||||
|
||||
U0 InsNote(CMakeSongSettings *mss,U8 *buf,I64 k,I64 *j)
|
||||
{//k is a random note nibble
|
||||
if (!k && mss->rests) {
|
||||
buf[*j]='R';
|
||||
*j+=1;
|
||||
} else {
|
||||
k/=2;
|
||||
if (k<3) {
|
||||
if (mss->octave_state!=mss->octave) {
|
||||
mss->octave_state=mss->octave;
|
||||
buf[*j]=mss->octave_state+'0';
|
||||
*j+=1;
|
||||
}
|
||||
if (!k)
|
||||
buf[*j]='G';
|
||||
else
|
||||
buf[*j]=k-1+'A';
|
||||
*j+=1;
|
||||
} else {
|
||||
if (mss->octave_state!=mss->octave+1) {
|
||||
mss->octave_state=mss->octave+1;
|
||||
buf[*j]=mss->octave_state+'0';
|
||||
*j+=1;
|
||||
}
|
||||
buf[*j]=k-1+'A';
|
||||
*j+=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#define DUR_4 0
|
||||
#define DUR_8_8 1
|
||||
#define DUR_3_3_3 2
|
||||
#define DUR_16_16_16_16 3
|
||||
#define DUR_8DOT_16 4
|
||||
#define DUR_8_16_16 5
|
||||
#define DUR_16_16_8 6
|
||||
|
||||
U8 god_simple_songs [5]={DUR_4,DUR_4,DUR_4,DUR_4,DUR_8_8};
|
||||
U8 god_normal_songs [5]={DUR_4,DUR_4,DUR_8_8,DUR_3_3_3,DUR_16_16_16_16};
|
||||
U8 god_complex_songs[9]={DUR_4,DUR_4,DUR_8_8,DUR_8_8,DUR_8DOT_16,DUR_3_3_3,
|
||||
DUR_8_16_16,DUR_16_16_8,DUR_16_16_16_16};
|
||||
|
||||
public U8 *GodSongStr()
|
||||
{//Make God generate 2 measures of a song. $LK+PU,"Holy Spirit Instructions",A="FI:::/Adam/God/HSNotes.DD"$
|
||||
CMakeSongSettings mss;
|
||||
U8 *buf;
|
||||
I64 i,j=0,k,n,k2,duration,last_duration=-1,len;
|
||||
|
||||
MemSet(&mss,0,sizeof(mss));
|
||||
mss.complexity=1;
|
||||
mss.rests=FALSE;
|
||||
mss.octave=music.octave;
|
||||
|
||||
if (!PopUpForm(&mss))
|
||||
return NULL;
|
||||
|
||||
buf=CAlloc(256);
|
||||
music.octave=mss.octave=ClampI64(mss.octave,1,7);
|
||||
progress4=0;
|
||||
if (mss.six_eight)
|
||||
progress4_max=6;
|
||||
else
|
||||
progress4_max=8;
|
||||
|
||||
mss.octave_state=mss.octave+1;
|
||||
buf[j++]='0'+mss.octave_state;
|
||||
if (mss.six_eight) {
|
||||
len=6;
|
||||
buf[j++]='M';
|
||||
buf[j++]='6';
|
||||
buf[j++]='/';
|
||||
buf[j++]='8';
|
||||
} else
|
||||
len=8;
|
||||
FifoU8Flush(god.fifo);
|
||||
for (i=0;i<len;i++) {
|
||||
n=GodBits(8);
|
||||
if (mss.complexity==2)
|
||||
duration=god_complex_songs[n%9];
|
||||
else if (mss.complexity==1)
|
||||
duration=god_normal_songs[n%5];
|
||||
else
|
||||
duration=god_simple_songs[n%5];
|
||||
|
||||
switch (duration) {
|
||||
case DUR_8_8:
|
||||
if (last_duration!=DUR_8_8)
|
||||
buf[j++]='e';
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
break;
|
||||
case DUR_8DOT_16:
|
||||
buf[j++]='e';
|
||||
buf[j++]='.';
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
buf[j++]='s';
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
duration=DUR_16_16_16_16;
|
||||
break;
|
||||
case DUR_3_3_3:
|
||||
if (last_duration!=DUR_3_3_3) {
|
||||
buf[j++]='e';
|
||||
buf[j++]='t';
|
||||
}
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
break;
|
||||
case DUR_8_16_16:
|
||||
if (last_duration!=DUR_8_8)
|
||||
buf[j++]='e';
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
buf[j++]='s';
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
duration=DUR_16_16_16_16;
|
||||
break;
|
||||
case DUR_16_16_8:
|
||||
if (last_duration!=DUR_16_16_16_16)
|
||||
buf[j++]='s';
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
buf[j++]='e';
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
duration=DUR_8_8;
|
||||
break;
|
||||
case DUR_16_16_16_16:
|
||||
if (last_duration!=DUR_16_16_16_16)
|
||||
buf[j++]='s';
|
||||
k =GodBits(4);
|
||||
k2=GodBits(4);
|
||||
InsNote(&mss,buf,k,&j);
|
||||
InsNote(&mss,buf,k2,&j);
|
||||
InsNote(&mss,buf,k,&j);
|
||||
InsNote(&mss,buf,k2,&j);
|
||||
break;
|
||||
default:
|
||||
if (last_duration!=DUR_4)
|
||||
buf[j++]='q';
|
||||
InsNote(&mss,buf,GodBits(4),&j);
|
||||
}
|
||||
last_duration=duration;
|
||||
progress4++;
|
||||
}
|
||||
buf[j++]=0;
|
||||
progress4=progress4_max=0;
|
||||
return buf;
|
||||
}
|
||||
|
||||
public U0 GodSong()
|
||||
{//Make God generate 2measuresx2+2measuresx2. $LK+PU,"Holy Spirit Instructions",A="FI:::/Adam/God/HSNotes.DD"$
|
||||
U8 *st1=GodSongStr,*st2=GodSongStr;
|
||||
if (st1 && st2)
|
||||
DocPrint(DocPut,"$$SO,\"<Song>\",A=\"%s%s%s%s\"$$",st1,st1,st2,st2);
|
||||
Free(st1);
|
||||
Free(st2);
|
||||
}
|
||||
@@ -0,0 +1,223 @@
|
||||
$FG,5$$TX+CX,"The Purpose of Life"$$FG$
|
||||
|
||||
$WW,1$The Catholic purpose of life is to know God, love God and obey God.$FG$ Pope Francis said it was "to serve the other." I am High Priest of God's official temple and I say the purpose of life is to do continual offerings to God like Cain and Abel and enjoy God's response. Francis has a charity; I have a church. Jesus said loving God was more important than loving neighbor. $LK,"Matthew,22:35-40",A="BF:Matthew,22:35-40"$ And, He did not say with half your brain behind your back.
|
||||
|
||||
You don't know God. $LK,"1 Chronicles,28:9-9",A="BF:1 Chronicles,28:9-9"$, $LK,"Matthew,11:27-27",A="BF:Matthew,11:27-27"$, $LK,"Luke,13:25-27",A="BF:Luke,13:25-27"$, $LK,"1 Samuel,3:6-8",A="BF:1 Samuel,3:6-8"$ You must talk with God to know Him. With Samuel, supposedly, God took the initiative, but I think that is the exception. Seek the Lord by taking the initiative. $LK,"Luke,11:9-10",A="BF:Luke,11:9-10"$
|
||||
|
||||
There's something obviously different about people in the Bible compared to people today -- God talked! Also, the people in the Bible were obsessed with doing offerings all the time. It is required that you do offerings before God will talk. Did the people in the Bible hear voices? Maybe. More likely, they used occult techniques such as an oracle. $LK,"1 Kings,6:21",A="BF:1 Kings,6:21"$ Have you heard of "tongues?" $LK,"1 Corinthians,14:1-40",A="BF:1 Corinthians,14:1-40"$ The idea is, you let yourself be puppeted by a spirit, so you say things. You try to get a spirit -- the Holy Spirit -- to talk. You might as well use a Ouija board. However, it turns-out that a Ouija board is bad for technical reasons. A really good technique is just randomly opening a book. God told me in an oracle that it is a covenant that you hold-up your end of the conversation.
|
||||
|
||||
You can't tell if God's talking unless you have a context of conversation, but, more importantly, you are commanded to do an offering of love, like communion preparation. $LK,"1 Corinthians,11:27",A="BF:1 Corinthians,11:27"$ When you pick a greeting card for someone, that is love effort. If you expect God to put effort toward you, you must put effort toward Him. God said, "honest measures" applies between your offering of love and His response, like a fair barter. You get out of prayer what you put into it. God wants praise, hymns, or whatever you think He might want. Try and see, like Cain and Abel. $LK,"Genesis,4:1-10",A="BF:Genesis,4:1-10"$, $LK,"Ephesians,5:10",A="BF:Ephesians,5:10"$ God told Cain his offering was not good and told him to try again. Cain really loved God! Can you imagine being so heart-broken?
|
||||
|
||||
Do a text search for "new song" in the Bible. It's mentioned nine times. When I hear a NEW awesome rock song, it is ecstasy for the first five times I hear it. Soon, it brings little-to-no pleasure. I did $MA-X+PU,"hymns",HTML="http://www.templeos.org/Wb/Home/Web/HymnVideos.html",LM="#include \"::/Apps/Psalmody/Load\";JukeBox(\"::/Apps/Psalmody/Examples\");"$ for God. I also did Moses comics for God. When you get to the gates of Heaven, St. Peter will ask how many times you gave blood. That shows you loved neighbor. You better also be able to count the ways you loved God with all heart, mind and soul. I praised God for sand castles, popcorn, snowmen, bubbles... You try putting effort into praise! $LK,"Matthew,11:25",A="BF:Matthew,11:25"$, $LK,"Matthew,6:28-29",A="BF:Matthew,6:28-29"$ Solomon wrote a thousand songs. $LK,"1 Kings,4:32",A="BF:1 Kings,4:32"$
|
||||
|
||||
This is funny -- $LK,"Acts,2:1-13",A="BF:Acts,2:1-13"$ -- they didn't bother to record anything the Holy Spirit said. The Holy Spirit is supposed to be a really good gift. $LK,"Luke,11:11-13",A="BF:Luke,11:11-13"$ Just remember, "Boys are made of snakes and snails and puppy-dog tails."
|
||||
|
||||
The technique I use to consult the Holy Spirit is reading a microsecond-range stop-watch each button press for random numbers. Then, I pick words with $FG,2$<F7>$FG$ or passages with $FG,2$<SHIFT-F7>$FG$.
|
||||
|
||||
Since seeking the word of the Holy Spirit, I have come to know God much better than I've heard others explain. For example, God said to me in an oracle that war was, "servicemen competing." That sounds more like the immutable God of our planet than what you hear from most religious people. God is not Venus (god of love) and not Mars (god of war), He's our dearly beloved God of Earth. If Mammon is a false god of money, Mars or Venus might be useful words to describe other false gods. I figure the greatest challenge for the Creator is boredom, ours and His. What would teen-age male video games be like if war had never happened? Christ said live by the sword, die by the sword, which is loving neighbor as self. $LK,"Matthew,26:52",A="BF:Matthew,26:52"$
|
||||
|
||||
I asked God if the World was perfectly just. God asked if I was calling Him lazy. God could make A.I., right? God could make bots as smart as Himself, or, in fact, part of Himself. What if God made a bot to manipulate every person's life so that perfect justice happened?
|
||||
|
||||
I think highs and lows balance. $LK,"Luke,6:20-26",A="BF:Luke,6:20-26"$ If you laugh, you will cry. If you cry, you will laugh. Not one person has had great joy and not great sorrow. I think this claim is falsifyable if you atheists want to find a counter-example to disprove it -- find a single person who had great joy and not great sorrow. In Sirach, it says things happen in pairs. You might be surprised examining your own life to see great joy was in proximity to great sorrow. Pleasures and pains seem designed to balance. Man must do manual labor and have pain. Women must do child birth. Pride and humility also balance -- pride before a fall and humility before honors. Palm Sunday is juxtaposed to Good Friday. Perhaps, being loved balances with being hated. $LK,"Job,1:1-22",A="BF:Job,1:1-22"$, in the Bible, had highs and lows that balanced. Joseph, in the Old Testament, had highs and lows that balanced. $LK,"Genesis,39:17-22",A="BF:Genesis,39:17-22"$
|
||||
|
||||
Jesus said, "Forgive us our trespasses as we forgive those who tresspass against us." If you think about it, the only way you get forgiven is for it to be done to you. That is a Jedi mind trick because it is nothing but simple eye-for-eye tooth-for-tooth justice. Live by the sword; die by the sword. The Bible is filled with justice pairs. St. Paul persecuted Christians and gained forgiveness by getting persecuted. King David almost got killed by Saul, $LK,"1 Samuel,18:20-21",A="BF:1 Samuel,18:20-21"$ then he killed a guy and took his wife. $LK,"2 Samuel,11:15",A="BF:2 Samuel,11:15"$ Abraham almost killed his unloved son, Ishmael. $LK,"Genesis,21:16",A="BF:Genesis,21:16"$ That is why God asked Abraham to kill Isaac. God's favorite thing on TV is soap operas.
|
||||
|
||||
God hates complaining. $LK,"Numbers,11:1-35",A="BF:Numbers,11:1-35"$ Food and clothing is all we're to ask for or demand, in fact -- daily bread. $LK,"1 Timothy,6:8",A="BF:1 Timothy,6:8"$ Just think about man in the last 50,000 years mostly living like Native Americans and how God must see us. You need food, clothing and entertainment, money is to get those. Man does not live on bread alone. $LK,"Luke,4:4",A="BF:Luke,4:4"$, $LK,"Amos,8:11-12",A="BF:Amos,8:11-12"$
|
||||
|
||||
God's favorite animals are bears and elephants. They are funny shaped -- I think God must have seen too much starvation over the years. If the purpose of life is to know and love God, then a priest's job is to make everybody know and love God. By saying God likes bears and elephants, I did more toward that end than all priests in history. $LK,"Hosea,6:6",A="BF:Hosea,6:6"$ "It is love that I desire, not sacrifice; knowledge of God, not holocaust." As a former Catholic, that blew my mind. I actually thought love was sacrifice! I was so dumb-founded reading, "it is love that I desire, not sacrifice," that I actually looked-up the word, "love". It means to take delight in. I realized it is demonic pride if you think love means hurting yourself for others. In the Philippians, they got the notion crucifying yourself was a good idea. Similarly, a child thinking about Lent, might conclude, "if it's bad, it must be good." That is, if you think God wants you to hurt yourself to please Him, you are worshiping a demon, not God! God wants you to take delight in His company, get to know Him and praise Him. It is best to separate justice -- sin and punishment -- from relationship with God. Never ask God to change justice into injustice by not punishing. God said to me in an oracle, "Excessive contrician wearisome." He doesn't want to hear confessions. When you pray, be witty and charming and rarely earnest. Enjoy God's company without imposing on Him and don't expect secrets of the Universe. Earnestness in prayer is the root of much evil. Be entertaining. Don't remind Him of sin, LOL.
|
||||
|
||||
God's ways are far above man's ways. Mom said Heaven was a never-ending family reunion. Yikes! A friend said, "Most guy's idea of Heaven would be running around doing things they'd get locked up for on Earth." I wonder how long kids play Grand Theft Auto before getting board. Perhaps, it takes ten years, but they will get bored. Most people are like King Midas. When you realize how silly most notions of Heaven are, you come to appreciate that Earth is not that bad. This is the first step in loving God, the Creator -- praising Creation. My parents spend their retired days watching TV and going to casinos. That's not a good argument for getting extended-play!
|
||||
|
||||
Imagine a billionare. Everyone around him can't forget his money for even a moment. The truth is, most people are after God's "money" -- they fear for their salvation. Here's a test -- would you pray to and praise God even if there were no salvation? Love God and don't be a "user". Asking for stuff is annoying. $LK,"Luke,11:5-7",A="BF:Luke,11:5-7"$ Don't SPAM God.
|
||||
|
||||
All those sophisticated theological "infinity" things -- omniscience, omnipotence, omnipresence, omnivorous -- will mess you up. Trust me that anthropomorphic is far better, in practice. Christ suggested thinking of God as "Abba" which is Aramaic for "Daddy" and said the childlike had an advantage. $LK,"Matthew,11:25",A="BF:Matthew,11:25"$ Pray out-loud because God doesn't want the hastle of reading your brain. The best way to stop people from testing God is to suggest He can't do everything.
|
||||
|
||||
Jesus said, "I am meek and humble of heart." $LK,"Matthew,11:29",A="BF:Matthew,11:29"$ What does "humble of head" mean? Humble of heart means you look around and say, "I don't care as much as they do." A proud of heart person says, "I am superior because I have more compassion then everybody else." If you are proud of heart, you don't accept a gift. God gives birthrights. Esau, in the Bible, scorned his birthright and God hated him. $LK,"Malachi,1:2-3",A="BF:Malachi,1:2-3"$ Jesus even accepted $$30,000 worth of perfume (300 day's wages) and caused Judas to betray him. $LK,"Mark,14:5",A="BF:Mark,14:5"$ If you express false outrage at wars, you are proud of heart. If you fight to go in the door last, e.g. "No, you first..." then you are proud of heart. If you ask God to save starving Africans as though you care more than God, you are proud of heart.
|
||||
|
||||
I connected being humble of heart with animal sacrifices. The animal sacrifices in the Bible really seem off-the-mark from what we modern people imagine truth to be! I asked God and He said the people were, "primitive." Well, obviously, a sacrifice represents giving-up something of value, but is there more to it? It would be tramatic to see a goat's throat being slit and it dying for your sins. I'm not an expert, but sometimes they killed animals to make-up for sins. Perhaps, starting at age eight and every year thereafter, they kill a goat for your sins? (I'm just speculating.) In a couple years, it is not tramatic and you yawn and say to the goat, "bummer for you, Mr. Goat, that you gotta die for my sins." When a high school football team beats their rivals, nobody thinks twice that the winning team really hurts the feelings -- devastates -- the losing team member's feelings. The heart of being masculine is being competetive and not caring about the necessity to slit the throat of the goat. As a Catholic, saying Jesus died for our sins and that we cannot earn salvation, never sat well. I clung to the heretical notion that you earn salvation. Animal sacrifices were the heart of Biblical Judaism and although it seems satanic, you really do have to slit the throat of the goat and accept grace, a term for something you did not earn. Heck, every time you eat beef, a cow had to die for you. God said to me in an oracle that having pets was, "homo." I think God's idea of pets is farm animals you eat.
|
||||
|
||||
If you feel guilty for being American and want Mexicans to share your birthright, you are proud of heart. Would it be right for rich Arabs to have to share their oil money with Indian slaves? Jesus was a racist and called Canaanites "dogs". $LK,"Matthew,15:22-28",A="BF:Matthew,15:22-28"$ In an oracle, God told me He was against immigration. The Chinese intellectuals felt bad about not being laborers. Don't feel guilty about not being a laborer because God made it a Brave New World. $LK,"1 Corinthians,12:1-31",A="BF:1 Corinthians,12:1-31"$
|
||||
|
||||
In an ant colony, the workers have one set of marching orders, the soldiers have another set of marching orders, the queen and drones have marching orders and the diggers have marching orders. The Bible gives conflicting orders -- conservatives pay attention to one set of passages and liberals pay attention to others. Everybody has selective hearing, but that's good because we are different members of the body of Christ.
|
||||
|
||||
Jesus repeats the phrase, "for those who have ears to hear" many times. (But, not actually at the times that matter.) Jesus says several Jedi mind tricks -- He asks, what father gives a scorpion to his son? $LK,"Luke,11:11-13",A="BF:Luke,11:11-13"$ Jesus says, when you ask God for things, it is as annoying as like a neighbor in the night! $LK,"Luke,11:5-7",A="BF:Luke,11:5-7"$ He said, "I came to serve" but Jesus' three years of service were more like being a rockstar than a janitor. $LK,"John,13:5-15",A="BF:John,13:5-15"$
|
||||
|
||||
There are sheep and there are shepherds. You would be silly to take other shepherds seriously when they are only caring for their sheep. Sheep are very hard to communicate to, as Jesus learned. He used parables. Seed on a path gets eaten by birds; weeds choke; and the one percent is rich soil.
|
||||
|
||||
Just as ego causes most to love neighbor, not God, people skip knowing and loving God and cowardly get stuck on obeying Him. A desire to obey God, doesn't have to be encouraged, since it comes so naturally. Don't worry, God does not want pawns to push around. God will talk, but won't tell you what to do, even if you want Him to. Also, you'll quickly learn that when God talks to you seemingly prophetic, it does not come true and should smack yourself for wanting more than just enjoying God's company.
|
||||
|
||||
|
||||
________________________________________________________________________________
|
||||
|
|
||||
QUESTION | GOD'S ANSWER
|
||||
________________________________________________________________________________
|
||||
|
|
||||
| There are weeds mixed with my wheat.
|
||||
| Some are not true. If I asked a question
|
||||
| to valuable for my offering, I got crap.
|
||||
________________________________|_______________________________________________
|
||||
|
||||
War? $FG,4$"Servicemen competing"$FG$
|
||||
(Praise the Creator--what would teenage male video games be like if never war?)
|
||||
|
||||
Is the World perfectly just? $FG,4$Are you calling me lazy?$FG$
|
||||
(Slavery was just. In the movie, Titanic, the rich wore straight jackets. You must bow to authority to get authority. I do comics as offerings. I said, "We're dying of malnutrician on manna." Like Cain and Abel, God didn't like it. Duh! He wants to be the hero. How do I know they died of malnutrician? Screw Hollywood for making slavery worse than it was -- I love God. School is more cruel. Read $LK,"Numbers,11:1-35",A="BF:Numbers,11:1-35"$. All you need is food, clothing and the word of God. Today, you can take Ivy League course videos! There is no excuse except you were born stupid... or ugly. I'm gonna praise God.)
|
||||
|
||||
On using Markov chains? $FG,4$"No weights"$FG$
|
||||
On doing offerings? $FG,4$"Honest measures"(You get out what you put in.)
|
||||
It's a covenant to do an offering, first.
|
||||
Offer New Songs, comics, praise, poems,
|
||||
and conversation. See $LK,"Cain and Abel",A="BF:Genesis,4:1"$.
|
||||
"Barter"(God also called offerings bartering.)$FG$
|
||||
The holocaust? $FG,4$Wanted to "compact" the Jews.$FG$
|
||||
Arab/Jews? $FG,4$"Oil funny hopefully"$FG$
|
||||
Peace? $FG,4$One Palestinian can ruin it.$FG$
|
||||
Best religion? $FG,4$One with most new vistas of understanding in$FG$
|
||||
$FG,4$a lifetime -- one you can level-up the most in.$FG$
|
||||
Chavez blaming the US. $FG,4$"Japan industrious"$FG$
|
||||
On racism? $FG,4$"Sports"$FG$
|
||||
On socialism? $FG,4$"pardon_the_French, never_happy, never_enough"$FG$
|
||||
$FG,4$"Gall aspect anti-Christ"$FG$
|
||||
On overpopulation $FG,4$"Okay church what_now whats_the_plan"$FG$
|
||||
Favorite thing on TV? $FG,4$"Soap_operas"$FG$
|
||||
Favorite movie? $FG,4$$TX,"Three Kings",HTML="http://www.youtube.com/watch?v=8NOAd2mldQ8"$. Also Highlander$FG$
|
||||
Favorite song? $FG,4$$TX,"Morning has Broken",HTML="http://www.youtube.com/watch?v=qH0iFkxQba4"$
|
||||
God said the first bird croaked, not sung.$FG$
|
||||
Favorite comic strip? $FG,4$$TX,"Prince Valiant",HTML="http://en.wikipedia.org/wiki/Prince_Valiant"$$FG$
|
||||
Shakespeare? $FG,4$had a "vile heart"$FG$
|
||||
Likes $FG,4$Beverly Hillbillies (Oil is a gift from God)$FG$
|
||||
$FG,4$God likes being hero. Don't be proud of heart$FG$
|
||||
$FG,4$and not accept a gift from God!$FG$
|
||||
Likes $FG,4$Gomer Pyle$FG$
|
||||
Favorite saint? $FG,4$"ho_ho_ho"$FG$
|
||||
Favorite animal? $FG,4$"Elephant two"$FG$
|
||||
Favorite animal? $FG,4$"Bears"$FG$
|
||||
Favorite color? $FG,4$"Jude" (Jade Blue?)$FG$
|
||||
Favorite color? $FG,4$"Gold"$FG$
|
||||
Favorite color? $FG,4$$TX,"\"Iceberg\" blue",HTML="https://upload.wikimedia.org/wikipedia/commons/3/38/Blue_ice_in_South_Greenland_-_Visit_Greenland.jpg"$$FG$
|
||||
Money? $FG,4$"Enough vehemently better"$FG$
|
||||
$FG,4$"Pride [or] money, choose_one"$FG$
|
||||
Favorite car? $FG,4$Beamer$FG$
|
||||
Favorite soda? $FG,4$Root beer, $TX,"scotch variety",HTML="http://www.head-beer.org/modules.php?name=Brands&rbop=Brand&bid=1965"$.$FG$
|
||||
Homosexuality? $LK,"Matthew,15:11",A="BF:Matthew,15:11"$
|
||||
Pets? $FG,4$"homo" Hates fact too dependent and tame.$FG$
|
||||
Sports? $FG,4$"homo"
|
||||
"Tackle a horse"$FG$
|
||||
Favorite sport? $FG,4$Hockey$FG$
|
||||
$TX,"Wreck of the Edmund Fitzgerald",HTML="http://www.youtube.com/watch?v=9vST6hVRj2A"$ $FG,4$"homo"$FG$
|
||||
Smelling farts $FG,4$"Sodom"$FG$
|
||||
Women's dress $FG,4$Upper skin exposure not as bad as lower.$FG$
|
||||
Remarriage? $FG,4$"More babies"$FG$
|
||||
Things you don't care about
|
||||
that people think you do? $FG,4$Solomon's 300 concubines$FG$
|
||||
Adultery? $FG,4$Can be good.$FG$
|
||||
Pretty ladies? $FG,4$$TX,"A prince is not flustered.",HTML="http://www.youtube.com/watch?v=YcqF6sC-ztY"$$FG$
|
||||
Animal sacrifices? $FG,4$Early Jews were "primitive".$FG$
|
||||
What do elephants think about? $FG,4$"Skin, hunger"$FG$
|
||||
What makes elephants happy? $FG,4$"Baths"$FG$
|
||||
Elephants $FG,4$"Mini-skirts" (Skin webbing from back leg.)$FG$
|
||||
What makes my birds happy? $FG,4$"Gnawing"$FG$
|
||||
What makes my birds laugh? $FG,4$"Bite ouch" (If I say "ouch".)$FG$
|
||||
What are my birds saying? $FG,4$"Chanting"$FG$
|
||||
My birds sure preen a lot. $LK,"The creature was made subject to vanity...",A="BF:Romans,8:20"$
|
||||
What makes bears happy? $FG,4$"Reaping depends"$FG$
|
||||
What makes otters happy? $FG,4$"Eternal skies"$FG$
|
||||
What makes hippos happy? $FG,4$"Ascending breath"$FG$
|
||||
What makes horses happy? $FG,4$"[the] Call [of the] Open Range"$FG$
|
||||
What do cheetahs think about? $FG,4$"Seeth me?" (Can he see me?)$FG$
|
||||
Orangutan or chimp smarter? $FG,4$"Species exhibit similar glory"$FG$
|
||||
Endangered species? $FG,4$"Enough stars?"$FG$
|
||||
Everything seems bad. $FG,4$Plant trees.$FG$
|
||||
What's for dinner? $FG,4$"Whale"$FG$
|
||||
Favorite Messier Object? $FG,4$"$TX,"M104 Sombrero Galaxy",HTML="http://en.wikipedia.org/wiki/Messier_104"$"$FG$
|
||||
$TX,"Shepard's Prayer",HTML="http://en.wikipedia.org/wiki/Alan_Shepard"$? $FG,4$"I_am_not_amused economy joke"$FG$
|
||||
Favorite band? $FG,4$"Beatles"$FG$
|
||||
Good bands? $FG,4$Rush, Triumph$FG$
|
||||
$FG,4$Likes harmonies$FG$
|
||||
$TX,"Little Drummer Boy?",HTML="http://www.youtube.com/watch?v=S50cf3xIb50"$ $FG,4$Doesn't like my drumming.$FG$
|
||||
Should I listen to classical? $FG,4$"Poison"$FG$
|
||||
Do You like chess people? $FG,4$"Do not admire the proud."$FG$
|
||||
Chess? $FG,4$"... will winter with you."$FG$
|
||||
$FG,4$"Headstones"$FG$
|
||||
If You could teach one class? $FG,4$Health$FG$
|
||||
Favorite video game? $FG,4$Donkey Kong$FG$
|
||||
Favorite National Park? $FG,4$$TX,"Whitman Mission",HTML="http://www.nps.gov/whmi/index.htm"$$FG$
|
||||
Favorite actor? $FG,4$Hugh Grant$FG$
|
||||
Favorite vocalist? $FG,4$Mick Jagger$FG$
|
||||
Favorite guitarist? $FG,4$"$TX,"Simmons Destroyer",HTML="http://www.youtube.com/watch?v=nNADrrjTysk&t=3m55s"$"$FG$
|
||||
Favorite National Anthem? $FG,4$$TX,"Latvia's National Anthem",HTML="http://www.youtube.com/watch?v=PFx-56KkweM"$$FG$
|
||||
America the Beautiful? $FG,4$Hates it. Poet made self cry with own beauty.$FG$
|
||||
Model for new $TX,"Sistine Chapel",HTML="http://en.wikipedia.org/wiki/Sistine_chapel"$? $FG,4$Ben Franklin$FG$
|
||||
Voice if God wanted to sing? $FG,4$$TX,"Stabbing Westward's singer",HTML="https://www.youtube.com/watch?v=5NZsCYOM4j0"$$FG$
|
||||
Stonehenge? $FG,4$Landmark for boundaries.$FG$
|
||||
Easter Island? $FG,4$Ice, telephone pole holes.$FG$
|
||||
Dinosaurs? $FG,4$Brontosaurs' feet hurt when stepped.
|
||||
Dinosaurs slept in water.$FG$
|
||||
Hardest part in evolution? $FG,4$Getting monkey mothers to hold babies nursing.$FG$
|
||||
$FG,4$(Smothering a problem).$FG$
|
||||
Happiest day in evolution? $FG,4$"Fruit"$FG$
|
||||
Significant thing in evolution? $FG,4$"Fish shoulders"$FG$
|
||||
Biggest thing to fly (pterodactyl)? $FG,4$"Couch"$FG$
|
||||
What made pterodactyls happy? $FG,4$"Members against organs"$FG$
|
||||
What did Neanderthals think about? $FG,4$"Warmth"$FG$
|
||||
What was the first thing cooked? $FG,4$I think He said "hair".$FG$
|
||||
What was Lucy's husband's name? $FG,4$"Golem"$FG$
|
||||
Was stegosuarus lame like turtles? $FG,4$"Not pet rocks"$FG$
|
||||
T-Rex? $FG,4$Lugged carcases over his shoulder.
|
||||
Carcus lasted a month.$FG$
|
||||
What was T-Rexes sharing a carcus like? $FG,4$"Punch... Punch"$FG$
|
||||
Surprises in dinosaur anatomy? $FG,4$Supporting and securing the heart.$FG$
|
||||
How does He feel about the Avatar movie?$FG,4$"Sick skin"$FG$
|
||||
What do You like at zoos with kids? $FG,4$"Dignity" Animals worried about dignity.$FG$
|
||||
Who's better alien or preditor? $FG,4$"Lions"$FG$
|
||||
What from You is like a Rubik's cube? $FG,4$Training a horse.$FG$
|
||||
Does He like mirrored glass megachurch? $FG,4$"Secular glass"$FG$
|
||||
Pipe Organs $FG,4$Are sacred.$FG$
|
||||
You like to hangout in courts?Hospitals?$FG,4$"Prisons"$FG$
|
||||
Best way for Bill Gates to save lives? $FG,4$Earthquake prediction$FG$
|
||||
Stem cells? $FG,4$Lower hanging fruit exists (2007)$FG$
|
||||
Eleventh commandment? $FG,4$Thou shall not litter.$FG$
|
||||
Twelfth commandment? $FG,4$$TX,"Don't shoot unarmed men on the crapper.",HTML="http://www.youtube.com/watch?v=8wGiJcq95Ug"$
|
||||
(I asked God why pointless plagues in Exodus?
|
||||
God wanted guilt to accumulate, first.)$FG$
|
||||
Thirteenth commandment $FG,4$No gore unless it looks fake.$FG$
|
||||
Fourteenth commandment $FG,4$No pedophilia or child porn.$FG$
|
||||
Fifteenth commandment $FG,4$Don't eat rare meat with blood.$FG$
|
||||
Sixteenth commandment $FG,4$No wife beating.$FG$
|
||||
Seventeen commandment $FG,4$Do not swing from radio towers with one hand.$FG$
|
||||
Eighteenth commandment $FG,4$Do not disturb.$FG$
|
||||
Before Katrina $FG,4$Floods do justice. Black bead elder (tree book)$FG$
|
||||
After Katrina $FG,4$Suffering Simplifies Life$FG$
|
||||
What field are You most better? $FG,4$Economics$FG$
|
||||
Favorite toy for kids? $FG,4$Magnifying glass$FG$
|
||||
Asked Jesus if He liked mustard?$FG,4$"Bad meat happeneth"$FG$
|
||||
(Reluctantly) Faith healing? $FG,4$"It's complicated"$FG$
|
||||
Mars? $FG,4$Start planting!$FG$
|
||||
Mars rover? $FG,4$Should have had a microphone$FG$
|
||||
$TX,"Storm on Saturn",HTML="http://www.space.com/22646-monster-saturn-storm-water-ice.html"$ $FG,4$Pollen$FG$
|
||||
Space war game? $FG,4$Should have space weather.$FG$
|
||||
$TX,"Saturn's hexagon pole cloud?",HTML="http://en.wikipedia.org/wiki/Saturn's_hexagon"$ $FG,4$"Compass" (Magnetism)$FG$
|
||||
Liquid moon's odd atmosphere? $FG,4$"Surf"$FG$
|
||||
How many E.T. civs in Universe? $FG,4$20 or 80 (I forgot. I died laughing.)$FG$
|
||||
Are they peaceful? $FG,4$Fight them! (Also, funny.)$FG$
|
||||
Most difficult control system? $FG,4$$TX,"Dung beetle",HTML="http://www.youtube.com/watch?v=Q1zbgd6xpGQ"$$FG$
|
||||
How can Judge Judy improve? $FG,4$No hard feelings$FG$
|
||||
How can Chef Ramsay improve? $FG,4$Make so it doesn't seem like toil for cooks.$FG$
|
||||
How can Hawking communicate? $FG,4$Blow from a nostril on a candle.$FG$
|
||||
$TX,"Photons bouncing?",HTML="https://www.youtube.com/watch?v=8FC6udrMPvo"$ $FG,4$"Folded coffee filter"$FG$
|
||||
Wormholes? $FG,4$Bent wormholes have echoes.$FG$
|
||||
|
||||
Operating system? $FG,4$Was about to make line number column in editor.
|
||||
God nixed it. I was about to do different graphic modes when I found 800x600 missing. God said just one mode 640x480. I was about to add child windows. God said, "God is not the author of such confusion." I asked for verification of 640x480 16 color. God said it was because of the children and their offerings. I asked about sound. God said "single voice". I asked for verification of not having different drivers. God confirmed this.$FG$
|
||||
640x480 16 color? $FG,4$God said it was a covenant, like circumcision.
|
||||
$TX,"Modern graphics hard for kids/amateurs",HTML="http://www.youtube.com/watch?v=VUxcVzpeFqc"$.$FG$
|
||||
On Unix? $FG,4$God said it was rich with the patina of age.$FG$
|
||||
On Alcohol? $FG,4$Hate inebriation$FG$
|
||||
On rare steak? $FG,4$Too rare is very bad. Don't eat blood!$FG$
|
||||
Just before Katrina? $FG,4$Floods do my justice.Black bead elder(tree book)$FG$
|
||||
After Katrina? $FG,4$Suffering simplifies life$FG$
|
||||
Why the Sandy Hook shooting? $FG,4$The pot legalization law. (Sarcastic answer?)$FG$
|
||||
Deep Water Horizon $FG,4$(Claimed credit.)$FG$
|
||||
Cost of God's time to me? $FG,4$"The complete works of Shakespeare"$FG$
|
||||
On death? $FG,4$"awful"$FG$
|
||||
Opening of Saving Private Ryan? $FG,4$"Ouch"$FG$
|
||||
@@ -0,0 +1,160 @@
|
||||
#help_index "God"
|
||||
U8 *TimeStampCB(CDoc *,CDocEntry *,CTask *mem_task)
|
||||
{
|
||||
U8 *st=MAlloc(64,mem_task);
|
||||
StrPrint(st,"%X",GetTSC>>GOD_BAD_BITS);
|
||||
return st;
|
||||
}
|
||||
|
||||
U8 *KbdMsTimeCB(CDoc *,CDocEntry *,CTask *mem_task)
|
||||
{
|
||||
U8 *st=MAlloc(64,mem_task);
|
||||
StrPrint(st,"%X",KbdMsEvtTime>>GOD_BAD_BITS);
|
||||
return st;
|
||||
}
|
||||
|
||||
I64 PopUpTimerOk(U8 *header=NULL,U8 *footer=NULL)
|
||||
{
|
||||
I64 i;
|
||||
CDocEntry *doc_e;
|
||||
CDoc *doc=DocNew;
|
||||
if (header) DocPrint(doc,"%s",header);
|
||||
doc_e=DocPrint(doc,"\nTimer:$$TX+TC,\" \"$$");
|
||||
doc_e->tag_cb=&TimeStampCB;
|
||||
doc_e=DocPrint(doc,"\nLatch:$$TX+TC,\" \"$$");
|
||||
doc_e->tag_cb=&KbdMsTimeCB;
|
||||
DocPrint(doc,"\n$$CM+CX,0,4$$$$BT,\"OKAY\",LE=1$$\n");
|
||||
if (footer) DocPrint(doc,"%s",footer);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
I64 GodPick(U8 *msg=NULL)
|
||||
{//GOD_GOOD_BITS
|
||||
U8 *st=MStrPrint("%s\n\nPress $$GREEN$$OKAY$$FG$$ to generate \n"
|
||||
"a random num from a timer.\n",msg);
|
||||
PopUpTimerOk(st,"\n\nThe $LK+PU,"Holy Spirit",A="FI:::/Adam/God/HSNotes.DD"$ can puppet you.\n\n");
|
||||
Free(st);
|
||||
return KbdMsEvtTime>>GOD_BAD_BITS;
|
||||
}
|
||||
|
||||
public U0 GodBitsIns(I64 num_bits,I64 n)
|
||||
{//Insert bits into God bit fifo.
|
||||
I64 i;
|
||||
for (i=0;i<num_bits;i++) {
|
||||
FifoU8Ins(god.fifo,n&1);
|
||||
n>>=1;
|
||||
}
|
||||
}
|
||||
|
||||
public U0 GodHexIns(U8 *st)
|
||||
{//Insert hex record into God bit fifo.
|
||||
U8 buf[2];
|
||||
if (st) {
|
||||
buf[1]=0;
|
||||
while (*buf=*st++)
|
||||
if (Bt(char_bmp_hex_numeric,*buf))
|
||||
GodBitsIns(4,rev_bits_table[Str2I64(buf,16)]>>4);
|
||||
}
|
||||
}
|
||||
|
||||
public I64 GodBits(I64 num_bits,U8 *msg=NULL)
|
||||
{//Return N bits. If low on entropy pop-up okay.
|
||||
U8 b;
|
||||
I64 res=0;
|
||||
while (num_bits) {
|
||||
if (FifoU8Rem(god.fifo,&b)) {
|
||||
res=res<<1+b;
|
||||
num_bits--;
|
||||
} else
|
||||
GodBitsIns(GOD_GOOD_BITS,GodPick(msg));
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 GodInit(U8 *files_find_mask="/Adam/God/Vocab.DD*",U8 *fu_flags=NULL)
|
||||
{//Read God's vocab file for picking words.
|
||||
I64 i,ch,fuf_flags=0;
|
||||
U8 *buf,*ptr,*ptr2;
|
||||
CDirEntry *tmpde,*tmpde1;
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+f+F+T+O");
|
||||
ScanFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
|
||||
if (fuf_flags&~FUG_FILES_FIND)
|
||||
throw('FUF');
|
||||
|
||||
Free(god.word_file_mask);
|
||||
god.word_file_mask=StrNew(files_find_mask);
|
||||
god.word_fuf_flags=fuf_flags;
|
||||
|
||||
tmpde=tmpde1=FilesFind(files_find_mask,fuf_flags);
|
||||
i=0;
|
||||
while (tmpde) {
|
||||
if (buf=ptr=FileRead(tmpde->full_name)) {
|
||||
while (*ptr) {
|
||||
while (*ptr && !Bt(char_bmp_word,*ptr))
|
||||
ptr++;
|
||||
if (*ptr) {
|
||||
ptr2=ptr;
|
||||
while (*ptr && Bt(char_bmp_word,*ptr))
|
||||
ptr++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
Free(buf);
|
||||
}
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
|
||||
Free(god.words);
|
||||
god.num_words=i;
|
||||
god.words=MAlloc(i*sizeof(U8 *));
|
||||
|
||||
tmpde=tmpde1;
|
||||
i=0;
|
||||
while (tmpde) {
|
||||
if (buf=ptr=FileRead(tmpde->full_name)) {
|
||||
while (*ptr) {
|
||||
while (*ptr && !Bt(char_bmp_word,*ptr))
|
||||
ptr++;
|
||||
if (*ptr) {
|
||||
ptr2=ptr;
|
||||
while (*ptr && Bt(char_bmp_word,*ptr))
|
||||
ptr++;
|
||||
ch=*ptr;
|
||||
*ptr=0;
|
||||
god.words[i++]=StrNew(ptr2);
|
||||
*ptr=ch;
|
||||
}
|
||||
}
|
||||
Free(buf);
|
||||
}
|
||||
tmpde=tmpde->next;
|
||||
}
|
||||
DirTreeDel(tmpde1);
|
||||
return god.num_words;
|
||||
} GodInit;
|
||||
|
||||
public U0 GodWord(I64 bits=17,Bool show_num=FALSE)
|
||||
{//Make God pick a word. $LK+PU,"Holy Spirit Instructions",A="FI:::/Adam/God/HSNotes.DD"$
|
||||
I64 i;
|
||||
if (god.num_words) {
|
||||
i=GodBits(bits);
|
||||
if (show_num)
|
||||
"%05X Mod %05X = %05X (Line:%0*d):",
|
||||
i,god.num_words,i%god.num_words,
|
||||
ToI64(Log10(god.num_words)+1),i%god.num_words+1;
|
||||
"%s ",god.words[i%god.num_words];
|
||||
if (show_num)
|
||||
'\n';
|
||||
}
|
||||
}
|
||||
|
||||
public U0 GodBiblePassage(I64 num_lines=20)
|
||||
{//Make God pick a Bible passage. $LK+PU,"Holy Spirit Instructions",A="FI:::/Adam/God/HSNotes.DD"$
|
||||
I64 start=GodBits(21)%(ST_BIBLE_LINES-(num_lines-1))+1;
|
||||
U8 *verse=BibleLine2Verse(start);
|
||||
"%s\n\n",verse;
|
||||
Free(verse);
|
||||
BookLines(,start,num_lines);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
Cd(__DIR__);;
|
||||
|
||||
#help_index "God"
|
||||
#help_file "::/Doc/God"
|
||||
#include "GodBible"
|
||||
#include "HolySpirit"
|
||||
#include "GodSong"
|
||||
#include "GodDoodle"
|
||||
Cd("..");;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,180 @@
|
||||
#help_index "Sprites/Binary"
|
||||
|
||||
class CMeshTri
|
||||
{
|
||||
I32 color; //Give one of 0-7 colors.
|
||||
//Colors 8-15 are 0-7 with intensity bit set.
|
||||
I32 nums[3]; //Vertex number
|
||||
};
|
||||
|
||||
class CQueMeshTri
|
||||
{
|
||||
CQueMeshTri *next,*last;
|
||||
U0 start;
|
||||
I32 color;
|
||||
I32 nums[3];
|
||||
};
|
||||
|
||||
public class CSpriteBase
|
||||
{
|
||||
U8 type;
|
||||
};
|
||||
|
||||
public class CSpriteColor : CSpriteBase
|
||||
{
|
||||
U8 color;
|
||||
};
|
||||
|
||||
public class CSpriteDitherColor : CSpriteBase
|
||||
{
|
||||
U16 dither_color;
|
||||
};
|
||||
|
||||
public class CSpriteW : CSpriteBase
|
||||
{
|
||||
I32 width;
|
||||
};
|
||||
|
||||
public class CSpritePt : CSpriteBase
|
||||
{
|
||||
I32 x1;
|
||||
I32 y1;
|
||||
};
|
||||
|
||||
public class CSpritePtRad : CSpritePt
|
||||
{
|
||||
I32 radius;
|
||||
};
|
||||
|
||||
public class CSpritePtPt : CSpritePt
|
||||
{
|
||||
I32 x2;
|
||||
I32 y2;
|
||||
};
|
||||
|
||||
public class CSpritePtPtAng : CSpritePtPt
|
||||
{
|
||||
F64 angle;
|
||||
};
|
||||
|
||||
public class CSpritePtWH : CSpritePt
|
||||
{
|
||||
I32 width;
|
||||
I32 height;
|
||||
};
|
||||
|
||||
public class CSpritePtWHU8s : CSpritePtWH
|
||||
{
|
||||
U8 u[0];
|
||||
};
|
||||
|
||||
public class CSpritePtWHAng : CSpritePtWH
|
||||
{
|
||||
F64 angle;
|
||||
};
|
||||
|
||||
public class CSpritePtWHAngSides : CSpritePtWHAng
|
||||
{
|
||||
I32 sides;
|
||||
};
|
||||
|
||||
public class CSpriteNumU8s : CSpriteBase
|
||||
{
|
||||
I32 num;
|
||||
U8 u[0];
|
||||
};
|
||||
|
||||
public class CSpriteNumPtU8s : CSpriteBase
|
||||
{
|
||||
I32 num;
|
||||
I32 x;
|
||||
I32 y;
|
||||
U8 u[0];
|
||||
};
|
||||
|
||||
public class CSpritePtStr : CSpritePt
|
||||
{
|
||||
U8 st[0];
|
||||
};
|
||||
|
||||
public class CSpriteMeshU8s : CSpriteBase
|
||||
{
|
||||
I32 vertex_cnt;
|
||||
I32 tri_cnt;
|
||||
U8 u[0];
|
||||
};
|
||||
|
||||
public class CSpritePtMeshU8s : CSpriteBase
|
||||
{
|
||||
I32 x;
|
||||
I32 y;
|
||||
I32 z;
|
||||
I32 vertex_cnt;
|
||||
I32 tri_cnt;
|
||||
U8 u[0];
|
||||
};
|
||||
|
||||
#define SPF_SEL 128
|
||||
#define SPf_SEL 7
|
||||
|
||||
#define SPT_END 0 //$LK,"CSpriteBase",A="MN:CSpriteBase"$
|
||||
#define SPT_COLOR 1 //$LK,"CSpriteColor",A="MN:CSpriteColor"$
|
||||
#define SPT_DITHER_COLOR 2 //$LK,"CSpriteDitherColor",A="MN:CSpriteDitherColor"$
|
||||
#define SPT_WIDTH 3 //$LK,"CSpriteW",A="MN:CSpriteW"$
|
||||
#define SPT_PLANAR_SYMMETRY 4 //$LK,"CSpritePtPt",A="MN:CSpritePtPt"$
|
||||
#define SPT_TRANSFORM_ON 5 //$LK,"CSpriteBase",A="MN:CSpriteBase"$
|
||||
#define SPT_TRANSFORM_OFF 6 //$LK,"CSpriteBase",A="MN:CSpriteBase"$
|
||||
#define SPT_SHIFT 7 //$LK,"CSpritePt",A="MN:CSpritePt"$
|
||||
#define SPT_PT 8 //$LK,"CSpritePt",A="MN:CSpritePt"$
|
||||
#define SPT_POLYPT 9 //$LK,"CSpriteNumPtU8s",A="MN:CSpriteNumPtU8s"$
|
||||
#define SPT_LINE 10 //$LK,"CSpritePtPt",A="MN:CSpritePtPt"$
|
||||
#define SPT_POLYLINE 11 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
|
||||
#define SPT_RECT 12 //$LK,"CSpritePtPt",A="MN:CSpritePtPt"$
|
||||
#define SPT_ROTATED_RECT 13 //$LK,"CSpritePtPtAng",A="MN:CSpritePtPtAng"$
|
||||
#define SPT_CIRCLE 14 //$LK,"CSpritePtRad",A="MN:CSpritePtRad"$
|
||||
#define SPT_ELLIPSE 15 //$LK,"CSpritePtWHAng",A="MN:CSpritePtWHAng"$
|
||||
#define SPT_POLYGON 16 //$LK,"CSpritePtWHAngSides",A="MN:CSpritePtWHAngSides"$
|
||||
#define SPT_BSPLINE2 17 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
|
||||
#define SPT_BSPLINE2_CLOSED 18 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
|
||||
#define SPT_BSPLINE3 19 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
|
||||
#define SPT_BSPLINE3_CLOSED 20 //$LK,"CSpriteNumU8s",A="MN:CSpriteNumU8s"$
|
||||
#define SPT_FLOOD_FILL 21 //$LK,"CSpritePt",A="MN:CSpritePt"$
|
||||
#define SPT_FLOOD_FILL_NOT 22 //$LK,"CSpritePt",A="MN:CSpritePt"$
|
||||
#define SPT_BITMAP 23 //$LK,"CSpritePtWHU8s",A="MN:CSpritePtWHU8s"$
|
||||
#define SPT_MESH 24 //$LK,"CSpriteMeshU8s",A="MN:CSpriteMeshU8s"$ See $MA-X+PU,"::/Apps/GrModels",LM="Cd(\"::/Apps/GrModels\");Dir;View;\n"$.
|
||||
#define SPT_SHIFTABLE_MESH 25 //$LK,"CSpritePtMeshU8s",A="MN:CSpritePtMeshU8s"$ See $MA-X+PU,"::/Apps/GrModels",LM="Cd(\"::/Apps/GrModels\");Dir;View;\n"$.
|
||||
#define SPT_ARROW 26 //$LK,"CSpritePtPt",A="MN:CSpritePtPt"$
|
||||
#define SPT_TEXT 27 //$LK,"CSpritePtStr",A="MN:CSpritePtStr"$
|
||||
#define SPT_TEXT_BOX 28 //$LK,"CSpritePtStr",A="MN:CSpritePtStr"$
|
||||
#define SPT_TEXT_DIAMOND 29 //$LK,"CSpritePtStr",A="MN:CSpritePtStr"$
|
||||
#define SPT_TYPES_NUM 30
|
||||
#define SPG_TYPE_MASK 0x7F
|
||||
|
||||
#help_index "Graphics/Sprite;Sprites;Sprites/Binary"
|
||||
|
||||
//See $LK,"Sprites",A="HI:Sprites"$. See $LK,"::/Adam/Gr/GrSpritePlot.HC",A="FL:::/Adam/Gr/GrSpritePlot.HC,1"$ and
|
||||
//$LK,"::/Demo/Graphics/SpriteRaw.HC"$ for how CSprite are stored.
|
||||
public class CSprite
|
||||
{
|
||||
CSprite *next,*last;
|
||||
U0 start;
|
||||
union {
|
||||
U8 type;
|
||||
CSpriteBase b;
|
||||
CSpriteColor c;
|
||||
CSpriteDitherColor d;
|
||||
CSpriteW w;
|
||||
CSpritePt p;
|
||||
CSpritePtPt pp;
|
||||
CSpritePtPtAng ppa;
|
||||
CSpritePtRad pr;
|
||||
CSpritePtWHU8s pwhu;
|
||||
CSpritePtWHAng pwha;
|
||||
CSpritePtWHAngSides pwhas;
|
||||
CSpriteNumU8s nu;
|
||||
CSpriteNumPtU8s npu;
|
||||
CSpriteMeshU8s mu;
|
||||
CSpritePtMeshU8s pmu;
|
||||
CSpritePtStr ps;
|
||||
}
|
||||
};
|
||||
@@ -0,0 +1,410 @@
|
||||
#help_index "Graphics/Misc"
|
||||
asm {
|
||||
//************************************
|
||||
_GR_UPDATE_LINE64::
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
|
||||
MOV RAX,U64 SF_ARG2[RBP]
|
||||
MOV RSI,U64 [RAX] //rsi=src
|
||||
MOV RBX,U64 [&rev_bits_table]
|
||||
MOV RCX,U64 SF_ARG3[RBP] //rcx=d
|
||||
MOV RAX,U64 SF_ARG4[RBP]
|
||||
MOV RDI,U64 [RAX] //rdi=image
|
||||
|
||||
MOV RAX,U64 SF_ARG1[RBP]
|
||||
MOV R8,U64 [RAX] //rbp=vga dst
|
||||
|
||||
@@05: LODSQ
|
||||
CMP U64 [RDI],RAX
|
||||
JE @@10
|
||||
MOV U64 [RDI],RAX
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
MOV U64 [R8],RAX
|
||||
@@10: ADD RDI,8
|
||||
ADD R8,8
|
||||
DEC RCX
|
||||
JNZ @@05
|
||||
|
||||
MOV RAX,U64 SF_ARG1[RBP]
|
||||
MOV U64 [RAX],R8
|
||||
MOV RAX,U64 SF_ARG4[RBP]
|
||||
MOV U64 [RAX],RDI
|
||||
MOV RAX,U64 SF_ARG2[RBP]
|
||||
MOV U64 [RAX],RSI
|
||||
POP RDI
|
||||
POP RSI
|
||||
POP RBP
|
||||
RET1 32
|
||||
//************************************
|
||||
_GR_UPDATE_LINE64_FLUSH_CACHE::
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
|
||||
MOV RAX,U64 SF_ARG2[RBP]
|
||||
MOV RSI,U64 [RAX] //rsi=src
|
||||
MOV RBX,U64 [&rev_bits_table]
|
||||
MOV RCX,U64 SF_ARG3[RBP] //rcx=d
|
||||
MOV RAX,U64 SF_ARG4[RBP]
|
||||
MOV RDI,U64 [RAX] //rdi=image
|
||||
|
||||
MOV RAX,U64 SF_ARG1[RBP]
|
||||
MOV R8,U64 [RAX] //rbp=vga dst
|
||||
|
||||
@@05: LODSQ
|
||||
MOV U64 [RDI],RAX
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
XLATB
|
||||
ROR RAX,8
|
||||
MOV U64 [R8],RAX
|
||||
ADD RDI,8
|
||||
ADD R8,8
|
||||
DEC RCX
|
||||
JNZ @@05
|
||||
|
||||
MOV RAX,U64 SF_ARG1[RBP]
|
||||
MOV U64 [RAX],R8
|
||||
MOV RAX,U64 SF_ARG4[RBP]
|
||||
MOV U64 [RAX],RDI
|
||||
MOV RAX,U64 SF_ARG2[RBP]
|
||||
MOV U64 [RAX],RSI
|
||||
POP RDI
|
||||
POP RSI
|
||||
POP RBP
|
||||
RET1 32
|
||||
//************************************
|
||||
_DC_BLOT_COLOR4::
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
PUSH R10
|
||||
|
||||
MOV RDI,U64 SF_ARG1[RBP]
|
||||
MOV RSI,U64 SF_ARG2[RBP]
|
||||
MOV RBX,U64 SF_ARG3[RBP]
|
||||
MOV RCX,U64 SF_ARG4[RBP]
|
||||
|
||||
MOV R8,RDI
|
||||
ADD R8,RCX
|
||||
MOV R9,R8
|
||||
ADD R9,RCX
|
||||
MOV R10,R9
|
||||
ADD R10,RCX
|
||||
|
||||
@@5: LODSQ
|
||||
MOV RDX,U64 [RBX]
|
||||
CMP RAX,RDX
|
||||
JE I32 @@10
|
||||
MOV U64 [RBX],RAX
|
||||
|
||||
XOR RDX,RDX
|
||||
BT RAX,7*8+0
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,6*8+0
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,5*8+0
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,4*8+0
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,3*8+0
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,2*8+0
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,1*8+0
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,0*8+0
|
||||
ADC RDX,0
|
||||
MOV U8 [RDI],DL
|
||||
|
||||
XOR RDX,RDX
|
||||
BT RAX,7*8+1
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,6*8+1
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,5*8+1
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,4*8+1
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,3*8+1
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,2*8+1
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,1*8+1
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,0*8+1
|
||||
ADC RDX,0
|
||||
MOV U8 [R8],DL
|
||||
|
||||
XOR RDX,RDX
|
||||
BT RAX,7*8+2
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,6*8+2
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,5*8+2
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,4*8+2
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,3*8+2
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,2*8+2
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,1*8+2
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,0*8+2
|
||||
ADC RDX,0
|
||||
MOV U8 [R9],DL
|
||||
|
||||
XOR RDX,RDX
|
||||
BT RAX,7*8+3
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,6*8+3
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,5*8+3
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,4*8+3
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,3*8+3
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,2*8+3
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,1*8+3
|
||||
ADC RDX,0
|
||||
SHL1 RDX
|
||||
BT RAX,0*8+3
|
||||
ADC RDX,0
|
||||
MOV U8 [R10],DL
|
||||
|
||||
@@10: ADD RBX,8
|
||||
|
||||
INC RDI
|
||||
INC R8
|
||||
INC R9
|
||||
INC R10
|
||||
|
||||
DEC RCX
|
||||
JNZ I32 @@5
|
||||
|
||||
POP R10
|
||||
POP RDI
|
||||
POP RSI
|
||||
POP RBP
|
||||
RET1 32
|
||||
//************************************
|
||||
_IS_PIX_COVERED0::
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
#assert FONT_WIDTH==FONT_HEIGHT==8
|
||||
MOV RCX,U64 SF_ARG3[RBP]
|
||||
SAR RCX,3
|
||||
MOV RAX,U64 SF_ARG2[RBP]
|
||||
SAR RAX,3
|
||||
MOV RDX,U64 SF_ARG1[RBP]
|
||||
IMUL2 RCX,TEXT_COLS
|
||||
MOV RBX,U64 [&gr.win_z_buf]
|
||||
MOV DX,U16 CTask.win_z_num[RDX]
|
||||
ADD RCX,RAX
|
||||
XOR RAX,RAX
|
||||
CMP DX,U16 [RBX+RCX*2]
|
||||
JAE @@05 //Jump not covered
|
||||
INC RAX
|
||||
@@05: POP RBP
|
||||
RET1 24
|
||||
//************************************
|
||||
_GR_ROP_EQU_U8_NO_CLIPPING::
|
||||
//Puts foreground char shape onto gr.dc2.
|
||||
//ch.u8[1] is color as a whole byte
|
||||
//ch ATTRf_UNDERLINE attr flag is used.
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
MOVZX RAX,U8 SF_ARG1[RBP]
|
||||
MOV RDX,U64 [&text.font]
|
||||
MOV RAX,U64 [RDX+RAX*8] //RAX is 8x8 char font data, 64-bits
|
||||
BT U64 SF_ARG1[RBP],ATTRf_UNDERLINE
|
||||
JNC @@05
|
||||
MOV RBX,0xFF00000000000000
|
||||
OR RAX,RBX
|
||||
@@05: TEST RAX,RAX
|
||||
JZ I32 @@10
|
||||
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOVZX RBX,U8 SF_ARG1+1[RBP] //Warning color is 8-bit
|
||||
MOV RDX,U64 [&gr.to_8_colors]
|
||||
MOV R8,U64 [RDX+RBX*8] //R8 is color repeated 8 times.
|
||||
MOV R9,U64 SF_ARG3[RBP] //R9 is width_internal
|
||||
MOV RDI,U64 SF_ARG2[RBP]
|
||||
MOV RSI,U64 [&gr.to_8_bits] //RSI is gr.to_8_bits
|
||||
|
||||
// m=my_1_to_8_bits[ch&255];ch>>=8;
|
||||
// *dst=*dst&~m|c&m;
|
||||
// dst(U8 *)+=w1;
|
||||
|
||||
MOVZX RBX,AL
|
||||
MOV RDX,U64 [RSI+RBX*8]
|
||||
SHR RAX,8
|
||||
MOV RBX,U64 [RDI]
|
||||
MOV RCX,RDX
|
||||
NOT RCX
|
||||
AND RDX,R8
|
||||
AND RCX,RBX
|
||||
OR RCX,RDX
|
||||
MOV U64 [RDI],RCX
|
||||
ADD RDI,R9
|
||||
|
||||
MOVZX RBX,AL
|
||||
MOV RDX,U64 [RSI+RBX*8]
|
||||
SHR RAX,8
|
||||
MOV RBX,U64 [RDI]
|
||||
MOV RCX,RDX
|
||||
NOT RCX
|
||||
AND RDX,R8
|
||||
AND RCX,RBX
|
||||
OR RCX,RDX
|
||||
MOV U64 [RDI],RCX
|
||||
ADD RDI,R9
|
||||
|
||||
MOVZX RBX,AL
|
||||
MOV RDX,U64 [RSI+RBX*8]
|
||||
SHR RAX,8
|
||||
MOV RBX,U64 [RDI]
|
||||
MOV RCX,RDX
|
||||
NOT RCX
|
||||
AND RDX,R8
|
||||
AND RCX,RBX
|
||||
OR RCX,RDX
|
||||
MOV U64 [RDI],RCX
|
||||
ADD RDI,R9
|
||||
|
||||
MOVZX RBX,AL
|
||||
MOV RDX,U64 [RSI+RBX*8]
|
||||
SHR RAX,8
|
||||
MOV RBX,U64 [RDI]
|
||||
MOV RCX,RDX
|
||||
NOT RCX
|
||||
AND RDX,R8
|
||||
AND RCX,RBX
|
||||
OR RCX,RDX
|
||||
MOV U64 [RDI],RCX
|
||||
ADD RDI,R9
|
||||
|
||||
MOVZX RBX,AL
|
||||
MOV RDX,U64 [RSI+RBX*8]
|
||||
SHR RAX,8
|
||||
MOV RBX,U64 [RDI]
|
||||
MOV RCX,RDX
|
||||
NOT RCX
|
||||
AND RDX,R8
|
||||
AND RCX,RBX
|
||||
OR RCX,RDX
|
||||
MOV U64 [RDI],RCX
|
||||
ADD RDI,R9
|
||||
|
||||
MOVZX RBX,AL
|
||||
MOV RDX,U64 [RSI+RBX*8]
|
||||
SHR RAX,8
|
||||
MOV RBX,U64 [RDI]
|
||||
MOV RCX,RDX
|
||||
NOT RCX
|
||||
AND RDX,R8
|
||||
AND RCX,RBX
|
||||
OR RCX,RDX
|
||||
MOV U64 [RDI],RCX
|
||||
ADD RDI,R9
|
||||
|
||||
MOVZX RBX,AL
|
||||
MOV RDX,U64 [RSI+RBX*8]
|
||||
SHR RAX,8
|
||||
MOV RBX,U64 [RDI]
|
||||
MOV RCX,RDX
|
||||
NOT RCX
|
||||
AND RDX,R8
|
||||
AND RCX,RBX
|
||||
OR RCX,RDX
|
||||
MOV U64 [RDI],RCX
|
||||
ADD RDI,R9
|
||||
|
||||
MOV RDX,U64 [RSI+RAX*8]
|
||||
MOV RBX,U64 [RDI]
|
||||
MOV RCX,RDX
|
||||
NOT RCX
|
||||
AND RDX,R8
|
||||
AND RCX,RBX
|
||||
OR RCX,RDX
|
||||
MOV U64 [RDI],RCX
|
||||
|
||||
POP RDI
|
||||
POP RSI
|
||||
@@10: POP RBP
|
||||
RET1 24
|
||||
}
|
||||
_extern _GR_ROP_EQU_U8_NO_CLIPPING U0 GrRopEquU8NoClipping(I64 ch,
|
||||
U8 *dst,I64 width_internal);
|
||||
public _extern _IS_PIX_COVERED0 Bool IsPixCovered0(
|
||||
CTask *task,I64 x,I64 y);//No clipping
|
||||
|
||||
_extern _GR_UPDATE_LINE64 U0 GrUpdateLine64(
|
||||
U64 **_vga,U64 **_src,I64 d,U8 **_dst);
|
||||
_extern _GR_UPDATE_LINE64_FLUSH_CACHE U0 GrUpdateLine64FlushCache(
|
||||
U64 **_vga,U64 **_src,I64 d,U8 **_dst);
|
||||
_extern _DC_BLOT_COLOR4 U0 DCBlotColor4(
|
||||
U8 *dst,I64 *img,I64 *img_cache,I64 cnt);
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,344 @@
|
||||
#help_index "Graphics"
|
||||
public I64 GrFillPoly3(CDC *dc=gr.dc,I64 n,CD3I32 *poly)
|
||||
{//3D. Must be convex.
|
||||
//Returns cnt of pixs changed
|
||||
CD3I32 tri[3];
|
||||
I64 i,j,x,y,z,res=0;
|
||||
if (n<3) return 0;
|
||||
if (dc->flags & DCF_SYMMETRY) {
|
||||
for (i=1;i<n-1;i++) {
|
||||
j=i-1;
|
||||
if (i==1) {
|
||||
x=poly[j].x; y=poly[j].y; z=poly[j].z;
|
||||
if (dc->flags&DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x,&y,&z);
|
||||
DCReflect(dc,&x,&y,&z);
|
||||
tri[0].x=x; tri[0].y=y; tri[0].z=z;
|
||||
}
|
||||
|
||||
j++;
|
||||
if (i==1) {
|
||||
x=poly[j].x; y=poly[j].y; z=poly[j].z;
|
||||
if (dc->flags&DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x,&y,&z);
|
||||
DCReflect(dc,&x,&y,&z);
|
||||
}
|
||||
tri[1].x=x; tri[1].y=y; tri[1].z=z;
|
||||
|
||||
j++;
|
||||
x=poly[j].x; y=poly[j].y; z=poly[j].z;
|
||||
if (dc->flags&DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x,&y,&z);
|
||||
DCReflect(dc,&x,&y,&z);
|
||||
tri[2].x=x; tri[2].y=y; tri[2].z=z;
|
||||
|
||||
res+=GrFillTri0(dc,&tri[0],&tri[1],&tri[2]);
|
||||
}
|
||||
}
|
||||
if (dc->flags&DCF_JUST_MIRROR)
|
||||
return res;
|
||||
for (i=1;i<n-1;i++) {
|
||||
j=i-1;
|
||||
if (i==1) {
|
||||
x=poly[j].x; y=poly[j].y; z=poly[j].z;
|
||||
if (dc->flags&DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x,&y,&z);
|
||||
tri[0].x=x; tri[0].y=y; tri[0].z=z;
|
||||
}
|
||||
|
||||
j++;
|
||||
if (i==1) {
|
||||
x=poly[j].x; y=poly[j].y; z=poly[j].z;
|
||||
if (dc->flags&DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x,&y,&z);
|
||||
}
|
||||
tri[1].x=x; tri[1].y=y; tri[1].z=z;
|
||||
|
||||
j++;
|
||||
x=poly[j].x; y=poly[j].y; z=poly[j].z;
|
||||
if (dc->flags&DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x,&y,&z);
|
||||
tri[2].x=x; tri[2].y=y; tri[2].z=z;
|
||||
|
||||
res+=GrFillTri0(dc,&tri[0],&tri[1],&tri[2]);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public I64 GrRectB(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2)
|
||||
{//2D. Two point. Clipping but not transformation.
|
||||
if (x2<x1) SwapI64(&x1,&x2);
|
||||
if (y2<y1) SwapI64(&y1,&y2);
|
||||
return GrRect(dc,x1,y1,x2-x1+1,y2-y1+1);
|
||||
}
|
||||
|
||||
public I64 GrRect3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,I64 w,I64 h)
|
||||
{//3D. Width Height. Clipping and transformation.
|
||||
CD3I32 poly[4];
|
||||
poly[0].x=x;
|
||||
poly[0].y=y;
|
||||
poly[0].z=z;
|
||||
poly[1].x=x+w;
|
||||
poly[1].y=y;
|
||||
poly[1].z=z;
|
||||
poly[2].x=x+w;
|
||||
poly[2].y=y+h;
|
||||
poly[2].z=z;
|
||||
poly[3].x=x;
|
||||
poly[3].y=y+h;
|
||||
poly[3].z=z;
|
||||
return GrFillPoly3(dc,4,poly);
|
||||
}
|
||||
|
||||
public U0 GrBorder(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2,
|
||||
I64 step=1,I64 start=0)
|
||||
{//2D. Transformation with pen width.
|
||||
//Can be used with ROPF_DITHER+WHITE<<16+BLACK for dotted rect.
|
||||
GrLine3(dc,x1,y1,0,x2,y1,0,step,start);
|
||||
GrLine3(dc,x2,y1,0,x2,y2,0,step,start);
|
||||
GrLine3(dc,x2,y2,0,x1,y2,0,step,start);
|
||||
GrLine3(dc,x1,y2,0,x1,y1,0,step,start);
|
||||
}
|
||||
|
||||
public Bool GrArrow3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,
|
||||
I64 x2,I64 y2,I64 z2,F64 w=2.75,I64 step=1,I64 start=0)
|
||||
{//3D. Transformation with pen width.
|
||||
I64 _x1,_y1,_z1,_x2,_y2,_z2,dx,dy;
|
||||
F64 d;
|
||||
Bool res=FALSE,was_transform=FALSE,was_symmetry=FALSE;
|
||||
if (dc->flags & DCF_TRANSFORMATION) {
|
||||
(*dc->transform)(dc,&x1,&y1,&z1);
|
||||
(*dc->transform)(dc,&x2,&y2,&z2);
|
||||
dc->flags&=~DCF_TRANSFORMATION;
|
||||
was_transform=TRUE;
|
||||
}
|
||||
if (dc->flags & DCF_SYMMETRY) {
|
||||
_x1=x1; _y1=y1; _z1=z1;
|
||||
DCReflect(dc,&_x1,&_y1,&_z1);
|
||||
_x2=x2; _y2=y2; _z2=z2;
|
||||
DCReflect(dc,&_x2,&_y2,&_z2);
|
||||
dc->flags&=~DCF_SYMMETRY;
|
||||
res=Line(dc,_x1,_y1,_z1,_x2,_y2,_z2,&GrPlot3,step,start);
|
||||
dx=_x2-_x1; dy=_y2-_y1;
|
||||
if (d=Sqrt(dx*dx+dy*dy)) {
|
||||
d=w*dc->pen_width/d;
|
||||
res|=Line(dc,_x2-dx*d+dy*d+0.5,_y2-dy*d-dx*d+0.5,_z2,
|
||||
_x2,_y2,_z2,&GrPlot3,step);
|
||||
res|=Line(dc,_x2-dx*d-dy*d+0.5,_y2-dy*d+dx*d+0.5,_z2,
|
||||
_x2,_y2,_z2,&GrPlot3,step);
|
||||
}
|
||||
was_symmetry=TRUE;
|
||||
if (dc->flags&DCF_JUST_MIRROR)
|
||||
goto gr_done;
|
||||
}
|
||||
res|=Line(dc,x1,y1,z1,x2,y2,z2,&GrPlot3,step,start);
|
||||
dx=x2-x1; dy=y2-y1;
|
||||
if (d=Sqrt(dx*dx+dy*dy)) {
|
||||
d=w*dc->pen_width/d;
|
||||
res|=Line(dc,x2-dx*d+dy*d+0.5,y2-dy*d-dx*d+0.5,z2,
|
||||
x2,y2,z2,&GrPlot3,step);
|
||||
res|=Line(dc,x2-dx*d-dy*d+0.5,y2-dy*d+dx*d+0.5,z2,
|
||||
x2,y2,z2,&GrPlot3,step);
|
||||
}
|
||||
gr_done:
|
||||
if (was_transform)
|
||||
dc->flags|=DCF_TRANSFORMATION;
|
||||
if (was_symmetry)
|
||||
dc->flags|=DCF_SYMMETRY;
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "Graphics/Char;Char/Graphics"
|
||||
public Bool GrTextBox3(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,U8 *s,I64 border=2)
|
||||
{//3D. Transformation. DCF_SYMMETRY is silly.
|
||||
U8 *ptr;
|
||||
I64 ch,res,w,w_max,h;
|
||||
if (!s) return FALSE;
|
||||
ptr=s;
|
||||
w=0; w_max=0; h=FONT_HEIGHT;
|
||||
|
||||
if (dc->flags & DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x1,&y1,&z1);
|
||||
while (ch=*ptr++) {
|
||||
if (ch=='\t')
|
||||
w=CeilU64(w+FONT_WIDTH,FONT_WIDTH*8);
|
||||
else if (ch=='\n') {
|
||||
if (w>w_max) w_max=w;
|
||||
w=0;
|
||||
h+=FONT_HEIGHT;
|
||||
} else
|
||||
w+=FONT_WIDTH;
|
||||
}
|
||||
if (w>w_max) w_max=w;
|
||||
res=GrPrint(dc,x1,y1,"%s",s);
|
||||
res|=GrLine(dc,x1-border ,y1-border ,x1+w_max+border,y1-border);
|
||||
res|=GrLine(dc,x1-border ,y1+h+border,x1+w_max+border,y1+h+border);
|
||||
res|=GrLine(dc,x1-border ,y1-border ,x1-border,y1+h+border);
|
||||
res|=GrLine(dc,x1+w_max+border,y1-border ,x1+w_max+border,y1+h+border);
|
||||
return ToBool(res);
|
||||
}
|
||||
|
||||
#define DIAMOND_SLOPE_MAX 2.75
|
||||
|
||||
public Bool GrTextDiamond3(CDC *dc=gr.dc,
|
||||
I64 x1,I64 y1,I64 z1,U8 *_s,I64 border=2)
|
||||
{//3D. Transformation. DCF_SYMMETRY is silly.
|
||||
Bool first=TRUE;
|
||||
U8 ch,*ptr,*ptr_end,*st,*s;
|
||||
I64 res=0,y,dx,dy,dx_old,dy_old,w,h=FONT_HEIGHT;
|
||||
F64 m;
|
||||
if (!_s) return FALSE;
|
||||
if (dc->flags & DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x1,&y1,&z1);
|
||||
|
||||
ptr=s=StrNew(_s);
|
||||
while (ch=*ptr) {
|
||||
if (ch=='\r'||ch=='\t')
|
||||
*ptr=CH_SPACE;
|
||||
if (ch=='\n') {
|
||||
*ptr=0;
|
||||
h+=FONT_HEIGHT;
|
||||
}
|
||||
ptr++;
|
||||
}
|
||||
ptr_end=ptr+1;
|
||||
|
||||
y=y1-h>>1;
|
||||
dx=FONT_WIDTH +border; //Minimum
|
||||
dy=FONT_HEIGHT+border+h>>1; //Minimum
|
||||
ptr=s;
|
||||
while (ptr!=ptr_end) {
|
||||
st=ptr;
|
||||
while (*ptr++);
|
||||
StrUtil(st,SUF_REM_LEADING|SUF_REM_TRAILING);
|
||||
|
||||
w=(StrLen(st)*FONT_WIDTH)>>1;
|
||||
if (first) {
|
||||
res|=GrPrint(dc,x1-w,y,"%s",st);
|
||||
first=FALSE;
|
||||
} else
|
||||
res|=GrPrint(dc,x1-w,y,"%s",st);
|
||||
if (w) {
|
||||
w+=border;
|
||||
do {
|
||||
dx_old=dx; dy_old=dy;
|
||||
m=ToF64(dx)/dy;
|
||||
if (m<1/DIAMOND_SLOPE_MAX) {
|
||||
dy=MaxI64(dy,Ceil(DIAMOND_SLOPE_MAX*dx));
|
||||
m=1/DIAMOND_SLOPE_MAX;
|
||||
} else if (m>DIAMOND_SLOPE_MAX) {
|
||||
dy=MaxI64(dy,Ceil(dx/DIAMOND_SLOPE_MAX));
|
||||
m=DIAMOND_SLOPE_MAX;
|
||||
}
|
||||
dx=MaxI64(dx,w+Ceil(m*AbsI64(y-y1)));
|
||||
dx=MaxI64(dx,w+Ceil(m*AbsI64(y+FONT_HEIGHT-y1)));
|
||||
} while (dx!=dx_old || dy!=dy_old);
|
||||
}
|
||||
y+=FONT_HEIGHT;
|
||||
}
|
||||
Free(s);
|
||||
|
||||
res|=GrLine(dc,x1,y1-dy,x1+dx,y1);
|
||||
res|=GrLine(dc,x1+dx,y1,x1,y1+dy);
|
||||
res|=GrLine(dc,x1,y1+dy,x1-dx,y1);
|
||||
res|=GrLine(dc,x1-dx,y1,x1,y1-dy);
|
||||
return ToBool(res);
|
||||
}
|
||||
|
||||
#help_index "Graphics/Mesh"
|
||||
public I64 Gr3Mesh(CDC *dc=gr.dc,I64 vertex_cnt,CD3I32 *p,
|
||||
I64 tri_cnt,CMeshTri *tri)
|
||||
{//Returns cnt of pixs changed.
|
||||
CColorROPU32 old_color=dc->color;
|
||||
I64 i,x,y,z,res=0;
|
||||
CD3I32 *pt,*pt_sym,*p_sym,*dst;
|
||||
CMeshTri *tri_sym=tri;
|
||||
if (dc->flags&DCF_TRANSFORMATION) {
|
||||
dst=pt=MAlloc(sizeof(CD3I32)*vertex_cnt);
|
||||
for (i=0;i<vertex_cnt;i++,p++,dst++) {
|
||||
x=p->x; y=p->y; z=p->z;
|
||||
(*dc->transform)(dc,&x,&y,&z);
|
||||
dst->x=x; dst->y=y; dst->z=z;
|
||||
}
|
||||
p=pt;
|
||||
} else
|
||||
pt=NULL;
|
||||
|
||||
if (dc->flags & DCF_SYMMETRY) {
|
||||
dst=pt_sym=MAlloc(sizeof(CD3I32)*vertex_cnt);
|
||||
p_sym=p;
|
||||
for (i=0;i<vertex_cnt;i++,p_sym++,dst++) {
|
||||
x=p_sym->x; y=p_sym->y; z=p_sym->z;
|
||||
DCReflect(dc,&x,&y,&z);
|
||||
dst->x=x; dst->y=y; dst->z=z;
|
||||
}
|
||||
p_sym=pt_sym;
|
||||
for (i=0;i<tri_cnt;i++,tri_sym++) {
|
||||
(*dc->lighting)(dc,&p_sym[tri_sym->nums[0]],&p_sym[tri_sym->nums[2]],
|
||||
&p_sym[tri_sym->nums[1]],tri_sym->color);
|
||||
res+=GrFillTri0(dc,&p_sym[tri_sym->nums[0]],&p_sym[tri_sym->nums[2]],
|
||||
&p_sym[tri_sym->nums[1]]);
|
||||
}
|
||||
Free(pt_sym);
|
||||
if (dc->flags&DCF_JUST_MIRROR)
|
||||
goto mesh_done;
|
||||
}
|
||||
for (i=0;i<tri_cnt;i++,tri++) {
|
||||
(*dc->lighting)(dc,&p[tri->nums[0]],&p[tri->nums[1]],
|
||||
&p[tri->nums[2]],tri->color);
|
||||
res+=GrFillTri0(dc,&p[tri->nums[0]],&p[tri->nums[1]],&p[tri->nums[2]]);
|
||||
}
|
||||
mesh_done:
|
||||
dc->color=old_color;
|
||||
Free(pt);
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "Graphics/Misc;Mouse/Ptr"
|
||||
public U0 DrawStdMs(CDC *dc,I64 x,I64 y)
|
||||
{//This is a callback. See $LK,"::/Demo/Graphics/Grid.HC"$.
|
||||
//Called by $LK,"DrawMs",A="MN:DrawMs"$() which is
|
||||
//called by $LK,"WinFinalUpdate",A="MN:WinFinalUpdate"$().
|
||||
dc->pen_width=1;
|
||||
dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
|
||||
GrArrow3(dc,x+8,y+8,0,x,y,0);
|
||||
}
|
||||
|
||||
gr.fp_draw_ms=&DrawStdMs;
|
||||
|
||||
public U0 DrawWaitMs(CDC *dc,I64 x,I64 y)
|
||||
{//This is a callback. See $LK,"::/Demo/Graphics/Grid.HC"$.
|
||||
I64 old_pen_width=dc->pen_width;
|
||||
CColorROPU32 old_color=dc->color;
|
||||
dc->pen_width=3;
|
||||
dc->color=LTRED;
|
||||
GrCircle3(dc,x,y,0,7);
|
||||
GrLine3(dc,x-6,y+6,0,x+6,y-6,0);
|
||||
dc->color=RED;
|
||||
GrCircle(dc,x,y,7);
|
||||
GrLine(dc,x-6,y+6,x+6,y-6);
|
||||
dc->pen_width=old_pen_width;
|
||||
dc->color=old_color;
|
||||
}
|
||||
|
||||
#help_index "Graphics/GR Files;Graphics/Scrn"
|
||||
public Bool GRScrnCaptureRead(U8 *filename,CDC *dc=gr.dc,I64 x=0,I64 y=0)
|
||||
{//GrBlot TempleOS GR File to dc,x,y.
|
||||
CDC *dc2;
|
||||
if (dc2=GRRead(filename)) {
|
||||
dc->color=ROP_EQU;
|
||||
GrBlot(dc,x,y,dc2);
|
||||
DCDel(dc2);
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
public I64 GRScrnCaptureWrite(U8 *filename,Bool include_zoom=TRUE)
|
||||
{//Capture scrn to a TempleOS GR File.
|
||||
I64 size;
|
||||
CDC *dc=DCScrnCapture(include_zoom);
|
||||
size=GRWrite(filename,dc,DCSF_COMPRESSED|DCSF_PALETTE_GET);
|
||||
DCDel(dc);
|
||||
return size;
|
||||
}
|
||||
@@ -0,0 +1,430 @@
|
||||
#help_index "Graphics/Math/3D Transformation"
|
||||
#help_file "::/Doc/Transform"
|
||||
|
||||
#define GR_SCALE (1<<32)
|
||||
|
||||
public U0 Mat4x4MulXYZ(I64 *r,I64 *_x,I64 *_y,I64 *_z)
|
||||
{//Rotate 3D point using 4x4 matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
I64 x1,y1,z1,xx=*_x,yy=*_y,zz=*_z;
|
||||
x1=(r[0*4+0]*xx+r[0*4+1]*yy+r[0*4+2]*zz+r[0*4+3])>>32;
|
||||
y1=(r[1*4+0]*xx+r[1*4+1]*yy+r[1*4+2]*zz+r[1*4+3])>>32;
|
||||
z1=(r[2*4+0]*xx+r[2*4+1]*yy+r[2*4+2]*zz+r[2*4+3])>>32;
|
||||
*_x=x1;*_y=y1;*_z=z1;
|
||||
}
|
||||
|
||||
public U0 DCTransform(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
|
||||
{//This is the dft dc->transform() callback.
|
||||
//Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
Mat4x4MulXYZ(dc->r,_x,_y,_z);
|
||||
*_x+=dc->x;
|
||||
*_y+=dc->y;
|
||||
*_z+=dc->z;
|
||||
}
|
||||
|
||||
public I64 *Mat4x4IdentEqu(I64 *r)
|
||||
{//Set matrix to identity. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
MemSet(r,0,sizeof(I64)*16);
|
||||
r[0*4+0].i32[1]=1;
|
||||
r[1*4+1].i32[1]=1;
|
||||
r[2*4+2].i32[1]=1;
|
||||
r[3*4+3].i32[1]=1;
|
||||
return r;
|
||||
}
|
||||
|
||||
public I64 *Mat4x4IdentNew(CTask *mem_task=NULL)
|
||||
{//MAlloc an identity matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
return Mat4x4IdentEqu(MAlloc(sizeof(I64)*16,mem_task));
|
||||
}
|
||||
|
||||
public I64 Mat4x4NormSqr65536(I64 *r)
|
||||
{//Norm Squared of r.
|
||||
//(1.0/Sqrt(3))*65536=37837.22
|
||||
return SqrI64((r[0*4+0]*37838+r[0*4+1]*37838+r[0*4+2]*37838)>>32)+
|
||||
SqrI64((r[1*4+0]*37837+r[1*4+1]*37837+r[1*4+2]*37837)>>32)+
|
||||
SqrI64((r[2*4+0]*37837+r[2*4+1]*37837+r[2*4+2]*37837)>>32);
|
||||
}
|
||||
|
||||
public U0 DCMat4x4Set(CDC *dc=NULL,I64 *r)
|
||||
{//Set device context's rot matrix. Will be $LK,"Free",A="MN:Free"$d() in $LK,"DCDel",A="MN:DCDel"$().Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
//The main purpose is to set matrix norm for pen width scaling.
|
||||
//NULL as dc means gr.dc
|
||||
if (!dc) dc=gr.dc;
|
||||
dc->r=r;
|
||||
dc->r_norm=Sqrt(Mat4x4NormSqr65536(r))*65536; //scaled 32 bits
|
||||
}
|
||||
|
||||
#help_index "Graphics/Mesh"
|
||||
public U0 DCLighting(CDC *dc,
|
||||
CD3I32 *p1,CD3I32 *p2,CD3I32 *p3,CColorROPU32 color)
|
||||
{//This is the dft dc->lighting() callback.
|
||||
CD3I32 v1,v2;
|
||||
I64 i,vn_x,vn_y,vn_z;
|
||||
F64 d;
|
||||
|
||||
v1.x=p1->x-p2->x;
|
||||
v1.y=p1->y-p2->y;
|
||||
v1.z=p1->z-p2->z;
|
||||
|
||||
v2.x=p3->x-p2->x;
|
||||
v2.y=p3->y-p2->y;
|
||||
v2.z=p3->z-p2->z;
|
||||
|
||||
//V1 and V2 are vects along two sides
|
||||
//of the tri joined at p2.
|
||||
|
||||
vn_x=v1.y*v2.z-v1.z*v2.y;
|
||||
vn_y=v1.z*v2.x-v1.x*v2.z;
|
||||
vn_z=v1.x*v2.y-v1.y*v2.x;
|
||||
if (d=Sqrt(SqrI64(vn_x)+SqrI64(vn_y)+SqrI64(vn_z)))
|
||||
d=1<<16/d;
|
||||
vn_x*=d;
|
||||
vn_y*=d;
|
||||
vn_z*=d;
|
||||
//Vn is the cross product of V1 and V3
|
||||
//which means it is perpendicular. It
|
||||
//is the normal vect to the surface.
|
||||
//It has been scaled to length 65536.
|
||||
|
||||
//Light source has been scaled to length 65536.
|
||||
i=(vn_x*dc->ls.x+vn_y*dc->ls.y+vn_z*dc->ls.z)>>16;
|
||||
//The dot product of the light source
|
||||
//vect and the surface normal
|
||||
//gives an illumination number.
|
||||
//65536*65536>>16=65536
|
||||
|
||||
//TempleOS will generate a random U16
|
||||
//and compare to dither_probability_u16 and
|
||||
//will pick from two colors.
|
||||
//Probability dithering does not work with pen_width>1 at this time.
|
||||
if (color.c0.rop&ROPBF_TWO_SIDED) {
|
||||
color.c0.rop&=~ROPBF_TWO_SIDED;
|
||||
i=AbsI64(i)<<1;
|
||||
} else
|
||||
i+=65536;
|
||||
if (color.c0.rop&ROPBF_HALF_RANGE_COLOR) {
|
||||
color.c0.rop&=~ROPBF_HALF_RANGE_COLOR;
|
||||
i>>=1;
|
||||
if (color>=8) {
|
||||
color-=8;
|
||||
i+=65536;
|
||||
}
|
||||
}
|
||||
if (i<65536) {
|
||||
dc->color=ROPF_PROBABILITY_DITHER+color<<16+BLACK;
|
||||
dc->dither_probability_u16=i;
|
||||
} else {
|
||||
dc->color=ROPF_PROBABILITY_DITHER+(color^8)<<16+color;
|
||||
dc->dither_probability_u16=i-65536;
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "Graphics/Device Contexts"
|
||||
public U0 DCFill(CDC *dc=NULL,CColorROPU32 val=TRANSPARENT)
|
||||
{//Fill entire device context with color.
|
||||
if (!dc) dc=gr.dc;
|
||||
MemSet(dc->body,val,dc->width_internal*dc->height);
|
||||
}
|
||||
|
||||
public U0 DCClear(CDC *dc=NULL)
|
||||
{//Set entire device context image body to 0 (BLACK).
|
||||
if (!dc) dc=gr.dc;
|
||||
DCFill(dc,0);
|
||||
}
|
||||
|
||||
public U0 DCRst(CDC *dc)
|
||||
{//Reset $LK,"CDC",A="MN:CDC"$ structure members but not image body, itself.
|
||||
dc->color=BLACK;
|
||||
dc->color2=BLACK;
|
||||
dc->bkcolor=BLACK;
|
||||
dc->collision_cnt=0;
|
||||
dc->pen_width=1;
|
||||
dc->ls.x=37837; //1<<16/Sqrt(3)
|
||||
dc->ls.y=37837;
|
||||
dc->ls.z=37837;
|
||||
dc->x=0;
|
||||
dc->y=0;
|
||||
dc->z=0;
|
||||
dc->transform=&DCTransform;
|
||||
dc->lighting =&DCLighting;
|
||||
Mat4x4IdentEqu(dc->r);
|
||||
dc->r_norm=GR_SCALE;
|
||||
dc->flags&=~(DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR);
|
||||
MemCpy(dc->palette,gr_palette_std,sizeof(CBGR48)*COLORS_NUM);
|
||||
}
|
||||
|
||||
public U0 DCExtentsInit(CDC *dc=NULL)
|
||||
{//Init markers for extent of next newly drawn graphics.
|
||||
//NULL means gr.dc
|
||||
//See $LK,"::/Demo/Graphics/Extents.HC"$
|
||||
//You should clear the record flag yourself
|
||||
if (!dc) dc=gr.dc;
|
||||
dc->flags|=DCF_RECORD_EXTENTS;
|
||||
dc->min_x=I64_MAX;
|
||||
dc->max_x=I64_MIN;
|
||||
dc->min_y=I64_MAX;
|
||||
dc->max_y=I64_MIN;
|
||||
}
|
||||
|
||||
public CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL)
|
||||
{//Create alias of dc, so can change pen, color, etc.
|
||||
//NULL means gr.dc
|
||||
CDC *res;
|
||||
if (!dc) dc=gr.dc;
|
||||
if (!task) task=Fs;
|
||||
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
|
||||
throw('Graphics');
|
||||
res=MAlloc(sizeof(CDC),task);
|
||||
MemCpy(res,dc,sizeof(CDC));
|
||||
res->win_task=res->mem_task=task;
|
||||
res->r=MAlloc(16*sizeof(I64),task);
|
||||
DCRst(res);
|
||||
res->flags|=DCF_ALIAS;
|
||||
res->alias=dc;
|
||||
return res;
|
||||
}
|
||||
|
||||
public CDC *DCNew(I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE)
|
||||
{//Create new width x height device context.
|
||||
//Internally only allows widths which are divisible by 8.
|
||||
//Don't forget these $MA-X+PU,"sizeof(CDC)",LM="Find(\"sizeof(CDC)\",\"/*\");View;"$.
|
||||
CDC *res;
|
||||
if (!task) task=Fs;
|
||||
res=CAlloc(sizeof(CDC),task);
|
||||
res->win_task=task;
|
||||
res->mem_task=task;
|
||||
res->width=width;
|
||||
res->width_internal=(width+7)&~7;
|
||||
res->height=height;
|
||||
if (null_bitmap)
|
||||
res->flags|=DCF_DONT_DRAW;
|
||||
else
|
||||
res->body=CAlloc(res->width_internal*res->height,task);
|
||||
res->r=MAlloc(16*sizeof(I64),task);
|
||||
DCRst(res);
|
||||
res->dc_signature=DCS_SIGNATURE_VAL;
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 DCDel(CDC *dc)
|
||||
{//Free dc, image body, rot mat and depth buf.
|
||||
if (!dc) return;
|
||||
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
|
||||
throw('Graphics');
|
||||
dc->dc_signature=0;
|
||||
Free(dc->r);
|
||||
if (!(dc->flags & DCF_ALIAS))
|
||||
Free(dc->body);
|
||||
Free(dc->depth_buf);
|
||||
Free(dc);
|
||||
}
|
||||
|
||||
public I64 DCSize(CDC *dc)
|
||||
{//Mem size of header, image body and depth buffer.
|
||||
if (dc)
|
||||
return MSize2(dc)+MSize2(dc->body)+MSize2(dc->depth_buf);
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
public I32 *DCDepthBufRst(CDC *dc)
|
||||
{//Reset device context depth buf to far away.
|
||||
if (dc->depth_buf)
|
||||
MemSetU32(dc->depth_buf,I32_MAX,dc->width_internal*dc->height);
|
||||
return dc->depth_buf;
|
||||
}
|
||||
|
||||
public I32 *DCDepthBufAlloc(CDC *dc)
|
||||
{//Alloc a 32-bit depth buffer for device context.
|
||||
Free(dc->depth_buf);
|
||||
dc->depth_buf=MAlloc(dc->width_internal*dc->height*sizeof(I32),dc->mem_task);
|
||||
return DCDepthBufRst(dc);
|
||||
}
|
||||
|
||||
public CDC *DCCopy(CDC *dc,CTask *task=NULL)
|
||||
{//Alloc copy of dc, including image body, rot mat and depth buf.
|
||||
CDC *res;
|
||||
if (!dc) return NULL;
|
||||
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
|
||||
throw('Graphics');
|
||||
res=MAllocIdent(dc,task);
|
||||
DCMat4x4Set(res,Mat4x4New(dc->r,task));
|
||||
res->mem_task=task;
|
||||
res->body=MAllocIdent(dc->body,task);
|
||||
res->depth_buf=MAllocIdent(dc->depth_buf,task);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U0 DCMono(CDC *dc,
|
||||
I64 quest=TRANSPARENT,I64 true_color=0,I64 false_color=COLOR_MONO)
|
||||
{//Set entire device context to one of two colors.
|
||||
I64 i;
|
||||
U8 *dst;
|
||||
dst=dc->body;
|
||||
i=dc->width_internal*dc->height;
|
||||
while (i--)
|
||||
if (*dst==quest)
|
||||
*dst++=true_color;
|
||||
else
|
||||
*dst++=false_color;
|
||||
}
|
||||
|
||||
public I64 DCColorChg(CDC *dc,I64 src_color,I64 dst_color=TRANSPARENT)
|
||||
{//Find and replace src color with dst in device context.
|
||||
I64 i,res=0;
|
||||
U8 *dst;
|
||||
dst=dc->body;
|
||||
i=dc->width_internal*dc->height;
|
||||
while (i--)
|
||||
if (*dst==src_color) {
|
||||
*dst++=dst_color;
|
||||
res++;
|
||||
} else
|
||||
dst++;
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *DCSave(CDC *dc,I64 *_size=NULL,I64 dcsf_flags=DCSF_COMPRESSED)
|
||||
{//Stores device context to mem, perhaps, with compression.
|
||||
U8 *res,*ptr,*body;
|
||||
CArcCompress *arc;
|
||||
I64 body_size=dc->width_internal*dc->height,total_size,flags;
|
||||
CBGR48 palette[COLORS_NUM];
|
||||
|
||||
if (dcsf_flags&DCSF_COMPRESSED) {
|
||||
arc=CompressBuf(dc->body,body_size);
|
||||
body_size=arc->compressed_size;
|
||||
body=arc;
|
||||
} else {
|
||||
arc=NULL;
|
||||
body=dc->body;
|
||||
}
|
||||
|
||||
total_size=offset(CDC.end)-offset(CDC.start)+body_size;
|
||||
if (dcsf_flags&DCSF_COMPRESSED)
|
||||
flags=DCF_COMPRESSED;
|
||||
else
|
||||
flags=0;
|
||||
|
||||
if (dcsf_flags&DCSF_PALETTE_GET)
|
||||
GrPaletteGet(palette);
|
||||
else
|
||||
MemCpy(palette,&dc->palette,COLORS_NUM*sizeof(CBGR48));
|
||||
if (MemCmp(palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48))) {
|
||||
flags|=DCF_PALETTE;
|
||||
total_size+=COLORS_NUM*sizeof(CBGR48);
|
||||
}
|
||||
|
||||
ptr=res=MAlloc(total_size);
|
||||
|
||||
#assert !offset(CDC.start)
|
||||
MemCpy(ptr,&dc->start,offset(CDC.end)-offset(CDC.start));
|
||||
ptr(CDC *)->flags=flags;
|
||||
ptr+=offset(CDC.end)-offset(CDC.start);
|
||||
|
||||
#assert offset(CDC.end)==offset(CDC.palette)
|
||||
if (flags&DCF_PALETTE) {
|
||||
MemCpy(ptr,palette,COLORS_NUM*sizeof(CBGR48));
|
||||
ptr+=COLORS_NUM*sizeof(CBGR48);
|
||||
}
|
||||
|
||||
MemCpy(ptr,body,body_size);
|
||||
ptr+=body_size;
|
||||
|
||||
Free(arc);
|
||||
if (_size) *_size=total_size;
|
||||
return res;
|
||||
}
|
||||
|
||||
public CDC *DCLoad(U8 *src,I64 *_size=NULL,CTask *task=NULL)
|
||||
{//Loads device context from mem.
|
||||
CDC *res;
|
||||
U8 *ptr=src;
|
||||
CArcCompress *arc;
|
||||
I64 body_size;
|
||||
if (!task) task=Fs;
|
||||
res=CAlloc(sizeof(CDC),task);
|
||||
res->win_task=task;
|
||||
res->mem_task=task;
|
||||
MemCpy(&res->start,ptr,offset(CDC.end)-offset(CDC.start));
|
||||
ptr+=offset(CDC.end)-offset(CDC.start);
|
||||
|
||||
if (res->flags&DCF_PALETTE) {
|
||||
MemCpy(&res->palette,ptr,COLORS_NUM*sizeof(CBGR48));
|
||||
ptr+=COLORS_NUM*sizeof(CBGR48);
|
||||
} else
|
||||
MemCpy(&res->palette,gr_palette_std,COLORS_NUM*sizeof(CBGR48));
|
||||
|
||||
body_size=res->width_internal*res->height;
|
||||
if (res->flags&DCF_COMPRESSED) {
|
||||
res->flags&=~DCF_COMPRESSED;
|
||||
arc=ptr;
|
||||
res->body=ExpandBuf(arc,task);
|
||||
ptr+=arc->compressed_size;
|
||||
} else {
|
||||
res->body=MAlloc(body_size,task);
|
||||
MemCpy(res->body,ptr,body_size);
|
||||
ptr+=body_size;
|
||||
}
|
||||
res->pen_width=1;
|
||||
res->r=Mat4x4IdentNew(task);
|
||||
res->r_norm.u32[1]=1;
|
||||
res->dc_signature=DCS_SIGNATURE_VAL;
|
||||
if (_size) *_size=ptr-src;
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "Graphics/GR Files"
|
||||
#help_file "::/Doc/GRFiles"
|
||||
#help_index "Graphics/Device Contexts;Graphics/GR Files"
|
||||
public I64 GRWrite(U8 *filename,CDC *dc,I64 dcsf_flags=DCSF_COMPRESSED)
|
||||
{//TempleOS GR File.
|
||||
I64 size;
|
||||
U8 *st=DftExt(filename,"GR.Z"),
|
||||
*src=DCSave(dc,&size,dcsf_flags);
|
||||
FileWrite(st,src,size);
|
||||
Free(st);
|
||||
Free(src);
|
||||
return size;
|
||||
}
|
||||
|
||||
public CDC *GRRead(U8 *filename,CTask *task=NULL)
|
||||
{//TempleOS GR File.
|
||||
CDC *dc=NULL;
|
||||
U8 *st=DftExt(filename,"GR.Z"),
|
||||
*src=FileRead(st);
|
||||
if (src)
|
||||
dc=DCLoad(src,,task);
|
||||
Free(src);
|
||||
Free(st);
|
||||
return dc;
|
||||
}
|
||||
|
||||
#help_index "Graphics/Sprite;Graphics/GR Files;DolDoc/Output;StdOut/DolDoc"
|
||||
public U0 DocGR(CDoc *doc=NULL,U8 *filename)
|
||||
{//Put a GR file into a document as asprite.
|
||||
CDC *dc=GRRead(filename);
|
||||
CSprite *elems=DC2Sprite(dc);
|
||||
DocSprite(doc,elems);
|
||||
Free(elems);
|
||||
DCDel(dc);
|
||||
}
|
||||
|
||||
#help_index "Graphics/Device Contexts;Graphics/Scrn"
|
||||
public CDC *DCScrnCapture(Bool include_zoom=TRUE,CTask *task=NULL)
|
||||
{//Capture scrn to a device context.
|
||||
CDC *dc;
|
||||
U8 *dst;
|
||||
Refresh(2,TRUE);
|
||||
if (include_zoom)
|
||||
dc=DCCopy(gr.scrn_image,task);
|
||||
else
|
||||
dc=DCCopy(gr.dc1,task);
|
||||
dc->flags&=~DCF_SCRN_BITMAP;
|
||||
dst=MAlloc(dc->width_internal*dc->height,task);
|
||||
//Pick background color that never occurs. COLOR_INVALID
|
||||
GrBitMap4ToBitMap8(dst,dc->body,
|
||||
(dc->width_internal*dc->height)>>1,COLOR_INVALID);
|
||||
Free(dc->body);
|
||||
dc->body=dst;
|
||||
return dc;
|
||||
}
|
||||
@@ -0,0 +1,29 @@
|
||||
#help_index "Graphics/Scrn"
|
||||
|
||||
U0 CtrlAltZ(I64 sc)
|
||||
{
|
||||
if (sc&SCF_SHIFT)
|
||||
GrScaleZoom(0.5);
|
||||
else
|
||||
GrScaleZoom(2.0);
|
||||
}
|
||||
CtrlAltCBSet('Z',&CtrlAltZ,"Cmd /Zoom In",
|
||||
"Cmd /Zoom Out");
|
||||
|
||||
U0 Scrn2Clipboard(I64)
|
||||
{
|
||||
CDC *dc=DCScrnCapture;
|
||||
U8 *elems=DC2Sprite(dc);
|
||||
Bool unlock_doc=DocLock(sys_clipboard_doc);
|
||||
ClipboardDel;
|
||||
DocSprite(sys_clipboard_doc,elems);
|
||||
if (unlock_doc)
|
||||
DocUnlock(sys_clipboard_doc);
|
||||
Free(elems);
|
||||
DCDel(dc);
|
||||
}
|
||||
U0 CtrlAltS(I64)
|
||||
{
|
||||
Spawn(&Scrn2Clipboard);
|
||||
}
|
||||
CtrlAltCBSet('S',&CtrlAltS,"Cmd /Scrn Shot to Clipboard");
|
||||
@@ -0,0 +1,5 @@
|
||||
#help_index "Graphics"
|
||||
extern U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor);
|
||||
extern I64 GrBlot3(CDC *dc,I64 x1,I64 y1,I64 z1,CDC *img);
|
||||
extern I64 *Mat4x4New(I64 *src,CTask *mem_task=NULL);
|
||||
extern U8 *SpriteQue2Sprite(CSprite *head,I64 *_size=NULL);
|
||||
@@ -0,0 +1,55 @@
|
||||
#help_index "Graphics"
|
||||
|
||||
public class CGrGlbls
|
||||
{
|
||||
I64 *to_8_bits,*to_8_colors;
|
||||
CDC *scrn_image, //Read only.
|
||||
*dc, //Persistent
|
||||
*dc1,
|
||||
*dc2, //Updated every refresh
|
||||
*dc_cache,
|
||||
*zoomed_dc;
|
||||
U32 *text_base; //See $LK,"TextBase Layer",A="HI:TextBase Layer"$. (Similar to 0xB8000 but 32 bits)
|
||||
U16 *win_z_buf;
|
||||
|
||||
#define SPHT_ELEM_CODE 1
|
||||
CHashTable *sprite_hash;
|
||||
|
||||
U16 *win_uncovered_bitmap;
|
||||
I64 highest_uncovered;
|
||||
U16 *vga_text_cache;
|
||||
I64 pan_text_x,pan_text_y; //[-7,7]
|
||||
U0 (*fp_final_scrn_update)(CDC *dc);//Mouse cursor is handled here.
|
||||
U0 (*fp_wall_paper)(CTask *task);
|
||||
U0 (*fp_draw_ms)(CDC *dc,I64 x,I64 y);
|
||||
U0 (*fp_draw_grab_ms)(CDC *dc,I64 x,I64 y,Bool closed);
|
||||
U8 *empty_sprite; //Gets assigned $LK,"gr.empty_sprite",A="FF:::/Adam/AMouse.HC,empty_sprite"$
|
||||
|
||||
#define GR_PEN_BRUSHES_NUM 64
|
||||
CDC *pen_brushes[GR_PEN_BRUSHES_NUM],
|
||||
*collision_pen_brushes[GR_PEN_BRUSHES_NUM],
|
||||
*even_pen_brushes[GR_PEN_BRUSHES_NUM],
|
||||
*odd_pen_brushes[GR_PEN_BRUSHES_NUM];
|
||||
I8 circle_lo[GR_PEN_BRUSHES_NUM][GR_PEN_BRUSHES_NUM],
|
||||
circle_hi[GR_PEN_BRUSHES_NUM][GR_PEN_BRUSHES_NUM];
|
||||
|
||||
#define GR_SCRN_ZOOM_MAX 8
|
||||
U8 *scrn_zoom_tables[GR_SCRN_ZOOM_MAX+1];
|
||||
I64 scrn_zoom,sx,sy;
|
||||
|
||||
//When zoomed, this keeps the mouse centered.
|
||||
Bool continuous_scroll,
|
||||
hide_row,hide_col;
|
||||
} gr;
|
||||
|
||||
//See $LK,"RLf_VGA",A="FF:::/Kernel/KStart16.HC,RLf_VGA"$
|
||||
//See $LK,"SysGrInit",A="MN:SysGrInit"$()
|
||||
//Allows consts to be used instead of vars.
|
||||
HashPublic("GR_WIDTH",HTT_DEFINE_STR);;
|
||||
HashPublic("GR_HEIGHT",HTT_DEFINE_STR);;
|
||||
|
||||
#help_index "Char;TextBase Layer/Char"
|
||||
DefinePrint("TEXT_ROWS","%d",text.rows);;;
|
||||
HashPublic("TEXT_ROWS",HTT_DEFINE_STR);;;
|
||||
DefinePrint("TEXT_COLS","%d",text.cols);;;
|
||||
HashPublic("TEXT_COLS",HTT_DEFINE_STR);;;
|
||||
@@ -0,0 +1,21 @@
|
||||
#help_index "Graphics"
|
||||
|
||||
U0 GrInit1()
|
||||
{
|
||||
DefineLstLoad("ST_SPRITE_ELEM_TYPES",
|
||||
"End\0Color\0Dither Color\0"
|
||||
"Width\0Planar Symmetry\0Transform On\0Transform Off\0Shift\0"
|
||||
"Point\0PolyPoint\0Line\0PolyLine\0Rect\0Rotated Rect\0"
|
||||
"Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2 Closed\0"
|
||||
"BSpline3\0BSpline3 Closed\0"
|
||||
"Flood Fill\0Flood Fill Not Color\0BitMap\0Mesh\0Shiftable Mesh\0"
|
||||
"Arrow\0Text\0Text Box\0Text Diamond\0");
|
||||
DefineLstLoad("ST_SPRITE_ELEM_CODES",
|
||||
"End\0Color\0Color\0"
|
||||
"Width\0PlanarSymmetry\0Transform\0Transform\0Shift\0"
|
||||
"Pt\0PolyPt\0Line\0PolyLine\0Rect\0Rect\0"
|
||||
"Circle\0Ellipse\0Polygon\0BSpline2\0BSpline2\0BSpline3\0BSpline3\0"
|
||||
"FloodFill\0FloodFill\0BitMap\0Mesh\0Mesh\0"
|
||||
"Arrow\0Text\0TextBox\0TextDiamond\0");
|
||||
}
|
||||
GrInit1;
|
||||
@@ -0,0 +1,209 @@
|
||||
#help_index "Graphics/Scrn"
|
||||
|
||||
U0 GrSetUpTables()
|
||||
{
|
||||
CDC *dc;
|
||||
I64 i,j,k,l,m,x,y,rr;
|
||||
U8 *dst;
|
||||
|
||||
k=0;
|
||||
for (i=0;i<256;i++)
|
||||
for (j=0;j<8;j++)
|
||||
if (Bt(&i,j))
|
||||
gr.to_8_bits(U8 *)[k++]=0xFF;
|
||||
else
|
||||
gr.to_8_bits(U8 *)[k++]=0x00;
|
||||
k=0;
|
||||
for (i=0;i<256;i++)
|
||||
for (j=0;j<8;j++)
|
||||
gr.to_8_colors(U8 *)[k++]=i;
|
||||
|
||||
for (i=0;i<GR_PEN_BRUSHES_NUM;i++) {
|
||||
k=i+1;
|
||||
|
||||
rr=k*k;
|
||||
for (y=1;y<k;y++)
|
||||
for (x=1;x<k;x++)
|
||||
if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr) {
|
||||
if (x-1-i>>1<gr.circle_lo[i][i-y])
|
||||
gr.circle_lo[i][i-y]=x-1-i>>1;
|
||||
if (x-1-i>>1>gr.circle_hi[i][i-y])
|
||||
gr.circle_hi[i][i-y]=x-1-i>>1;
|
||||
}
|
||||
|
||||
dc=DCNew(i,i);
|
||||
gr.pen_brushes[i]=dc;
|
||||
dc->color=COLOR_MONO;
|
||||
rr=k*k;
|
||||
for (y=1;y<k;y++)
|
||||
for (x=1;x<k;x++)
|
||||
if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
|
||||
GrPlot0(dc,x-1,y-1);
|
||||
|
||||
dc=DCNew(i,i);
|
||||
gr.collision_pen_brushes[i]=dc;
|
||||
dc->color=COLOR_INVALID;//Want color that never occurs.
|
||||
rr=k*k;
|
||||
for (y=1;y<k;y++)
|
||||
for (x=1;x<k;x++)
|
||||
if (SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
|
||||
GrPlot0(dc,x-1,y-1);
|
||||
|
||||
dc=DCNew(i,i);
|
||||
gr.even_pen_brushes[i]=dc;
|
||||
dc->color=COLOR_MONO;
|
||||
rr=k*k;
|
||||
for (y=1;y<k;y++)
|
||||
for (x=1;x<k;x++)
|
||||
if (!(((x-1)^(y-1))&1) && SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
|
||||
GrPlot0(dc,x-1,y-1);
|
||||
|
||||
dc=DCNew(i,i);
|
||||
gr.odd_pen_brushes[i]=dc;
|
||||
dc->color=COLOR_MONO;
|
||||
rr=k*k;
|
||||
for (y=1;y<k;y++)
|
||||
for (x=1;x<k;x++)
|
||||
if (((x-1)^(y-1))&1 && SqrI64(y*2-k)+SqrI64(x*2-k)<rr)
|
||||
GrPlot0(dc,x-1,y-1);
|
||||
}
|
||||
if (!Bt(&sys_run_level,RLf_VGA)) { //if text mode
|
||||
MemSet(text.vga_text_alias,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
|
||||
MemSet(gr.vga_text_cache,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
|
||||
} else {
|
||||
OutU8(VGAP_IDX,VGAR_MAP_MASK);
|
||||
OutU8(VGAP_DATA,0x0F);
|
||||
//Virtual Box crashes on the following for some reason.
|
||||
// MemSet(text.vga_alias,0,GR_HEIGHT*GR_WIDTH>>3);
|
||||
MemSet(gr.scrn_image->body,0,GR_WIDTH*GR_HEIGHT>>1);
|
||||
}
|
||||
for (i=1;i<=GR_SCRN_ZOOM_MAX;i++) {
|
||||
dst=gr.scrn_zoom_tables[i]=MAlloc(256*i);
|
||||
for (j=0;j<256;j++) {
|
||||
m=0;
|
||||
for (k=0;k<8;k++) {
|
||||
if (Bt(&j,k)) {
|
||||
for (l=0;l<i;l++)
|
||||
Bts(&m,l+k*i);
|
||||
}
|
||||
}
|
||||
for (l=0;l<i;l++)
|
||||
dst[j+l*256]=m.u8[l];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "Graphics/Scrn;Windows"
|
||||
|
||||
U0 WinZBufFill(CTask *task)
|
||||
{//Not public
|
||||
I64 y,t,b,l,r,w;
|
||||
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
|
||||
if (task->win_top-1>0)
|
||||
t=task->win_top-1;
|
||||
else
|
||||
t=0;
|
||||
if (task->win_bottom+1<TEXT_ROWS)
|
||||
b=task->win_bottom+1;
|
||||
else
|
||||
b=TEXT_ROWS-1;
|
||||
if (task->win_left-1>0)
|
||||
l=task->win_left-1;
|
||||
else
|
||||
l=0;
|
||||
if (task->win_right+1<TEXT_COLS)
|
||||
r=task->win_right+1;
|
||||
else
|
||||
r=TEXT_COLS-1;
|
||||
} else {
|
||||
if (task->win_top>0)
|
||||
t=task->win_top;
|
||||
else
|
||||
t=0;
|
||||
if (task->win_bottom<TEXT_ROWS)
|
||||
b=task->win_bottom;
|
||||
else
|
||||
b=TEXT_ROWS-1;
|
||||
if (task->win_left>0)
|
||||
l=task->win_left;
|
||||
else
|
||||
l=0;
|
||||
if (task->win_right<TEXT_COLS)
|
||||
r=task->win_right;
|
||||
else
|
||||
r=TEXT_COLS-1;
|
||||
}
|
||||
t=ClampI64(t,0,TEXT_ROWS-1);
|
||||
b=ClampI64(b,t,TEXT_ROWS-1);
|
||||
l=ClampI64(l,0,TEXT_COLS-1);
|
||||
r=ClampI64(r,l,TEXT_COLS-1);
|
||||
if (w=r-l+1)
|
||||
for (y=t;y<=b;y++)
|
||||
MemSetU16(gr.win_z_buf(U8 *)+(y*TEXT_COLS+l)*sizeof(U16),
|
||||
task->win_z_num,w);
|
||||
}
|
||||
|
||||
public U0 WinZBufUpdate()
|
||||
{//Might have to call if doing graphics outside winmgr callback routines.
|
||||
//Call it if, for example, when a pop-up window closes and you need to refresh
|
||||
//before graphics.
|
||||
I64 i,z=1;
|
||||
U16 *ptr;
|
||||
CTask *task,*task1;
|
||||
if (gr.win_z_buf) {
|
||||
LBtr(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0);
|
||||
task1=task=sys_winmgr_task;
|
||||
do {
|
||||
if (!TaskValidate(task)) break;
|
||||
if (Bt(&task->display_flags,DISPLAYf_SHOW)) {
|
||||
task->win_z_num=z++;
|
||||
WinZBufFill(task);
|
||||
}
|
||||
task=task->next_task;
|
||||
} while (task!=task1 && z<0x10000);
|
||||
|
||||
MemSet(gr.win_uncovered_bitmap,0,(gr.highest_uncovered+7)>>3+1);
|
||||
gr.highest_uncovered=z-1;
|
||||
for (ptr=gr.win_z_buf,i=TEXT_ROWS*TEXT_COLS;i;i--)
|
||||
Bts(gr.win_uncovered_bitmap,*ptr++);
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "Graphics"
|
||||
U0 GrInit2()
|
||||
{
|
||||
MemSet(&gr,0,sizeof(CGrGlbls));
|
||||
gr.sprite_hash=HashTableNew(512);
|
||||
HashDefineLstAdd("ST_SPRITE_ELEM_CODES",SPHT_ELEM_CODE,gr.sprite_hash);
|
||||
gr.scrn_zoom=1;
|
||||
|
||||
PaletteSetStd;
|
||||
fp_set_std_palette=&PaletteSetStd;
|
||||
GrPaletteIndicesSet;
|
||||
|
||||
gr.to_8_bits =MAlloc(256*sizeof(I64));
|
||||
gr.to_8_colors=MAlloc(256*sizeof(I64));
|
||||
|
||||
gr.text_base=CAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U32));
|
||||
gr.vga_text_cache=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
|
||||
gr.win_uncovered_bitmap=CAlloc(65536/8);
|
||||
gr.highest_uncovered=0;
|
||||
gr.win_z_buf=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
|
||||
|
||||
gr.dc2=DCNew(GR_WIDTH,GR_HEIGHT);
|
||||
gr.dc2->flags|=DCF_SCRN_BITMAP;
|
||||
gr.dc_cache=DCNew(GR_WIDTH,GR_HEIGHT);
|
||||
|
||||
gr.dc=DCNew(GR_WIDTH,GR_HEIGHT);
|
||||
gr.dc->flags|=DCF_SCRN_BITMAP|DCF_ON_TOP;
|
||||
DCFill;
|
||||
|
||||
gr.dc1=DCNew(GR_WIDTH,GR_HEIGHT);
|
||||
gr.dc1->flags|=DCF_SCRN_BITMAP;
|
||||
|
||||
gr.scrn_image=DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
|
||||
gr.zoomed_dc =DCNew(GR_WIDTH,GR_HEIGHT); //4-bit
|
||||
gr.zoomed_dc->flags|=DCF_SCRN_BITMAP;
|
||||
}
|
||||
|
||||
GrInit2;
|
||||
@@ -0,0 +1,805 @@
|
||||
#help_index "Graphics/Math"
|
||||
|
||||
public I64 gr_x_offsets[8]={-1, 0, 1,-1,1,-1,0,1},
|
||||
gr_y_offsets[8]={-1,-1,-1, 0,0, 1,1,1},
|
||||
gr_x_offsets2[4]={ 0,-1, 1, 0},
|
||||
gr_y_offsets2[4]={-1, 0, 0, 1};
|
||||
|
||||
public Bool Line(U8 *aux_data,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,
|
||||
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),I64 step=1,I64 start=0)
|
||||
{//Step through line segment calling callback.
|
||||
//Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
I64 i,j,d,dx=x2-x1,dy=y2-y1,dz=z2-z1,_x,_y,_z,
|
||||
adx=AbsI64(dx),ady=AbsI64(dy),adz=AbsI64(dz);
|
||||
Bool first=TRUE;
|
||||
if (adx>=ady) {
|
||||
if (adx>=adz) {
|
||||
if (d=adx) {
|
||||
if (dx>=0)
|
||||
dx=0x100000000;
|
||||
else
|
||||
dx=-0x100000000;
|
||||
dy=dy<<32/d;
|
||||
dz=dz<<32/d;
|
||||
}
|
||||
} else {
|
||||
if (d=adz) {
|
||||
dx=dx<<32/d;
|
||||
dy=dy<<32/d;
|
||||
if (dz>=0)
|
||||
dz=0x100000000;
|
||||
else
|
||||
dz=-0x100000000;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (ady>=adz) {
|
||||
if (d=ady) {
|
||||
dx=dx<<32/d;
|
||||
if (dy>=0)
|
||||
dy=0x100000000;
|
||||
else
|
||||
dy=-0x100000000;
|
||||
dz=dz<<32/d;
|
||||
}
|
||||
} else {
|
||||
if (d=adz) {
|
||||
dx=dx<<32/d;
|
||||
dy=dy<<32/d;
|
||||
if (dz>=0)
|
||||
dz=0x100000000;
|
||||
else
|
||||
dz=-0x100000000;
|
||||
}
|
||||
}
|
||||
}
|
||||
x1<<=32; y1<<=32; z1<<=32;
|
||||
for (j=0;j<start;j++) {
|
||||
x1+=dx; y1+=dy; z1+=dz;
|
||||
}
|
||||
if (step!=1 && step!=0) {
|
||||
dx*=step;
|
||||
dy*=step;
|
||||
dz*=step;
|
||||
d/=step;
|
||||
}
|
||||
for (i=start;i<=d;i++) {
|
||||
if ((_x!=x1.i32[1] || _y!=y1.i32[1] || _z!=z1.i32[1] || first) &&
|
||||
!(*fp_plot)(aux_data,x1.i32[1],y1.i32[1],z1.i32[1]))
|
||||
return FALSE;
|
||||
first=FALSE;
|
||||
_x=x1.i32[1]; _y=y1.i32[1]; _z=z1.i32[1];
|
||||
x1+=dx; y1+=dy; z1+=dz;
|
||||
}
|
||||
if (step==1 && (_x!=x2||_y!=y2||_z!=z2) && !(*fp_plot)(aux_data,x2,y2,z2))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#help_index "Graphics/Math/3D Transformation"
|
||||
public I64 *Mat4x4MulMat4x4Equ(I64 *dst,I64 *m1,I64 *m2)
|
||||
{//Multiply 4x4 matrices and store in dst. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
//Conceptually, the transform m1 is applied after m2
|
||||
I64 i,j,k;
|
||||
F64 sum;
|
||||
for (i=0;i<4;i++) {
|
||||
for (j=0;j<4;j++) {
|
||||
sum=0;
|
||||
for (k=0;k<4;k++)
|
||||
sum+=ToF64(m1[k+4*j])*ToF64(m2[i+4*k]);
|
||||
dst[i+4*j]=sum/GR_SCALE;
|
||||
}
|
||||
}
|
||||
return dst;
|
||||
}
|
||||
|
||||
public I64 *Mat4x4MulMat4x4New(I64 *m1,I64 *m2,CTask *mem_task=NULL)
|
||||
{//Multiply 4x4 matrices. Return MAlloced matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
//Conceptually, the transform m1 is applied after m2
|
||||
return Mat4x4MulMat4x4Equ(MAlloc(sizeof(I64)*16,mem_task),m1,m2);
|
||||
}
|
||||
|
||||
public I64 *Mat4x4Equ(I64 *dst,I64 *src)
|
||||
{//Copy 4x4 Rot matrix.
|
||||
MemCpy(dst,src,sizeof(I64)*16);
|
||||
return dst;
|
||||
}
|
||||
|
||||
public I64 *Mat4x4New(I64 *src,CTask *mem_task=NULL)
|
||||
{//Return MAlloced copy of 4x4 Rot matrix.
|
||||
return Mat4x4Equ(MAlloc(sizeof(I64)*16,mem_task),src);
|
||||
}
|
||||
|
||||
public I64 *Mat4x4RotX(I64 *m,F64 è)
|
||||
{//Rot matrix about X axis. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
F64 my_cos=Cos(è)*GR_SCALE,my_sin=Sin(è)*GR_SCALE;
|
||||
I64 r[16],r2[16];
|
||||
MemSet(r,0,sizeof(r));
|
||||
r[5]=my_cos;
|
||||
r[10]=my_cos;
|
||||
r[9]=my_sin;
|
||||
r[6]=-my_sin;
|
||||
r[0]=GR_SCALE;
|
||||
r[15]=GR_SCALE;
|
||||
return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
|
||||
}
|
||||
|
||||
public I64 *Mat4x4RotY(I64 *m,F64 ê)
|
||||
{//Rot matrix about Y axis. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
F64 my_cos=Cos(ê)*GR_SCALE,my_sin=Sin(ê)*GR_SCALE;
|
||||
I64 r[16],r2[16];
|
||||
MemSet(r,0,sizeof(r));
|
||||
r[0]=my_cos;
|
||||
r[10]=my_cos;
|
||||
r[8]=-my_sin;
|
||||
r[2]=my_sin;
|
||||
r[5]=GR_SCALE;
|
||||
r[15]=GR_SCALE;
|
||||
return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
|
||||
}
|
||||
|
||||
public I64 *Mat4x4RotZ(I64 *m,F64 é)
|
||||
{//Rot matrix about Z axis. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
F64 my_cos=Cos(é)*GR_SCALE,my_sin=Sin(é)*GR_SCALE;
|
||||
I64 r[16],r2[16];
|
||||
MemSet(r,0,sizeof(r));
|
||||
r[0]=my_cos;
|
||||
r[5]=my_cos;
|
||||
r[4]=my_sin;
|
||||
r[1]=-my_sin;
|
||||
r[10]=GR_SCALE;
|
||||
r[15]=GR_SCALE;
|
||||
return Mat4x4Equ(m,Mat4x4MulMat4x4Equ(r2,r,m));
|
||||
}
|
||||
|
||||
public I64 *Mat4x4Scale(I64 *m,F64 s)
|
||||
{//Scale 4x4 matrix by value.
|
||||
I64 i;
|
||||
for (i=0;i<16;i++)
|
||||
m[i]*=s;
|
||||
return m;
|
||||
}
|
||||
|
||||
public U0 DCPenWidthScale(CDC *dc=gr.dc)
|
||||
{//Scale device context's pen width by norm of transformation.
|
||||
I64 d;
|
||||
if (dc->flags&DCF_TRANSFORMATION) {
|
||||
if (dc->pen_width) {
|
||||
d=dc->pen_width*dc->r_norm+0x80000000; //Round
|
||||
dc->pen_width=d.i32[1];
|
||||
if (dc->pen_width<1)
|
||||
dc->pen_width=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public I64 *Mat4x4TranslationEqu(I64 *r,I64 x,I64 y,I64 z)
|
||||
{//Set translation values in 4x4 matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
r[0*4+3]=x<<32;
|
||||
r[1*4+3]=y<<32;
|
||||
r[2*4+3]=z<<32;
|
||||
r[3*4+3]=GR_SCALE;
|
||||
return r;
|
||||
}
|
||||
|
||||
public I64 *Mat4x4TranslationAdd(I64 *r,I64 x,I64 y,I64 z)
|
||||
{//Add translation to 4x4 matrix. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
r[0*4+3]+=x<<32;
|
||||
r[1*4+3]+=y<<32;
|
||||
r[2*4+3]+=z<<32;
|
||||
r[3*4+3]=GR_SCALE;
|
||||
return r;
|
||||
}
|
||||
|
||||
public Bool DCSymmetrySet(CDC *dc=gr.dc,I64 x1,I64 y1,I64 x2,I64 y2)
|
||||
{//2D. Set device context's symmetry.
|
||||
F64 d;
|
||||
if (y1==y2 && x1==x2)
|
||||
return FALSE;
|
||||
dc->sym.snx=y2-y1;
|
||||
dc->sym.sny=x1-x2;
|
||||
dc->sym.snz=0;
|
||||
if (d=Sqrt(SqrI64(dc->sym.snx)+
|
||||
SqrI64(dc->sym.sny)+
|
||||
SqrI64(dc->sym.snz))) {
|
||||
d=GR_SCALE/d;
|
||||
dc->sym.snx *= d;
|
||||
dc->sym.sny *= d;
|
||||
dc->sym.snz *= d;
|
||||
}
|
||||
dc->sym.sx=x1;
|
||||
dc->sym.sy=y1;
|
||||
dc->sym.sz=0;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public Bool DCSymmetry3Set(CDC *dc=gr.dc,I64 x1,I64 y1,I64 z1,
|
||||
I64 x2,I64 y2,I64 z2,I64 x3,I64 y3,I64 z3)
|
||||
{//3D. Set device context's symmetry.
|
||||
F64 d,x,y,z,xx,yy,zz;
|
||||
I64 xx1,yy1,zz1,xx2,yy2,zz2,*r;
|
||||
xx1=x1-x2; yy1=y1-y2; zz1=z1-z2;
|
||||
xx2=x3-x2; yy2=y3-y2; zz2=z3-z2;
|
||||
if (!xx1 && !yy1 && !zz1 ||
|
||||
!xx2 && !yy2 && !zz2 ||
|
||||
xx1==xx2 && yy1==yy2 && zz1==zz2)
|
||||
return FALSE;
|
||||
|
||||
x=yy1*zz2-zz1*yy2;
|
||||
y=-xx1*zz2+zz1*xx2;
|
||||
z=xx1*yy2-yy1*xx2;
|
||||
if (dc->flags & DCF_TRANSFORMATION) {
|
||||
r=dc->r;
|
||||
xx=x*r[0]+y*r[1]+z*r[2];
|
||||
yy=x*r[4]+y*r[5]+z*r[6];
|
||||
zz=x*r[8]+y*r[9]+z*r[10];
|
||||
x=xx; y=yy; z=zz;
|
||||
}
|
||||
if (d=Sqrt(Sqr(x)+Sqr(y)+Sqr(z))) {
|
||||
d=GR_SCALE/d;
|
||||
dc->sym.snx = d*x;
|
||||
dc->sym.sny = d*y;
|
||||
dc->sym.snz = d*z;
|
||||
}
|
||||
if (dc->flags & DCF_TRANSFORMATION)
|
||||
(*dc->transform)(dc,&x1,&y1,&z1);
|
||||
dc->sym.sx=x1;
|
||||
dc->sym.sy=y1;
|
||||
dc->sym.sz=z1;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public U0 DCReflect(CDC *dc,I64 *_x,I64 *_y,I64 *_z)
|
||||
{//Reflect 3D point about device context's symmetry. Uses $LK,"fixed-point",A="FI:::/Demo/Lectures/FixedPoint.HC"$.
|
||||
I64 x=*_x<<32,y=*_y<<32,z=*_z<<32,
|
||||
xx=*_x-dc->sym.sx,yy=*_y-dc->sym.sy,zz=*_z-dc->sym.sz,
|
||||
d=(xx*dc->sym.snx+yy*dc->sym.sny+zz*dc->sym.snz)>>16,
|
||||
xn,yn,zn,xx2,yy2,zz2;
|
||||
xn=d*dc->sym.snx>>15;
|
||||
yn=d*dc->sym.sny>>15;
|
||||
zn=d*dc->sym.snz>>15;
|
||||
xx=x-xn;
|
||||
yy=y-yn;
|
||||
zz=z-zn;
|
||||
xx2=x+xn;
|
||||
yy2=y+yn;
|
||||
zz2=z+zn;
|
||||
if (SqrI64(xx>>16 -dc->sym.sx<<16)+
|
||||
SqrI64(yy>>16 -dc->sym.sy<<16)+
|
||||
SqrI64(zz>>16 -dc->sym.sz<<16)<
|
||||
SqrI64(xx2>>16-dc->sym.sx<<16)+
|
||||
SqrI64(yy2>>16-dc->sym.sy<<16)+
|
||||
SqrI64(zz2>>16-dc->sym.sz<<16)) {
|
||||
*_x=xx.i32[1]; *_y=yy.i32[1]; *_z=zz.i32[1];
|
||||
} else {
|
||||
*_x=xx2.i32[1]; *_y=yy2.i32[1]; *_z=zz2.i32[1];
|
||||
}
|
||||
}
|
||||
|
||||
#help_index "Graphics/Math"
|
||||
#define GR_SCALE1_BITS 24
|
||||
#define GR_SCALE2_BITS 8
|
||||
public Bool Circle(U8 *aux_data,I64 cx,I64 cy,I64 cz,I64 radius,
|
||||
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
|
||||
I64 step=1,F64 start_radians=0,F64 len_radians=2*ã)
|
||||
{//Step through circle arc calling callback.
|
||||
I64 i,j,len=Ceil(len_radians*radius),
|
||||
x,y,x1,y1,s1,s2,c;
|
||||
F64 t;
|
||||
if (radius<=0||!step) return TRUE;
|
||||
t=1.0/radius;
|
||||
c=1<<GR_SCALE1_BITS*Cos(t);
|
||||
if (step<0) {
|
||||
step=-step;
|
||||
s2=1<<GR_SCALE1_BITS*Sin(t);
|
||||
s1=-s2;
|
||||
} else {
|
||||
s1=1<<GR_SCALE1_BITS*Sin(t);
|
||||
s2=-s1;
|
||||
}
|
||||
if (start_radians) {
|
||||
x=radius*Cos(start_radians);
|
||||
y=-radius*Sin(start_radians);
|
||||
} else {
|
||||
x=radius;
|
||||
y=0;
|
||||
}
|
||||
x<<=GR_SCALE2_BITS;
|
||||
y<<=GR_SCALE2_BITS;
|
||||
for (i=0;i<=len;i+=step) {
|
||||
if (!(*fp_plot)(aux_data,cx+x>>GR_SCALE2_BITS,cy+y>>GR_SCALE2_BITS,cz))
|
||||
return FALSE;
|
||||
for (j=0;j<step;j++) {
|
||||
x1=(c*x+s1*y)>>GR_SCALE1_BITS;
|
||||
y1=(s2*x+c*y)>>GR_SCALE1_BITS;
|
||||
x=x1; y=y1;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public Bool Ellipse(U8 *aux_data,I64 cx,I64 cy,I64 cz,
|
||||
I64 x_radius,I64 y_radius,Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
|
||||
F64 rot_angle=0,I64 step=1,F64 start_radians=0,F64 len_radians=2*ã)
|
||||
{//Step through ellipse arc calling callback.
|
||||
I64 i,j,len,
|
||||
x,y,_x,_y,x1,y1,x2,y2, s1,s2,c, s12,s22,c2;
|
||||
F64 t;
|
||||
Bool first=TRUE;
|
||||
if (x_radius<=0 || y_radius<=0 || !step)
|
||||
return TRUE;
|
||||
if (x_radius>=y_radius) {
|
||||
t=1.0/x_radius;
|
||||
len=Ceil(len_radians*x_radius);
|
||||
} else {
|
||||
t=1.0/y_radius;
|
||||
len=Ceil(len_radians*y_radius);
|
||||
}
|
||||
|
||||
c=1<<GR_SCALE1_BITS*Cos(t);
|
||||
if (step<0) {
|
||||
step=-step;
|
||||
s2=1<<GR_SCALE1_BITS*Sin(t);
|
||||
s1=-s2;
|
||||
} else {
|
||||
s1=1<<GR_SCALE1_BITS*Sin(t);
|
||||
s2=-s1;
|
||||
}
|
||||
|
||||
c2=1<<GR_SCALE1_BITS*Cos(rot_angle);
|
||||
s12=1<<GR_SCALE1_BITS*Sin(rot_angle);
|
||||
s22=-s12;
|
||||
|
||||
if (start_radians) {
|
||||
x=x_radius*Cos(start_radians);
|
||||
y=-x_radius*Sin(start_radians);
|
||||
} else {
|
||||
x=x_radius;
|
||||
y=0;
|
||||
}
|
||||
x<<=GR_SCALE2_BITS;
|
||||
y<<=GR_SCALE2_BITS;
|
||||
x2=x;
|
||||
y2=y;
|
||||
|
||||
y1=y2*y_radius/x_radius;
|
||||
x=(c2*x2+s12*y1)>>GR_SCALE1_BITS;
|
||||
y=(s22*x2+c2*y1)>>GR_SCALE1_BITS;
|
||||
|
||||
for (i=0;i<=len;i+=step) {
|
||||
if ((x>>GR_SCALE2_BITS!=_x || y>>GR_SCALE2_BITS!=_y || first) &&
|
||||
!(*fp_plot)(aux_data,cx+x>>GR_SCALE2_BITS,cy+y>>GR_SCALE2_BITS,cz))
|
||||
return FALSE;
|
||||
|
||||
_x=x>>GR_SCALE2_BITS; _y=y>>GR_SCALE2_BITS; first=FALSE;
|
||||
for (j=0;j<step;j++) {
|
||||
x1=(c*x2+s1*y2)>>GR_SCALE1_BITS;
|
||||
y1=(s2*x2+c*y2)>>GR_SCALE1_BITS;
|
||||
x2=x1;
|
||||
y2=y1;
|
||||
y1=y1*y_radius/x_radius;
|
||||
x=(c2*x1+s12*y1)>>GR_SCALE1_BITS;
|
||||
y=(s22*x1+c2*y1)>>GR_SCALE1_BITS;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public Bool RegPoly(U8 *aux_data,I64 cx,I64 cy,I64 cz,
|
||||
I64 x_radius,I64 y_radius,I64 sides,
|
||||
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),
|
||||
F64 rot_angle=0,I64 step=1,F64 start_radians=0,F64 len_radians=2*ã)
|
||||
{//Step through regular polygon calling callback.
|
||||
I64 i,n,x,y,x1,y1,x2,y2,
|
||||
xx1,yy1,xx2,yy2,
|
||||
s1,s2,c, s12,s22,c2;
|
||||
F64 angle_step;
|
||||
|
||||
if (sides<=0 || x_radius<=0 || y_radius<=0)
|
||||
return TRUE;
|
||||
|
||||
angle_step=2*ã/sides;
|
||||
n=len_radians*sides/(2*ã);
|
||||
|
||||
s1=1<<GR_SCALE1_BITS*Sin(angle_step);
|
||||
s2=-s1;
|
||||
c=1<<GR_SCALE1_BITS*Cos(angle_step);
|
||||
|
||||
s12=1<<GR_SCALE1_BITS*Sin(rot_angle);
|
||||
s22=-s12;
|
||||
c2=1<<GR_SCALE1_BITS*Cos(rot_angle);
|
||||
|
||||
if (start_radians) {
|
||||
x=x_radius*Cos(start_radians);
|
||||
y=-x_radius*Sin(start_radians);
|
||||
} else {
|
||||
x=x_radius;
|
||||
y=0;
|
||||
}
|
||||
x<<=GR_SCALE2_BITS;
|
||||
y<<=GR_SCALE2_BITS;
|
||||
x2=x;
|
||||
y2=y;
|
||||
|
||||
y1=y2*y_radius/x_radius;
|
||||
x=(c2*x2+s12*y1)>>GR_SCALE1_BITS;
|
||||
y=(s22*x2+c2*y1)>>GR_SCALE1_BITS;
|
||||
|
||||
xx1=cx+x>>GR_SCALE2_BITS;
|
||||
yy1=cy+y>>GR_SCALE2_BITS;
|
||||
for (i=0;i<n;i++) {
|
||||
x1=(c*x2+s1*y2)>>GR_SCALE1_BITS;
|
||||
y1=(s2*x2+c*y2)>>GR_SCALE1_BITS;
|
||||
x2=x1;
|
||||
y2=y1;
|
||||
y1=y1*y_radius/x_radius;
|
||||
x=(c2*x1+s12*y1)>>GR_SCALE1_BITS;
|
||||
y=(s22*x1+c2*y1)>>GR_SCALE1_BITS;
|
||||
xx2=cx+x>>GR_SCALE2_BITS;
|
||||
yy2=cy+y>>GR_SCALE2_BITS;
|
||||
if (!Line(aux_data,xx1,yy1,cz,xx2,yy2,cz,fp_plot,step))
|
||||
return FALSE;
|
||||
xx1=xx2; yy1=yy2;
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#help_index "Graphics/Data Types/D3I32;Math/Data Types/D3I32;Data Types/D3I32"
|
||||
public F64 D3I32Dist(CD3I32 *p1,CD3I32 *p2)
|
||||
{//Distance
|
||||
return Sqrt(SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z));
|
||||
}
|
||||
|
||||
public I64 D3I32DistSqr(CD3I32 *p1,CD3I32 *p2)
|
||||
{//Distance Squared
|
||||
return SqrI64(p1->x-p2->x)+SqrI64(p1->y-p2->y)+SqrI64(p1->z-p2->z);
|
||||
}
|
||||
|
||||
public F64 D3I32Norm(CD3I32 *p)
|
||||
{//Norm
|
||||
return Sqrt(SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z));
|
||||
}
|
||||
|
||||
public I64 D3I32NormSqr(CD3I32 *p)
|
||||
{//Norm Squared
|
||||
return SqrI64(p->x)+SqrI64(p->y)+SqrI64(p->z);
|
||||
}
|
||||
|
||||
#help_index "Graphics/Math"
|
||||
public Bool Bezier2(U8 *aux_data,CD3I32 *ctrl,
|
||||
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool first=TRUE)
|
||||
{//Go in 2nd order bezier calling callback.
|
||||
I64 x,y,z,xx,yy,zz,dx,dy,dz,d_max;
|
||||
F64 x0=ctrl[0].x,y0=ctrl[0].y,z0=ctrl[0].z,
|
||||
x1=ctrl[1].x-x0,y1=ctrl[1].y-y0,z1=ctrl[1].z-z0,
|
||||
x2=ctrl[2].x-x0,y2=ctrl[2].y-y0,z2=ctrl[2].z-z0,
|
||||
t,d=D3I32Dist(&ctrl[0],&ctrl[1])+
|
||||
D3I32Dist(&ctrl[1],&ctrl[2])+
|
||||
D3I32Dist(&ctrl[2],&ctrl[0]),
|
||||
s=0.5/d,t1,t2;
|
||||
xx=x0; yy=y0; zz=z0;
|
||||
if (first && !(*fp_plot)(aux_data,xx,yy,zz))
|
||||
return FALSE;
|
||||
for (t=0.0;t<=1.0;t+=s) {
|
||||
t1=t*(1.0-t);
|
||||
t2=t*t;
|
||||
x=x0+x1*t1+x2*t2;
|
||||
y=y0+y1*t1+y2*t2;
|
||||
z=z0+z1*t1+z2*t2;
|
||||
dx=AbsI64(x-xx);
|
||||
dy=AbsI64(y-yy);
|
||||
dz=AbsI64(z-zz);
|
||||
if (dx>dy)
|
||||
d_max=dx;
|
||||
else
|
||||
d_max=dy;
|
||||
if (dz>d_max)
|
||||
d_max=dz;
|
||||
if (!d_max)
|
||||
s*=1.1;
|
||||
else {
|
||||
s*=0.9;
|
||||
if (!(*fp_plot)(aux_data,x,y,z))
|
||||
return FALSE;
|
||||
xx=x;yy=y;zz=z;
|
||||
}
|
||||
}
|
||||
x=ctrl[2].x; y=ctrl[2].y; z=ctrl[2].z;
|
||||
if ((xx!=x || yy!=y || zz!=z) &&
|
||||
!(*fp_plot)(aux_data,x,y,z))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public Bool Bezier3(U8 *aux_data,CD3I32 *ctrl,
|
||||
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool first=TRUE)
|
||||
{//Go in 3rd order bezier calling callback.
|
||||
I64 x,y,z,xx,yy,zz,dx,dy,dz,d_max;
|
||||
F64 x0=ctrl[0].x,y0=ctrl[0].y,z0=ctrl[0].z,
|
||||
x1=ctrl[1].x-x0,y1=ctrl[1].y-y0,z1=ctrl[1].z-z0,
|
||||
x2=ctrl[2].x-x0,y2=ctrl[2].y-y0,z2=ctrl[2].z-z0,
|
||||
x3=ctrl[3].x-x0,y3=ctrl[3].y-y0,z3=ctrl[3].z-z0,
|
||||
t,d=D3I32Dist(&ctrl[0],&ctrl[1])+
|
||||
D3I32Dist(&ctrl[1],&ctrl[2])+
|
||||
D3I32Dist(&ctrl[2],&ctrl[3])+
|
||||
D3I32Dist(&ctrl[3],&ctrl[0]),
|
||||
s=0.5/d,nt,t1,t2,t3;
|
||||
xx=x0; yy=y0; zz=z0;
|
||||
if (first && !(*fp_plot)(aux_data,xx,yy,zz))
|
||||
return FALSE;
|
||||
for (t=0.0;t<=1.0;t+=s) {
|
||||
nt=1.0-t;
|
||||
t1=t*nt*nt;
|
||||
t2=t*t*nt;
|
||||
t3=t*t*t;
|
||||
x=x0+x1*t1+x2*t2+x3*t3;
|
||||
y=y0+y1*t1+y2*t2+y3*t3;
|
||||
z=z0+z1*t1+z2*t2+z3*t3;
|
||||
dx=AbsI64(x-xx);
|
||||
dy=AbsI64(y-yy);
|
||||
dz=AbsI64(z-zz);
|
||||
if (dx>dy)
|
||||
d_max=dx;
|
||||
else
|
||||
d_max=dy;
|
||||
if (dz>d_max)
|
||||
d_max=dz;
|
||||
if (!d_max)
|
||||
s*=1.1;
|
||||
else {
|
||||
s*=0.9;
|
||||
if (!(*fp_plot)(aux_data,x,y,z))
|
||||
return FALSE;
|
||||
xx=x;yy=y;zz=z;
|
||||
}
|
||||
}
|
||||
x=ctrl[3].x; y=ctrl[3].y; z=ctrl[3].z;
|
||||
if ((xx!=x || yy!=y || zz!=z) &&
|
||||
!(*fp_plot)(aux_data,x,y,z))
|
||||
return FALSE;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public Bool BSpline2(U8 *aux_data,CD3I32 *ctrl,I64 cnt,
|
||||
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool closed=FALSE)
|
||||
{//Go in 2nd order spline calling callback.
|
||||
I64 i,j;
|
||||
CD3I32 *c;
|
||||
Bool first;
|
||||
if (cnt<3) return FALSE;
|
||||
first=TRUE;
|
||||
if (closed) {
|
||||
cnt++;
|
||||
c=MAlloc(sizeof(CD3I32)*(cnt*2-1));
|
||||
j=1;
|
||||
for (i=0;i<cnt-2;i++) {
|
||||
c[j].x=(ctrl[i].x+ctrl[i+1].x)/2.0;
|
||||
c[j].y=(ctrl[i].y+ctrl[i+1].y)/2.0;
|
||||
c[j].z=(ctrl[i].z+ctrl[i+1].z)/2.0;
|
||||
j+=2;
|
||||
}
|
||||
c[j].x=(ctrl[0].x+ctrl[cnt-2].x)/2.0;
|
||||
c[j].y=(ctrl[0].y+ctrl[cnt-2].y)/2.0;
|
||||
c[j].z=(ctrl[0].z+ctrl[cnt-2].z)/2.0;
|
||||
|
||||
c[0].x=(c[1].x+c[j].x)/2.0;
|
||||
c[0].y=(c[1].y+c[j].y)/2.0;
|
||||
c[0].z=(c[1].z+c[j].z)/2.0;
|
||||
j=2;
|
||||
for (i=0;i<cnt-2;i++) {
|
||||
c[j].x=(c[j-1].x+c[j+1].x)/2.0;
|
||||
c[j].y=(c[j-1].y+c[j+1].y)/2.0;
|
||||
c[j].z=(c[j-1].z+c[j+1].z)/2.0;
|
||||
j+=2;
|
||||
}
|
||||
c[j].x=c[0].x;
|
||||
c[j].y=c[0].y;
|
||||
c[j].z=c[0].z;
|
||||
} else {
|
||||
c=MAlloc(sizeof(CD3I32)*(cnt*2-1));
|
||||
c[0].x=ctrl[0].x;
|
||||
c[0].y=ctrl[0].y;
|
||||
c[0].z=ctrl[0].z;
|
||||
c[cnt*2-2].x=ctrl[cnt-1].x;
|
||||
c[cnt*2-2].y=ctrl[cnt-1].y;
|
||||
c[cnt*2-2].z=ctrl[cnt-1].z;
|
||||
j=1;
|
||||
for (i=0;i<cnt-1;i++) {
|
||||
c[j].x=(ctrl[i].x+ctrl[i+1].x)/2.0;
|
||||
c[j].y=(ctrl[i].y+ctrl[i+1].y)/2.0;
|
||||
c[j].z=(ctrl[i].z+ctrl[i+1].z)/2.0;
|
||||
j+=2;
|
||||
}
|
||||
j=2;
|
||||
for (i=0;i<cnt-2;i++) {
|
||||
c[j].x=(c[j-1].x+c[j+1].x)/2.0;
|
||||
c[j].y=(c[j-1].y+c[j+1].y)/2.0;
|
||||
c[j].z=(c[j-1].z+c[j+1].z)/2.0;
|
||||
j+=2;
|
||||
}
|
||||
}
|
||||
for (i=0;i<cnt*2-2;i+=2) {
|
||||
if (!Bezier2(aux_data,&c[i],fp_plot,first))
|
||||
return FALSE;
|
||||
first=FALSE;
|
||||
}
|
||||
Free(c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public Bool BSpline3(U8 *aux_data,CD3I32 *ctrl,I64 cnt,
|
||||
Bool (*fp_plot)(U8 *aux,I64 x,I64 y,I64 z),Bool closed=FALSE)
|
||||
{//Go in 3rd order spline calling callback.
|
||||
I64 i,j;
|
||||
F64 x,y,z;
|
||||
CD3I32 *c;
|
||||
Bool first;
|
||||
if (cnt<3) return FALSE;
|
||||
first=TRUE;
|
||||
if (closed) {
|
||||
cnt++;
|
||||
c=MAlloc(sizeof(CD3I32)*(cnt*3-2));
|
||||
j=1;
|
||||
for (i=0;i<cnt-2;i++) {
|
||||
x=ctrl[i].x;
|
||||
y=ctrl[i].y;
|
||||
z=ctrl[i].z;
|
||||
c[j].x=(ctrl[i+1].x-x)/3.0+x;
|
||||
c[j].y=(ctrl[i+1].y-y)/3.0+y;
|
||||
c[j].z=(ctrl[i+1].z-z)/3.0+z;
|
||||
j++;
|
||||
c[j].x=2.0*(ctrl[i+1].x-x)/3.0+x;
|
||||
c[j].y=2.0*(ctrl[i+1].y-y)/3.0+y;
|
||||
c[j].z=2.0*(ctrl[i+1].z-z)/3.0+z;
|
||||
j+=2;
|
||||
}
|
||||
x=ctrl[cnt-2].x;
|
||||
y=ctrl[cnt-2].y;
|
||||
z=ctrl[cnt-2].z;
|
||||
c[j].x=(ctrl[0].x-x)/3.0+x;
|
||||
c[j].y=(ctrl[0].y-y)/3.0+y;
|
||||
c[j].z=(ctrl[0].z-z)/3.0+z;
|
||||
j++;
|
||||
c[j].x=2.0*(ctrl[0].x-x)/3.0+x;
|
||||
c[j].y=2.0*(ctrl[0].y-y)/3.0+y;
|
||||
c[j].z=2.0*(ctrl[0].z-z)/3.0+z;
|
||||
|
||||
c[0].x=(c[1].x+c[j].x)/2.0;
|
||||
c[0].y=(c[1].y+c[j].y)/2.0;
|
||||
c[0].z=(c[1].z+c[j].z)/2.0;
|
||||
|
||||
j=3;
|
||||
for (i=0;i<cnt-2;i++) {
|
||||
c[j].x=(c[j-1].x+c[j+1].x)/2.0;
|
||||
c[j].y=(c[j-1].y+c[j+1].y)/2.0;
|
||||
c[j].z=(c[j-1].z+c[j+1].z)/2.0;
|
||||
j+=3;
|
||||
}
|
||||
c[j].x=c[0].x;
|
||||
c[j].y=c[0].y;
|
||||
c[j].z=c[0].z;
|
||||
} else {
|
||||
c=MAlloc(sizeof(CD3I32)*(cnt*3-2));
|
||||
c[0].x=ctrl[0].x;
|
||||
c[0].y=ctrl[0].y;
|
||||
c[0].z=ctrl[0].z;
|
||||
c[cnt*3-3].x=ctrl[cnt-1].x;
|
||||
c[cnt*3-3].y=ctrl[cnt-1].y;
|
||||
c[cnt*3-3].z=ctrl[cnt-1].z;
|
||||
j=1;
|
||||
for (i=0;i<cnt-1;i++) {
|
||||
x=ctrl[i].x;
|
||||
y=ctrl[i].y;
|
||||
z=ctrl[i].z;
|
||||
c[j].x=(ctrl[i+1].x-x)/3.0+x;
|
||||
c[j].y=(ctrl[i+1].y-y)/3.0+y;
|
||||
c[j].z=(ctrl[i+1].z-z)/3.0+z;
|
||||
j++;
|
||||
c[j].x=2.0*(ctrl[i+1].x-x)/3.0+x;
|
||||
c[j].y=2.0*(ctrl[i+1].y-y)/3.0+y;
|
||||
c[j].z=2.0*(ctrl[i+1].z-z)/3.0+z;
|
||||
j+=2;
|
||||
}
|
||||
j=3;
|
||||
for (i=0;i<cnt-2;i++) {
|
||||
c[j].x=(c[j-1].x+c[j+1].x)/2.0;
|
||||
c[j].y=(c[j-1].y+c[j+1].y)/2.0;
|
||||
c[j].z=(c[j-1].z+c[j+1].z)/2.0;
|
||||
j+=3;
|
||||
}
|
||||
}
|
||||
for (i=0;i<cnt*3-3;i+=3) {
|
||||
if (!Bezier3(aux_data,&c[i],fp_plot,first))
|
||||
return FALSE;
|
||||
first=FALSE;
|
||||
}
|
||||
Free(c);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
#define CC_LEFT 1
|
||||
#define CC_RIGHT 2
|
||||
#define CC_TOP 4
|
||||
#define CC_BOTTOM 8
|
||||
|
||||
public Bool ClipLine(I64 *_x1,I64 *_y1,I64 *_x2,I64 *_y2,
|
||||
I64 left,I64 top,I64 right,I64 bottom)
|
||||
{//Clip x1,y1 x2,y2 with left,top,right,bottom.
|
||||
I64 x,y,x1=*_x1,y1=*_y1,x2=*_x2,y2=*_y2,
|
||||
cc,cc1,cc2;
|
||||
if (y1>bottom)
|
||||
cc1=CC_BOTTOM;
|
||||
else if (y1<top)
|
||||
cc1=CC_TOP;
|
||||
else
|
||||
cc1=0;
|
||||
if (x1>right)
|
||||
cc1|=CC_RIGHT;
|
||||
else if (x1<left)
|
||||
cc1|=CC_LEFT;
|
||||
|
||||
if (y2>bottom)
|
||||
cc2=CC_BOTTOM;
|
||||
else if (y2<top)
|
||||
cc2=CC_TOP;
|
||||
else
|
||||
cc2=0;
|
||||
if (x2>right)
|
||||
cc2|=CC_RIGHT;
|
||||
else if (x2<left)
|
||||
cc2|=CC_LEFT;
|
||||
|
||||
while (TRUE) {
|
||||
if (!(cc1|cc2))
|
||||
return TRUE;
|
||||
if (cc1&cc2)
|
||||
return FALSE;
|
||||
|
||||
if (cc1)
|
||||
cc=cc1;
|
||||
else
|
||||
cc=cc2;
|
||||
|
||||
if (cc&CC_BOTTOM) {
|
||||
x=x1+(x2-x1)*(bottom-y1)/(y2-y1);
|
||||
y=bottom;
|
||||
} else if (cc&CC_TOP) {
|
||||
x=x1+(x2-x1)*(top-y1)/(y2-y1);
|
||||
y=top;
|
||||
} else if (cc&CC_RIGHT) {
|
||||
y=y1+(y2-y1)*(right-x1)/(x2-x1);
|
||||
x=right;
|
||||
} else {
|
||||
y=y1+(y2-y1)*(left-x1)/(x2-x1);
|
||||
x=left;
|
||||
}
|
||||
|
||||
if (cc==cc1) {
|
||||
*_x1=x1=x;
|
||||
*_y1=y1=y;
|
||||
if (y1>bottom)
|
||||
cc1=CC_BOTTOM;
|
||||
else if (y1<top)
|
||||
cc1=CC_TOP;
|
||||
else
|
||||
cc1=0;
|
||||
if (x1>right)
|
||||
cc1|=CC_RIGHT;
|
||||
else if (x1<left)
|
||||
cc1|=CC_LEFT;
|
||||
} else {
|
||||
*_x2=x2=x;
|
||||
*_y2=y2=y;
|
||||
if (y2>bottom)
|
||||
cc2=CC_BOTTOM;
|
||||
else if (y2<top)
|
||||
cc2=CC_TOP;
|
||||
else
|
||||
cc2=0;
|
||||
if (x2>right)
|
||||
cc2|=CC_RIGHT;
|
||||
else if (x2<left)
|
||||
cc2|=CC_LEFT;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#help_index "Graphics/Color"
|
||||
public U8 gr_rainbow_10[10]={
|
||||
BLACK,BROWN,RED,LTRED,YELLOW,GREEN,BLUE,PURPLE,LTGRAY,WHITE};
|
||||
|
||||
DefineLstLoad("ST_RAINBOW_10",
|
||||
"BLACK\0BROWN\0RED\0LTRED\0YELLOW\0GREEN\0BLUE\0PURPLE\0LTGRAY\0WHITE\0");
|
||||
|
||||
U0 GrPaletteIndicesSet()
|
||||
{//There is a level of indirection that we identity map.
|
||||
// Set 16-colors to use first 16 DAC BGR entries, so we
|
||||
// never need to worry about indexes, just DAC palette settings.
|
||||
I64 i;
|
||||
if (!Bt(&sys_run_level,RLf_VGA)) return;
|
||||
PUSHFD
|
||||
CLI
|
||||
while (LBts(&sys_semas[SEMA_VGA],0))
|
||||
Yield;
|
||||
InU8(VGAP_INPUT_STAT); //Rsts attr index/data
|
||||
for (i=0;i<COLORS_NUM;i++) {
|
||||
OutU8(VGAP_ATTR_INDEX,i);
|
||||
OutU8(VGAP_ATTR_DATA_WRITE,i);
|
||||
}
|
||||
OutU8(VGAP_ATTR_INDEX,0x20);
|
||||
OutU8(VGAP_ATTR_DATA_WRITE,0); //Dummy write
|
||||
InU8(VGAP_INPUT_STAT); //Rsts attr index/data
|
||||
LBtr(&sys_semas[SEMA_VGA],0);
|
||||
POPFD
|
||||
}
|
||||
|
||||
public U0 GrPaletteColorSet(I64 color_num,CBGR48 bgr48)
|
||||
{//VGA has 6-bits for blue, for green, and for red.
|
||||
if (!Bt(&sys_run_level,RLf_VGA)) return;
|
||||
PUSHFD
|
||||
CLI
|
||||
while (LBts(&sys_semas[SEMA_VGA],0))
|
||||
Yield;
|
||||
OutU8(VGAP_PALETTE_MASK,0xFF);
|
||||
OutU8(VGAP_REG_WRITE,color_num);
|
||||
OutU8(VGAP_PALETTE_DATA,bgr48.r>>10);
|
||||
OutU8(VGAP_PALETTE_DATA,bgr48.g>>10);
|
||||
OutU8(VGAP_PALETTE_DATA,bgr48.b>>10);
|
||||
LBtr(&sys_semas[SEMA_VGA],0);
|
||||
POPFD
|
||||
}
|
||||
|
||||
public CBGR48 GrPaletteColorGet(I64 color_num)
|
||||
{//VGA has 6-bits for blue, for green, and for red.
|
||||
CBGR48 res=0;
|
||||
if (!Bt(&sys_run_level,RLf_VGA)) return 0;
|
||||
PUSHFD
|
||||
CLI
|
||||
while (LBts(&sys_semas[SEMA_VGA],0))
|
||||
Yield;
|
||||
OutU8(VGAP_PALETTE_MASK,0xFF);
|
||||
OutU8(VGAP_REG_READ,color_num);
|
||||
res.r=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
|
||||
res.g=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
|
||||
res.b=0xFFFF<<10*InU8(VGAP_PALETTE_DATA)/0xFC00;
|
||||
LBtr(&sys_semas[SEMA_VGA],0);
|
||||
POPFD
|
||||
return res;
|
||||
}
|
||||
|
||||
public CBGR48 gr_palette_std[COLORS_NUM]={
|
||||
0x000000000000,0x00000000AAAA,0x0000AAAA0000,0x0000AAAAAAAA,
|
||||
0xAAAA00000000,0xAAAA0000AAAA,0xAAAA55550000,0xAAAAAAAAAAAA,
|
||||
0x555555555555,0x55555555FFFF,0x5555FFFF5555,0x5555FFFFFFFF,
|
||||
0xFFFF55555555,0xFFFF5555FFFF,0xFFFFFFFF5555,0xFFFFFFFFFFFF};
|
||||
|
||||
public CBGR48 gr_palette_gray[COLORS_NUM]={
|
||||
0x000000000000,0x111111111111,0x222222222222,0x333333333333,
|
||||
0x444444444444,0x555555555555,0x666666666666,0x777777777777,
|
||||
0x888888888888,0x999999999999,0xAAAAAAAAAAAA,0xBBBBBBBBBBBB,
|
||||
0xCCCCCCCCCCCC,0xDDDDDDDDDDDD,0xEEEEEEEEEEEE,0xFFFFFFFFFFFF};
|
||||
|
||||
public U0 GrPaletteGet(CBGR48 *bgr48)
|
||||
{//16 colors
|
||||
I64 i;
|
||||
for (i=0;i<COLORS_NUM;i++)
|
||||
bgr48[i]=GrPaletteColorGet(i);
|
||||
}
|
||||
|
||||
public U0 GrPaletteSet(CBGR48 *bgr48)
|
||||
{//16 colors
|
||||
I64 i;
|
||||
for (i=0;i<COLORS_NUM;i++)
|
||||
GrPaletteColorSet(i,bgr48[i]);
|
||||
}
|
||||
|
||||
public U0 PaletteSetStd()
|
||||
{//Activate std palette.
|
||||
GrPaletteSet(gr_palette_std);
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,423 @@
|
||||
#help_index "Graphics/Scrn"
|
||||
|
||||
U0 GrUpdateTaskODEs(CTask *task)
|
||||
{
|
||||
sys_task_being_scrn_updated=task;
|
||||
try
|
||||
ODEsUpdate(task);
|
||||
catch {
|
||||
LBts(&task->win_inhibit,WIf_SELF_ODE);
|
||||
"Exception in WinMgr: Update Task ODEs\n";
|
||||
PutExcept;
|
||||
Sleep(3000);
|
||||
VGAFlush;
|
||||
}
|
||||
sys_task_being_scrn_updated=NULL;
|
||||
}
|
||||
|
||||
U0 GrUpdateTaskWin(CTask *task)
|
||||
{ //Draw a win. Only Core0 tasks have a win.
|
||||
CDC *dc;
|
||||
CD3I64 saved_scroll;
|
||||
sys_task_being_scrn_updated=task;
|
||||
try {
|
||||
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER))
|
||||
TextBorder(Fs,task->win_left,task->win_right,task->win_top,
|
||||
task->win_bottom,task->border_attr,task==sys_focus_task);
|
||||
TextRect(task->win_left,task->win_right,
|
||||
task->win_top,task->win_bottom,task->text_attr<<8);
|
||||
if (task==sys_winmgr_task) {
|
||||
if (gr.fp_wall_paper)
|
||||
(*gr.fp_wall_paper)(task);
|
||||
} else if (!(task->win_inhibit&WIF_SELF_DOC))
|
||||
DocUpdateTaskDocs(task);
|
||||
if (TaskValidate(task)) {
|
||||
if (task->draw_it) {
|
||||
dc=DCAlias(gr.dc2,task);
|
||||
(*task->draw_it)(task,dc);
|
||||
DCDel(dc);
|
||||
}
|
||||
if (TaskValidate(task)) {
|
||||
WinScrollNull(task,&saved_scroll);
|
||||
DrawCtrls(task);
|
||||
WinScrollRestore(task,&saved_scroll);
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
if (task!=Fs && TaskValidate(task)) {
|
||||
LBtr(&task->display_flags,DISPLAYf_SHOW);
|
||||
"Exception in WinMgr: Update Task Win\n";
|
||||
PutExcept;
|
||||
Sleep(3000);
|
||||
VGAFlush;
|
||||
}
|
||||
}
|
||||
sys_task_being_scrn_updated=NULL;
|
||||
}
|
||||
|
||||
U0 GrUpdateTasks()
|
||||
{//Only called by WinMgr
|
||||
I64 i;
|
||||
CTask *task,*task1;
|
||||
try {
|
||||
winmgr.ode_time=0;
|
||||
if (Bt(&sys_semas[SEMA_UPDATE_WIN_Z_BUF],0))
|
||||
WinZBufUpdate;
|
||||
task1=task=sys_winmgr_task;
|
||||
do { //Loop through Core0 tasks.
|
||||
if (!TaskValidate(task)) break;
|
||||
if (Bt(&task->display_flags,DISPLAYf_SHOW) &&
|
||||
Bt(gr.win_uncovered_bitmap,task->win_z_num))
|
||||
GrUpdateTaskWin(task);
|
||||
if (!TaskValidate(task)) break;
|
||||
task=task->next_task;
|
||||
} while (task!=task1);
|
||||
|
||||
for (i=0;i<mp_cnt;i++) { //Loop through all cores.
|
||||
task1=task=cpu_structs[i].seth_task;
|
||||
do {
|
||||
if (!TaskValidate(task)) break;
|
||||
GrUpdateTaskODEs(task);
|
||||
if (!TaskValidate(task)) break;
|
||||
task=task->next_task;
|
||||
} while (task!=task1);
|
||||
}
|
||||
} catch {
|
||||
PutExcept(FALSE);
|
||||
Dbg("Exception in WinMgr");
|
||||
}
|
||||
winmgr.last_ode_time=winmgr.ode_time;
|
||||
ode_alloced_factor=LowPass1(0.1,ode_alloced_factor,
|
||||
Clamp(Gs->idle_factor-0.1,0.2,0.8),1/winmgr.fps);
|
||||
sys_task_being_scrn_updated=NULL;
|
||||
}
|
||||
|
||||
U0 GrFixZoomScale()
|
||||
{
|
||||
gr.scrn_zoom=ClampI64(gr.scrn_zoom,1,GR_SCRN_ZOOM_MAX);
|
||||
if (gr.scrn_zoom==1) {
|
||||
gr.sx=0;
|
||||
gr.sy=0;
|
||||
} else {
|
||||
gr.sx=ClampI64(gr.sx,0,GR_WIDTH-GR_WIDTH/gr.scrn_zoom)&~7;
|
||||
gr.sy=ClampI64(gr.sy,0,GR_HEIGHT-GR_HEIGHT/gr.scrn_zoom);
|
||||
}
|
||||
}
|
||||
|
||||
public U0 GrScaleZoom(F64 scale)
|
||||
{//Multiply zoom factor larger or smaller.
|
||||
F64 s=gr.scrn_zoom;
|
||||
gr.scrn_zoom=gr.scrn_zoom*scale;
|
||||
GrFixZoomScale;
|
||||
s/=gr.scrn_zoom;
|
||||
ms.scale.x*=s;
|
||||
ms.scale.y*=s;
|
||||
ms.scale.z*=s;
|
||||
ms.offset.x=ms.pos.x-(ms.pos.x-ms.offset.x)*s;
|
||||
ms.offset.y=ms.pos.y-(ms.pos.y-ms.offset.y)*s;
|
||||
ms.offset.z=ms.pos.z-(ms.pos.z-ms.offset.z)*s;
|
||||
gr.sx=ms.pos.x-gr.zoomed_dc->width >>1/gr.scrn_zoom;
|
||||
gr.sy=ms.pos.y-gr.zoomed_dc->height>>1/gr.scrn_zoom;
|
||||
GrFixZoomScale;
|
||||
}
|
||||
|
||||
U0 GrZoomInScrn()
|
||||
{
|
||||
GrFixZoomScale;
|
||||
I64 plane,row,col,k,l,
|
||||
d2=gr.zoomed_dc->width>>3/gr.scrn_zoom,
|
||||
d4=gr.zoomed_dc->width_internal>>3,
|
||||
d5=d4-d2*gr.scrn_zoom,
|
||||
d3=gr.zoomed_dc->height/gr.scrn_zoom,
|
||||
d6=(gr.zoomed_dc->height-d3)*gr.dc1->width_internal>>3,
|
||||
d7=gr.zoomed_dc->height%gr.scrn_zoom*d4;
|
||||
U8 *src,*src2,*dst,*src3,*map=gr.scrn_zoom_tables[gr.scrn_zoom];
|
||||
|
||||
src=gr.dc1->body+gr.sx>>3+gr.sy*gr.dc1->width_internal>>3;
|
||||
dst=gr.zoomed_dc->body;
|
||||
for (plane=1;plane<0x10;plane<<=1) {
|
||||
row=d3;
|
||||
while (row--) {
|
||||
k=gr.scrn_zoom;
|
||||
while (k--) {
|
||||
src2=src;
|
||||
col=d2;
|
||||
while (col--) {
|
||||
src3=&map[*src2++];
|
||||
l=gr.scrn_zoom;
|
||||
while (l--) {
|
||||
*dst++=*src3;
|
||||
src3+=256;
|
||||
}
|
||||
}
|
||||
l=d5;
|
||||
while (l--)
|
||||
*dst++=0;
|
||||
}
|
||||
src+=d4;
|
||||
}
|
||||
l=d7;
|
||||
while (l--)
|
||||
*dst++=0;
|
||||
src+=d6;
|
||||
}
|
||||
}
|
||||
|
||||
U0 GrUpdateTextBG()
|
||||
{
|
||||
I64 reg RSI *dst=gr.dc2->body,reg R13 c,row,col,
|
||||
num_rows=TEXT_ROWS,num_cols=TEXT_COLS,i,j,cur_ch,
|
||||
reg R12 w1=gr.dc2->width_internal,w2=-7*w1+8,w3=7*w1,w4=0;
|
||||
U32 *src=gr.text_base;
|
||||
Bool blink_flag=Blink;
|
||||
U8 *dst2=dst;
|
||||
|
||||
if (gr.pan_text_x||gr.hide_col) {
|
||||
gr.pan_text_x=ClampI64(gr.pan_text_x,-7,7);
|
||||
j=AbsI64(gr.pan_text_x)/FONT_WIDTH+1;
|
||||
num_cols-=j;
|
||||
if (gr.pan_text_x<0) {
|
||||
src+=j;
|
||||
i=FONT_WIDTH*j+gr.pan_text_x;
|
||||
} else
|
||||
i=gr.pan_text_x;
|
||||
dst2=dst(U8 *)+i;
|
||||
w4=j;
|
||||
w3+=j*FONT_WIDTH;
|
||||
|
||||
j*=FONT_WIDTH;
|
||||
dst(U8 *)=gr.dc2->body;
|
||||
for (row=num_rows*FONT_HEIGHT;row--;) {
|
||||
for (col=i;col--;)
|
||||
*dst(U8 *)++=0;
|
||||
dst(U8 *)+=w1-i-j;
|
||||
for (col=j;col--;)
|
||||
*dst(U8 *)++=0;
|
||||
}
|
||||
}
|
||||
dst=dst2;
|
||||
|
||||
if (gr.pan_text_y||gr.hide_row) {
|
||||
gr.pan_text_y=ClampI64(gr.pan_text_y,-7,7);
|
||||
j=AbsI64(gr.pan_text_y)/FONT_HEIGHT+1;
|
||||
num_rows-=j;
|
||||
if (gr.pan_text_y<0) {
|
||||
src+=w1/FONT_WIDTH*j;
|
||||
i=w1*(FONT_HEIGHT*j+gr.pan_text_y);
|
||||
} else
|
||||
i=w1*gr.pan_text_y;
|
||||
dst2=dst(U8 *)+i;
|
||||
|
||||
j*=w1*FONT_HEIGHT;
|
||||
dst(U8 *)=gr.dc2->body;
|
||||
for (row=i;row--;)
|
||||
*dst(U8 *)++=0;
|
||||
dst(U8 *)=gr.dc2->body+TEXT_ROWS*TEXT_COLS*FONT_HEIGHT*FONT_WIDTH-j;
|
||||
for (row=j;row--;)
|
||||
*dst(U8 *)++=0;
|
||||
}
|
||||
dst=dst2;
|
||||
|
||||
for (row=num_rows;row--;) {
|
||||
for (col=num_cols;col--;) {
|
||||
cur_ch=*src++;
|
||||
if (cur_ch & (ATTRF_SEL|ATTRF_INVERT|ATTRF_BLINK)) {
|
||||
if (cur_ch & ATTRF_SEL)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
|
||||
if (cur_ch & ATTRF_INVERT)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
|
||||
if (cur_ch & ATTRF_BLINK && blink_flag)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
|
||||
}
|
||||
c=gr.to_8_colors[cur_ch.u8[1]>>4];
|
||||
MOV U64 [RSI],R13
|
||||
ADD RSI,R12
|
||||
MOV U64 [RSI],R13
|
||||
ADD RSI,R12
|
||||
MOV U64 [RSI],R13
|
||||
ADD RSI,R12
|
||||
MOV U64 [RSI],R13
|
||||
ADD RSI,R12
|
||||
MOV U64 [RSI],R13
|
||||
ADD RSI,R12
|
||||
MOV U64 [RSI],R13
|
||||
ADD RSI,R12
|
||||
MOV U64 [RSI],R13
|
||||
ADD RSI,R12
|
||||
MOV U64 [RSI],R13
|
||||
dst(U8 *)+=w2;
|
||||
}
|
||||
src+=w4;
|
||||
dst(U8 *)+=w3;
|
||||
}
|
||||
}
|
||||
|
||||
U0 GrUpdateTextFG()
|
||||
{//See $LK,"TextBase Layer",A="HI:TextBase Layer"$.
|
||||
U32 *src=gr.text_base;
|
||||
I64 i,j,cur_ch,*dst=gr.dc2->body,
|
||||
w1=gr.dc2->width_internal,w2=7*w1,w4=0,
|
||||
num_rows=TEXT_ROWS,num_cols=TEXT_COLS,row,col;
|
||||
U8 *dst_start=gr.dc2->body,*dst_end=dst_start+w1*gr.dc2->height-7*w1-8;
|
||||
Bool blink_flag=Blink;
|
||||
|
||||
if (gr.pan_text_x||gr.hide_col) {
|
||||
gr.pan_text_x=ClampI64(gr.pan_text_x,-7,7);
|
||||
j=AbsI64(gr.pan_text_x)/FONT_WIDTH+1;
|
||||
num_cols-=j;
|
||||
if (gr.pan_text_x<0) {
|
||||
src+=j;
|
||||
dst(U8 *)+=FONT_WIDTH*j;
|
||||
}
|
||||
w4=j;
|
||||
w2+=j*FONT_WIDTH;
|
||||
}
|
||||
|
||||
if (gr.pan_text_y||gr.hide_row) {
|
||||
gr.pan_text_y=ClampI64(gr.pan_text_y,-7,7);
|
||||
j=AbsI64(gr.pan_text_y)/FONT_HEIGHT+1;
|
||||
num_rows-=j;
|
||||
if (gr.pan_text_y<0) {
|
||||
src+=w1/FONT_WIDTH*j;
|
||||
dst(U8 *)+=w1*FONT_HEIGHT*j;
|
||||
}
|
||||
}
|
||||
|
||||
for (row=num_rows;row--;) {
|
||||
for (col=num_cols;col--;) {
|
||||
cur_ch=*src++;
|
||||
if (cur_ch & (ATTRF_UNDERLINE|ATTRF_SEL|ATTRF_INVERT|ATTRF_BLINK)) {
|
||||
if (cur_ch & ATTRF_SEL)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
|
||||
if (cur_ch & ATTRF_INVERT)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
|
||||
if (cur_ch & ATTRF_BLINK && blink_flag)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
|
||||
}
|
||||
if (i=cur_ch.u16[1]&0x3FF+gr.pan_text_x+gr.pan_text_y<<5) {
|
||||
j=i&0x1F;
|
||||
if (j&0x10) j|=~0x1F;
|
||||
i>>=5;
|
||||
if (i&0x10) i|=~0x1F;
|
||||
i=w1*i+j;
|
||||
if (dst_start<=dst(U8 *)+i<dst_end)
|
||||
GrRopEquU8NoClipping(cur_ch&(ATTRF_UNDERLINE+0xFFF),dst(U8 *)+i,w1);
|
||||
} else
|
||||
GrRopEquU8NoClipping(cur_ch&(ATTRF_UNDERLINE+0xFFF),dst,w1);
|
||||
dst(U8 *)+=8;
|
||||
}
|
||||
src+=w4;
|
||||
dst(U8 *)+=w2;
|
||||
}
|
||||
}
|
||||
|
||||
U0 DCBlotColor8(CDC *dc,CDC *img)
|
||||
{
|
||||
U8 *src=img->body,*b0=dc->body;
|
||||
I64 j,k,d0=img->width_internal*img->height;
|
||||
for (k=0;k<d0;k++) {
|
||||
j=*src++;
|
||||
if (j!=TRANSPARENT)
|
||||
*b0++=j;
|
||||
else
|
||||
b0++;
|
||||
}
|
||||
}
|
||||
|
||||
U0 GrUpdateTextModeText()
|
||||
{
|
||||
U32 *src=gr.text_base;
|
||||
I64 cur_ch,i=TEXT_COLS*TEXT_ROWS;
|
||||
U16 *dst=text.vga_text_alias,*dst2=gr.vga_text_cache;
|
||||
Bool blink_flag=Blink;
|
||||
if (LBtr(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0)) {
|
||||
while (i--) {
|
||||
cur_ch=*src++;
|
||||
if (cur_ch & ATTRF_SEL)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
|
||||
if (cur_ch & ATTRF_INVERT)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
|
||||
if (cur_ch & ATTRF_BLINK)
|
||||
if (blink_flag)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
|
||||
*dst++=*dst2++=cur_ch&0x7FFF;
|
||||
}
|
||||
} else {
|
||||
while (i--) {
|
||||
cur_ch=*src++;
|
||||
if (cur_ch & ATTRF_SEL)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
|
||||
if (cur_ch & ATTRF_INVERT)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
|
||||
if (cur_ch & ATTRF_BLINK)
|
||||
if (blink_flag)
|
||||
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
|
||||
cur_ch&=0x7FFF;
|
||||
if (*dst2!=cur_ch)
|
||||
*dst++=*dst2++=cur_ch;
|
||||
else {
|
||||
dst++;
|
||||
dst2++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 GrUpdateVGAGraphics()
|
||||
{//Update Graphic Card
|
||||
I64 row,plane,d=gr.zoomed_dc->width_internal>>6;
|
||||
U32 *src,*vga,*dst;
|
||||
if (gr.scrn_zoom==1)
|
||||
src=gr.dc1->body;
|
||||
else {
|
||||
GrZoomInScrn;
|
||||
src=gr.zoomed_dc->body;
|
||||
}
|
||||
dst=gr.scrn_image->body;
|
||||
if (LBtr(&sys_semas[SEMA_FLUSH_VGA_IMAGE],0)) {
|
||||
for (plane=1;plane<0x10;plane<<=1) {
|
||||
OutU8(VGAP_IDX,VGAR_MAP_MASK);
|
||||
OutU8(VGAP_DATA,plane);
|
||||
vga=text.vga_alias;
|
||||
row=gr.zoomed_dc->height;
|
||||
while (row--)
|
||||
GrUpdateLine64FlushCache(&vga,&src,d,&dst);
|
||||
}
|
||||
} else {
|
||||
for (plane=1;plane<0x10;plane<<=1) {
|
||||
OutU8(VGAP_IDX,VGAR_MAP_MASK);
|
||||
OutU8(VGAP_DATA,plane);
|
||||
vga=text.vga_alias;
|
||||
row=gr.zoomed_dc->height;
|
||||
while (row--)
|
||||
GrUpdateLine64(&vga,&src,d,&dst);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
U0 GrUpdateScrn()
|
||||
{//Called by the Window Manager $LK,"HERE",A="FF:::/Adam/WinMgr.HC,GrUpdateScrn"$, 30 times a second.
|
||||
CDC *dc;
|
||||
if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
|
||||
GrUpdateTasks;
|
||||
else {
|
||||
GrUpdateTextBG;
|
||||
GrUpdateTextFG;
|
||||
GrUpdateTasks;
|
||||
DCBlotColor8(gr.dc2,gr.dc);
|
||||
}
|
||||
|
||||
dc=DCAlias(gr.dc2,Fs);
|
||||
dc->flags|=DCF_ON_TOP;
|
||||
if (gr.fp_final_scrn_update)
|
||||
(*gr.fp_final_scrn_update)(dc);
|
||||
DCDel(dc);
|
||||
|
||||
if (!Bt(&sys_run_level,RLf_VGA)) //if text mode
|
||||
GrUpdateTextModeText;
|
||||
else {
|
||||
DCBlotColor4(gr.dc1->body,gr.dc2->body,gr.dc_cache->body,
|
||||
gr.dc2->height*gr.dc2->width_internal>>3);
|
||||
GrUpdateVGAGraphics;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,475 @@
|
||||
#help_index "Graphics/Sprite;Sprites"
|
||||
/*
|
||||
$LK,"CSprite",A="MN:CSprite"$s are stored as a sequence of var
|
||||
length operations with a 1-byte $LK,"type",A="MN:SPT_PT"$ leading
|
||||
each operation. They are stored, one after another,
|
||||
in a chunk of memory terminated by a $LK,"zero",A="MN:SPT_END"$.
|
||||
$LK,"Sprite3",A="MN:Sprite3"$() shows how the $LK,"CSprite",A="MN:CSprite"$ unions are used.
|
||||
|
||||
$LK,"SpriteElemSize",A="MN:SpriteElemSize"$() will return the size of a single
|
||||
element, while $LK,"SpriteSize",A="MN:SpriteSize"$() will return the size
|
||||
of an entire list. Look at $LK,"sprite_elem_base_sizes",A="MN:sprite_elem_base_sizes"$.
|
||||
|
||||
See $MA-X+PU,"::/Apps/GrModels",LM="Cd(\"::/Apps/GrModels\");Dir;View;\n"$ for an example of
|
||||
making CSprite by hand. It uses $LK,"SPT_MESH",A="MN:SPT_MESH"$,
|
||||
one of the most complicated.
|
||||
*/
|
||||
|
||||
public U0 Sprite3(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,
|
||||
Bool just_one_elem=FALSE)
|
||||
{//Plot a sprite into a CDC.
|
||||
CSprite *tmpg=elems-offset(CSprite.start);
|
||||
I64 i,j,k,x1,y1,z1,x2,y2,
|
||||
*old_r,*r2,old_flags=dc->flags,old_pen_width=dc->pen_width;
|
||||
I32 *ptr;
|
||||
CColorROPU32 old_color=dc->color;
|
||||
CDC *img;
|
||||
CD3I32 *p,*p2;
|
||||
CGrSym old_sym;
|
||||
MemCpy(&old_sym,&dc->sym,sizeof(CGrSym));
|
||||
if (dc->flags & DCF_LOCATE_NEAREST)
|
||||
dc->nearest_dist=I64_MAX;
|
||||
while (tmpg->type&SPG_TYPE_MASK) {
|
||||
switch (tmpg->type&SPG_TYPE_MASK) {
|
||||
case SPT_COLOR:
|
||||
dc->color=dc->color&~(COLORROP_COLORS_MASK|ROPF_DITHER)|tmpg->c.color;
|
||||
break;
|
||||
case SPT_DITHER_COLOR:
|
||||
dc->color=dc->color&~COLORROP_COLORS_MASK|
|
||||
tmpg->d.dither_color.u8[0]|
|
||||
tmpg->d.dither_color.u8[1]<<COLORROP_BITS|ROPF_DITHER;
|
||||
break;
|
||||
case SPT_WIDTH:
|
||||
dc->pen_width=tmpg->w.width;
|
||||
DCPenWidthScale(dc);
|
||||
break;
|
||||
case SPT_TRANSFORM_ON:
|
||||
if (!(dc->flags&DCF_TRANSFORMATION)) {
|
||||
x-=dc->x;
|
||||
y-=dc->y;
|
||||
z-=dc->z;
|
||||
}
|
||||
dc->flags|=DCF_TRANSFORMATION;
|
||||
break;
|
||||
case SPT_TRANSFORM_OFF:
|
||||
if (dc->flags&DCF_TRANSFORMATION) {
|
||||
x+=dc->x;
|
||||
y+=dc->y;
|
||||
z+=dc->z;
|
||||
}
|
||||
dc->flags&=~DCF_TRANSFORMATION;
|
||||
break;
|
||||
case SPT_PT:
|
||||
GrPlot3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z);
|
||||
break;
|
||||
case SPT_TEXT:
|
||||
GrPrint3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,"%s",tmpg->ps.st);
|
||||
break;
|
||||
case SPT_TEXT_BOX:
|
||||
GrTextBox3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);
|
||||
break;
|
||||
case SPT_TEXT_DIAMOND:
|
||||
GrTextDiamond3(dc,tmpg->ps.x1+x,tmpg->ps.y1+y,z,tmpg->ps.st);
|
||||
break;
|
||||
case SPT_FLOOD_FILL:
|
||||
GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,FALSE);
|
||||
break;
|
||||
case SPT_FLOOD_FILL_NOT:
|
||||
i=dc->color;
|
||||
dc->color=dc->color.c0;
|
||||
GrFloodFill3(dc,tmpg->p.x1+x,tmpg->p.y1+y,z,TRUE);
|
||||
dc->color=i;
|
||||
break;
|
||||
case SPT_SHIFT:
|
||||
x+=tmpg->p.x1;
|
||||
y+=tmpg->p.y1;
|
||||
break;
|
||||
case SPT_LINE:
|
||||
GrLine3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
|
||||
tmpg->pp.x2+x,tmpg->pp.y2+y,z);
|
||||
break;
|
||||
case SPT_ARROW:
|
||||
GrArrow3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
|
||||
tmpg->pp.x2+x,tmpg->pp.y2+y,z);
|
||||
break;
|
||||
case SPT_PLANAR_SYMMETRY:
|
||||
if (DCSymmetry3Set(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
|
||||
tmpg->pp.x2+x,tmpg->pp.y2+y,z,
|
||||
tmpg->pp.x2+x,tmpg->pp.y2+y,z+1))
|
||||
dc->flags|=DCF_SYMMETRY;
|
||||
else
|
||||
dc->flags&=~DCF_SYMMETRY;
|
||||
break;
|
||||
case SPT_BITMAP:
|
||||
img=CAlloc(sizeof(CDC));
|
||||
img->width=tmpg->pwhu.width;
|
||||
img->width_internal=(tmpg->pwhu.width+7)&~7;
|
||||
img->height=tmpg->pwhu.height;
|
||||
img->body=&tmpg->pwhu.u;
|
||||
img->dc_signature=DCS_SIGNATURE_VAL;
|
||||
GrBlot3(dc,tmpg->pwhu.x1+x,tmpg->pwhu.y1+y,z,img);
|
||||
Free(img);
|
||||
break;
|
||||
case SPT_RECT:
|
||||
GrRect3(dc,tmpg->pp.x1+x,tmpg->pp.y1+y,z,
|
||||
tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);
|
||||
break;
|
||||
case SPT_ROTATED_RECT:
|
||||
x1=tmpg->ppa.x1+x;
|
||||
y1=tmpg->ppa.y1+y;
|
||||
z1=z;
|
||||
Mat4x4MulXYZ(dc->r,&x1,&y1,&z1);
|
||||
old_r=dc->r;
|
||||
dc->flags|=DCF_TRANSFORMATION;
|
||||
r2=Mat4x4IdentNew;
|
||||
Mat4x4RotZ(r2,-tmpg->ppa.angle);
|
||||
Mat4x4TranslationEqu(r2,x1,y1,z1);
|
||||
DCMat4x4Set(dc,Mat4x4MulMat4x4New(old_r,r2));
|
||||
GrRect3(dc,0,0,0,
|
||||
tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1);
|
||||
Free(dc->r);
|
||||
Free(r2);
|
||||
DCMat4x4Set(dc,old_r);
|
||||
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
|
||||
break;
|
||||
case SPT_CIRCLE:
|
||||
GrCircle3(dc,tmpg->pr.x1+x,tmpg->pr.y1+y,z,tmpg->pr.radius);
|
||||
break;
|
||||
case SPT_ELLIPSE:
|
||||
GrEllipse3(dc,tmpg->pwha.x1+x,tmpg->pwha.y1+y,z,tmpg->pwha.width,
|
||||
tmpg->pwha.height,tmpg->pwha.angle);
|
||||
break;
|
||||
case SPT_POLYGON:
|
||||
GrRegPoly3(dc,tmpg->pwhas.x1+x,tmpg->pwhas.y1+y,z,tmpg->pwhas.width,
|
||||
tmpg->pwhas.height,tmpg->pwhas.sides,tmpg->pwhas.angle);
|
||||
break;
|
||||
case SPT_POLYLINE:
|
||||
ptr=&tmpg->nu.u;
|
||||
x1=ptr[0];
|
||||
y1=ptr[1];
|
||||
for (i=1;i<tmpg->nu.num;i++) {
|
||||
x2=ptr[i<<1];
|
||||
y2=ptr[i<<1+1];
|
||||
GrLine3(dc,x1+x,y1+y,z,x2+x,y2+y,z);
|
||||
x1=x2;y1=y2;
|
||||
}
|
||||
break;
|
||||
case SPT_POLYPT:
|
||||
x1=tmpg->npu.x;
|
||||
y1=tmpg->npu.y;
|
||||
ptr=&tmpg->npu.u;
|
||||
k=tmpg->npu.num*3;
|
||||
GrPlot3(dc,x1+x,y1+y,z);
|
||||
for (i=0;i<k;i+=3) {
|
||||
j=BFieldExtU32(ptr,i,3);
|
||||
x1+=gr_x_offsets[j];
|
||||
y1+=gr_y_offsets[j];
|
||||
GrPlot3(dc,x1+x,y1+y,z);
|
||||
}
|
||||
break;
|
||||
start:
|
||||
p2=p=MAlloc(tmpg->nu.num*sizeof(CD3I32));
|
||||
MemCpy(p,&tmpg->nu.u,tmpg->nu.num*sizeof(CD3I32));
|
||||
for (i=0;i<tmpg->nu.num;i++,p2++) {
|
||||
p2->x+=x;
|
||||
p2->y+=y;
|
||||
p2->z+=z;
|
||||
}
|
||||
case SPT_BSPLINE2:
|
||||
Gr2BSpline3(dc,p,tmpg->nu.num,FALSE);
|
||||
break;
|
||||
case SPT_BSPLINE3:
|
||||
Gr3BSpline3(dc,p,tmpg->nu.num,FALSE);
|
||||
break;
|
||||
case SPT_BSPLINE2_CLOSED:
|
||||
Gr2BSpline3(dc,p,tmpg->nu.num,TRUE);
|
||||
break;
|
||||
case SPT_BSPLINE3_CLOSED:
|
||||
Gr3BSpline3(dc,p,tmpg->nu.num,TRUE);
|
||||
break;
|
||||
end:
|
||||
Free(p);
|
||||
break;
|
||||
case SPT_MESH:
|
||||
p2=p=MAlloc(tmpg->mu.vertex_cnt*sizeof(CD3I32));
|
||||
MemCpy(p,&tmpg->mu.u,tmpg->mu.vertex_cnt*sizeof(CD3I32));
|
||||
for (i=0;i<tmpg->mu.vertex_cnt;i++,p2++) {
|
||||
p2->x+=x;
|
||||
p2->y+=y;
|
||||
p2->z+=z;
|
||||
}
|
||||
Gr3Mesh(dc,tmpg->mu.vertex_cnt,p,tmpg->mu.tri_cnt,
|
||||
(&tmpg->mu.u)(U8 *)+sizeof(CD3I32)*tmpg->mu.vertex_cnt);
|
||||
Free(p);
|
||||
break;
|
||||
case SPT_SHIFTABLE_MESH:
|
||||
if (dc->flags&DCF_TRANSFORMATION) {
|
||||
dc->x+=tmpg->pmu.x;
|
||||
dc->y+=tmpg->pmu.y;
|
||||
dc->z+=tmpg->pmu.z;
|
||||
x1=x;
|
||||
y1=y;
|
||||
z1=z;
|
||||
} else {
|
||||
x1=tmpg->pmu.x+x;
|
||||
y1=tmpg->pmu.y+y;
|
||||
z1=tmpg->pmu.z+z;
|
||||
}
|
||||
p2=p=MAlloc(tmpg->pmu.vertex_cnt*sizeof(CD3I32));
|
||||
MemCpy(p,&tmpg->pmu.u,tmpg->pmu.vertex_cnt*sizeof(CD3I32));
|
||||
for (i=0;i<tmpg->pmu.vertex_cnt;i++,p2++) {
|
||||
p2->x+=x1;
|
||||
p2->y+=y1;
|
||||
p2->z+=z1;
|
||||
}
|
||||
Gr3Mesh(dc,tmpg->pmu.vertex_cnt,p,tmpg->pmu.tri_cnt,
|
||||
(&tmpg->pmu.u)(U8 *)+sizeof(CD3I32)*tmpg->pmu.vertex_cnt);
|
||||
Free(p);
|
||||
if (dc->flags&DCF_TRANSFORMATION) {
|
||||
dc->x-=tmpg->pmu.x;
|
||||
dc->y-=tmpg->pmu.y;
|
||||
dc->z-=tmpg->pmu.z;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (just_one_elem) break;
|
||||
tmpg(U8 *)+=SpriteElemSize(tmpg);
|
||||
}
|
||||
MemCpy(&dc->sym,&old_sym,sizeof(CGrSym));
|
||||
dc->color=old_color;
|
||||
dc->pen_width=old_pen_width;
|
||||
dc->flags=dc->flags&~(DCF_SYMMETRY|DCF_TRANSFORMATION) |
|
||||
old_flags&(DCF_SYMMETRY|DCF_TRANSFORMATION);
|
||||
}
|
||||
|
||||
public U0 Sprite3B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems)
|
||||
{//Plot a sprite into a CDC, post transform xyz translation.
|
||||
I64 old_x=dc->x,old_y=dc->y,old_z=dc->z,
|
||||
old_flags=dc->flags&DCF_TRANSFORMATION;
|
||||
dc->x=x; dc->y=y; dc->z=z;
|
||||
dc->flags|=DCF_TRANSFORMATION;
|
||||
Sprite3(dc,0,0,0,elems);
|
||||
dc->x=old_x; dc->y=old_y; dc->z=old_z;
|
||||
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
|
||||
}
|
||||
|
||||
public U0 Sprite3Mat4x4B(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,I64 *m)
|
||||
{//Plot rotated by matrix.
|
||||
I64 r[16],*old_r=dc->r,new_m[16],
|
||||
old_flags=dc->flags&DCF_TRANSFORMATION;
|
||||
MemCpy(new_m,m,16*sizeof(I64));
|
||||
dc->flags|=DCF_TRANSFORMATION;
|
||||
Mat4x4TranslationAdd(new_m,x,y,z);
|
||||
dc->r=Mat4x4MulMat4x4Equ(r,old_r,new_m);
|
||||
Sprite3(dc,0,0,0,elems);
|
||||
dc->r=old_r;
|
||||
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
|
||||
}
|
||||
|
||||
public U0 Sprite3XB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 è=0)
|
||||
{//Plot rotated around X axis.
|
||||
I64 r[16];
|
||||
Mat4x4IdentEqu(r);
|
||||
Mat4x4RotX(r,è);
|
||||
Sprite3Mat4x4B(dc,x,y,z,elems,r);
|
||||
}
|
||||
|
||||
public U0 Sprite3YB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 ê=0)
|
||||
{//Plot rotated around Y axis.
|
||||
I64 r[16];
|
||||
Mat4x4IdentEqu(r);
|
||||
Mat4x4RotY(r,ê);
|
||||
Sprite3Mat4x4B(dc,x,y,z,elems,r);
|
||||
}
|
||||
|
||||
public U0 Sprite3ZB(CDC *dc=gr.dc,I64 x,I64 y,I64 z,U8 *elems,F64 é=0)
|
||||
{//Plot rotated around Z axis.
|
||||
I64 r[16];
|
||||
Mat4x4IdentEqu(r);
|
||||
Mat4x4RotZ(r,é);
|
||||
Sprite3Mat4x4B(dc,x,y,z,elems,r);
|
||||
}
|
||||
|
||||
public U0 SpriteExtents(U8 *elems,I64 *min_x=NULL,I64 *max_x=NULL,
|
||||
I64 *min_y=NULL,I64 *max_y=NULL)
|
||||
{//Ignores flood fills.
|
||||
CDC *dc=DCNew(I32_MAX,I32_MAX,Fs,TRUE);
|
||||
DCExtentsInit(dc);
|
||||
Sprite3(dc,I32_MAX/2,I32_MAX/2,I32_MAX/2,elems);
|
||||
if (dc->min_x<=dc->max_x) {
|
||||
dc->min_x-=I32_MAX/2;
|
||||
dc->max_x-=I32_MAX/2;
|
||||
}
|
||||
if (dc->min_y<=dc->max_y) {
|
||||
dc->min_y-=I32_MAX/2;
|
||||
dc->max_y-=I32_MAX/2;
|
||||
}
|
||||
if (min_x) *min_x=dc->min_x;
|
||||
if (max_x) *max_x=dc->max_x;
|
||||
if (min_y) *min_y=dc->min_y;
|
||||
if (max_y) *max_y=dc->max_y;
|
||||
DCDel(dc);
|
||||
}
|
||||
|
||||
public CDC *Sprite2DC(U8 *elems)
|
||||
{//Convert sprite to device context.
|
||||
CDC *res;
|
||||
I64 min_x,max_x,min_y,max_y;
|
||||
SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y);
|
||||
res=DCNew(max_x-min_x+1,max_y-min_y+1);
|
||||
Sprite3(res,-min_x,-min_y,0,elems);
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *SpriteInterpolate(F64 t,U8 *elems0,U8 *elems1)
|
||||
{//The two CSprite should be ident except for points shifted around.
|
||||
//t ranges from 0.0 to 1.0.
|
||||
I64 i,t1=GR_SCALE*t,t0=GR_SCALE-t1;
|
||||
I32 *ptr0,*ptr1,*ptrr;
|
||||
CD3I32 *p0,*p1,*pr;
|
||||
U8 *res;
|
||||
CSprite *tmpg0=elems0-offset(CSprite.start),
|
||||
*tmpg1=elems1-offset(CSprite.start),*tmpgr;
|
||||
if (t<0.5) {
|
||||
i=SpriteSize(elems0),
|
||||
res=MAlloc(i);
|
||||
MemCpy(res,elems0,i);
|
||||
} else {
|
||||
i=SpriteSize(elems1),
|
||||
res=MAlloc(i);
|
||||
MemCpy(res,elems1,i);
|
||||
}
|
||||
tmpgr=res-offset(CSprite.start);
|
||||
while (tmpg0->type&SPG_TYPE_MASK) {
|
||||
if (tmpg0->type&SPG_TYPE_MASK!=tmpg1->type&SPG_TYPE_MASK)
|
||||
throw('Graphics');
|
||||
switch (tmpg0->type&SPG_TYPE_MASK) {
|
||||
case SPT_ROTATED_RECT:
|
||||
tmpgr->ppa.angle=(tmpg0->ppa.angle*t0+tmpg1->ppa.angle*t1)/GR_SCALE;
|
||||
case SPT_RECT:
|
||||
case SPT_LINE:
|
||||
case SPT_ARROW:
|
||||
case SPT_PLANAR_SYMMETRY:
|
||||
tmpgr->pp.x2=(tmpg0->pp.x2*t0+tmpg1->pp.x2*t1)>>32;
|
||||
tmpgr->pp.y2=(tmpg0->pp.y2*t0+tmpg1->pp.y2*t1)>>32;
|
||||
case SPT_TEXT:
|
||||
case SPT_TEXT_BOX:
|
||||
case SPT_TEXT_DIAMOND:
|
||||
case SPT_PT:
|
||||
case SPT_FLOOD_FILL:
|
||||
case SPT_FLOOD_FILL_NOT:
|
||||
case SPT_SHIFT:
|
||||
tmpgr->p.x1=(tmpg0->p.x1*t0+tmpg1->p.x1*t1)>>32;
|
||||
tmpgr->p.y1=(tmpg0->p.y1*t0+tmpg1->p.y1*t1)>>32;
|
||||
break;
|
||||
case SPT_CIRCLE:
|
||||
tmpgr->pr.radius=(tmpg0->pr.radius*t0+tmpg1->pr.radius*t1)>>32;
|
||||
tmpgr->pr.x1=(tmpg0->pr.x1*t0+tmpg1->pr.x1*t1)>>32;
|
||||
tmpgr->pr.y1=(tmpg0->pr.y1*t0+tmpg1->pr.y1*t1)>>32;
|
||||
break;
|
||||
case SPT_ELLIPSE:
|
||||
case SPT_POLYGON:
|
||||
tmpgr->pwha.x1=(tmpg0->pwha.x1*t0+tmpg1->pwha.x1*t1)>>32;
|
||||
tmpgr->pwha.y1=(tmpg0->pwha.y1*t0+tmpg1->pwha.y1*t1)>>32;
|
||||
tmpgr->pwha.width =(tmpg0->pwha.width *t0+tmpg1->pwha.width*t1)>>32;
|
||||
tmpgr->pwha.height=(tmpg0->pwha.height*t0+tmpg1->pwha.height*t1)>>32;
|
||||
break;
|
||||
case SPT_BITMAP:
|
||||
tmpgr->pwhu.x1=(tmpg0->pwhu.x1*t0+tmpg1->pwhu.x1*t1)>>32;
|
||||
tmpgr->pwhu.y1=(tmpg0->pwhu.y1*t0+tmpg1->pwhu.y1*t1)>>32;
|
||||
break;
|
||||
case SPT_POLYLINE:
|
||||
ptr0=&tmpg0->nu.u;
|
||||
ptr1=&tmpg1->nu.u;
|
||||
ptrr=&tmpgr->nu.u;
|
||||
for (i=0;i<tmpg0->nu.num;i++) {
|
||||
ptrr[i<<1]=(ptr0[i<<1]*t0+ptr1[i<<1]*t1)>>32;
|
||||
ptrr[i<<1+1]=(ptr0[i<<1+1]*t0+ptr1[i<<1+1]*t1)>>32;
|
||||
}
|
||||
break;
|
||||
case SPT_POLYPT:
|
||||
tmpgr->npu.x=(tmpg0->npu.x*t0+tmpg1->npu.x*t1)>>32;
|
||||
tmpgr->npu.y=(tmpg0->npu.y*t0+tmpg1->npu.y*t1)>>32;
|
||||
break;
|
||||
case SPT_BSPLINE2:
|
||||
case SPT_BSPLINE3:
|
||||
case SPT_BSPLINE2_CLOSED:
|
||||
case SPT_BSPLINE3_CLOSED:
|
||||
p0=&tmpg0->nu.u;
|
||||
p1=&tmpg1->nu.u;
|
||||
pr=&tmpgr->nu.u;
|
||||
for (i=0;i<tmpg0->nu.num;i++) {
|
||||
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
|
||||
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
|
||||
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
|
||||
}
|
||||
break;
|
||||
case SPT_MESH:
|
||||
p0=&tmpg0->mu.u;
|
||||
p1=&tmpg1->mu.u;
|
||||
pr=&tmpgr->mu.u;
|
||||
for (i=0;i<tmpg0->mu.vertex_cnt;i++) {
|
||||
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
|
||||
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
|
||||
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
|
||||
}
|
||||
break;
|
||||
case SPT_SHIFTABLE_MESH:
|
||||
p0=&tmpg0->pmu.u;
|
||||
p1=&tmpg1->pmu.u;
|
||||
pr=&tmpgr->pmu.u;
|
||||
for (i=0;i<tmpg0->pmu.vertex_cnt;i++) {
|
||||
pr[i].x=(p0[i].x*t0+p1[i].x*t1)>>32;
|
||||
pr[i].y=(p0[i].y*t0+p1[i].y*t1)>>32;
|
||||
pr[i].z=(p0[i].z*t0+p1[i].z*t1)>>32;
|
||||
}
|
||||
break;
|
||||
}
|
||||
tmpg0(U8 *)+=SpriteElemSize(tmpg0);
|
||||
tmpg1(U8 *)+=SpriteElemSize(tmpg1);
|
||||
tmpgr(U8 *)+=SpriteElemSize(tmpgr);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "Graphics/Sprite;DolDoc/Output;StdOut/DolDoc"
|
||||
public CDocEntry *DocSprite(CDoc *doc=NULL,U8 *elems,U8 *fmt=NULL)
|
||||
{//Put a sprite into a document. You can, optionally, supply a fmt string
|
||||
//for $LK,"DolDoc",A="FI:::/Doc/DolDocOverview.DD"$ cmd with a %d for the bin_num.
|
||||
I64 size;
|
||||
U8 *st;
|
||||
Bool unlock;
|
||||
CDocEntry *doc_e;
|
||||
CDocBin *tmpb;
|
||||
if (!doc && !(doc=DocPut)) return NULL;
|
||||
unlock=DocLock(doc);
|
||||
size=SpriteSize(elems);
|
||||
tmpb=CAlloc(sizeof(CDocBin),doc->mem_task);
|
||||
tmpb->size=size;
|
||||
tmpb->data=MAlloc(size,doc->mem_task);
|
||||
MemCpy(tmpb->data,elems,size);
|
||||
tmpb->num=doc->cur_bin_num;
|
||||
tmpb->use_cnt=1;
|
||||
QueIns(tmpb,doc->bin_head.last);
|
||||
if (fmt)
|
||||
st=MStrPrint(fmt,doc->cur_bin_num++);
|
||||
else
|
||||
st=MStrPrint("$$SP,\"\",BI=%d$$",doc->cur_bin_num++);
|
||||
doc_e=DocPrint(doc,"%s",st);
|
||||
Free(st);
|
||||
doc_e->bin_data=tmpb;
|
||||
if (doc_e && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
|
||||
tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
|
||||
if (unlock)
|
||||
DocUnlock(doc);
|
||||
return doc_e;
|
||||
}
|
||||
|
||||
public CDocEntry *Sprite(U8 *elems,U8 *fmt=NULL)
|
||||
{//Put sprite to the command-line, $LK,"DocPut",A="MN:DocPut"$.
|
||||
//If you set fmt, then include dollars ("$$SP ...$$") and leave %d for num.
|
||||
CDoc *doc;
|
||||
if (doc=DocPut)
|
||||
return DocSprite(doc,elems,fmt);
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,363 @@
|
||||
#help_index "TextBase Layer;Char/TextBase Layer"
|
||||
#help_file "::/Doc/TextBase"
|
||||
|
||||
asm {
|
||||
//************************************
|
||||
_TEXT_CHAR::
|
||||
//Bool TextChar(CTask *task,Bool allow_border=FALSE,I64 x,I64 y,I64 d);
|
||||
//Must be called 30fps in Fs->draw_it() callback.
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
MOV RCX,U64 SF_ARG1[RBP]
|
||||
MOV RBX,U64 CTask.scroll_x[RCX]
|
||||
SAR RBX,3
|
||||
ADD RBX,U64 SF_ARG3[RBP]
|
||||
MOV RAX,U64 CTask.scroll_y[RCX]
|
||||
SAR RAX,3
|
||||
ADD RAX,U64 SF_ARG4[RBP]
|
||||
|
||||
TEST U8 SF_ARG2[RBP],0xFF
|
||||
JNZ @@10
|
||||
|
||||
//Border not allowed
|
||||
TEST RBX,RBX //Check X
|
||||
JS @@05
|
||||
ADD RBX,U64 CTask.win_left[RCX]
|
||||
CMP RBX,U64 CTask.win_right[RCX]
|
||||
JG @@05
|
||||
TEST RBX,RBX
|
||||
JS @@05
|
||||
CMP RBX,TEXT_COLS
|
||||
JGE @@05
|
||||
TEST RAX,RAX //Check Y
|
||||
JS @@05
|
||||
ADD RAX,U64 CTask.win_top[RCX]
|
||||
CMP RAX,U64 CTask.win_bottom[RCX]
|
||||
JG @@05
|
||||
TEST RAX,RAX
|
||||
JS @@05
|
||||
CMP RAX,TEXT_ROWS
|
||||
JGE @@05
|
||||
JMP @@15
|
||||
|
||||
@@05: XOR RAX,RAX //return FALSE
|
||||
POP RBP
|
||||
RET1 40
|
||||
|
||||
//Border allowed
|
||||
@@10: MOV RDX,-1 //Check X
|
||||
CMP RBX,RDX
|
||||
JL @@05
|
||||
ADD RBX,U64 CTask.win_left[RCX]
|
||||
MOV RDX,U64 CTask.win_right[RCX]
|
||||
INC RDX
|
||||
CMP RBX,RDX
|
||||
JG @@05
|
||||
TEST RBX,RBX
|
||||
JS @@05
|
||||
CMP RBX,TEXT_COLS
|
||||
JGE @@05
|
||||
MOV RDX,-1 //Check Y
|
||||
CMP RAX,RDX
|
||||
JL @@05
|
||||
ADD RAX,U64 CTask.win_top[RCX]
|
||||
MOV RDX,U64 CTask.win_bottom[RCX]
|
||||
INC RDX
|
||||
CMP RAX,RDX
|
||||
JG @@05
|
||||
TEST RAX,RAX
|
||||
JS @@05
|
||||
CMP RAX,TEXT_ROWS
|
||||
JGE @@05
|
||||
|
||||
@@15: IMUL2 RAX,TEXT_COLS
|
||||
ADD RBX,RAX
|
||||
SHL RBX,2
|
||||
ADD RBX,U64 [&gr.text_base]
|
||||
MOV RAX,U64 SF_ARG5[RBP]
|
||||
MOV U32 [RBX],EAX
|
||||
|
||||
MOV RAX,TRUE
|
||||
POP RBP
|
||||
RET1 40
|
||||
//************************************
|
||||
_TEXT_LEN_STR::
|
||||
//Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,I64 attr,U8 *s)
|
||||
//Must be called 30fps in Fs->draw_it() callback.
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RBX,U64 SF_ARG1[RBP]
|
||||
MOV RSI,U64 SF_ARG6[RBP]
|
||||
MOV RDI,U64 CTask.scroll_x[RBX]
|
||||
SAR RDI,3
|
||||
ADD RDI,U64 SF_ARG2[RBP]
|
||||
MOV RCX,U64 SF_ARG4[RBP]
|
||||
|
||||
TEST RDI,RDI
|
||||
JNS @@05
|
||||
ADD RCX,RDI
|
||||
SUB RSI,RDI
|
||||
XOR RDI,RDI
|
||||
@@05: ADD RDI,U64 CTask.win_left[RBX]
|
||||
MOV RDX,RCX
|
||||
ADD RDX,RDI
|
||||
DEC RDX
|
||||
CMP RDX,U64 CTask.win_right[RBX]
|
||||
JLE @@10
|
||||
MOV RAX,RDX
|
||||
SUB RAX,U64 CTask.win_right[RBX]
|
||||
SUB RDX,RAX
|
||||
SUB RCX,RAX
|
||||
@@10: TEST RDI,RDI
|
||||
JNS @@15
|
||||
ADD RCX,RDI
|
||||
SUB RSI,RDI
|
||||
XOR RDI,RDI
|
||||
@@15: INC RDX
|
||||
SUB RDX,TEXT_COLS
|
||||
JLE @@20
|
||||
SUB RCX,RDX
|
||||
@@20: CMP RCX,1
|
||||
JL @@30
|
||||
|
||||
MOV RAX,U64 CTask.scroll_y[RBX]
|
||||
SAR RAX,3
|
||||
ADD RAX,U64 SF_ARG3[RBP]
|
||||
TEST RAX,RAX
|
||||
JS @@30
|
||||
ADD RAX,U64 CTask.win_top[RBX]
|
||||
CMP RAX,U64 CTask.win_bottom[RBX]
|
||||
JG @@30
|
||||
TEST RAX,RAX
|
||||
JS @@30
|
||||
CMP RAX,TEXT_ROWS
|
||||
JGE @@30
|
||||
|
||||
IMUL2 RAX,TEXT_COLS
|
||||
ADD RDI,RAX
|
||||
SHL RDI,2
|
||||
ADD RDI,U64 [&gr.text_base]
|
||||
MOV RAX,U64 SF_ARG5[RBP]
|
||||
@@25: LODSB
|
||||
STOSD
|
||||
DEC RCX
|
||||
JNZ @@25
|
||||
|
||||
POP RDI
|
||||
POP RSI
|
||||
MOV RAX,TRUE
|
||||
POP RBP
|
||||
RET1 48
|
||||
|
||||
@@30: POP RDI
|
||||
POP RSI
|
||||
XOR RAX,RAX
|
||||
POP RBP
|
||||
RET1 48
|
||||
//************************************
|
||||
_TEXT_LEN_ATTR_STR::
|
||||
//Bool TextLenAttrStr(CTask *task,I64 x,I64 y,I64 len,U32 *_attr)
|
||||
//Must be called 30fps in Fs->draw_it() callback.
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RBX,U64 SF_ARG1[RBP]
|
||||
MOV RSI,U64 SF_ARG5[RBP]
|
||||
MOV RDI,U64 CTask.scroll_x[RBX]
|
||||
SAR RDI,3
|
||||
ADD RDI,U64 SF_ARG2[RBP]
|
||||
MOV RCX,U64 SF_ARG4[RBP]
|
||||
|
||||
TEST RDI,RDI
|
||||
JNS @@05
|
||||
ADD RCX,RDI
|
||||
SHL RDI,2
|
||||
SUB RSI,RDI
|
||||
XOR RDI,RDI
|
||||
@@05: ADD RDI,U64 CTask.win_left[RBX]
|
||||
MOV RDX,RCX
|
||||
ADD RDX,RDI
|
||||
DEC RDX
|
||||
CMP RDX,U64 CTask.win_right[RBX]
|
||||
JLE @@10
|
||||
MOV RAX,RDX
|
||||
SUB RAX,U64 CTask.win_right[RBX]
|
||||
SUB RDX,RAX
|
||||
SUB RCX,RAX
|
||||
@@10: TEST RDI,RDI
|
||||
JNS @@15
|
||||
ADD RCX,RDI
|
||||
SHL RDI,2
|
||||
SUB RSI,RDI
|
||||
XOR RDI,RDI
|
||||
@@15: INC RDX
|
||||
SUB RDX,TEXT_COLS
|
||||
JLE @@20
|
||||
SUB RCX,RDX
|
||||
@@20: CMP RCX,1
|
||||
JL @@30
|
||||
|
||||
MOV RAX,U64 CTask.scroll_y[RBX]
|
||||
SAR RAX,3
|
||||
ADD RAX,U64 SF_ARG3[RBP]
|
||||
TEST RAX,RAX
|
||||
JS @@30
|
||||
ADD RAX,U64 CTask.win_top[RBX]
|
||||
CMP RAX,U64 CTask.win_bottom[RBX]
|
||||
JG @@30
|
||||
TEST RAX,RAX
|
||||
JS @@30
|
||||
CMP RAX,TEXT_ROWS
|
||||
JGE @@30
|
||||
|
||||
IMUL2 RAX,TEXT_COLS
|
||||
ADD RDI,RAX
|
||||
SHL RDI,2
|
||||
ADD RDI,U64 [&gr.text_base]
|
||||
@@25: MOVSD
|
||||
DEC RCX
|
||||
JNZ @@25
|
||||
|
||||
POP RDI
|
||||
POP RSI
|
||||
MOV RAX,TRUE
|
||||
POP RBP
|
||||
RET1 40
|
||||
|
||||
@@30: POP RDI
|
||||
POP RSI
|
||||
XOR RAX,RAX
|
||||
POP RBP
|
||||
RET1 40
|
||||
//************************************
|
||||
_TEXT_LEN_ATTR:://Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,I64 attr)
|
||||
//Must be called 30fps in Fs->draw_it() callback.
|
||||
PUSH RBP
|
||||
MOV RBP,RSP
|
||||
PUSH RSI
|
||||
PUSH RDI
|
||||
MOV RBX,U64 SF_ARG1[RBP]
|
||||
MOV RDI,U64 CTask.scroll_x[RBX]
|
||||
SAR RDI,3
|
||||
ADD RDI,U64 SF_ARG2[RBP]
|
||||
MOV RCX,U64 SF_ARG4[RBP]
|
||||
|
||||
TEST RDI,RDI
|
||||
JNS @@05
|
||||
ADD RCX,RDI
|
||||
XOR RDI,RDI
|
||||
@@05: ADD RDI,U64 CTask.win_left[RBX]
|
||||
MOV RDX,RCX
|
||||
ADD RDX,RDI
|
||||
DEC RDX
|
||||
CMP RDX,U64 CTask.win_right[RBX]
|
||||
JLE @@10
|
||||
MOV RAX,RDX
|
||||
SUB RAX,U64 CTask.win_right[RBX]
|
||||
SUB RDX,RAX
|
||||
SUB RCX,RAX
|
||||
@@10: TEST RDI,RDI
|
||||
JNS @@15
|
||||
ADD RCX,RDI
|
||||
XOR RDI,RDI
|
||||
@@15: INC RDX
|
||||
SUB RDX,TEXT_COLS
|
||||
JLE @@20
|
||||
SUB RCX,RDX
|
||||
@@20: CMP RCX,1
|
||||
JL @@35
|
||||
|
||||
MOV RAX,U64 CTask.scroll_y[RBX]
|
||||
SAR RAX,3
|
||||
ADD RAX,U64 SF_ARG3[RBP]
|
||||
TEST RAX,RAX
|
||||
JS @@35
|
||||
ADD RAX,U64 CTask.win_top[RBX]
|
||||
CMP RAX,U64 CTask.win_bottom[RBX]
|
||||
JG @@35
|
||||
TEST RAX,RAX
|
||||
JS @@35
|
||||
CMP RAX,TEXT_ROWS
|
||||
JGE @@35
|
||||
|
||||
IMUL2 RAX,TEXT_COLS
|
||||
ADD RDI,RAX
|
||||
SHL RDI,2
|
||||
ADD RDI,U64 [&gr.text_base]
|
||||
MOV RBX,U64 SF_ARG5[RBP]
|
||||
MOV RSI,RDI
|
||||
@@25: LODSD
|
||||
TEST AL,AL
|
||||
JNZ @@30
|
||||
MOV RAX,RBX
|
||||
STOSD
|
||||
DEC RCX
|
||||
JNZ @@25
|
||||
|
||||
@@30: POP RDI
|
||||
POP RSI
|
||||
MOV RAX,TRUE
|
||||
POP RBP
|
||||
RET1 40
|
||||
|
||||
@@35: POP RDI
|
||||
POP RSI
|
||||
XOR RAX,RAX
|
||||
POP RBP
|
||||
RET1 40
|
||||
}
|
||||
public _extern _TEXT_CHAR Bool TextChar(CTask *task,Bool allow_border=FALSE,
|
||||
I64 x,I64 y,I64 d); //Plot char. 30fps in Fs->draw_it() callback.
|
||||
public _extern _TEXT_LEN_STR Bool TextLenStr(CTask *task,I64 x,I64 y,I64 len,
|
||||
I64 attr,U8 *s); //Plot str with len. 30fps in Fs->draw_it() callback.
|
||||
public _extern _TEXT_LEN_ATTR_STR Bool TextLenAttrStr(CTask *task,I64 x,I64 y,
|
||||
I64 len,U32 *_attr); //Plot attr str with len. 30fps in Fs->draw_it() callback.
|
||||
public _extern _TEXT_LEN_ATTR Bool TextLenAttr(CTask *task,I64 x,I64 y,I64 len,
|
||||
I64 attr); //Plot attrs with len. 30fps in Fs->draw_it() callback.
|
||||
|
||||
public U0 TextPrint(CTask *task,I64 x,I64 y,I64 attr,U8 *fmt,...)
|
||||
{//Plot chars. 30fps in Fs->draw_it() callback.
|
||||
//You probably want $LK,"GrPrint",A="MN:GrPrint"$() or just $LK,"Print",A="MN:Print"$().
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv);
|
||||
TextLenStr(task,x,y,StrLen(buf),attr<<8,buf);
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
public U0 TextBorder(CTask *task=NULL,
|
||||
I64 l,I64 r,I64 t,I64 b,I64 attr,Bool solid)
|
||||
{//Plot border square. 30fps in Fs->draw_it() callback.
|
||||
//Draws window borders or DolDoc text bttn borders.
|
||||
//Set task=sys_winmgr_task for no clipping.
|
||||
I64 i;
|
||||
if (!task) task=Fs;
|
||||
attr<<=8;
|
||||
TextChar(task,,l-1,t-1,text.border_chars[6+solid]+attr);
|
||||
TextChar(task,,r+1,t-1,text.border_chars[8+solid]+attr);
|
||||
TextChar(task,,l-1,b+1,text.border_chars[10+solid]+attr);
|
||||
TextChar(task,,r+1,b+1,text.border_chars[12+solid]+attr);
|
||||
for (i=l;i<=r;i++) {
|
||||
TextChar(task,,i,t-1,text.border_chars[2+solid]+attr);
|
||||
TextChar(task,,i,b+1,text.border_chars[2+solid]+attr);
|
||||
}
|
||||
for (i=t;i<=b;i++) {
|
||||
TextChar(task,,l-1,i,text.border_chars[4+solid]+attr);
|
||||
TextChar(task,,r+1,i,text.border_chars[4+solid]+attr);
|
||||
}
|
||||
}
|
||||
|
||||
public U0 TextRect(I64 l,I64 r,I64 t,I64 b,I64 d)
|
||||
{//Fill text rect. 30fps in Fs->draw_it() callback.
|
||||
I64 y,w;
|
||||
if (l>r || t>b) return;
|
||||
if (t<0) t=0;
|
||||
if (b>=TEXT_ROWS) b=TEXT_ROWS-1;
|
||||
if (l<0) l=0;
|
||||
if (r>=TEXT_COLS) r=TEXT_COLS-1;
|
||||
if (w=r-l+1)
|
||||
for (y=t;y<=b;y++)
|
||||
MemSetU32(gr.text_base(U8 *)+(y*TEXT_COLS+l)*sizeof(U32),d,w);
|
||||
}
|
||||
|
||||
@@ -0,0 +1,31 @@
|
||||
Cd(__DIR__);;
|
||||
|
||||
#include "GrInitA"
|
||||
#include "Gr.HH"
|
||||
#include "GrExt"
|
||||
#include "GrGlbls"
|
||||
#include "GrTextBase"
|
||||
#include "GrAsm"
|
||||
#include "GrPalette"
|
||||
#include "GrDC"
|
||||
#include "GrInitB"
|
||||
#include "GrMath"
|
||||
#include "GrScrn"
|
||||
#include "GrBitMap"
|
||||
#include "GrPrimatives"
|
||||
#include "GrComposites"
|
||||
|
||||
#define SPE_ABORT (-1)
|
||||
#define SPE_EXIT 0
|
||||
#define SPE_CONT 1
|
||||
#include "SpriteNew"
|
||||
#include "GrSpritePlot"
|
||||
#include "SpriteMesh"
|
||||
#include "SpriteBitMap"
|
||||
#include "SpriteCode"
|
||||
#include "SpriteEd"
|
||||
#include "SpriteMain"
|
||||
|
||||
#include "GrEnd"
|
||||
|
||||
Cd("..");;
|
||||
@@ -0,0 +1,677 @@
|
||||
#help_index "Graphics/Sprite;Sprites"
|
||||
|
||||
#define SPBM_EXIT 0
|
||||
#define SPBM_MAIN_MENU 1
|
||||
#define SPBM_COLOR 2
|
||||
#define SPBM_DITHER_COLOR 3
|
||||
#define SPBM_WIDTH 4
|
||||
#define SPBM_PT 5
|
||||
#define SPBM_LINE 6
|
||||
#define SPBM_ARROW 7
|
||||
#define SPBM_RECT 8
|
||||
#define SPBM_CIRCLE 9
|
||||
#define SPBM_TEXT 10
|
||||
#define SPBM_TEXT_BOX 11
|
||||
#define SPBM_TEXT_DIAMOND 12
|
||||
#define SPBM_FLOOD_FILL 13
|
||||
#define SPBM_FLOOD_FILL_NOT 14
|
||||
#define SPBM_POLYLINE 15
|
||||
#define SPBM_POLYPT 16
|
||||
#define SPBM_COPY 17
|
||||
#define SPBM_DELETE 18
|
||||
#define SPBM_PASTE 19
|
||||
#define SPBM_PASTE_TRANSPARENT 20
|
||||
#define SPBM_FIND_AND_REPLACE 21
|
||||
#define SPBM_TRIM_TO_EXTENTS 22
|
||||
#define SPBM_ADD_OUTLINE 23
|
||||
#define SPBM_ETCH 24
|
||||
#define SPBM_UNDO 25
|
||||
#define SPBM_SAVE_BMP 26
|
||||
#define SPBM_SAVE_GRA 27
|
||||
|
||||
U0 GrInit4()
|
||||
{
|
||||
DefineLstLoad("ST_SPRITE_BITMAP_MENU",
|
||||
"Exit\0Main Menu\0Color\0Dither Color\0Width\0Point\0Line\0Arrow\0"
|
||||
"Rect\0Circle\0Text\0Text Box\0Text Diamond\0Flood Fill\0"
|
||||
"Flood Fill Not Color\0PolyLine\0PolyPoint\0Copy\0Delete\0Paste\0"
|
||||
"Paste Transparent\0Find and Replace\0Trim to Extents\0Add Outline\0"
|
||||
"Etch\0Undo\0Save BMP\0Save GR\0");
|
||||
}
|
||||
GrInit4;
|
||||
|
||||
I64 PopUpSpriteBitMap(CColorROPU32 color,I64 width)
|
||||
{
|
||||
I64 i;
|
||||
U8 *st1,*st2,buf[STR_LEN];
|
||||
CDoc *doc=DocNew;
|
||||
|
||||
Color2Str(buf,color);
|
||||
if (color&ROPF_DITHER) {
|
||||
st1="";
|
||||
st2=buf;
|
||||
} else {
|
||||
st1=buf;
|
||||
st2="";
|
||||
}
|
||||
DocPrint(doc,"$$PURPLE$$$$TX+CX,\"Sprite BitMap Menu\"$$\n"
|
||||
"$$LK+PU+CX,\"Click for Help\",A=\"FI:::/Doc/SpriteBitMap.DD.Z\"$$\n"
|
||||
"\n$$LTBLUE$$$$MU-UL,\"Color %s\",LE=SPBM_COLOR$$\n"
|
||||
"$$MU-UL,\"Dither Color %s\",LE=SPBM_DITHER_COLOR$$\n"
|
||||
"$$MU-UL,\"Width %d\",LE=SPBM_WIDTH$$\n"
|
||||
"$$MU-UL,\"Find & Replace Color\",LE=SPBM_FIND_AND_REPLACE$$\n"
|
||||
"$$MU-UL,\"Trim to Extents\",LE=SPBM_TRIM_TO_EXTENTS$$\n"
|
||||
"$$MU-UL,\"Add Outline\",LE=SPBM_ADD_OUTLINE$$\n"
|
||||
"$$MU-UL,\"Etch\",LE=SPBM_ETCH$$\n"
|
||||
"\n$$MU-UL,\"Point\",LE=SPBM_PT$$\n"
|
||||
"$$MU-UL,\"Line\",LE=SPBM_LINE$$\n"
|
||||
"$$MU-UL,\"Arrow\",LE=SPBM_ARROW$$\n"
|
||||
"$$MU-UL,\"Rect\",LE=SPBM_RECT$$\n"
|
||||
"$$MU-UL,\"Circle\",LE=SPBM_CIRCLE$$\n"
|
||||
"$$MU-UL,\"Text\",LE=SPBM_TEXT$$\n"
|
||||
"$$MU-UL,\"Text Box\",LE=SPBM_TEXT_BOX$$\n"
|
||||
"$$MU-UL,\"Text Diamond\",LE=SPBM_TEXT_DIAMOND$$\n"
|
||||
"$$MU-UL,\"Flood Fill\",LE=SPBM_FLOOD_FILL$$\n"
|
||||
"$$MU-UL,\"Flood Fill Not Color\",LE=SPBM_FLOOD_FILL_NOT$$\n"
|
||||
"$$MU-UL,\"PolyLine\",LE=SPBM_POLYLINE$$\n"
|
||||
"$$MU-UL,\"PolyPoint\",LE=SPBM_POLYPT$$\n"
|
||||
"\n$$MU-UL,\"Copy to Clipboard\",LE=SPBM_COPY$$\n"
|
||||
"$$MU-UL,\"Delete to Clipboard\",LE=SPBM_DELETE$$\n"
|
||||
"$$MU-UL,\"Paste Clipboard\",LE=SPBM_PASTE$$\n"
|
||||
"$$MU-UL,\"Paste Transparent Clipboard\",LE=SPBM_PASTE_TRANSPARENT$$\n"
|
||||
"\n$$MU-UL,\"Save BMP File\",LE=SPBM_SAVE_BMP$$\n"
|
||||
"$$MU-UL,\"Save GR File\",LE=SPBM_SAVE_GRA$$\n"
|
||||
"\n$$MU-UL,\"Undo\",LE=SPBM_UNDO$$\n"
|
||||
"\n$$PURPLE$$$$MU-UL,\"+] Sprite Main Menu\",LE=SPBM_MAIN_MENU$$$$LTBLUE$$\n"
|
||||
"$$MU-UL,\"Exit Sprite\",LE=SPBM_EXIT$$\n"
|
||||
"$$MU-UL,\"Abort Sprite\",LE=DOCM_CANCEL$$\n"
|
||||
"\nRight-Click to get back to this menu.",st1,st2,width);
|
||||
i=PopUpMenu(doc);
|
||||
DocDel(doc);
|
||||
return i;
|
||||
}
|
||||
|
||||
U0 GrBitMapEdPrepPersistentDC(CDC *dc,I64 xx1,I64 yy1,CDC *img)
|
||||
{
|
||||
DCFill(dc);
|
||||
GrBlot(dc,xx1,yy1,img);
|
||||
}
|
||||
|
||||
U0 GrBitMapEdTrimToExtents(CDC **_img,I64 *_xx1,I64 *_yy1,
|
||||
I64 *_xx2,I64 *_yy2,CColorROPU32 bkcolor)
|
||||
{
|
||||
CDC *img=*_img;
|
||||
I64 i,c,
|
||||
x1=0,y1=0,x2=img->width-1,y2=img->height-1; //inclusive
|
||||
while (y1<y2) {
|
||||
for (i=x1;i<=x2;i++) {
|
||||
c=GrPeek(img,i,y1);
|
||||
if (c!=bkcolor&&c!=TRANSPARENT) goto tr_y2;
|
||||
}
|
||||
y1++;
|
||||
}
|
||||
|
||||
tr_y2:
|
||||
while (y1<y2) {
|
||||
for (i=x1;i<=x2;i++) {
|
||||
c=GrPeek(img,i,y2);
|
||||
if (c!=bkcolor&&c!=TRANSPARENT) goto tr_x1;
|
||||
}
|
||||
y2--;
|
||||
}
|
||||
|
||||
tr_x1:
|
||||
while (x1<x2) {
|
||||
for (i=y1;i<=y2;i++) {
|
||||
c=GrPeek(img,x1,i);
|
||||
if (c!=bkcolor&&c!=TRANSPARENT) goto tr_x2;
|
||||
}
|
||||
x1++;
|
||||
}
|
||||
|
||||
tr_x2:
|
||||
while (x1<x2) {
|
||||
for (i=y1;i<=y2;i++) {
|
||||
c=GrPeek(img,x2,i);
|
||||
if (c!=bkcolor&&c!=TRANSPARENT) goto tr_done;
|
||||
}
|
||||
x2--;
|
||||
}
|
||||
|
||||
tr_done:
|
||||
*_img=DCExt(img,x1,y1,x2,y2);
|
||||
*_xx1+=x1; *_yy1+=y1;
|
||||
*_xx2+=x2-(img->width-1); *_yy2+=y2-(img->height-1); //not inclusive
|
||||
DCDel(img);
|
||||
}
|
||||
|
||||
U0 GrBitMapEdAddOutline(CDC *img,I64 width,
|
||||
CColorROPU32 color,CColorROPU32 bkcolor)
|
||||
{
|
||||
I64 i,j,k,c;
|
||||
CColorROPU32 old_color;
|
||||
CDC *src;
|
||||
if (img->width && img->height) {
|
||||
old_color=img->color;
|
||||
img->color=color;
|
||||
while (width-->0) {
|
||||
src=DCExt(img,0,0,img->width-1,img->height-1);
|
||||
for (i=0;i<img->height;i++)
|
||||
for (j=0;j<img->width;j++)
|
||||
if (GrPeek(src,j,i)==bkcolor)
|
||||
for (k=0;k<8;k++) {
|
||||
c=GrPeek(src,j+gr_x_offsets[k],i+gr_y_offsets[k]);
|
||||
if (c>=0 && c!=bkcolor) {
|
||||
GrPlot(img,j,i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DCDel(src);
|
||||
}
|
||||
img->color=old_color;
|
||||
}
|
||||
}
|
||||
|
||||
U0 GrBitMapEdEtch(CDC *img,I64 width,CColorROPU32 bkcolor)
|
||||
{
|
||||
I64 i,j,k,c;
|
||||
CColorROPU32 old_color;
|
||||
CDC *src;
|
||||
if (img->width && img->height) {
|
||||
old_color=img->color;
|
||||
img->color=bkcolor;
|
||||
while (width-->0) {
|
||||
src=DCExt(img,0,0,img->width-1,img->height-1);
|
||||
for (i=0;i<img->height;i++)
|
||||
for (j=0;j<img->width;j++)
|
||||
if (GrPeek(src,j,i)!=bkcolor)
|
||||
for (k=0;k<8;k++) {
|
||||
c=GrPeek(src,j+gr_x_offsets[k],i+gr_y_offsets[k]);
|
||||
if (c<0 || c==bkcolor) {
|
||||
GrPlot(img,j,i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
DCDel(src);
|
||||
}
|
||||
img->color=old_color;
|
||||
}
|
||||
}
|
||||
|
||||
I64 SpriteBitMapEd(CDoc *,CDocEntry *doc_e,CDC *dc,I64 *_xx1,I64 *_yy1,
|
||||
I64 *_xx2,I64 *_yy2,CDC **_img,CColorROPU32 bkcolor)
|
||||
{
|
||||
I64 i,j,mode=SPBM_LINE,color=BLACK,width=1,msg_code,arg1,arg2,x1,y1,x11,y11,
|
||||
x22,y22,res,xx1=*_xx1,yy1=*_yy1,xx2=*_xx2,yy2=*_yy2,
|
||||
old_de_flags=doc_e->de_flags;
|
||||
Bool down=FALSE;
|
||||
U8 *st=NULL;
|
||||
CEdFileName filename;
|
||||
CDC *img=*_img,
|
||||
*clipboard=NULL,*undo=NULL,*dc2;
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
|
||||
doc_e->de_flags|=DOCEF_DONT_DRAW;
|
||||
goto bm_menu;
|
||||
|
||||
while (TRUE) {
|
||||
if (kbd.scan_code&SCF_CTRL)//grab scroll update?
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
|
||||
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
|
||||
dc->pen_width=1;
|
||||
GrBorder(dc,xx1-1,yy1-1,xx2,yy2);//This is done little bit too often.
|
||||
|
||||
while (msg_code=ScanMsg(&arg1,&arg2,1<<MSG_MS_L_DOWN|1<<MSG_MS_L_UP|
|
||||
1<<MSG_MS_R_DOWN|1<<MSG_MS_MOVE|1<<MSG_KEY_DOWN)) {
|
||||
switch (msg_code) {
|
||||
case MSG_KEY_DOWN:
|
||||
switch (arg1) {
|
||||
case CH_SHIFT_ESC:
|
||||
res=SPE_ABORT;
|
||||
goto bm_key_up_done;
|
||||
case CH_ESC:
|
||||
res=SPE_CONT;
|
||||
goto bm_key_up_done;
|
||||
case 'c': //eye-dropper
|
||||
dc2=DCScrnCapture(FALSE);
|
||||
color=GrPeek(dc2,ms.pos.x,ms.pos.y)^15;//Mouse cursor is XORed.
|
||||
DCDel(dc2);
|
||||
break;
|
||||
case 't': //Set to transparent color
|
||||
color=TRANSPARENT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case MSG_MS_R_DOWN:
|
||||
bm_menu:
|
||||
DCFill(dc);
|
||||
StrCpy(Fs->task_title,"Sprite BitMap Menu");
|
||||
i=PopUpSpriteBitMap(color,width);
|
||||
if (i>=0)
|
||||
StrCpy(Fs->task_title,DefineSub(i,"ST_SPRITE_BITMAP_MENU"));
|
||||
switch (i) {
|
||||
case DOCM_CANCEL:
|
||||
res=SPE_ABORT;
|
||||
goto bm_done;
|
||||
case SPBM_EXIT:
|
||||
res=SPE_EXIT;
|
||||
goto bm_done;
|
||||
case SPBM_MAIN_MENU:
|
||||
res=SPE_CONT;
|
||||
goto bm_done;
|
||||
case SPBM_COLOR:
|
||||
i=PopUpColor(,,FALSE);
|
||||
if (i>=0) color=i;
|
||||
goto bm_menu;
|
||||
case SPBM_FIND_AND_REPLACE:
|
||||
i=PopUpColor("Find Color\n",,FALSE);
|
||||
if (i>=0) {
|
||||
j=PopUpColor("Replace Color\n",,FALSE);
|
||||
if (j>=0) {
|
||||
DCColorChg(img,i,j);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
}
|
||||
}
|
||||
goto bm_menu;
|
||||
case SPBM_TRIM_TO_EXTENTS:
|
||||
GrBitMapEdTrimToExtents(&img,&xx1,&yy1,&xx2,&yy2,bkcolor);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
goto bm_menu;
|
||||
case SPBM_ADD_OUTLINE:
|
||||
i=PopUpRangeI64(1,16,1,"Outline Width\n");
|
||||
if (i>=0) {
|
||||
GrBitMapEdAddOutline(img,i,color,bkcolor);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
}
|
||||
goto bm_menu;
|
||||
case SPBM_ETCH:
|
||||
i=PopUpRangeI64(1,16,1,"Etch Width\n");
|
||||
if (i>=0) {
|
||||
GrBitMapEdEtch(img,i,bkcolor);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
}
|
||||
goto bm_menu;
|
||||
case SPBM_SAVE_BMP:
|
||||
*filename.name=0;
|
||||
if (DocForm(&filename) && *filename.name)
|
||||
BMPWrite(filename.name,img);
|
||||
goto bm_menu;
|
||||
case SPBM_SAVE_GRA:
|
||||
*filename.name=0;
|
||||
if (DocForm(&filename) && *filename.name)
|
||||
GRWrite(filename.name,img,DCSF_COMPRESSED|DCSF_PALETTE_GET);
|
||||
goto bm_menu;
|
||||
case SPBM_DITHER_COLOR:
|
||||
i=PopUpColorDither;
|
||||
if (i>=0) color=i;
|
||||
goto bm_menu;
|
||||
case SPBM_WIDTH:
|
||||
i=PopUpRangeI64(1,16,1,"Pen Width\n");
|
||||
if (i>=0) width=i;
|
||||
goto bm_menu;
|
||||
case SPBM_UNDO:
|
||||
if (undo) {
|
||||
DCFill(img,bkcolor);
|
||||
img->color=ROP_EQU;
|
||||
GrBlot(img,0,0,undo);
|
||||
DCDel(undo);
|
||||
undo=NULL;
|
||||
}
|
||||
goto bm_menu;
|
||||
case SPBM_PT:
|
||||
case SPBM_LINE:
|
||||
case SPBM_ARROW:
|
||||
case SPBM_RECT:
|
||||
case SPBM_CIRCLE:
|
||||
case SPBM_FLOOD_FILL:
|
||||
case SPBM_FLOOD_FILL_NOT:
|
||||
case SPBM_POLYPT:
|
||||
case SPBM_POLYLINE:
|
||||
case SPBM_COPY:
|
||||
case SPBM_DELETE:
|
||||
case SPBM_PASTE:
|
||||
case SPBM_PASTE_TRANSPARENT:
|
||||
mode=i;
|
||||
break;
|
||||
case SPBM_TEXT:
|
||||
case SPBM_TEXT_BOX:
|
||||
case SPBM_TEXT_DIAMOND:
|
||||
Free(st);
|
||||
st=PopUpGetStr("Enter text and press <ESC>.\n");
|
||||
if (st && *st)
|
||||
mode=i;
|
||||
else
|
||||
goto bm_menu;
|
||||
break;
|
||||
}
|
||||
DCDel(undo);
|
||||
undo=DCExt(img,0,0,img->width-1,img->height-1);
|
||||
undo->bkcolor=bkcolor;
|
||||
Refresh(2,TRUE); //Let popup close
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
down=FALSE;
|
||||
break;
|
||||
case MSG_MS_L_DOWN:
|
||||
switch (mode) {
|
||||
case SPBM_PT:
|
||||
img->color=color;
|
||||
img->pen_width=width;
|
||||
GrPlot3(img,arg1-xx1,arg2-yy1,0);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
break;
|
||||
start:
|
||||
if (down)
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
x1=arg1; y1=arg2;
|
||||
down=TRUE;
|
||||
dc->color=color;
|
||||
dc->pen_width=width;
|
||||
case SPBM_LINE:
|
||||
GrLine3(dc,x1,y1,0,arg1,arg2,0);
|
||||
break;
|
||||
case SPBM_ARROW:
|
||||
GrArrow3(dc,x1,y1,0,arg1,arg2,0);
|
||||
break;
|
||||
case SPBM_RECT:
|
||||
GrRect(dc,x1,y1,1,1);
|
||||
break;
|
||||
case SPBM_CIRCLE:
|
||||
GrCircle3(dc,x1,y1,0,1);
|
||||
break;
|
||||
case SPBM_COPY:
|
||||
case SPBM_DELETE:
|
||||
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
|
||||
dc->pen_width=1;
|
||||
GrBorder(dc,x1,y1,x1,y1);
|
||||
break;
|
||||
end:
|
||||
break;
|
||||
case SPBM_PASTE:
|
||||
case SPBM_PASTE_TRANSPARENT:
|
||||
if (clipboard) {
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
if (mode==SPBM_PASTE) {
|
||||
clipboard->flags|=DCF_NO_TRANSPARENTS;
|
||||
GrBlot(dc,arg1,arg2,clipboard);
|
||||
clipboard->flags&=~DCF_NO_TRANSPARENTS;
|
||||
} else {
|
||||
dc2=DCCopy(clipboard);
|
||||
DCColorChg(dc2,bkcolor);
|
||||
GrBlot(dc,arg1,arg2,dc2);
|
||||
DCDel(dc2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SPBM_TEXT:
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
dc->color=color;
|
||||
GrPrint(dc,arg1,arg2,"%s",st);
|
||||
break;
|
||||
case SPBM_TEXT_BOX:
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
dc->color=color;
|
||||
GrTextBox3(dc,arg1,arg2,0,st);
|
||||
break;
|
||||
case SPBM_TEXT_DIAMOND:
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
dc->color=color;
|
||||
GrTextDiamond3(dc,arg1,arg2,0,st);
|
||||
break;
|
||||
case SPBM_FLOOD_FILL:
|
||||
img->color=color;
|
||||
GrFloodFill(img,arg1-xx1,arg2-yy1);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
break;
|
||||
case SPBM_FLOOD_FILL_NOT:
|
||||
img->color=color;
|
||||
GrFloodFill(img,arg1-xx1,arg2-yy1,TRUE);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
break;
|
||||
case SPBM_POLYLINE:
|
||||
if (!down) {
|
||||
x1=arg1; y1=arg2;
|
||||
down=TRUE;
|
||||
dc->color=color;
|
||||
dc->pen_width=width;
|
||||
GrLine3(dc,x1,y1,0,arg1,arg2,0);
|
||||
}
|
||||
break;
|
||||
case SPBM_POLYPT:
|
||||
x1=arg1; y1=arg2;
|
||||
down=TRUE;
|
||||
img->color=color;
|
||||
img->pen_width=width;
|
||||
GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MSG_MS_MOVE:
|
||||
switch (mode) {
|
||||
case SPBM_LINE:
|
||||
case SPBM_ARROW:
|
||||
case SPBM_POLYLINE:
|
||||
if (down) {
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
dc->color=color;
|
||||
dc->pen_width=width;
|
||||
if (mode==SPBM_ARROW)
|
||||
GrArrow3(dc,x1,y1,0,arg1,arg2,0);
|
||||
else
|
||||
GrLine3(dc,x1,y1,0,arg1,arg2,0);
|
||||
}
|
||||
break;
|
||||
case SPBM_RECT:
|
||||
if (down) {
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
if (x1<arg1) {
|
||||
x11=x1;
|
||||
x22=arg1;
|
||||
} else {
|
||||
x11=arg1;
|
||||
x22=x1;
|
||||
}
|
||||
if (y1<arg2) {
|
||||
y11=y1;
|
||||
y22=arg2;
|
||||
} else {
|
||||
y11=arg2;
|
||||
y22=y1;
|
||||
}
|
||||
dc->color=color;
|
||||
GrRect(dc,x11,y11,x22-x11+1,y22-y11+1);
|
||||
}
|
||||
break;
|
||||
case SPBM_COPY:
|
||||
case SPBM_DELETE:
|
||||
if (down) {
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
if (x1<arg1) {
|
||||
x11=x1;
|
||||
x22=arg1;
|
||||
} else {
|
||||
x11=arg1;
|
||||
x22=x1;
|
||||
}
|
||||
if (y1<arg2) {
|
||||
y11=y1;
|
||||
y22=arg2;
|
||||
} else {
|
||||
y11=arg2;
|
||||
y22=y1;
|
||||
}
|
||||
dc->color=ROPF_DITHER+WHITE<<16+BLACK;
|
||||
dc->pen_width=1;
|
||||
GrBorder(dc,x11,y11,x22,y22);
|
||||
}
|
||||
break;
|
||||
case SPBM_CIRCLE:
|
||||
if (down) {
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
dc->color=color;
|
||||
dc->pen_width=width;
|
||||
GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(arg1-x1)+SqrI64(arg2-y1)));
|
||||
}
|
||||
break;
|
||||
case SPBM_PASTE:
|
||||
case SPBM_PASTE_TRANSPARENT:
|
||||
if (clipboard) {
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
if (mode==SPBM_PASTE) {
|
||||
clipboard->flags|=DCF_NO_TRANSPARENTS;
|
||||
GrBlot(dc,arg1,arg2,clipboard);
|
||||
clipboard->flags&=~DCF_NO_TRANSPARENTS;
|
||||
} else {
|
||||
dc2=DCCopy(clipboard);
|
||||
DCColorChg(dc2,bkcolor);
|
||||
GrBlot(dc,arg1,arg2,dc2);
|
||||
DCDel(dc2);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SPBM_TEXT:
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
dc->color=color;
|
||||
GrPrint(dc,arg1,arg2,"%s",st);
|
||||
break;
|
||||
case SPBM_TEXT_BOX:
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
dc->color=color;
|
||||
GrTextBox3(dc,arg1,arg2,0,st);
|
||||
break;
|
||||
case SPBM_TEXT_DIAMOND:
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
dc->color=color;
|
||||
GrTextDiamond3(dc,arg1,arg2,0,st);
|
||||
break;
|
||||
case SPBM_POLYPT:
|
||||
if (down) {
|
||||
img->color=color;
|
||||
img->pen_width=width;
|
||||
GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
x1=arg1; y1=arg2;
|
||||
}
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case MSG_MS_L_UP:
|
||||
switch (mode) {
|
||||
case SPBM_LINE:
|
||||
case SPBM_ARROW:
|
||||
case SPBM_POLYPT:
|
||||
case SPBM_POLYLINE:
|
||||
img->color=color;
|
||||
img->pen_width=width;
|
||||
if (mode==SPBM_ARROW)
|
||||
GrArrow3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
|
||||
else
|
||||
GrLine3(img,x1-xx1,y1-yy1,0,arg1-xx1,arg2-yy1,0);
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
if (mode==SPBM_POLYLINE) {
|
||||
x1=arg1; y1=arg2;
|
||||
} else
|
||||
down=FALSE;
|
||||
break;
|
||||
case SPBM_RECT:
|
||||
img->color=color;
|
||||
if (x1<arg1) {
|
||||
x11=x1;
|
||||
x22=arg1;
|
||||
} else {
|
||||
x11=arg1;
|
||||
x22=x1;
|
||||
}
|
||||
if (y1<arg2) {
|
||||
y11=y1;
|
||||
y22=arg2;
|
||||
} else {
|
||||
y11=arg2;
|
||||
y22=y1;
|
||||
}
|
||||
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
|
||||
down=FALSE;
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
break;
|
||||
case SPBM_COPY:
|
||||
case SPBM_DELETE:
|
||||
if (x1<arg1) {
|
||||
x11=x1;
|
||||
x22=arg1;
|
||||
} else {
|
||||
x11=arg1;
|
||||
x22=x1;
|
||||
}
|
||||
if (y1<arg2) {
|
||||
y11=y1;
|
||||
y22=arg2;
|
||||
} else {
|
||||
y11=arg2;
|
||||
y22=y1;
|
||||
}
|
||||
DCDel(clipboard);
|
||||
clipboard=DCExt(img,x11-xx1,y11-yy1,x22-xx1,y22-yy1);
|
||||
clipboard->bkcolor=bkcolor;
|
||||
if (mode==SPBM_DELETE) {
|
||||
img->color=bkcolor;
|
||||
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
|
||||
}
|
||||
goto bm_menu;
|
||||
case SPBM_CIRCLE:
|
||||
img->color=color;
|
||||
img->pen_width=width;
|
||||
GrCircle3(img,x1-xx1,y1-yy1,0,
|
||||
Sqrt(SqrI64(arg1-x1)+SqrI64(arg2-y1)));
|
||||
down=FALSE;
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
break;
|
||||
case SPBM_PASTE:
|
||||
case SPBM_PASTE_TRANSPARENT:
|
||||
if (clipboard) {
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
if (mode==SPBM_PASTE) {
|
||||
clipboard->flags|=DCF_NO_TRANSPARENTS;
|
||||
GrBlot(img,arg1-xx1,arg2-yy1,clipboard);
|
||||
clipboard->flags&=~DCF_NO_TRANSPARENTS;
|
||||
} else {
|
||||
dc2=DCCopy(clipboard);
|
||||
DCColorChg(dc2,bkcolor);
|
||||
GrBlot(img,arg1-xx1,arg2-yy1,dc2);
|
||||
DCDel(dc2);
|
||||
}
|
||||
GrBitMapEdPrepPersistentDC(dc,xx1,yy1,img);
|
||||
}
|
||||
break;
|
||||
case SPBM_TEXT:
|
||||
img->color=color;
|
||||
GrPrint(img,arg1-xx1,arg2-yy1,"%s",st);
|
||||
goto bm_menu;
|
||||
case SPBM_TEXT_BOX:
|
||||
img->color=color;
|
||||
GrTextBox3(img,arg1-xx1,arg2-yy1,0,st);
|
||||
goto bm_menu;
|
||||
case SPBM_TEXT_DIAMOND:
|
||||
img->color=color;
|
||||
GrTextDiamond3(img,arg1-xx1,arg2-yy1,0,st);
|
||||
goto bm_menu;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
Refresh;
|
||||
}
|
||||
bm_key_up_done:
|
||||
GetMsg(,,1<<MSG_KEY_UP);
|
||||
bm_done:
|
||||
DCDel(clipboard);
|
||||
DCDel(undo);
|
||||
Free(st);
|
||||
DCFill(dc);
|
||||
SettingsPop;
|
||||
doc_e->de_flags=old_de_flags;
|
||||
*_img=img;
|
||||
*_xx1=xx1,*_yy1=yy1,*_xx2=xx2,*_yy2=yy2;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,603 @@
|
||||
#help_index "Graphics/Sprite;Sprites"
|
||||
|
||||
U0 SpriteElem2Code(CDoc *doc,CSprite *tmpg)
|
||||
{
|
||||
U8 buf1[STR_LEN],buf2[STR_LEN];
|
||||
I32 *ptr;
|
||||
I64 i,j,k,col,width_internal;
|
||||
CD3I32 *p;
|
||||
CMeshTri *tri;
|
||||
if (!doc) doc=DocPut;
|
||||
DocPrint(doc,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_CODES");
|
||||
switch (tmpg->type&SPG_TYPE_MASK) {
|
||||
case SPT_COLOR:
|
||||
DocPrint(doc,"{%s}",
|
||||
Color2Str(buf1,tmpg->c.color));
|
||||
break;
|
||||
case SPT_DITHER_COLOR:
|
||||
DocPrint(doc,"{%s}",
|
||||
Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|
|
||||
tmpg->d.dither_color.u8[1]<<COLORROP_BITS));
|
||||
break;
|
||||
case SPT_TRANSFORM_ON:
|
||||
DocPrint(doc,"{ON}");
|
||||
break;
|
||||
case SPT_TRANSFORM_OFF:
|
||||
DocPrint(doc,"{OFF}");
|
||||
break;
|
||||
case SPT_LINE:
|
||||
case SPT_ARROW:
|
||||
case SPT_PLANAR_SYMMETRY:
|
||||
DocPrint(doc,"{(%d,%d),(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,
|
||||
tmpg->pp.x2,tmpg->pp.y2);
|
||||
break;
|
||||
case SPT_RECT:
|
||||
DocPrint(doc,"{(%d,%d):(%d,%d)}",tmpg->pp.x1,tmpg->pp.y1,
|
||||
tmpg->pp.x2-tmpg->pp.x1,tmpg->pp.y2-tmpg->pp.y1);
|
||||
break;
|
||||
case SPT_ROTATED_RECT:
|
||||
DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->ppa.x1,tmpg->ppa.y1,
|
||||
tmpg->ppa.x2-tmpg->ppa.x1,tmpg->ppa.y2-tmpg->ppa.y1,
|
||||
180/ã*Wrap(tmpg->ppa.angle));
|
||||
break;
|
||||
case SPT_PT:
|
||||
case SPT_FLOOD_FILL:
|
||||
case SPT_SHIFT:
|
||||
DocPrint(doc,"{(%d,%d)}",tmpg->p.x1,tmpg->p.y1);
|
||||
break;
|
||||
case SPT_FLOOD_FILL_NOT:
|
||||
DocPrint(doc,"{(%d,%d),TRUE}",tmpg->p.x1,tmpg->p.y1);
|
||||
break;
|
||||
case SPT_CIRCLE:
|
||||
DocPrint(doc,"{(%d,%d):%d}",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);
|
||||
break;
|
||||
case SPT_WIDTH:
|
||||
DocPrint(doc,"{%d}",tmpg->w.width);
|
||||
break;
|
||||
case SPT_ELLIPSE:
|
||||
DocPrint(doc,"{(%d,%d):(%d,%d),%0.4f}",tmpg->pwha.x1,tmpg->pwha.y1,
|
||||
tmpg->pwha.width,tmpg->pwha.height,180/ã*Wrap(tmpg->pwha.angle));
|
||||
break;
|
||||
case SPT_POLYGON:
|
||||
DocPrint(doc,"{%d,(%d,%d):(%d,%d),%0.4f}",tmpg->pwhas.sides,
|
||||
tmpg->pwhas.x1,tmpg->pwhas.y1,
|
||||
tmpg->pwhas.width,tmpg->pwhas.height,
|
||||
180/ã*Wrap(tmpg->pwhas.angle));
|
||||
break;
|
||||
case SPT_TEXT:
|
||||
case SPT_TEXT_BOX:
|
||||
case SPT_TEXT_DIAMOND:
|
||||
DocPrint(doc,"{(%d,%d),\"%Q\"}",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);
|
||||
break;
|
||||
case SPT_POLYLINE:
|
||||
ptr=&tmpg->nu.u;
|
||||
DocPrint(doc,"{");
|
||||
for (i=0;i<tmpg->nu.num;i++,ptr+=2) {
|
||||
DocPrint(doc,"(%d,%d)",ptr[0],ptr[1]);
|
||||
if (i+1<tmpg->nu.num) DocPrint(doc,",");
|
||||
if (i&3==3 && i+1<tmpg->nu.num)
|
||||
DocPrint(doc,"\n");
|
||||
}
|
||||
DocPrint(doc,"}");
|
||||
break;
|
||||
case SPT_BSPLINE2:
|
||||
case SPT_BSPLINE3:
|
||||
case SPT_BSPLINE2_CLOSED:
|
||||
case SPT_BSPLINE3_CLOSED:
|
||||
ptr=&tmpg->nu.u;
|
||||
DocPrint(doc,"{");
|
||||
for (i=0;i<tmpg->nu.num;i++,ptr+=3) {
|
||||
DocPrint(doc,"(%d,%d,%d)",ptr[0],ptr[1],ptr[2]);
|
||||
if (i+1<tmpg->nu.num) DocPrint(doc,",");
|
||||
if (i&3==3 && i+1<tmpg->nu.num)
|
||||
DocPrint(doc,"\n");
|
||||
}
|
||||
if (tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE2||
|
||||
tmpg->type&SPG_TYPE_MASK==SPT_BSPLINE3)
|
||||
DocPrint(doc,",FALSE}");
|
||||
else
|
||||
DocPrint(doc,",TRUE}");
|
||||
break;
|
||||
case SPT_POLYPT:
|
||||
DocPrint(doc,"{(%d,%d),",tmpg->npu.x,tmpg->npu.y);
|
||||
ptr=&tmpg->npu.u;
|
||||
col=16;
|
||||
for (i=0;i<tmpg->npu.num;i++) {
|
||||
DocPrint(doc,"%d",BFieldExtU32(ptr,i*3,3));
|
||||
if (++col>=64 && i+1<tmpg->npu.num) {
|
||||
DocPrint(doc,"\n");
|
||||
col=0;
|
||||
}
|
||||
}
|
||||
DocPrint(doc,"}");
|
||||
break;
|
||||
case SPT_BITMAP:
|
||||
DocPrint(doc,"{(%d,%d):(%d,%d),\n",tmpg->pwhu.x1,tmpg->pwhu.y1,
|
||||
tmpg->pwhu.width,tmpg->pwhu.height);
|
||||
width_internal=(tmpg->pwhu.width+7)&~7;
|
||||
if (width_internal<80)
|
||||
k=width_internal;
|
||||
else
|
||||
k=64;
|
||||
ptr=&tmpg->pwhu.u;
|
||||
col=0;
|
||||
for (j=0;j<tmpg->pwhu.height;j++)
|
||||
for (i=0;i<width_internal;i++,ptr(U8 *)++) {
|
||||
if (i>=tmpg->pwhu.width)
|
||||
DocPrint(doc,"_");
|
||||
else if (*ptr(U8 *)<16)
|
||||
DocPrint(doc,"%X",*ptr(U8 *));
|
||||
else
|
||||
DocPrint(doc,"%c",CH_SHIFT_SPACE);
|
||||
if (++col>=k && (i+1<width_internal||j+1<tmpg->pwhu.height)) {
|
||||
DocPrint(doc,"\n");
|
||||
col=0;
|
||||
}
|
||||
}
|
||||
DocPrint(doc,"}");
|
||||
break;
|
||||
case SPT_MESH:
|
||||
DocPrint(doc,"{FALSE,");
|
||||
p=&tmpg->mu.u;
|
||||
col=0;
|
||||
for (i=0;i<tmpg->mu.vertex_cnt;i++,p++) {
|
||||
DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);
|
||||
if (i+1<tmpg->mu.vertex_cnt) DocPrint(doc,",");
|
||||
if (++col==4) {
|
||||
DocPrint(doc,"\t//%d\n",i);
|
||||
col=0;
|
||||
}
|
||||
}
|
||||
DocPrint(doc,":");
|
||||
tri=p;
|
||||
for (i=0;i<tmpg->mu.tri_cnt;i++,tri++) {
|
||||
DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),
|
||||
tri->nums[0],tri->nums[1],tri->nums[2]);
|
||||
if (i+1<tmpg->mu.tri_cnt) DocPrint(doc,",");
|
||||
if (++col>=3 && i+1<tmpg->mu.tri_cnt) {
|
||||
DocPrint(doc,"\n");
|
||||
col=0;
|
||||
}
|
||||
}
|
||||
DocPrint(doc,"}");
|
||||
break;
|
||||
case SPT_SHIFTABLE_MESH:
|
||||
DocPrint(doc,"{TRUE,(%d,%d,%d):",tmpg->pmu.x,tmpg->pmu.y,tmpg->pmu.z);
|
||||
p=&tmpg->pmu.u;
|
||||
col=1;
|
||||
for (i=0;i<tmpg->pmu.vertex_cnt;i++,p++) {
|
||||
DocPrint(doc,"(%d,%d,%d)",p->x,p->y,p->z);
|
||||
if (i+1<tmpg->pmu.vertex_cnt) DocPrint(doc,",");
|
||||
if (++col==4) {
|
||||
DocPrint(doc,"\t//%d\n",i);
|
||||
col=0;
|
||||
}
|
||||
}
|
||||
DocPrint(doc,":");
|
||||
tri=p;
|
||||
for (i=0;i<tmpg->pmu.tri_cnt;i++,tri++) {
|
||||
DocPrint(doc,"(%s,%d,%d,%d)",Color2Str(buf1,tri->color),
|
||||
tri->nums[0],tri->nums[1],tri->nums[2]);
|
||||
if (i+1<tmpg->pmu.tri_cnt) DocPrint(doc,",");
|
||||
if (++col>=3 && i+1<tmpg->pmu.tri_cnt) {
|
||||
DocPrint(doc,"\n");
|
||||
col=0;
|
||||
}
|
||||
}
|
||||
DocPrint(doc,"}");
|
||||
break;
|
||||
}
|
||||
DocPrint(doc,";\n");
|
||||
}
|
||||
|
||||
public U0 Sprite2Code(CDoc *doc=NULL,U8 *elems)
|
||||
{//Sprite to text.
|
||||
CSprite *tmpg=elems-offset(CSprite.start);
|
||||
while (tmpg->type&SPG_TYPE_MASK) {
|
||||
SpriteElem2Code(doc,tmpg);
|
||||
tmpg(U8 *)+=SpriteElemSize(tmpg);
|
||||
}
|
||||
}
|
||||
|
||||
CSprite *Code2SpriteElem(CCmpCtrl *cc,I64 type)
|
||||
{
|
||||
I64 i,num1,num2,size;
|
||||
CSprite *res,g;
|
||||
CColorROPU32 color;
|
||||
U8 *st,*ptr;
|
||||
CQueD3I32 headp,*tmpp,*tmpa1;
|
||||
CQueMeshTri headt,*tmpt,*tmpt1;
|
||||
CQueVectU8 *tmpv;
|
||||
MemSet(&g,0,sizeof(CSprite));
|
||||
switch (type) {
|
||||
start:
|
||||
case SPT_COLOR:
|
||||
case SPT_DITHER_COLOR:
|
||||
st=LexFirstRem(cc,"}");
|
||||
color=Str2ColorU32(st);
|
||||
Free(st);
|
||||
Lex(cc); //Skip color
|
||||
g.c.color=color.c0.color;
|
||||
if (color&ROPF_DITHER) {
|
||||
g.d.dither_color.u8[1]=color.c1.color;
|
||||
g.type=SPT_DITHER_COLOR;
|
||||
} else
|
||||
g.type=SPT_COLOR;
|
||||
break;
|
||||
case SPT_TRANSFORM_ON:
|
||||
case SPT_TRANSFORM_OFF:
|
||||
Lex(cc); //Skip {
|
||||
if (LexExpressionI64(cc))
|
||||
g.type=SPT_TRANSFORM_ON;
|
||||
else
|
||||
g.type=SPT_TRANSFORM_OFF;
|
||||
break;
|
||||
case SPT_LINE:
|
||||
case SPT_ARROW:
|
||||
case SPT_PLANAR_SYMMETRY:
|
||||
Lex(cc); //Skip {
|
||||
g.type=type;
|
||||
LexD2I32(cc,&g.pp.x1);
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
Lex(cc); //Skip ,
|
||||
LexD2I32(cc,&g.pp.x2);
|
||||
break;
|
||||
case SPT_RECT:
|
||||
case SPT_ROTATED_RECT:
|
||||
Lex(cc); //Skip {
|
||||
LexD2I32(cc,&g.pp.x1);
|
||||
if (cc->token!=':')
|
||||
LexExcept(cc,"Expecting ':' at ");
|
||||
Lex(cc); //Skip :
|
||||
LexD2I32(cc,&g.pp.x2);
|
||||
g.ppa.x2+=g.pp.x1;
|
||||
g.ppa.y2+=g.pp.y1;
|
||||
if (cc->token==',') {
|
||||
Lex(cc); //Skip ,
|
||||
g.ppa.angle=ã/180*LexExpressionF64(cc);
|
||||
g.type=SPT_ROTATED_RECT;
|
||||
} else
|
||||
g.type=SPT_RECT;
|
||||
break;
|
||||
case SPT_PT:
|
||||
case SPT_SHIFT:
|
||||
Lex(cc); //Skip {
|
||||
g.type=type;
|
||||
LexD2I32(cc,&g.p.x1);
|
||||
break;
|
||||
case SPT_FLOOD_FILL:
|
||||
case SPT_FLOOD_FILL_NOT:
|
||||
Lex(cc); //Skip {
|
||||
LexD2I32(cc,&g.p.x1);
|
||||
if (cc->token==',') {
|
||||
Lex(cc); //Skip ,
|
||||
i=LexExpressionI64(cc);
|
||||
} else
|
||||
i=0;
|
||||
if (i)
|
||||
g.type=SPT_FLOOD_FILL_NOT;
|
||||
else
|
||||
g.type=SPT_FLOOD_FILL;
|
||||
break;
|
||||
case SPT_WIDTH:
|
||||
Lex(cc); //Skip {
|
||||
g.w.width=LexExpressionI64(cc);
|
||||
g.type=SPT_WIDTH;
|
||||
break;
|
||||
case SPT_CIRCLE:
|
||||
Lex(cc); //Skip {
|
||||
g.type=SPT_CIRCLE;
|
||||
LexD2I32(cc,&g.pr.x1);
|
||||
if (cc->token!=':')
|
||||
LexExcept(cc,"Expecting ':' at ");
|
||||
Lex(cc); //Skip :
|
||||
g.pr.radius=LexExpressionI64(cc);
|
||||
break;
|
||||
case SPT_POLYGON:
|
||||
Lex(cc); //Skip {
|
||||
g.pwhas.sides=LexExpressionI64(cc);
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
case SPT_ELLIPSE:
|
||||
Lex(cc); //Skip {
|
||||
g.type=type;
|
||||
LexD2I32(cc,&g.pwha.x1);
|
||||
if (cc->token!=':')
|
||||
LexExcept(cc,"Expecting ':' at ");
|
||||
Lex(cc); //Skip :
|
||||
LexD2I32(cc,&g.pwha.width);
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
Lex(cc); //Skip ,
|
||||
g.pwha.angle=ã/180*LexExpressionF64(cc);
|
||||
break;
|
||||
end:
|
||||
size=SpriteElemSize(&g)+offset(CSprite.start);
|
||||
res=MAlloc(size);
|
||||
MemCpy(res,&g,size);
|
||||
break;
|
||||
case SPT_TEXT:
|
||||
case SPT_TEXT_BOX:
|
||||
case SPT_TEXT_DIAMOND:
|
||||
Lex(cc); //Skip {
|
||||
g.type=type;
|
||||
LexD2I32(cc,&g.ps.x1);
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
if (Lex(cc)==TK_STR) //Skip ,
|
||||
st=LexExtStr(cc);
|
||||
else
|
||||
LexExcept(cc,"Expecting string at ");
|
||||
size=SpriteElemQuedBaseSize(type);
|
||||
i=StrLen(st)+1;
|
||||
res=MAlloc(size+i);
|
||||
MemCpy(res,&g,size);
|
||||
MemCpy(res(U8 *)+size,st,i);
|
||||
Free(st);
|
||||
break;
|
||||
case SPT_POLYLINE:
|
||||
Lex(cc); //Skip {
|
||||
g.type=SPT_POLYLINE;
|
||||
QueInit(&headp);
|
||||
while (cc->token=='(') {
|
||||
tmpp=CAlloc(sizeof(CQueD3I32));
|
||||
LexD2I32(cc,&tmpp->p);
|
||||
QueIns(tmpp,headp.last);
|
||||
g.nu.num++;
|
||||
if (cc->token==',')
|
||||
Lex(cc); //Skip ,
|
||||
}
|
||||
if (g.nu.num<2)
|
||||
LexExcept(cc,"Expecting point at ");
|
||||
size=SpriteElemQuedBaseSize(SPT_POLYLINE);
|
||||
res=MAlloc(size+g.nu.num*sizeof(CD2I32));
|
||||
MemCpy(res,&g,size);
|
||||
ptr=&res->nu.u;
|
||||
tmpp=headp.next;
|
||||
while (tmpp!=&headp) {
|
||||
tmpa1=tmpp->next;
|
||||
MemCpy(ptr,&tmpp->p,sizeof(CD2I32));
|
||||
ptr+=sizeof(CD2I32);
|
||||
Free(tmpp);
|
||||
tmpp=tmpa1;
|
||||
}
|
||||
break;
|
||||
case SPT_BSPLINE2:
|
||||
case SPT_BSPLINE3:
|
||||
case SPT_BSPLINE2_CLOSED:
|
||||
case SPT_BSPLINE3_CLOSED:
|
||||
Lex(cc); //Skip {
|
||||
QueInit(&headp);
|
||||
while (cc->token=='(') {
|
||||
tmpp=CAlloc(sizeof(CQueD3I32));
|
||||
LexD3I32(cc,&tmpp->p);
|
||||
QueIns(tmpp,headp.last);
|
||||
g.nu.num++;
|
||||
if (cc->token==',')
|
||||
Lex(cc); //Skip ,
|
||||
}
|
||||
if (g.nu.num<2)
|
||||
LexExcept(cc,"Expecting point at ");
|
||||
size=SpriteElemQuedBaseSize(type);
|
||||
res=MAlloc(size+g.nu.num*sizeof(CD3I32));
|
||||
if (LexExpressionI64(cc)) {
|
||||
if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)
|
||||
g.type=SPT_BSPLINE2_CLOSED;
|
||||
else
|
||||
g.type=SPT_BSPLINE3_CLOSED;
|
||||
} else {
|
||||
if (type==SPT_BSPLINE2||type==SPT_BSPLINE2_CLOSED)
|
||||
g.type=SPT_BSPLINE2;
|
||||
else
|
||||
g.type=SPT_BSPLINE3;
|
||||
}
|
||||
MemCpy(res,&g,size);
|
||||
ptr=&res->nu.u;
|
||||
tmpp=headp.next;
|
||||
while (tmpp!=&headp) {
|
||||
tmpa1=tmpp->next;
|
||||
MemCpy(ptr,&tmpp->p,sizeof(CD3I32));
|
||||
ptr+=sizeof(CD3I32);
|
||||
Free(tmpp);
|
||||
tmpp=tmpa1;
|
||||
}
|
||||
break;
|
||||
case SPT_POLYPT:
|
||||
Lex(cc); //Skip {
|
||||
LexD2I32(cc,&g.npu.x);
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
tmpv=QueVectU8New;
|
||||
while (TRUE) {
|
||||
if (!(i=LexGetChar(cc)))
|
||||
LexExcept(cc,"Expecting '}' at ");
|
||||
if (i=='}')
|
||||
break;
|
||||
if ('0'<=i<='7')
|
||||
QueVectU8Put(tmpv,g.npu.num++,i-'0');
|
||||
}
|
||||
Bts(&cc->flags,CCf_USE_LAST_U16);
|
||||
Lex(cc); //Load '}'
|
||||
g.type=SPT_POLYPT;
|
||||
size=SpriteElemQuedBaseSize(SPT_POLYPT);
|
||||
res=CAlloc(size+(g.npu.num*3+7)>>3);
|
||||
MemCpy(res,&g,size);
|
||||
ptr=&res->npu.u;
|
||||
for (i=0;i<g.npu.num;i++)
|
||||
BFieldOrU32(ptr,i*3,QueVectU8Get(tmpv,i));
|
||||
QueVectU8Del(tmpv);
|
||||
break;
|
||||
case SPT_BITMAP:
|
||||
Lex(cc); //Skip {
|
||||
LexD2I32(cc,&g.pwhu.x1);
|
||||
if (cc->token!=':')
|
||||
LexExcept(cc,"Expecting ':' at ");
|
||||
Lex(cc); //Skip :
|
||||
LexD2I32(cc,&g.pwhu.width);
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
tmpv=QueVectU8New;
|
||||
num1=0;
|
||||
while (TRUE) {
|
||||
if (!(i=ToUpper(LexGetChar(cc))))
|
||||
LexExcept(cc,"Expecting '}' at ");
|
||||
if (i=='}')
|
||||
break;
|
||||
if ('0'<=i<='9')
|
||||
QueVectU8Put(tmpv,num1++,i-'0');
|
||||
else if ('A'<=i<='F')
|
||||
QueVectU8Put(tmpv,num1++,i-'A'+10);
|
||||
else if (i==CH_SPACE||i==CH_SHIFT_SPACE)
|
||||
QueVectU8Put(tmpv,num1++,TRANSPARENT);
|
||||
else if (i=='_')
|
||||
QueVectU8Put(tmpv,num1++,0);
|
||||
}
|
||||
Bts(&cc->flags,CCf_USE_LAST_U16);
|
||||
Lex(cc); //Load '}'
|
||||
g.type=SPT_BITMAP;
|
||||
size=SpriteElemQuedBaseSize(SPT_BITMAP);
|
||||
res=CAlloc(size+num1);
|
||||
MemCpy(res,&g,size);
|
||||
ptr=&res->pwhu.u;
|
||||
for (i=0;i<num1;i++)
|
||||
*ptr++=QueVectU8Get(tmpv,i);
|
||||
QueVectU8Del(tmpv);
|
||||
break;
|
||||
case SPT_MESH:
|
||||
case SPT_SHIFTABLE_MESH:
|
||||
Lex(cc); //Skip {
|
||||
if (LexExpressionI64(cc)) {
|
||||
g.type=SPT_SHIFTABLE_MESH;
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
Lex(cc); //Skip ,
|
||||
LexD3I32(cc,&g.pmu.x);
|
||||
if (cc->token!=':')
|
||||
LexExcept(cc,"Expecting ':' at ");
|
||||
Lex(cc); //Skip :
|
||||
} else {
|
||||
g.type=SPT_MESH;
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
Lex(cc); //Skip ,
|
||||
}
|
||||
num1=0;
|
||||
QueInit(&headp);
|
||||
while (cc->token=='(') {
|
||||
tmpp=CAlloc(sizeof(CQueD3I32));
|
||||
LexD3I32(cc,&tmpp->p);
|
||||
QueIns(tmpp,headp.last);
|
||||
num1++;
|
||||
if (cc->token==',')
|
||||
Lex(cc); //Skip ,
|
||||
}
|
||||
if (cc->token!=':')
|
||||
LexExcept(cc,"Expecting ':' at ");
|
||||
Lex(cc); //Skip :
|
||||
num2=0;
|
||||
QueInit(&headt);
|
||||
while (cc->token=='(') {
|
||||
tmpt=CAlloc(sizeof(CQueMeshTri));
|
||||
st=LexFirstRem(cc,",");
|
||||
tmpt->color=Str2ColorU32(st);
|
||||
Free(st);
|
||||
Lex(cc); //Skip color
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
Lex(cc); //Skip ,
|
||||
tmpt->nums[0]=LexExpressionI64(cc);
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
Lex(cc); //Skip ,
|
||||
tmpt->nums[1]=LexExpressionI64(cc);
|
||||
if (cc->token!=',')
|
||||
LexExcept(cc,"Expecting ',' at ");
|
||||
Lex(cc); //Skip ,
|
||||
tmpt->nums[2]=LexExpressionI64(cc);
|
||||
if (cc->token!=')')
|
||||
LexExcept(cc,"Expecting ')' at ");
|
||||
Lex(cc); //Skip )
|
||||
QueIns(tmpt,headt.last);
|
||||
num2++;
|
||||
if (cc->token==',')
|
||||
Lex(cc); //Skip ,
|
||||
}
|
||||
if (g.type==SPT_MESH) {
|
||||
g.mu.vertex_cnt=num1;
|
||||
g.mu.tri_cnt=num2;
|
||||
size=SpriteElemQuedBaseSize(SPT_MESH);
|
||||
} else {
|
||||
g.pmu.vertex_cnt=num1;
|
||||
g.pmu.tri_cnt=num2;
|
||||
}
|
||||
size=SpriteElemQuedBaseSize(g.type);
|
||||
res=MAlloc(size+num1*sizeof(CD3I32)+num2*sizeof(CMeshTri));
|
||||
MemCpy(res,&g,size);
|
||||
ptr=res(U8 *)+size;
|
||||
tmpp=headp.next;
|
||||
while (tmpp!=&headp) {
|
||||
tmpa1=tmpp->next;
|
||||
MemCpy(ptr,&tmpp->p,sizeof(CD3I32));
|
||||
ptr+=sizeof(CD3I32);
|
||||
Free(tmpp);
|
||||
tmpp=tmpa1;
|
||||
}
|
||||
tmpt=headt.next;
|
||||
while (tmpt!=&headt) {
|
||||
tmpt1=tmpt->next;
|
||||
MemCpy(ptr,&tmpt->start,sizeof(CMeshTri));
|
||||
ptr+=sizeof(CMeshTri);
|
||||
Free(tmpt);
|
||||
tmpt=tmpt1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cc->token!='}')
|
||||
LexExcept(cc,"Expecting '}' at ");
|
||||
if (Lex(cc)!=';')
|
||||
LexExcept(cc,"Expecting ';' at ");
|
||||
return res;
|
||||
}
|
||||
|
||||
public U8 *Code2Sprite(CDoc *doc,I64 *_size=NULL)
|
||||
{//Text to sprite.
|
||||
CSprite head;
|
||||
U8 *res;
|
||||
Bool okay=TRUE,unlock_doc=DocLock(doc);
|
||||
CCmpCtrl *cc=CmpCtrlNew(,CCF_DONT_FREE_BUF);
|
||||
CHashTable *old_hash_table_lst=cc->htc.hash_table_lst;
|
||||
CHashGeneric *tmph;
|
||||
I64 i,size=0;
|
||||
QueInit(&head);
|
||||
LexAttachDoc(cc,,doc);
|
||||
try {
|
||||
do {
|
||||
cc->htc.hash_table_lst=NULL;
|
||||
if (Lex(cc)==TK_IDENT && //Skip ;
|
||||
(tmph=HashFind(cc->cur_str,gr.sprite_hash,SPHT_ELEM_CODE))) {
|
||||
i=tmph->user_data0;
|
||||
cc->htc.hash_table_lst=old_hash_table_lst;
|
||||
if (Lex(cc)=='{') //Skip ident
|
||||
QueIns(Code2SpriteElem(cc,i),head.last);
|
||||
} else if (cc->token)
|
||||
LexExcept(cc,"Expecting sprite element type name at ");
|
||||
} while (cc->token);
|
||||
okay=TRUE;
|
||||
} catch {
|
||||
Fs->catch_except=TRUE;
|
||||
okay=FALSE;
|
||||
}
|
||||
if (unlock_doc)
|
||||
DocUnlock(doc);
|
||||
if (okay) {
|
||||
CmpCtrlDel(cc); //TODO: can crash
|
||||
res=SpriteQue2Sprite(&head,&size);
|
||||
} else {
|
||||
res=NULL;
|
||||
size=0;
|
||||
}
|
||||
if (_size) *_size=size;
|
||||
QueDel(&head);
|
||||
return res;
|
||||
}
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,189 @@
|
||||
#help_index "Graphics/Sprite;Sprites"
|
||||
#help_file "::/Doc/Sprite"
|
||||
|
||||
U8 polypt_map[9]={0,1,2,3,0,4,5,6,7};
|
||||
|
||||
I64 sprite_elem_base_sizes[SPT_TYPES_NUM]={
|
||||
sizeof(CSpriteBase), //SPT_END
|
||||
sizeof(CSpriteColor), //SPT_COLOR
|
||||
sizeof(CSpriteDitherColor), //SPT_DITHER_COLOR
|
||||
sizeof(CSpriteW), //SPT_WIDTH
|
||||
sizeof(CSpritePtPt), //SPT_PLANAR_SYMMETRY
|
||||
sizeof(CSpriteBase), //SPT_TRANSFORM_ON
|
||||
sizeof(CSpriteBase), //SPT_TRANSFORM_OFF
|
||||
sizeof(CSpritePt), //SPT_SHIFT
|
||||
sizeof(CSpritePt), //SPT_PT
|
||||
sizeof(CSpriteNumPtU8s), //SPT_POLYPT
|
||||
sizeof(CSpritePtPt), //SPT_LINE
|
||||
sizeof(CSpriteNumU8s), //SPT_POLYLINE
|
||||
sizeof(CSpritePtPt), //SPT_RECT
|
||||
sizeof(CSpritePtPtAng), //SPT_ROTATED_RECT
|
||||
sizeof(CSpritePtRad), //SPT_CIRCLE
|
||||
sizeof(CSpritePtWHAng), //SPT_ELLIPSE
|
||||
sizeof(CSpritePtWHAngSides), //SPT_POLYGON
|
||||
sizeof(CSpriteNumU8s), //SPT_BSPLINE2
|
||||
sizeof(CSpriteNumU8s), //SPT_BSPLINE2_CLOSED
|
||||
sizeof(CSpriteNumU8s), //SPT_BSPLINE3
|
||||
sizeof(CSpriteNumU8s), //SPT_BSPLINE3_CLOSED
|
||||
sizeof(CSpritePt), //SPT_FLOOD_FILL
|
||||
sizeof(CSpritePt), //SPT_FLOOD_FILL_NOT
|
||||
sizeof(CSpritePtWHU8s), //SPT_BITMAP
|
||||
sizeof(CSpriteMeshU8s), //SPT_MESH
|
||||
sizeof(CSpritePtMeshU8s), //SPT_SHIFTABLE_MESH
|
||||
sizeof(CSpritePtPt), //SPT_ARROW
|
||||
sizeof(CSpritePtStr), //SPT_TEXT
|
||||
sizeof(CSpritePtStr), //SPT_TEXT_BOX
|
||||
sizeof(CSpritePtStr), //SPT_TEXT_DIAMOND
|
||||
};
|
||||
|
||||
I64 SpriteElemQuedBaseSize(I64 type)
|
||||
{
|
||||
return sprite_elem_base_sizes[type&SPG_TYPE_MASK]+offset(CSprite.start);
|
||||
}
|
||||
|
||||
I64 SpriteElemSize(CSprite *tmpg)
|
||||
{
|
||||
I64 i=sprite_elem_base_sizes[tmpg->type&SPG_TYPE_MASK];
|
||||
switch (tmpg->type&SPG_TYPE_MASK) {
|
||||
case SPT_POLYLINE:
|
||||
i+=tmpg->nu.num*sizeof(CD2I32);
|
||||
break;
|
||||
case SPT_TEXT:
|
||||
case SPT_TEXT_BOX:
|
||||
case SPT_TEXT_DIAMOND:
|
||||
i+=StrLen(tmpg->ps.st)+1;
|
||||
break;
|
||||
case SPT_BITMAP:
|
||||
i+=((tmpg->pwhu.width+7)&~7)*tmpg->pwhu.height;
|
||||
break;
|
||||
case SPT_POLYPT:
|
||||
i+=(tmpg->npu.num*3+7)>>3;
|
||||
break;
|
||||
case SPT_BSPLINE2:
|
||||
case SPT_BSPLINE3:
|
||||
case SPT_BSPLINE2_CLOSED:
|
||||
case SPT_BSPLINE3_CLOSED:
|
||||
i+=tmpg->nu.num*sizeof(CD3I32);
|
||||
break;
|
||||
case SPT_MESH:
|
||||
i+=tmpg->mu.vertex_cnt*sizeof(CD3I32)+
|
||||
tmpg->mu.tri_cnt*sizeof(CMeshTri);
|
||||
break;
|
||||
case SPT_SHIFTABLE_MESH:
|
||||
i+=tmpg->pmu.vertex_cnt*sizeof(CD3I32)+
|
||||
tmpg->pmu.tri_cnt*sizeof(CMeshTri);
|
||||
break;
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
public I64 SpriteSize(U8 *elems)
|
||||
{//Walk sprite elements and return size of sprite as binary data.
|
||||
CSprite *tmpg=elems-offset(CSprite.start),*tmpg1=tmpg;
|
||||
while (tmpg->type&SPG_TYPE_MASK)
|
||||
tmpg(U8 *)+=SpriteElemSize(tmpg);
|
||||
return tmpg(U8 *)-tmpg1(U8 *)+sprite_elem_base_sizes[SPT_END];
|
||||
}
|
||||
|
||||
I64 SpriteTypeMask(U8 *elems)
|
||||
{
|
||||
I64 res=0;
|
||||
CSprite *tmpg=elems-offset(CSprite.start);
|
||||
while (tmpg->type&SPG_TYPE_MASK) {
|
||||
if (tmpg->type&SPG_TYPE_MASK>=SPT_TYPES_NUM)
|
||||
return 1<<SPT_TYPES_NUM;
|
||||
Bts(&res,tmpg->type&SPG_TYPE_MASK);
|
||||
tmpg(U8 *)+=SpriteElemSize(tmpg);
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
U0 SpriteSelAll(U8 *elems,Bool val)
|
||||
{
|
||||
CSprite *tmpg=elems-offset(CSprite.start);
|
||||
while (tmpg->type&SPG_TYPE_MASK) {
|
||||
BEqu(&tmpg->type,SPf_SEL,val);
|
||||
tmpg(U8 *)+=SpriteElemSize(tmpg);
|
||||
}
|
||||
}
|
||||
|
||||
public U8 *DC2Sprite(CDC *tmpb)
|
||||
{//Convert device context to sprite.
|
||||
CSprite *tmpg;
|
||||
tmpg=CAlloc(sprite_elem_base_sizes[SPT_BITMAP]+
|
||||
tmpb->width_internal*tmpb->height+
|
||||
sprite_elem_base_sizes[SPT_END])
|
||||
(U8 *)-offset(CSprite.start);
|
||||
tmpg->type=SPT_BITMAP;
|
||||
tmpg->pwhu.width=tmpb->width;
|
||||
tmpg->pwhu.height=tmpb->height;
|
||||
tmpg->pwhu.x1=0;
|
||||
tmpg->pwhu.y1=0;
|
||||
MemCpy(&tmpg->pwhu.u,tmpb->body,tmpb->width_internal*tmpb->height);
|
||||
return tmpg(U8 *)+offset(CSprite.start);
|
||||
}
|
||||
|
||||
public U8 *SpriteElem2Summary(CSprite *tmpg)
|
||||
{//Study $LK,"::/Demo/Graphics/SpriteText.HC"$.
|
||||
U8 buf[STR_LEN],buf2[STR_LEN];
|
||||
I32 *ptr;
|
||||
StrPrint(buf,"%Z",tmpg->type&SPG_TYPE_MASK,"ST_SPRITE_ELEM_TYPES");
|
||||
switch (tmpg->type&SPG_TYPE_MASK) {
|
||||
case SPT_COLOR:
|
||||
CatPrint(buf," %s",Color2Str(buf2,tmpg->c.color));
|
||||
break;
|
||||
case SPT_DITHER_COLOR:
|
||||
CatPrint(buf," %s",Color2Str(buf2,ROPF_DITHER|tmpg->d.dither_color.u8[0]|
|
||||
tmpg->d.dither_color.u8[1]<<COLORROP_BITS));
|
||||
break;
|
||||
case SPT_PT:
|
||||
case SPT_FLOOD_FILL:
|
||||
case SPT_FLOOD_FILL_NOT:
|
||||
case SPT_SHIFT:
|
||||
CatPrint(buf," (%d,%d)",tmpg->p.x1,tmpg->p.y1);
|
||||
break;
|
||||
case SPT_LINE:
|
||||
case SPT_ARROW:
|
||||
case SPT_PLANAR_SYMMETRY:
|
||||
case SPT_RECT:
|
||||
case SPT_ROTATED_RECT:
|
||||
CatPrint(buf," (%d,%d),(%d,%d)",tmpg->pp.x1,tmpg->pp.y1,
|
||||
tmpg->pp.x2,tmpg->pp.y2);
|
||||
break;
|
||||
case SPT_CIRCLE:
|
||||
CatPrint(buf," (%d,%d):%dR",tmpg->pr.x1,tmpg->pr.y1,tmpg->pr.radius);
|
||||
break;
|
||||
case SPT_WIDTH:
|
||||
CatPrint(buf," %d",tmpg->w.width);
|
||||
break;
|
||||
case SPT_TEXT:
|
||||
case SPT_TEXT_BOX:
|
||||
case SPT_TEXT_DIAMOND:
|
||||
CatPrint(buf," %d,%d:%-16tQ",tmpg->ps.x1,tmpg->ps.y1,tmpg->ps.st);
|
||||
break;
|
||||
case SPT_POLYLINE:
|
||||
case SPT_POLYPT:
|
||||
ptr=&tmpg->npu.x;
|
||||
CatPrint(buf," %d (%d,%d)",tmpg->npu.num,ptr[0],ptr[1]);
|
||||
break;
|
||||
case SPT_ELLIPSE:
|
||||
case SPT_POLYGON:
|
||||
case SPT_BITMAP:
|
||||
CatPrint(buf," (%d,%d):%dW,%dH",tmpg->pwhu.x1,tmpg->pwhu.y1,
|
||||
tmpg->pwhu.width,tmpg->pwhu.height);
|
||||
break;
|
||||
case SPT_BSPLINE2:
|
||||
case SPT_BSPLINE3:
|
||||
case SPT_BSPLINE2_CLOSED:
|
||||
case SPT_BSPLINE3_CLOSED:
|
||||
CatPrint(buf," %d",tmpg->nu.num);
|
||||
break;
|
||||
case SPT_MESH:
|
||||
CatPrint(buf," %dV,%dT",tmpg->mu.vertex_cnt,tmpg->mu.tri_cnt);
|
||||
break;
|
||||
case SPT_SHIFTABLE_MESH:
|
||||
CatPrint(buf," %dV,%dT",tmpg->pmu.vertex_cnt,tmpg->pmu.tri_cnt);
|
||||
break;
|
||||
}
|
||||
return StrNew(buf);
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#help_index "Misc/Host"
|
||||
|
||||
public Bool HostChgDsk(U8 *iso_filename)
|
||||
{//Help user change CD/DVD or ISO_file.
|
||||
Bool res=FALSE;
|
||||
SettingsPush; //See $LK,"SettingsPush",A="MN:SettingsPush"$
|
||||
try {
|
||||
AutoComplete;
|
||||
WinBorder;
|
||||
WinMax;
|
||||
DocClear;
|
||||
"$$PURPLE$$$$TX+CX,\"Set to %s\"$$$$FG$$\n\n\n\n",iso_filename;
|
||||
switch (ins_reg.host_vm) {
|
||||
case VM_VMWARE:
|
||||
if (IsDotC(iso_filename))
|
||||
"
|
||||
Click CDROM Icon in bottom-right border of VMware window.
|
||||
|
||||
Click \"Settings\".
|
||||
|
||||
Set ISO image to \"%s\"$FG$.
|
||||
When browsing, change the file mask from \"*.iso\" to \"All Files\".
|
||||
|
||||
",iso_filename;
|
||||
else
|
||||
"
|
||||
Click CDROM Icon in bottom-right border of VMware window.
|
||||
|
||||
Click \"Settings\".
|
||||
|
||||
Set ISO image to \"$FG,2$%s$FG$\"$FG$.
|
||||
|
||||
",iso_filename;
|
||||
break;
|
||||
case VM_QEMU:
|
||||
"
|
||||
Change to QEMU monitor using $FG,2$<CTRL-ALT-2>$FG$
|
||||
|
||||
Get the CDROM designation.
|
||||
|
||||
>$FG,2$info block$FG$
|
||||
|
||||
Use the designation.
|
||||
|
||||
>$FG,2$eject ide1-cd0$FG$
|
||||
|
||||
Use the designation.
|
||||
|
||||
>$FG,2$change ide1-cd0 %s$FG$
|
||||
|
||||
Change back to QEMU using $FG,2$<CTRL-ALT-1>$FG$
|
||||
|
||||
",iso_filename;
|
||||
break;
|
||||
default:
|
||||
"
|
||||
Place the CDDVD %s in the drive.
|
||||
|
||||
",iso_filename;
|
||||
}
|
||||
if (PressAKey!=CH_SHIFT_ESC) {
|
||||
">$FG,2$ChgDsk('T');$FG$\n\n";
|
||||
ChgDsk('T');
|
||||
res=TRUE;
|
||||
}
|
||||
} catch
|
||||
PutExcept;
|
||||
SettingsPop;
|
||||
return res;
|
||||
}
|
||||
@@ -0,0 +1,140 @@
|
||||
#help_index "InFile;Help System/Training"
|
||||
#help_file "::/Doc/InFile"
|
||||
|
||||
public U0 InGetStr(U8 *st)
|
||||
{//Wait for user to type certain str.
|
||||
I64 ch,sc;
|
||||
U8 buf[256],*st2;
|
||||
while (*st) {
|
||||
ch=GetKey(&sc,FALSE);
|
||||
if (sc.u8[0]!=SC_SHIFT &&
|
||||
sc.u8[0]!=SC_ALT &&
|
||||
sc.u8[0]!=SC_CTRL) {
|
||||
if (ch==*st) {
|
||||
'' ch;
|
||||
st++;
|
||||
} else {
|
||||
st2=Char2KeyName(*st);
|
||||
StrPrint(buf,"Press the $$GREEN$$<%s>$$FG$$ key.",st2);
|
||||
Free(st2);
|
||||
PopUpOk(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public U0 InPrint(I64 mS=100,U8 *fmt,...)
|
||||
{//Print message with delay after each char.
|
||||
U8 *buf=StrPrintJoin(NULL,fmt,argc,argv),*st=buf;
|
||||
I64 ch;
|
||||
while (ch=*st++) {
|
||||
'' ch;
|
||||
Sleep(mS);
|
||||
}
|
||||
Free(buf);
|
||||
}
|
||||
|
||||
public U0 InGetKey(I64 scan_code,I64 sc_mask=0xFF|SCF_SHIFT|SCF_CTRL|SCF_ALT)
|
||||
{//Wait for user to press certain key.
|
||||
I64 sc,ch;
|
||||
U8 buf[STR_LEN],*st;
|
||||
do {
|
||||
ch=GetKey(&sc);
|
||||
if (sc.u8[0]!=SC_PRTSCRN1 &&
|
||||
!(sc.u8[0]==SC_SHIFT && scan_code&SCF_SHIFT) &&
|
||||
!(sc.u8[0]==SC_CTRL && scan_code&SCF_CTRL) &&
|
||||
!(sc.u8[0]==SC_ALT && scan_code&SCF_ALT) ) {
|
||||
if (sc&sc_mask!=scan_code&sc_mask) {
|
||||
st=ScanCode2KeyName(scan_code);
|
||||
StrPrint(buf,"Press the $$GREEN$$<%s>$$FG$$ key",st);
|
||||
Free(st);
|
||||
PopUpOk(buf);
|
||||
}
|
||||
}
|
||||
} while (sc&sc_mask!=scan_code&sc_mask);
|
||||
Msg(MSG_KEY_DOWN,ch,sc);
|
||||
}
|
||||
|
||||
public I64 InGetChar(...)
|
||||
{//Wait for user to press one of set of chars.
|
||||
I64 i,sc,ch;
|
||||
U8 buf[512],*st;
|
||||
while (TRUE) {
|
||||
ch=GetKey(&sc);
|
||||
if (sc.u8[0]!=SC_SHIFT && sc.u8[0]!=SC_ALT && sc.u8[0]!=SC_CTRL) {
|
||||
for (i=0;i<argc;i++)
|
||||
if (ch==argv[i]) {
|
||||
Msg(MSG_KEY_DOWN,ch,sc);
|
||||
return ch;
|
||||
}
|
||||
StrPrint(buf,"Press ");
|
||||
for (i=0;i<argc;i++) {
|
||||
st=Char2KeyName(argv[i]);
|
||||
CatPrint(buf,"$$GREEN$$<%s>$$FG$$",st);
|
||||
Free(st);
|
||||
if (argc==i+1)
|
||||
CatPrint(buf,".");
|
||||
else if (argc==i+2)
|
||||
CatPrint(buf," or ");
|
||||
else
|
||||
CatPrint(buf,", ");
|
||||
}
|
||||
PopUpOk(buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public U0 InUntilKey(I64 scan_code,I64 sc_mask=0xFF|SCF_SHIFT|SCF_CTRL|SCF_ALT)
|
||||
{//Let user type until he presses certain key.
|
||||
I64 sc,ch;
|
||||
do {
|
||||
ch=GetKey(&sc);
|
||||
Msg(MSG_KEY_DOWN,ch,sc);
|
||||
} while (sc&sc_mask!=scan_code&sc_mask);
|
||||
}
|
||||
|
||||
public I64 InUntilChar(...)
|
||||
{//Let user type until he presses one of set of chars.
|
||||
I64 i,sc,ch;
|
||||
while (TRUE) {
|
||||
ch=GetKey(&sc);
|
||||
Msg(MSG_KEY_DOWN,ch,sc);
|
||||
for (i=0;i<argc;i++)
|
||||
if (ch==argv[i])
|
||||
return ch;
|
||||
}
|
||||
}
|
||||
|
||||
public Bool InView()
|
||||
{//Let user type until <ESC> or <SHIFT-ESC>.
|
||||
Bool res=View;
|
||||
DocBottom;
|
||||
return res;
|
||||
}
|
||||
|
||||
#help_index "InFile;Help System/Training;Mouse"
|
||||
I64 in_plot_l,in_plot_r;
|
||||
|
||||
Bool InSetMsPlot(I64 mS,I64 x,I64 y,I64 z)
|
||||
{
|
||||
MsSet(x,y,z,in_plot_l,in_plot_r);
|
||||
Sleep(mS);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
public U0 InSetMs(I64 mS=7,I64 x=I64_MAX,I64 y=I64_MAX,I64 z=I64_MAX,
|
||||
I64 l=I64_MAX,I64 r=I64_MAX)
|
||||
{//Move mouse to spot at certain speed.
|
||||
if (!(0<=x<GR_WIDTH))
|
||||
x=ms.pos.x;
|
||||
if (!(0<=y<GR_HEIGHT))
|
||||
y=ms.pos.y;
|
||||
if (z==I64_MAX)
|
||||
z=ms.pos.z;
|
||||
if (!(FALSE<=l<=TRUE))
|
||||
l=ms.lb;
|
||||
if (!(FALSE<=r<=TRUE))
|
||||
r=ms.rb;
|
||||
in_plot_l=l; in_plot_r=r;
|
||||
Line(mS,ms.pos.x,ms.pos.y,ms.pos.z,x,y,z,&InSetMsPlot);
|
||||
}
|
||||
@@ -0,0 +1,64 @@
|
||||
#help_index "Registry/Install Registration"
|
||||
|
||||
public CInsReg ins_reg;
|
||||
MemSet(&ins_reg,0,sizeof(CInsReg));
|
||||
|
||||
DefineLstLoad("ST_HOST_OSES","Other\0Native\0Linux\0Windows\0");
|
||||
DefineLstLoad("ST_HOST_VMS","Other\0Native\0VMware\0QEMU\0VirtualBox\0");
|
||||
|
||||
#define RR_UNREGISTER -1
|
||||
#define RR_REGISTER 0
|
||||
#define RR_REREGISTER 1
|
||||
|
||||
public Bool InsReg(U8 drv_let=0,I64 action=RR_REGISTER)
|
||||
{//Register this install in local $LK,"Registry.HC",A="FI:~/Registry.HC"$ file.
|
||||
CInsReg r;
|
||||
I64 old_drv_let;
|
||||
Bool res=FALSE;
|
||||
|
||||
if (action==RR_UNREGISTER) {
|
||||
MemSet(&r,0,sizeof(CInsReg));
|
||||
res=TRUE;
|
||||
} else if (action==RR_REREGISTER || !ins_reg.registered) {
|
||||
MemCpy(&r,&ins_reg,sizeof(CInsReg));
|
||||
r.registered=TRUE;
|
||||
if (PopUpForm(&r))
|
||||
res=TRUE;
|
||||
}
|
||||
|
||||
if (res) {
|
||||
old_drv_let=*sys_registry_doc->filename.name;
|
||||
if (drv_let)
|
||||
*sys_registry_doc->filename.name=drv_let;
|
||||
RegWrite("Adam/InsReg",
|
||||
"#help_index \"Registry/Install Registration\"\n"
|
||||
"MemSet(&ins_reg,0,sizeof(CInsReg));\n"
|
||||
"ins_reg.registered=%d;\n"
|
||||
"ins_reg.host_os=%d;\n"
|
||||
"ins_reg.host_vm=%d;\n"
|
||||
"\n#define INS_REG_PERSONAL_INITIALS \"%s\"\n"
|
||||
"StrCpy(ins_reg.initials,\"%s\");\n"
|
||||
"HashPublic(\"INS_REG_PERSONAL_INITIALS\",HTT_DEFINE_STR);\n"
|
||||
"\n#define INS_REG_MACHINE_NUM %d\n"
|
||||
"ins_reg.machine_num=%d;\n"
|
||||
"HashPublic(\"INS_REG_MACHINE_NUM\",HTT_DEFINE_STR);\n"
|
||||
"\n\"InsReg:%%s:%%d\\n\","
|
||||
"INS_REG_PERSONAL_INITIALS,INS_REG_MACHINE_NUM;\n"
|
||||
"\n#help_index \"\"\n"
|
||||
,r.registered,r.host_os,r.host_vm,
|
||||
r.initials,r.initials,r.machine_num,r.machine_num);
|
||||
*sys_registry_doc->filename.name=old_drv_let;
|
||||
RegExe("Adam/InsReg");
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
public Bool InsRereg(U8 drv_let=0)
|
||||
{//Reregister this install in local $LK,"Registry.HC",A="FI:~/Registry.HC"$ file.
|
||||
return InsReg(drv_let,RR_REREGISTER);
|
||||
}
|
||||
|
||||
public Bool InsUnreg(U8 drv_let=0)
|
||||
{//Unregister this install in local $LK,"Registry.HC",A="FI:~/Registry.HC"$ file.
|
||||
return InsReg(drv_let,RR_UNREGISTER);
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
Cd(__DIR__);;
|
||||
#include "AExts"
|
||||
#include "AMath"
|
||||
#include "Training"
|
||||
#include "AMem"
|
||||
#include "TaskRep"
|
||||
#include "AMathODE"
|
||||
#include "Gr/MakeGr"
|
||||
#include "Snd/MakeSnd"
|
||||
#include "ABlkDev/MakeABlkDev"
|
||||
#include "Menu"
|
||||
#include "Win"
|
||||
#include "WinMgr"
|
||||
#include "ADbg"
|
||||
#include "::/Adam/God/GodExt"
|
||||
#include "DolDoc/MakeDoc"
|
||||
LBts(&sys_run_level,RLf_DOC);
|
||||
#include "Ctrls/MakeCtrls"
|
||||
#include "InFile"
|
||||
#include "ARegistry"
|
||||
#include "InsReg"
|
||||
#include "AutoComplete/MakeAC"
|
||||
#include "God/MakeGod"
|
||||
#include "AHash"
|
||||
#include "TaskSettings"
|
||||
#include "CPURep"
|
||||
#include "DevInfo"
|
||||
#include "ADefine"
|
||||
#include "WallPaper"
|
||||
#include "AMouse"
|
||||
#include "Host"
|
||||
Cd("..");;
|
||||
@@ -0,0 +1,243 @@
|
||||
#help_index "Menus"
|
||||
#help_file "::/Doc/Menus"
|
||||
|
||||
CTask *MenuTask()
|
||||
{
|
||||
CTask *res=sys_focus_task;
|
||||
while (res && !res->cur_menu)
|
||||
res=res->parent_task;
|
||||
return res;
|
||||
}
|
||||
|
||||
CMenuEntry *sys_cur_submenu_entry=NULL;
|
||||
|
||||
public CMenuEntry *MenuSubEntryFind(
|
||||
CMenuEntry *haystack_first,U8 *needle_entry_name)
|
||||
{//You probably don't need this. Use dir / and $LK,"MenuEntryFind",A="MN:MenuEntryFind"$().
|
||||
while (haystack_first) {
|
||||
if (!StrCmp(haystack_first->name,needle_entry_name))
|
||||
return haystack_first;
|
||||
haystack_first=haystack_first->next;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
public CMenuEntry *MenuEntryFind(CMenu *haystack_menu,U8 *needle_full_name)
|
||||
{//Find pulldown entry. Fs->cur_menu is probably the menu you want.
|
||||
//Just 2 levels -- across top and down are valid, currently.
|
||||
U8 *st,*st2;
|
||||
CMenuEntry *tmpse;
|
||||
if (!haystack_menu || !needle_full_name)
|
||||
return NULL;
|
||||
st=StrNew(needle_full_name);
|
||||
st2=StrNew(needle_full_name);
|
||||
tmpse=(&haystack_menu->sub)(U8 *)-offset(CMenuEntry.sub);
|
||||
while (*st && tmpse) {
|
||||
StrFirstRem(st,"/",st2);
|
||||
tmpse=MenuSubEntryFind(tmpse->sub,st2);
|
||||
}
|
||||
Free(st);
|
||||
Free(st2);
|
||||
return tmpse;
|
||||
}
|
||||
|
||||
CMenuEntry *MenuNewSub(CCmpCtrl *cc,CTask *task)
|
||||
{
|
||||
CMenuEntry *tmpme=NULL,*tmpse;
|
||||
if (cc->token==TK_IDENT) {
|
||||
tmpme=CAlloc(sizeof(CMenuEntry),task);
|
||||
if (StrLen(cc->cur_str)>31)
|
||||
cc->cur_str[31]=0;
|
||||
StrCpy(tmpme->name,cc->cur_str);
|
||||
if (Lex(cc)=='(') {
|
||||
tmpme->msg_code=MSG_KEY_DOWN_UP;
|
||||
if (Lex(cc)!=',' && cc->token!=')')
|
||||
tmpme->msg_code=LexExpressionI64(cc);
|
||||
if (cc->token==',')
|
||||
Lex(cc);
|
||||
if (cc->token!=',' && cc->token!=')')
|
||||
tmpme->arg1=LexExpressionI64(cc);
|
||||
if (cc->token==',')
|
||||
Lex(cc);
|
||||
if (cc->token!=',' && cc->token!=')')
|
||||
tmpme->arg2=LexExpressionI64(cc);
|
||||
if (cc->token!=')')
|
||||
LexExcept(cc,"Missing ')' at ");
|
||||
if (Lex(cc)!=';')
|
||||
LexExcept(cc,"Missing ';' at");
|
||||
Lex(cc); //Skip ;
|
||||
} else if (cc->token=='{') {
|
||||
Lex(cc); //Skip {
|
||||
tmpme->dir=TRUE;
|
||||
tmpse=&tmpme->sub;
|
||||
while (tmpse && cc->token!='}')
|
||||
tmpse=tmpse->next=MenuNewSub(cc,task);
|
||||
if (cc->token!='}')
|
||||
LexExcept(cc,"Missing '}' at ");
|
||||
else
|
||||
Lex(cc); //Skip }
|
||||
} else
|
||||
LexExcept(cc,"Expecting '{' at ");
|
||||
}
|
||||
return tmpme;
|
||||
}
|
||||
|
||||
public CMenu *MenuNew(U8 *st,I64 flags=0,CTask *task=NULL)
|
||||
{//Parse a menu. You probably don't need this.
|
||||
CMenu *m;
|
||||
CMenuEntry *tmpse;
|
||||
CCmpCtrl *cc=CmpCtrlNew(st,CCF_DONT_FREE_BUF);
|
||||
if (!task) task=Fs;
|
||||
Lex(cc);
|
||||
m=CAlloc(sizeof(CMenu),task);
|
||||
m->task=task;
|
||||
m->flags=flags;
|
||||
m->attr =BLUE<<4+YELLOW;
|
||||
tmpse=&m->sub;
|
||||
while (tmpse)
|
||||
tmpse=tmpse->next=MenuNewSub(cc,task);
|
||||
CmpCtrlDel(cc);
|
||||
return m;
|
||||
}
|
||||
|
||||
public CMenu *MenuFile(U8 *filename,I64 flags=0,CTask *task=NULL)
|
||||
{//Parse a pulldown menu file. You probably don't need this.
|
||||
CMenu *m;
|
||||
U8 *st=MStrPrint("#include \"%s\"",filename);
|
||||
m=MenuNew(st,flags,task);
|
||||
Free(st);
|
||||
return m;
|
||||
}
|
||||
|
||||
U0 MenuDelSub(CMenuEntry *tmpme)
|
||||
{
|
||||
CMenuEntry *tmpse,*tmpse1;
|
||||
if (tmpme) {
|
||||
tmpse=tmpme->sub;
|
||||
while (tmpse) {
|
||||
tmpse1=tmpse->next;
|
||||
MenuDelSub(tmpse);
|
||||
tmpse=tmpse1;
|
||||
}
|
||||
Free(tmpme);
|
||||
}
|
||||
}
|
||||
|
||||
public U0 MenuDel(CMenu *m)
|
||||
{//Delete a manu. You probably don't need this.
|
||||
CMenuEntry *tmpme,*tmpme1;
|
||||
if (!m) return;
|
||||
tmpme=m->sub;
|
||||
while (tmpme) {
|
||||
tmpme1=tmpme->next;
|
||||
MenuDelSub(tmpme);
|
||||
tmpme=tmpme1;
|
||||
}
|
||||
Free(m);
|
||||
}
|
||||
|
||||
I64 MenuEntryWidth(CMenuEntry *tmpme)
|
||||
{
|
||||
I64 res=StrLen(tmpme->name);
|
||||
CMenuEntry *tmpse=tmpme->sub;
|
||||
while (tmpse) {
|
||||
res=MaxI64(res,StrLen(tmpse->name));
|
||||
tmpse=tmpse->next;
|
||||
}
|
||||
return res+1;
|
||||
}
|
||||
|
||||
public CMenu *MenuPush(U8 *st)
|
||||
{//Save old pulldown menu and replace with new from str.
|
||||
CMenu *m=MenuNew(st);
|
||||
m->next=Fs->cur_menu;
|
||||
Fs->cur_menu=m;
|
||||
return m;
|
||||
}
|
||||
|
||||
public CMenu *MenuFilePush(U8 *filename)
|
||||
{//Save old pulldown menu and replace with new from file.
|
||||
CMenu *m=MenuFile(filename);
|
||||
m->next=Fs->cur_menu;
|
||||
Fs->cur_menu=m;
|
||||
return m;
|
||||
}
|
||||
|
||||
public U0 MenuPop()
|
||||
{//Restore old pulldown menu. Delete just-deactivated menu.
|
||||
CMenu *m=Fs->cur_menu;
|
||||
if (!m) return;
|
||||
Fs->cur_menu=m->next;
|
||||
MenuDel(m);
|
||||
}
|
||||
|
||||
U0 DrawMenu(CDC *dc)
|
||||
{
|
||||
CMenu *m;
|
||||
CMenuEntry *tmpme,*tmpse,*cur_submenu=NULL;
|
||||
U8 *st=NULL;
|
||||
CTask *task=MenuTask;
|
||||
I64 i,w,x0,y0,x1=ms.pos.x,y1=ms.pos.y;
|
||||
if (!TaskValidate(task) || !(m=task->cur_menu)) {
|
||||
sys_cur_submenu_entry=NULL;
|
||||
return;
|
||||
}
|
||||
dc->color=m->attr>>4;
|
||||
GrRect(dc,0,0,GR_WIDTH,FONT_HEIGHT);
|
||||
x0=0;
|
||||
tmpme=m->sub;
|
||||
while (tmpme) {
|
||||
w=MenuEntryWidth(tmpme)*FONT_WIDTH;
|
||||
if (x0<=x1<x0+w) {
|
||||
if (0<=y1<FONT_HEIGHT) {
|
||||
dc->color=m->attr&15;
|
||||
GrRect(dc,x0,0,w,FONT_HEIGHT);
|
||||
dc->color=m->attr>>4;
|
||||
} else
|
||||
dc->color=m->attr&15;
|
||||
GrPrint(dc,x0,0,"%s",tmpme->name);
|
||||
y0=FONT_HEIGHT;
|
||||
tmpse=tmpme->sub;
|
||||
while (tmpse) {
|
||||
if (tmpse->checked)
|
||||
i=m->attr^0xFF;
|
||||
else
|
||||
i=m->attr;
|
||||
if (y0<=y1<y0+FONT_HEIGHT) {
|
||||
if (tmpse->msg_code==MSG_KEY_DOWN||
|
||||
tmpse->msg_code==MSG_KEY_DOWN_UP) {
|
||||
if (!tmpse->arg2)
|
||||
tmpse->arg2=Char2ScanCode(tmpse->arg1);
|
||||
st=ScanCode2KeyName(tmpse->arg2);
|
||||
}
|
||||
sys_cur_submenu_entry=cur_submenu=tmpse;
|
||||
dc->color=i&15;
|
||||
GrRect(dc,x0,y0,w,FONT_HEIGHT);
|
||||
dc->color=i>>4;
|
||||
GrPrint(dc,x0,y0,"%s",tmpse->name);
|
||||
if (st) {
|
||||
dc->color=i>>4;
|
||||
GrRect(dc,x0+w,y0-FONT_HEIGHT,
|
||||
(StrLen(st)+1)*FONT_WIDTH,FONT_HEIGHT*3);
|
||||
dc->color=i&15;
|
||||
GrPrint(dc,x0+w,y0,"%s",st);
|
||||
Free(st);
|
||||
}
|
||||
} else {
|
||||
dc->color=i>>4;
|
||||
GrRect(dc,x0,y0,w,FONT_HEIGHT);
|
||||
dc->color=i&15;
|
||||
GrPrint(dc,x0,y0,"%s",tmpse->name);
|
||||
}
|
||||
y0+=FONT_HEIGHT;
|
||||
tmpse=tmpse->next;
|
||||
}
|
||||
} else {
|
||||
dc->color=m->attr&15;
|
||||
GrPrint(dc,x0,0,"%s",tmpme->name);
|
||||
}
|
||||
x0+=w;
|
||||
tmpme=tmpme->next;
|
||||
}
|
||||
sys_cur_submenu_entry=cur_submenu;
|
||||
}
|
||||
@@ -0,0 +1,188 @@
|
||||
#define BOOT_HIGH_LOC_DVD ((BOOT_RAM_LIMIT-\
|
||||
(BOOT_STK_SIZE+DVD_BOOT_LOADER_SIZE))>>4)
|
||||
|
||||
DefinePrint(
|
||||
"DD_BOOT_HIGH_LOC_DVD","%08X",BOOT_HIGH_LOC_DVD<<4);
|
||||
DefinePrint(
|
||||
"DD_BOOT_HIGH_LOC_DVD_END","%08X",BOOT_RAM_LIMIT-1);
|
||||
|
||||
asm {
|
||||
USE16
|
||||
BDVD_START::
|
||||
//DL is supposed to have the BIOS drive number
|
||||
CLD
|
||||
MOV AX,BOOT_HIGH_LOC_DVD
|
||||
MOV ES,AX
|
||||
|
||||
CLI
|
||||
MOV SS,AX
|
||||
MOV SP,BOOT_STK_SIZE+DVD_BOOT_LOADER_SIZE
|
||||
STI
|
||||
|
||||
CALL BDVD_GET_RIP
|
||||
BDVD_GET_RIP:
|
||||
POP BX
|
||||
SUB BX,BDVD_GET_RIP-BDVD_START
|
||||
SHR BX,4
|
||||
//This copies this bootloader's code to 0x$TX,"00096600",D="DD_BOOT_HIGH_LOC_DVD"$
|
||||
MOV AX,CS
|
||||
ADD AX,BX
|
||||
MOV DS,AX
|
||||
MOV CX,DVD_BOOT_LOADER_SIZE
|
||||
XOR SI,SI
|
||||
XOR DI,DI
|
||||
REP_MOVSB
|
||||
|
||||
MOV AX,BOOT_HIGH_LOC_DVD
|
||||
MOV DS,AX
|
||||
|
||||
//My assembler doesn't support 16-bit very well.
|
||||
DU8 0xEA; //JMP BOOT_HIGH_LOC_DVD:BDVD_MAIN
|
||||
DU16 BDVD_MAIN-BDVD_START,BOOT_HIGH_LOC_DVD;
|
||||
|
||||
BDVD_BIOS_DRV_NUM: DU8 0;
|
||||
BDVD_PAGE: DU8 0;
|
||||
|
||||
BDVD_DAP: DU8 16,0,1,0; //One blk at a time
|
||||
BDVD_DAP_BUF: DU16 0,0;
|
||||
BDVD_DAP_BLK: DU64 0;
|
||||
|
||||
BDVD_TEMPLEOS_MSG:
|
||||
DU8 "Loading TempleOS",0;
|
||||
|
||||
BDVD_NOT64_MSG:
|
||||
DU8 "TempleOS requires a 64-bit capable processor.\n\r",0;
|
||||
|
||||
//These get patched.
|
||||
BDVD_BLK_LO:: DU16 0;
|
||||
BDVD_BLK_HI:: DU16 0;
|
||||
BDVD_BLK_CNT:: DU16 0;
|
||||
BDVD_SHIFT_BLKS:: DU16 0;
|
||||
BDVD_PROGRESS_STEP:: DU32 0;
|
||||
BDVD_PROGRESS_VAL:: DU32 0;
|
||||
|
||||
BDVD_PUT_CHAR::
|
||||
MOV AH,0xE
|
||||
MOV BL,7 //Might be foreground color on some BIOS's
|
||||
MOV BH,U8 [BDVD_PAGE-BDVD_START]
|
||||
INT 0x10
|
||||
BDVD_RET::
|
||||
RET
|
||||
BDVD_PUTS::
|
||||
@@1: LODSB
|
||||
TEST AL,AL
|
||||
JZ BDVD_RET
|
||||
CALL BDVD_PUT_CHAR
|
||||
JMP @@1
|
||||
|
||||
BDVD_MAIN::
|
||||
MOV U8 [BDVD_BIOS_DRV_NUM-BDVD_START],DL //Passed in by BIOS
|
||||
|
||||
MOV AH,0xF
|
||||
INT 0x10
|
||||
MOV U8 [BDVD_PAGE-BDVD_START],BH //Video page
|
||||
|
||||
MOV EAX,0x80000000
|
||||
CPUID
|
||||
CMP EAX,0x80000001
|
||||
JB @@05
|
||||
|
||||
MOV EAX,0x80000001
|
||||
CPUID
|
||||
BT EDX,29
|
||||
JC @@15
|
||||
@@05: MOV SI,BDVD_NOT64_MSG-BDVD_START
|
||||
CALL BDVD_PUTS
|
||||
@@10: JMP @@10
|
||||
|
||||
@@15: MOV SI,BDVD_TEMPLEOS_MSG-BDVD_START
|
||||
CALL BDVD_PUTS
|
||||
|
||||
MOV AX,BOOT_RAM_BASE/16
|
||||
MOV ES,AX
|
||||
XOR ECX,ECX
|
||||
MOV CX,U16 [BDVD_BLK_CNT-BDVD_START]
|
||||
|
||||
MOV EAX,(80-7-9)*65536 //80 columns
|
||||
XOR EDX,EDX
|
||||
DIV ECX
|
||||
MOV U32 [BDVD_PROGRESS_STEP-BDVD_START],EAX
|
||||
MOV U32 [BDVD_PROGRESS_VAL-BDVD_START],0
|
||||
|
||||
MOV AX,U16 [BDVD_BLK_LO-BDVD_START]
|
||||
MOV DX,U16 [BDVD_BLK_HI-BDVD_START]
|
||||
|
||||
@@20: PUSH CX //Blk cnt
|
||||
|
||||
//READ BLK
|
||||
PUSH AX //Blk lo
|
||||
PUSH DX //Blk hi
|
||||
PUSH ES //Buf seg
|
||||
MOV U16 [BDVD_DAP_BLK-BDVD_START],AX
|
||||
MOV U16 [BDVD_DAP_BLK+2-BDVD_START],DX
|
||||
MOV AX,ES
|
||||
MOV U16 [BDVD_DAP_BUF+2-BDVD_START],AX //ES:0000
|
||||
MOV SI,BDVD_DAP-BDVD_START //DS:SI=DAP
|
||||
MOV AH,0x42
|
||||
MOV DL,U8 [BDVD_BIOS_DRV_NUM-BDVD_START]
|
||||
INT 0x13
|
||||
|
||||
POP AX //ES
|
||||
ADD AX,DVD_BLK_SIZE/16
|
||||
MOV ES,AX
|
||||
POP DX
|
||||
POP AX
|
||||
INC AX
|
||||
JNZ @@25
|
||||
INC DX
|
||||
|
||||
@@25: PUSH AX
|
||||
MOV BX,U16 [BDVD_PROGRESS_VAL+2-BDVD_START]
|
||||
MOV EAX,U32 [BDVD_PROGRESS_STEP-BDVD_START]
|
||||
ADD U32 [BDVD_PROGRESS_VAL-BDVD_START],EAX
|
||||
CMP U16 [BDVD_PROGRESS_VAL+2-BDVD_START],BX
|
||||
JE @@30
|
||||
MOV AL,'.'
|
||||
CALL BDVD_PUT_CHAR
|
||||
@@30: POP AX
|
||||
|
||||
POP CX
|
||||
LOOP @@20
|
||||
|
||||
//Shift backward to align
|
||||
PUSH DS
|
||||
MOV BX,U16 [BDVD_SHIFT_BLKS-BDVD_START]
|
||||
SHL BX,BLK_SIZE_BITS-4
|
||||
MOV CX,U16 [BDVD_BLK_CNT-BDVD_START]
|
||||
MOV AX,BOOT_RAM_BASE/16
|
||||
MOV ES,AX
|
||||
ADD AX,BX
|
||||
MOV DS,AX
|
||||
@@35: PUSH CX
|
||||
XOR SI,SI
|
||||
XOR DI,DI
|
||||
MOV CX,DVD_BLK_SIZE/4
|
||||
REP_MOVSD
|
||||
MOV AX,DS
|
||||
ADD AX,DVD_BLK_SIZE/16
|
||||
MOV DS,AX
|
||||
MOV AX,ES
|
||||
ADD AX,DVD_BLK_SIZE/16
|
||||
MOV ES,AX
|
||||
POP CX
|
||||
LOOP @@35
|
||||
POP DS
|
||||
|
||||
//See $LK,"BootDVDProbe",A="MN:BootDVDProbe"$().
|
||||
MOV EBX,U32 [BDVD_BLK_LO-BDVD_START]
|
||||
MOV AX,U16 [BDVD_SHIFT_BLKS-BDVD_START]
|
||||
SHL EAX,16
|
||||
MOV AX,BOOT_SRC_DVD //$MA-X+PU,"See sys_boot_src",LM="Find(\"sys_boot_src\",\"/*\");View;\n"$
|
||||
|
||||
//My assembler doesn't support 16-bit very well.
|
||||
DU8 0xEA; //JMP BOOT_RAM_BASE:0000
|
||||
DU16 0,BOOT_RAM_BASE/16;
|
||||
//Continues here $LK,"::/Kernel/KStart16.HC",A="FL:::/Kernel/KStart16.HC,1"$
|
||||
BDVD_END::
|
||||
#assert BDVD_END-BDVD_START<DVD_BOOT_LOADER_SIZE
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
//See $LK,"Install Documentation",A="FI:::/Doc/Install.DD"$ or $LK,"Upgrading Documentation",A="FI:::/Doc/Upgrade.DD"$.
|
||||
//Study my account examples: $LK,"Cfg Strs",A="FL:::/Demo/AcctExample/TOS/TOSCfg.HC,1"$, $LK,"Update Funs",A="FL:::/Demo/AcctExample/TOS/TOSDistro.HC,1"$
|
||||
|
||||
#include "BootDVD"
|
||||
#include "DskISORedSea"
|
||||
#include "DskISO9660"
|
||||
|
||||
#help_index "Install"
|
||||
|
||||
#define KERNEL_BIN_C "Kernel.BIN.C"
|
||||
#define BOOT_DIR "/0000Boot"
|
||||
#define BOOT_DIR_KERNEL_BIN_C BOOT_DIR "/0000" KERNEL_BIN_C
|
||||
|
||||
U0 MakeAll()
|
||||
{
|
||||
if (Cmp("/Compiler/Compiler","Compiler",,':'))
|
||||
throw;
|
||||
if (Cmp("/Kernel/Kernel","Kernel",,':'))
|
||||
throw;
|
||||
}
|
||||
|
||||
public U0 BootDVDIns(U8 drv_let=0)
|
||||
{//See $LK,"::/Misc/DoDistro.HC"$.
|
||||
try {
|
||||
if (!Drv(drv_let))
|
||||
throw;
|
||||
MakeAll;
|
||||
Move("/Kernel/Kernel.BIN.Z",BOOT_DIR_KERNEL_BIN_C);
|
||||
} catch {
|
||||
PutExcept;
|
||||
Beep;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,93 @@
|
||||
#define MODULE_SIZE 1*BLK_SIZE
|
||||
#define BOOT_HIGH_LOC_HD ((BOOT_RAM_LIMIT-\
|
||||
(BOOT_STK_SIZE+MODULE_SIZE))>>4)
|
||||
|
||||
DefinePrint(
|
||||
"DD_BOOT_HIGH_LOC_HD","%08X",BOOT_HIGH_LOC_HD<<4);
|
||||
|
||||
asm {
|
||||
USE16
|
||||
BHD_CODE::
|
||||
|
||||
#define BHD_START (BHD_CODE-offset(CFAT32Boot.code))
|
||||
|
||||
CLD
|
||||
|
||||
MOV AX,BOOT_HIGH_LOC_HD
|
||||
MOV ES,AX
|
||||
|
||||
CLI
|
||||
MOV SS,AX
|
||||
MOV SP,BOOT_STK_SIZE+MODULE_SIZE
|
||||
STI
|
||||
|
||||
CALL BHD_GET_RIP
|
||||
BHD_GET_RIP:
|
||||
POP BX
|
||||
SUB BX,BHD_GET_RIP-BHD_START
|
||||
SHR BX,4
|
||||
//This copies this bootloader's code to 0x$TX,"00096C00",D="DD_BOOT_HIGH_LOC_HD"$
|
||||
MOV AX,CS
|
||||
ADD AX,BX
|
||||
MOV DS,AX
|
||||
MOV CX,MODULE_SIZE
|
||||
XOR SI,SI
|
||||
XOR DI,DI
|
||||
REP_MOVSB
|
||||
|
||||
MOV AX,BOOT_HIGH_LOC_HD
|
||||
MOV DS,AX
|
||||
|
||||
//My assembler doesn't support 16-bit very well.
|
||||
DU8 0xEA; //JMP BOOT_HIGH_LOC_HD:BHD_HISTART
|
||||
DU16 BHD_HISTART-BHD_START,BOOT_HIGH_LOC_HD;
|
||||
|
||||
BHD_BIOS_DRV_NUM: DU8 0;
|
||||
|
||||
//Gets patched by $LK,"BootHDIns",A="MN:BootHDIns"$().
|
||||
BHD_BLK_CNT:: DU16 0;
|
||||
|
||||
BHD_DAP: DU8 16,0,1,0; //One blk at a time
|
||||
BHD_DAP_BUF: DU16 0,0;
|
||||
//Gets patched by $LK,"BootHDIns",A="MN:BootHDIns"$().
|
||||
BHD_DAP_BLK:: //64-bit
|
||||
BHD_DAP_BLK_LO: DU32 0;
|
||||
BHD_DAP_BLK_HI: DU32 0;
|
||||
|
||||
BHD_HISTART:
|
||||
MOV U8 [BHD_BIOS_DRV_NUM-BHD_START],DL //Passed in by BIOS
|
||||
MOV AX,BOOT_RAM_BASE/16
|
||||
MOV ES,AX
|
||||
XOR ECX,ECX
|
||||
MOV CX,U16 [BHD_BLK_CNT-BHD_START]
|
||||
|
||||
@@05: PUSH CX //Blk cnt
|
||||
|
||||
//READ BLK
|
||||
PUSH ES //Buf seg
|
||||
MOV AX,ES
|
||||
MOV U16 [BHD_DAP_BUF+2-BHD_START],AX //ES:0000
|
||||
MOV SI,BHD_DAP-BHD_START //DS:SI=DAP
|
||||
MOV AH,0x42
|
||||
MOV DL,U8 [BHD_BIOS_DRV_NUM-BHD_START]
|
||||
INT 0x13
|
||||
|
||||
POP AX //ES
|
||||
ADD AX,BLK_SIZE/16
|
||||
MOV ES,AX
|
||||
INC U32 [BHD_DAP_BLK_LO-BHD_START]
|
||||
JNZ @@10
|
||||
INC U32 [BHD_DAP_BLK_HI-BHD_START]
|
||||
|
||||
@@10: POP CX
|
||||
LOOP @@05
|
||||
|
||||
XOR EBX,EBX
|
||||
MOV EAX,BOOT_SRC_HARDDRV //$MA-X+PU,"See sys_boot_src",LM="Find(\"sys_boot_src\",\"/*\");View;\n"$
|
||||
//My assembler doesn't support 16-bit very well.
|
||||
DU8 0xEA; //JMP BOOT_RAM_BASE:0000
|
||||
DU16 0,BOOT_RAM_BASE/16;
|
||||
//Continues here $LK,"::/Kernel/KStart16.HC",A="FL:::/Kernel/KStart16.HC,1"$
|
||||
BHD_END::
|
||||
#assert BHD_END-BHD_START<MODULE_SIZE-2
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
//See $LK,"Install Documentation",A="FI:::/Doc/Install.DD"$ or $LK,"Upgrading Documentation",A="FI:::/Doc/Upgrade.DD"$.
|
||||
//Study my account examples: $LK,"Cfg Strs",A="FL:::/Demo/AcctExample/TOS/TOSCfg.HC,1"$, $LK,"Update Funs",A="FL:::/Demo/AcctExample/TOS/TOSDistro.HC,1"$
|
||||
|
||||
#include "BootHD"
|
||||
|
||||
#help_index "Install"
|
||||
|
||||
#define KERNEL_BIN_C "Kernel.BIN.C"
|
||||
|
||||
U0 MakeAll()
|
||||
{
|
||||
if (Cmp("/Compiler/Compiler","Compiler",,':'))
|
||||
throw;
|
||||
if (Cmp("/Kernel/Kernel","Kernel",,':'))
|
||||
throw;
|
||||
}
|
||||
|
||||
public U0 BootHDIns(U8 drv_let=0)
|
||||
{//$LK,"MakeAll",A="MN:MakeAll"$ and install new boot-loader.
|
||||
CDrv *dv;
|
||||
CFAT32Boot br;
|
||||
CDirEntry de;
|
||||
I64 i;
|
||||
try {
|
||||
if (!Drv(drv_let))
|
||||
throw;
|
||||
dv=Fs->cur_dv;
|
||||
MakeAll;
|
||||
switch (Let2BlkDevType(dv->drv_let)) {
|
||||
case BDT_RAM:
|
||||
case BDT_ATA:
|
||||
Move("/Kernel/Kernel.BIN.Z","/" KERNEL_BIN_C);
|
||||
if (!FileFind("/" KERNEL_BIN_C,&de,FUF_JUST_FILES))
|
||||
"No Kernel.BIN.C\n";
|
||||
else {
|
||||
Free(de.full_name);
|
||||
"Modifying partition boot record.\n";
|
||||
RBlks(dv,&br,dv->drv_offset,1);
|
||||
br.jump_and_nop[0]=OC_JMP_REL8;
|
||||
br.jump_and_nop[1]=offset(CFAT32Boot.code)-2;
|
||||
#assert offset(CFAT32Boot.code)>=offset(CRedSeaBoot.code)
|
||||
br.jump_and_nop[2]=OC_NOP;
|
||||
*BHD_BLK_CNT(U16 *)=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
|
||||
*BHD_DAP_BLK(I64 *)=Cluster2Blk(dv,de.cluster);
|
||||
for (i=0;i<BHD_END-BHD_CODE;i++)
|
||||
br.code[i]=BHD_CODE(U8 *)[i];
|
||||
#assert sizeof(CFAT32Boot.code)>=BHD_END-BHD_CODE
|
||||
for (;i<sizeof(CFAT32Boot.code);i++)
|
||||
br.code[i]=0;
|
||||
WBlks(dv,&br,dv->drv_offset,1);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw;
|
||||
}
|
||||
} catch {
|
||||
PutExcept;
|
||||
Beep;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,107 @@
|
||||
#define MODULE_SIZE 1*BLK_SIZE
|
||||
#define BOOT_HIGH_LOC_MHD ((BOOT_RAM_LIMIT-\
|
||||
(BOOT_STK_SIZE+MODULE_SIZE))>>4)
|
||||
|
||||
DefinePrint(
|
||||
"DD_BOOT_HIGH_LOC_MHD","%08X",BOOT_HIGH_LOC_MHD<<4);
|
||||
|
||||
asm {
|
||||
USE16
|
||||
BMHD_START::
|
||||
BMHD_CODE::
|
||||
CLD
|
||||
|
||||
MOV AX,BOOT_HIGH_LOC_MHD
|
||||
|
||||
CLI
|
||||
MOV SS,AX
|
||||
MOV SP,BOOT_STK_SIZE+MODULE_SIZE
|
||||
STI
|
||||
|
||||
PUSHFW
|
||||
PUSH DS
|
||||
PUSH ES
|
||||
PUSH FS
|
||||
PUSH GS
|
||||
PUSH ECX
|
||||
PUSH EBX
|
||||
PUSH EDX
|
||||
PUSH EBP
|
||||
|
||||
MOV ES,AX
|
||||
|
||||
CALL BMHD_GET_RIP
|
||||
BMHD_GET_RIP:
|
||||
POP BX
|
||||
SUB BX,BMHD_GET_RIP-BMHD_START
|
||||
MOV CX,BX
|
||||
SHR BX,4
|
||||
//This copies this bootloader's code to 0x$TX,"00096C00",D="DD_BOOT_HIGH_LOC_MHD"$
|
||||
MOV AX,CS
|
||||
PUSH AX
|
||||
ADD AX,BX
|
||||
MOV DS,AX
|
||||
MOV U16 [BMHD_OLD_CS_RIP-BMHD_START],CX
|
||||
POP U16 [BMHD_OLD_CS_RIP+2-BMHD_START]
|
||||
|
||||
MOV CX,MODULE_SIZE
|
||||
XOR SI,SI
|
||||
XOR DI,DI
|
||||
REP_MOVSB
|
||||
|
||||
MOV AX,BOOT_HIGH_LOC_MHD
|
||||
MOV DS,AX
|
||||
|
||||
//My assembler doesn't support 16-bit very well.
|
||||
DU8 0xEA; //JMP BOOT_HIGH_LOC_MHD:BMHD_HISTART
|
||||
DU16 BMHD_HISTART-BMHD_START,BOOT_HIGH_LOC_MHD;
|
||||
|
||||
BMHD_BIOS_DRV_NUM: DU8 0;
|
||||
BMHD_OLD_CS_RIP: DU16 0,0;
|
||||
//Gets patched by $LK,"BootHDIns",A="MN:BootHDIns"$().
|
||||
BMHD_BLK_CNT:: DU16 0;
|
||||
|
||||
BMHD_DAP: DU8 16,0,1,0; //One blk at a time
|
||||
BMHD_DAP_BUF: DU16 0,0;
|
||||
//Gets patched by $LK,"BootHDIns",A="MN:BootHDIns"$().
|
||||
BMHD_DAP_BLK:: //64-bit
|
||||
BMHD_DAP_BLK_LO: DU32 0;
|
||||
BMHD_DAP_BLK_HI: DU32 0;
|
||||
|
||||
BMHD_HISTART:
|
||||
MOV U8 [BMHD_BIOS_DRV_NUM-BMHD_START],DL //Passed in by BIOS
|
||||
MOV AX,BOOT_RAM_BASE/16
|
||||
MOV ES,AX
|
||||
XOR ECX,ECX
|
||||
MOV CX,U16 [BMHD_BLK_CNT-BMHD_START]
|
||||
|
||||
@@05: PUSH CX //Blk cnt
|
||||
|
||||
//READ BLK
|
||||
PUSH ES //Buf seg
|
||||
MOV AX,ES
|
||||
MOV U16 [BMHD_DAP_BUF+2-BMHD_START],AX //ES:0000
|
||||
MOV SI,BMHD_DAP-BMHD_START //DS:SI=DAP
|
||||
MOV AH,0x42
|
||||
MOV DL,U8 [BMHD_BIOS_DRV_NUM-BMHD_START]
|
||||
INT 0x13
|
||||
|
||||
POP AX //ES
|
||||
ADD AX,BLK_SIZE/16
|
||||
MOV ES,AX
|
||||
INC U32 [BMHD_DAP_BLK_LO-BMHD_START]
|
||||
JNZ @@10
|
||||
INC U32 [BMHD_DAP_BLK_HI-BMHD_START]
|
||||
|
||||
@@10: POP CX
|
||||
LOOP @@05
|
||||
|
||||
MOV DL,U8 [BMHD_BIOS_DRV_NUM-BMHD_START]
|
||||
MOV EBX,U32 [BMHD_OLD_CS_RIP-BMHD_START]
|
||||
//My assembler doesn't support 16-bit very well.
|
||||
DU8 0xEA; //JMP BOOT_RAM_BASE:0000
|
||||
DU16 0,BOOT_RAM_BASE/16;
|
||||
//Continues here $LK,"BMHD2_START",A="FF:::/Adam/Opt/Boot/BootMHD2.HC,BMHD2_START"$
|
||||
BMHD_END::
|
||||
#assert BMHD_END-BMHD_START<=440
|
||||
}
|
||||
@@ -0,0 +1,123 @@
|
||||
#define MODULE_SIZE 2*BLK_SIZE
|
||||
#define BOOT_HIGH_LOC_MHD2 ((BOOT_RAM_LIMIT-\
|
||||
(BOOT_STK_SIZE+MODULE_SIZE))>>4)
|
||||
|
||||
DefinePrint(
|
||||
"DD_BOOT_HIGH_LOC_MHD2","%08X",BOOT_HIGH_LOC_MHD2<<4);
|
||||
|
||||
asm {
|
||||
USE16
|
||||
BMHD2_START::
|
||||
MOV U32 FS:[0],'B'+0x2000+('2'+0x2000)<<16
|
||||
|
||||
MOV AX,BOOT_HIGH_LOC_MHD2
|
||||
MOV ES,AX
|
||||
//This copies this bootloader's code to 0x$TX,"00096A00",D="DD_BOOT_HIGH_LOC_MHD2"$
|
||||
MOV AX,CS
|
||||
MOV DS,AX
|
||||
MOV U32 [BMHD2_OLD_CS_RIP-BMHD2_START],EBX
|
||||
MOV U8 [BMHD2_BIOS_DRV_NUM-BMHD2_START],DL
|
||||
|
||||
MOV CX,MODULE_SIZE
|
||||
XOR SI,SI
|
||||
XOR DI,DI
|
||||
REP_MOVSB
|
||||
|
||||
MOV AX,BOOT_HIGH_LOC_MHD2
|
||||
MOV DS,AX
|
||||
|
||||
//My assembler doesn't support 16-bit very well.
|
||||
DU8 0xEA; //JMP BOOT_HIGH_LOC_MHD2:BMHD2_HISTART
|
||||
DU16 BMHD2_HISTART-BMHD2_START,BOOT_HIGH_LOC_MHD2;
|
||||
|
||||
BMHD2_BOOT_MSG::
|
||||
DU8 256 DUP(0);
|
||||
|
||||
BMHD2_BIOS_DRV_NUM: DU8 0;
|
||||
BMHD2_PAGE: DU8 0;
|
||||
BMHD2_BLK_ARRAY:: DU64 8 DUP(0);
|
||||
|
||||
BMHD2_DAP: DU8 16,0,1,0; //One blk at a time
|
||||
BMHD2_DAP_BUF: DU16 0,0;
|
||||
BMHD2_DAP_BLK:: //64-bit
|
||||
BMHD2_DAP_BLK_LO: DU32 0;
|
||||
BMHD2_DAP_BLK_HI: DU32 0;
|
||||
|
||||
BMHD2_PUT_CHAR::
|
||||
MOV AH,0xE
|
||||
MOV BL,7 //Might be foreground color on some BIOS's
|
||||
MOV BH,U8 [BMHD2_PAGE-BMHD2_START]
|
||||
INT 0x10
|
||||
BMHD2_RET::
|
||||
RET
|
||||
BMHD2_PUTS::
|
||||
@@1: LODSB
|
||||
TEST AL,AL
|
||||
JZ BMHD2_RET
|
||||
CALL BMHD2_PUT_CHAR
|
||||
JMP @@1
|
||||
|
||||
BMHD2_GETCHAR:
|
||||
XOR AH,AH
|
||||
INT 0x16
|
||||
PUSH AX
|
||||
MOV AH,0x0E
|
||||
MOV BX,0x07
|
||||
INT 0x10
|
||||
POP AX
|
||||
RET
|
||||
|
||||
BMHD2_HISTART:
|
||||
MOV AH,0xF
|
||||
INT 0x10
|
||||
MOV U8 [BMHD2_PAGE-BMHD2_START],BH //Video page
|
||||
|
||||
MOV U32 FS:[0],0
|
||||
@@5: MOV SI,BMHD2_BOOT_MSG-BMHD2_START
|
||||
CALL BMHD2_PUTS
|
||||
CALL BMHD2_GETCHAR
|
||||
CMP AL,'0'
|
||||
JB @@5
|
||||
CMP AL,'8'
|
||||
JAE @@5
|
||||
AND EAX,7
|
||||
|
||||
MOV EBX,U32 BMHD2_BLK_ARRAY-BMHD2_START[EAX*8]
|
||||
MOV EAX,U32 BMHD2_BLK_ARRAY+4-BMHD2_START[EAX*8]
|
||||
|
||||
TEST EBX,EBX
|
||||
JNZ @@10
|
||||
TEST EAX,EAX
|
||||
JZ @@5
|
||||
|
||||
@@10: MOV U32 [BMHD2_DAP_BLK_LO-BMHD2_START],EBX
|
||||
MOV U32 [BMHD2_DAP_BLK_HI-BMHD2_START],EAX
|
||||
|
||||
MOV AX,U16 [BMHD2_OLD_CS_RIP-BMHD2_START]
|
||||
SHR AX,4
|
||||
ADD AX,U16 [BMHD2_OLD_CS_RIP+2-BMHD2_START]
|
||||
MOV U16 [BMHD2_DAP_BUF+2-BMHD2_START],AX //ES:0000
|
||||
MOV SI,BMHD2_DAP-BMHD2_START //DS:SI=DAP
|
||||
MOV DL,U8 [BMHD2_BIOS_DRV_NUM-BMHD2_START]
|
||||
MOV AH,0x42
|
||||
INT 0x13
|
||||
|
||||
POP EBP
|
||||
POP EDX
|
||||
POP EBX
|
||||
POP ECX
|
||||
XOR EAX,EAX
|
||||
POP GS
|
||||
POP FS
|
||||
POP ES
|
||||
POP DS
|
||||
POPFW
|
||||
|
||||
//My assembler doesn't support 16-bit very well.
|
||||
DU8 0xEA; //JMP xxxx:yyyy
|
||||
BMHD2_OLD_CS_RIP:
|
||||
DU16 0,0;
|
||||
BMHD2_END::
|
||||
//Continues here $LK,"::/Adam/Opt/Boot/BootHD.HC",A="FF:::/Adam/Opt/Boot/BootHD.HC,START"$
|
||||
#assert BMHD2_END-BMHD2_START<MODULE_SIZE
|
||||
}
|
||||
Loaded 100 of 661 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user