Initial (manual) import

This commit is contained in:
minexew committed 2017-01-22 20:26:44 +01:00
1 parent f39611c506
commit 895fe109de
661 files changed
+245862

No files matched your search

Binary file not shown.
+252
View File
@@ -0,0 +1,252 @@
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
public U8 *DBlk(I64 blk,Bool write=FALSE)
{//Dump disk block. Optionally, write.
//If you set write to TRUE, the block will
//be written when you press <ESC>.
//See $LK,"::/Demo/Dsk/DskRaw.HC"$.
U8 *buf=MAlloc(BLK_SIZE);
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);
}
+191
View File
@@ -0,0 +1,191 @@
#help_index "File/Internal"
I64 DirTreeSerializeSize(CDirEntry *tmpde)
{
I64 res=0;
while (tmpde) {
res+=CDIR_SIZE+1;
if (tmpde->attr & RS_ATTR_DIR)
res+=DirTreeSerializeSize(tmpde->sub);
tmpde=tmpde->next;
}
return res+1;
}
I64 DirTreeSerializeFill(CDirEntry *tmpde,U8 *dst)
{
I64 res=0,i;
while (tmpde) {
*dst++=1;
res++;
MemCpy(dst,&tmpde->start,CDIR_SIZE);
dst+=CDIR_SIZE;
res+=CDIR_SIZE;
if (tmpde->attr & RS_ATTR_DIR) {
i=DirTreeSerializeFill(tmpde->sub,dst);
dst+=i;
res+=i;
}
tmpde=tmpde->next;
}
*dst=0;
return res+1;
}
public U8 *DirTreeSerialize(CDirEntry *tmpde,I64 *_size=NULL)
{//Serialize tree returned from $LK,"FilesFind",A="MN:FilesFind"$() into a one contiguous U8 array.
I64 size=DirTreeSerializeSize(tmpde);
U8 *buf=MAlloc(size);
DirTreeSerializeFill(tmpde,buf);
if (_size) *_size=size;
return buf;
}
U8 *DirTreeUnserialize2(U8 *src,CDirEntry **tmpde)
{
CDirEntry *tmpde1;
if (*src++) {
tmpde1=CAlloc(sizeof(CDirEntry));
*tmpde=tmpde1;
MemCpy(&tmpde1->start,src,CDIR_SIZE);
src+=CDIR_SIZE;
if (tmpde1->attr & RS_ATTR_DIR)
src=DirTreeUnserialize2(src,&tmpde1->sub);
src=DirTreeUnserialize2(src,&tmpde1->next);
} else
*tmpde=NULL;
return src;
}
public CDirEntry *DirTreeUnserialize(U8 *src)
{//Unserialize tree to make it like a tree returned from $LK,"FilesFind",A="MN:FilesFind"$().
CDirEntry *tmpde=NULL;
DirTreeUnserialize2(src,&tmpde);
return tmpde;
}
#help_index "File/Program Routines"
U0 FOFlatten(CDirEntry *tmpde,CDirEntry **a,I64 *i)
{
CDirEntry *tmpde1;
while (tmpde) {
tmpde1=tmpde->next;
if (tmpde->attr&RS_ATTR_DIR) {
FOFlatten(tmpde->sub,a,i);
DirEntryDel(tmpde);
} else {
a[*i]=tmpde;
*i=*i+1;
}
tmpde=tmpde1;
}
}
I64 Size1(CDirEntry *tmpde,I64 *_fuf_flags,I64 round_to)
{
U8 buf[BLK_SIZE];
I64 res=0,i;
CDrv *dv;
while (tmpde) {
if ((i=tmpde->size) && Bt(_fuf_flags,FUf_EXPAND) &&
!(tmpde->attr&RS_ATTR_DIR) &&
FileAttr(tmpde->name)&RS_ATTR_COMPRESSED) {
dv=Let2Drv(*tmpde->full_name);
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;
}
+444
View File
@@ -0,0 +1,444 @@
#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically)"
Bool ChkDskConfirm(Bool *_fix,Bool *_confirm)
{
if (*_fix && *_confirm) {
"Fix ";
if (!YorN)
*_fix=FALSE;
*_confirm=FALSE;
}
return *_fix;
}
I64 RedSeaChkDskLst(CDrv *dv,CDirEntry *tmpde1,
U8 *bits,U8 *bits2,I64 size,I64 bpc)
{
CDirEntry *tmpde2;
I64 i,j,errs=0;
while (tmpde1) {
tmpde2=tmpde1->next;
if (tmpde1->attr & RS_ATTR_DIR && tmpde1->sub)
errs+=RedSeaChkDskLst(dv,tmpde1->sub,bits,bits2,size,bpc);
j=(tmpde1->size+bpc-1)/bpc;
for (i=0;i<j;i++) {
if (i+tmpde1->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;
}
+809
View File
@@ -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;
}
+8
View File
@@ -0,0 +1,8 @@
Cd(__DIR__);;
#include "ADskA"
#include "ADskB"
#include "PrtDsk"
#include "Mount"
#include "ChkDsk"
#include "FileMgr"
Cd("..");;
+159
View File
@@ -0,0 +1,159 @@
#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically);"
U8 Mount2(U8 boot_drv_let,CDoc *_doc,Bool _caller_is_prtdsk)
{//If _doc, called by $LK,"::/Kernel/KCfg.HC"$ else called by $LK,"Mount",A="MN:Mount"$().
I64 cnt,total=0,num_hints,drv_let,type,unit,prt_num;
U8 blks_buf[STR_LEN],addr_buf[STR_LEN],base0_buf[STR_LEN],base1_buf[STR_LEN],
*filename=NULL,*filename2=NULL,res=0;
CATARep *head=NULL,*tmpha;
Bool whole_drv,make_free;
CDoc *doc;
if (boot_drv_let)
boot_drv_let=Let2Let(boot_drv_let);
do {
cnt=0;
if (!_doc)
DrvRep;
"\n****** Mount Drives ******\n"
"$$GREEN$$A$$FG$$-$$GREEN$$B$$FG$$ are RAM drives.\n"
"$$GREEN$$C$$FG$$-$$GREEN$$L$$FG$$ are ATA hard drives.\n"
"$$GREEN$$M$$FG$$-$$GREEN$$P$$FG$$ are ISO file read drives.\n"
"$$GREEN$$Q$$FG$$-$$GREEN$$S$$FG$$ are ISO file write drives.\n"
"$$GREEN$$T$$FG$$-$$GREEN$$Z$$FG$$ are ATAPI CD/DVD drives.\n"
"\nDrive Letter ($$PURPLE$$<ENTER>$$FG$$ to exit):";
drv_let=Let2Let(GetChar);
'\n';
if (type=Let2BlkDevType(drv_let)) {
whole_drv=FALSE;
if (_doc) { //Called by $LK,"::/Kernel/KCfg.HC"$
doc=_doc;
make_free=FALSE;
} else { //Called by $LK,"Mount",A="MN:Mount"$()
doc=DocNew;
DocPrint(doc,"CBlkDev *bd;\n");
make_free=TRUE;
}
unit=0;
prt_num=I64_MIN;
switch (type) {
case BDT_RAM:
"Addr of RAM disk ($$PURPLE$$<ENTER>$$FG$$ to MAlloc):";
GetS(addr_buf,STR_LEN);
case BDT_ISO_FILE_WRITE:
"Blks of 512 bytes:";
GetS(blks_buf,STR_LEN);
break;
case BDT_ISO_FILE_READ:
filename=GetStr("File Name:");
break;
case BDT_ATA:
prt_num=GetI64("Partition Num (Default=All):",prt_num);
case BDT_ATAPI:
num_hints=ATARep(,,&head);
if (type==BDT_ATAPI && boot_drv_let)
"<ENTER> to use booted CD/DVD\n"; //Only $LK,"::/Kernel/KCfg.HC"$
do {
if (num_hints)
"Enter dev number or\nport with $$PURPLE$$0x$$FG$$ prefix.\n"
"I/O Port Base0:\n";
else
"Include $$PURPLE$$0x$$FG$$ prefix.\nI/O Port Base0:\n";
GetS(base0_buf,STR_LEN);
} while (!Str2I64(base0_buf) && (type!=BDT_ATAPI || !boot_drv_let));
if (1<=Str2I64(base0_buf)<=num_hints) {
tmpha=ATARepFind(head,Str2I64(base0_buf));
StrPrint(base0_buf,"0x%X",tmpha->base0);
StrPrint(base1_buf,"0x%X",tmpha->base1);
unit=tmpha->unit;
} else if (type!=BDT_ATAPI || *base0_buf) {
if (type==BDT_ATAPI)
StrCpy(base1_buf,"0");
else
do {
"I/O Port Base1:\n";
GetS(base1_buf,STR_LEN);
} while (!Str2I64(base1_buf));
do {
"\t$$PURPLE$$0$$FG$$=Master\n\t$$PURPLE$$1$$FG$$=Slave\nUnit:";
unit=GetChar-'0';
} while (!(0<=unit<=1));
'\n';
}
LinkedLstDel(head);
break;
}
DocPrint(doc,"bd=BlkDevNextFreeSlot(\'%C\',%d);bd->unit=%d;\n",
drv_let,type,unit);
switch (type) {
case BDT_RAM:
if (!*addr_buf) StrCpy(addr_buf,"0");
DocPrint(doc,"bd->RAM_dsk=%s;\n",addr_buf);
case BDT_ISO_FILE_WRITE:
if (!*blks_buf) StrCpy(blks_buf,"0");
DocPrint(doc,"bd->max_blk=(%s)-1;\n",blks_buf);
DocPrint(doc,"bd->drv_offset=19<<2+"
"(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;\n");
break;
case BDT_ISO_FILE_READ:
filename2=FileNameAbs(filename);
DocPrint(doc,"bd->file_dsk_name=AStrNew(\"%s\");\n",filename2);
DocPrint(doc,"bd->drv_offset=19<<2+"
"(DVD_BLK_SIZE*2+DVD_BOOT_LOADER_SIZE)/BLK_SIZE;\n");
break;
case BDT_ATA:
case BDT_ATAPI:
if (type==BDT_ATAPI && !*base0_buf) {
DocPrint(doc,"GetBaseUnit(bd);\n"); //Only $LK,"::/Kernel/KCfg.HC"$
if (drv_let==boot_drv_let)
make_free=TRUE;
} else
DocPrint(doc,"bd->base0=%s;bd->base1=%s;\n",base0_buf,base1_buf);
if (type==BDT_ATA && _caller_is_prtdsk) {
"\nReformat WHOLE drive!";
whole_drv=YorN;
}
break;
}
DocPrint(doc,"BlkDevAdd(bd,%d,%d,%d);\n",prt_num,whole_drv,make_free);
if (_doc) //Called by $LK,"::/Kernel/KCfg.HC"$
cnt++;
else { //Called by $LK,"Mount",A="MN:Mount"$()
if ((cnt=ExeDoc(doc)) && whole_drv) {
if (_caller_is_prtdsk) {
res=drv_let;
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;
}
+167
View File
@@ -0,0 +1,167 @@
#help_index "Install;File/Cmd Line (Typically);Cmd Line (Typically)"
#define ROUND_DRV_TO (63*255)
#define DRV_HEADER 63
class CPlannedDrv
{
CPlannedDrv *next,*last;
I64 size;
Bool pri;
};
public I64 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;
}
+270
View File
@@ -0,0 +1,270 @@
#help_index "Debugging/Dump"
Bool ClassRep2(CDoc *doc,U8 *_d,U8 *class_name=lastclass,
I64 depth,I64 max_depth,Bool dynamic,I64 types=HTT_CLASS,I64 offset=0)
{//See $LK,"::/Demo/LastClass.HC"$.
I64 i,j,stars,*ptr;
CMemberLst *ml;
CDocEntry *doc_e;
Bool unlock;
CHashClass *tmpc,*tmpc2;
if (depth>=max_depth) return TRUE;
if (!(tmpc=HashFind(class_name,Fs->hash_table,types))) {
DocPrint(doc,"Class Not Found.\n");
return FALSE;
}
if (!ChkPtr(_d) || !ChkPtr(_d(U8 *)+tmpc->size)) {
DocPrint(doc,"Bad Ptr:%016X\n",_d);
return FALSE;
}
if (tmpc->base_class && !ClassRep2(doc,_d,tmpc->base_class->str,
depth,max_depth,dynamic,types,offset))
return FALSE;
unlock=DocLock(doc);
DocPrint(doc,"Class:\"%s\"\n",class_name);
ml=tmpc->member_lst_and_root;
while (ml) {
tmpc2=ml->member_class;
ptr=_d(U8 *)+ml->offset;
DocPrint(doc,"%08X ",ptr(U8 *)+offset);
stars=tmpc2->ptr_stars_cnt;
tmpc2=OptClassFwd(tmpc2);
tmpc2-=tmpc2->ptr_stars_cnt;
if (tmpc2->type & HTT_INTERNAL_TYPE) {
DocPrint(doc,"$$GREEN$$%-20ts:$$FG$$",ml->str);
if (stars==1 && (tmpc2->raw_type==RT_I8 || tmpc2->raw_type==RT_U8)) {
ptr=*ptr;
if (ChkPtr(ptr)) {
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$$\n");
doc_e->data=ptr;
DocDataFmt(doc,doc_e);
} else
DocPrint(doc,"%40ts\n",ptr);
}
} else if (!stars) {
j=MinI64(ml->dim.total_cnt,32);
if (tmpc2->raw_type==RT_I8 || tmpc2->raw_type==RT_U8) {
if (j==1) {
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U8,A=\"%%c\"$$\n");
doc_e->data=ptr;
} else
DocPrint(doc,"%c\n",*ptr(U8 *));
} else {
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM-P+RD,LEN=64,A=\"%%40ts\"$$\n");
doc_e->data=ptr;
DocDataFmt(doc,doc_e);
} else
DocPrint(doc,"%40ts\n",ptr);
}
}
for (i=0;i<j;i++) {
switch (tmpc2->raw_type) {
case RT_I0:
case RT_U0:
break;
case RT_I8:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=I8,A=\"%%02X\"$$ ");
doc_e->data=ptr(I8 *)++;
} else
DocPrint(doc,"%02X ",*ptr(I8 *)++);
break;
case RT_U8:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U8,A=\"%%02X\"$$ ");
doc_e->data=ptr(U8 *)++;
} else
DocPrint(doc,"%02X ",*ptr(U8 *)++);
break;
case RT_I16:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=I16,A=\"%%04X\"$$ ");
doc_e->data=ptr(I16 *)++;
} else
DocPrint(doc,"%04X ",*ptr(I16 *)++);
break;
case RT_U16:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U16,A=\"%%04X\"$$ ");
doc_e->data=ptr(U16 *)++;
} else
DocPrint(doc,"%04X ",*ptr(U16 *)++);
break;
case RT_I32:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=I32,A=\"%%08X\"$$ ");
doc_e->data=ptr(I32 *)++;
} else
DocPrint(doc,"%08X ",*ptr(I32 *)++);
break;
case RT_U32:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U32,A=\"%%08X\"$$ ");
doc_e->data=ptr(U32 *)++;
} else
DocPrint(doc,"%08X ",*ptr(U32 *)++);
break;
case RT_U64:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=U64,A=\"%%08X\"$$ ");
doc_e->data=ptr(U64 *)++;
} else
DocPrint(doc,"%08X ",*ptr(U64 *)++);
break;
case RT_F64:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,RT=F64,A=\"%%16g\"$$ ");
doc_e->data=ptr(F64 *)++;
} else
DocPrint(doc,"%16g ",*ptr(I64 *)++);
break;
default:
if (dynamic) {
doc_e=DocPrint(doc,"$$DA-TRM+RD+UD,A=\"%%016X\"$$ ");
doc_e->data=ptr(I64 *)++;
} else
DocPrint(doc,"%016X ",*ptr(I64 *)++);
}
if (dynamic)
DocDataFmt(doc,doc_e);
}
if (j<ml->dim.total_cnt)
DocPrint(doc,"...");
} else
DocPrint(doc,"%016X",*ptr);
DocPrint(doc,"\n");
} else {
if (depth<2) {
if (stars==1 && !ChkPtr(*ptr))
DocPrint(doc,"%-20ts:%016X\n",ml->str,*ptr);
else {
DocPrint(doc,"$$TR,\"%s\"$$\n",ml->str);
DocPrint(doc,"$$ID,2$$");
if (!stars)
ClassRep2(doc,ptr,tmpc2->str,depth+1,max_depth,dynamic);
else if (stars==1)
ClassRep2(doc,*ptr,tmpc2->str,depth+1,max_depth,dynamic);
DocPrint(doc,"$$ID,-2$$");
}
} else
DocPrint(doc,"%-20ts\n",ml->str);
}
ml=ml->next;
}
if (unlock)
DocUnlock(doc);
return TRUE;
}
public U0 ClassRep(U8 *_d,U8 *class_name=lastclass,
I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
{//Displays members of a record by using the compiler's info.
CDoc *doc;
if (IsRaw)
doc=DocNew;
else {
DocMax;
doc=DocPut;
}
if (fun)
ClassRep2(doc,_d,class_name,0,max_depth,FALSE,HTT_FUN,offset);
else
ClassRep2(doc,_d,class_name,0,max_depth,FALSE,HTT_CLASS,offset);
DocPrint(doc,"\n");
DocRecalc(doc);
if (IsRaw) {
DocDump(doc,100000);
DocDel(doc);
}
}
public U0 ClassRepD(U8 *_d,U8 *class_name=lastclass,
I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
{//Dynamic ClassRep. Uses hex_ed widgit for live changes.
CDoc *doc;
if (IsRaw)
doc=DocNew;
else {
DocMax;
doc=DocPut;
}
if (fun)
ClassRep2(doc,_d,class_name,0,max_depth,TRUE,HTT_FUN,offset);
else
ClassRep2(doc,_d,class_name,0,max_depth,TRUE,HTT_CLASS,offset);
DocPrint(doc,"\n");
DocRecalc(doc);
if (IsRaw) {
DocDump(doc,100000);
DocDel(doc);
}
}
U0 UpdateRegVarImg(CHashFun *tmpf,U8 *_b,CTask *task)
{
CMemberLst *ml;
CHashClass *tmpc;
ml=tmpf->member_lst_and_root;
while (ml) {
if (ml->reg!=REG_NONE) {
tmpc=OptClassFwd(ml->member_class);
MemCpy(_b+ml->offset,TaskRegAddr(task,ml->reg),tmpc->size);
}
ml=ml->next;
}
}
public U0 FunRep(U8 *st,U8 *rbp=NULL,I64 max_depth=2,CTask *task=NULL)
{//Shows names and vals of a fun's local vars using compiler's info.
I64 size;
U8 *img;
CHashFun *tmpf=HashFind(st,Fs->hash_table,HTT_FUN);
CMemberLst *tmpm;
if (tmpf) {
if (rbp) {
if (task) {
//tmpf->size is negative. It's the bottom
//of the fun local var space relative to RBP .
size=tmpf->arg_cnt*8-tmpf->size+16;
img=MAlloc(size);
MemCpy(img,rbp+tmpf->size,size);
UpdateRegVarImg(tmpf,img-tmpf->size,task);
ClassRep(img-tmpf->size,st,max_depth,TRUE,rbp-img+tmpf->size);
Free(img);
} else
ClassRep(rbp,st,max_depth,TRUE);
} else {
tmpm=tmpf->member_lst_and_root;
while (tmpm) {
if (0<=tmpm->reg<REG_REGS_NUM)
"%08Z %s\n",tmpm->reg,"ST_U64_REGS",tmpm->str;
else
"%08tX %s\n",tmpm->offset,tmpm->str;
tmpm=tmpm->next;
}
"%08tX Stk Size\n",tmpf->size;
}
}
}
#help_index "Debugging/Unassemble"
public U0 Uf(U8 *st)
{//Unassembles a named fun
I64 i;
CHashSrcSym *tmpf;
CDbgInfo *dbg_info;
if (tmpf=HashFind(st,Fs->hash_table,HTT_FUN|HTT_EXPORT_SYS_SYM)) {
if (tmpf->type&HTT_FUN)
FunRep(st);
if (dbg_info=tmpf->dbg_info) {
i=dbg_info->body[dbg_info->max_line+1-dbg_info->min_line]
-dbg_info->body[0];
Un(dbg_info->body[0],i);
"Code Size:%04X\n",i;
} else
U(HashVal(tmpf));
}
}
+41
View File
@@ -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;
+101
View File
@@ -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;
+433
View File
@@ -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);
}
+135
View File
@@ -0,0 +1,135 @@
#help_index "Math"
public U0 R2P(F64 *_mag=NULL,F64 *_arg=NULL,F64 x,F64 y)
{//Rect to polar
//Returns angle in range (-ã,ã]
if (_arg)
*_arg=Arg(x,y);
if (_mag)
*_mag=Sqrt(x*x+y*y);
}
public U0 P2R(F64 *_x=NULL,F64 *_y=NULL,F64 mag,F64 arg)
{//Polar to Rect
if (_x)
*_x=mag*Cos(arg);
if (_y)
*_y=mag*Sin(arg);
}
public F64 Wrap(F64 é,F64 base=-ã)
{//Returns angle in range [base,base+2*ã)
F64 res=é%(2*ã);
if (res>=base+2*ã)
res-=2*ã;
else if (res<base)
res+=2*ã;
return res;
}
public I64 DistSqrI64(I64 x1,I64 y1,I64 x2,I64 y2)
{//Distance-squared between 2 points.
I64 dx=x1-x2,dy=y1-y2;
return dx*dx+dy*dy;
}
public F64 ASin(F64 s)
{//Arc Sin (Inverse Sin).
F64 c;
c=s*s;
if (c>=1.0)
return ã/2.0;
c=Sqrt(1.0-c);
return ATan(s/c);
}
public F64 ACos(F64 c)
{//Arc Cos (Inverse Cos).
F64 s;
if (!c)
return ã/2.0;
s=c*c;
if (s>=1.0)
return 0.0;
s=Sqrt(1.0-s);
return ATan(s/c);
}
public F64 Sinh(F64 x)
{//Hyperbolic Sine.
return 0.5*(Exp(x)-Exp(-x));
}
public F64 Cosh(F64 x)
{//Hyperbolic Cosine.
return 0.5*(Exp(x)+Exp(-x));
}
#help_index "Math/Complex;Data Types/Complex"
public Complex *CAdd(Complex *sum,Complex *n1,Complex *n2)
{//sum=n1+n2
sum->x=n1->x+n2->x;
sum->y=n1->y+n2->y;
return sum;
}
public Complex *CSub(Complex *diff,Complex *n1,Complex *n2)
{//diff=n1-n2
diff->x=n1->x-n2->x;
diff->y=n1->y-n2->y;
return diff;
}
public Complex *CMul(Complex *prod,Complex *n1,Complex *n2)
{//prod=n1*n2
prod->x=n1->x*n2->x-n1->y*n2->y;
prod->y=n1->x*n2->y+n1->y*n2->x;
return prod;
}
public Complex *CDiv(Complex *quot,Complex *n1,Complex *n2)
{//quot=n1/n2
F64 m1,arg1,m2,arg2;
R2P(&m1,&arg1,n1->x,n1->y);
R2P(&m2,&arg2,n2->x,n2->y);
m1/=m2;
arg1-=arg2;
quot->x=m1*Cos(arg1);
quot->y=m1*Sin(arg1);
return quot;
}
public Complex *CScale(Complex *dst,F64 s)
{//dst*=s
dst->x*=s;
dst->y*=s;
return dst;
}
public Complex *CCopy(Complex *dst,Complex *src)
{//dst=src
dst->x=src->x;
dst->y=src->y;
return dst;
}
public Complex *CEqu(Complex *dst,F64 x,F64 y)
{//dst=(x,y)
dst->x=x;
dst->y=y;
return dst;
}
public Complex *CPoly(Complex *dst,I64 n,Complex *zeros,Complex *x)
{//Eval complex polynomial
I64 i;
Complex n1,n2;
if (n>0) {
CSub(dst,x,&zeros[0]);
for (i=1;i<n;i++) {
CCopy(&n1,dst);
CMul(dst,&n1,CSub(&n2,x,&zeros[i]));
}
} else
CEqu(dst,1.0,0.0);
return dst;
}
+609
View File
@@ -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;
}
}
+179
View File
@@ -0,0 +1,179 @@
#help_index "Memory/Task"
public I64 TaskMemAlloced(CTask *task=NULL,Bool override_validate=FALSE)
{//Count of bytes alloced to a task, used+unused.
I64 res;
if (!task) task=Fs;
if (override_validate || TaskValidate(task)) {
res=task->code_heap->alloced_u8s;
if (task->code_heap!=task->data_heap)
res+=task->data_heap->alloced_u8s;
return res;
} else
return 0;
}
public I64 TaskMemUsed(CTask *task=NULL,Bool override_validate=FALSE)
{//Count of bytes alloced to a task and in use.
I64 res;
if (!task) task=Fs;
if (override_validate || TaskValidate(task)) {
res=task->code_heap->used_u8s;
if (task->data_heap!=task->code_heap)
res+=task->data_heap->used_u8s;
return res;
} else
return 0;
}
#help_index "Memory/Task;Debugging/Heap;Memory/Debugging"
public Bool HeapRep(CTask *task)
{//Report status of task's heap.
I64 i,cnt;
CMemUnused *uum;
if (!task || task==Fs) {
"Task can't HeapRep on self.\n";
return FALSE;
}
if (!TaskValidate(task)) return FALSE;
PUSHFD
CLI
while (LBts(&task->code_heap->locked_flags,HClf_LOCKED))
PAUSE
if (task->data_heap!=task->code_heap)
while (LBts(&task->data_heap->locked_flags,HClf_LOCKED))
PAUSE
for (i=0;i<MEM_HEAP_HASH_SIZE>>3;i++) {
cnt=0;
uum=task->code_heap->heap_hash[i];
while (uum) {
cnt+=uum->size;
uum=uum->next;
}
if (task->data_heap!=task->code_heap) {
uum=task->data_heap->heap_hash[i];
while (uum) {
cnt+=uum->size;
uum=uum->next;
}
}
if (cnt)
"%03X:%08X\n",i<<3,cnt;
}
'\n';
uum=task->code_heap->malloc_free_lst;
while (uum) {
"%X, ",uum->size;
uum=uum->next;
}
if (task->data_heap!=task->code_heap) {
uum=task->data_heap->malloc_free_lst;
while (uum) {
"%X, ",uum->size;
uum=uum->next;
}
}
if (task->data_heap!=task->code_heap)
LBtr(&task->data_heap->locked_flags,HClf_LOCKED);
LBtr(&task->code_heap->locked_flags,HClf_LOCKED);
POPFD
'\n';
}
#help_index "Memory/HeapCtrl;Debugging/Heap;Memory/Debugging"
public Bool IsInHeapCtrl(U8 *a,CHeapCtrl *hc,Bool lock=TRUE)
{//Check addr if in HeapCtrl.
CMemBlk *m;
PUSHFD
CLI
if (lock)
while (LBts(&hc->locked_flags,HClf_LOCKED))
PAUSE
m=hc->next_mem_blk;
while (m!=&hc->next_mem_blk) {
if (a>=m && a<m(U8 *)+m->pags<<MEM_PAG_BITS) {
if (lock)
LBtr(&hc->locked_flags,HClf_LOCKED);
POPFD
return TRUE;
}
m=m->next;
}
if (lock)
LBtr(&hc->locked_flags,HClf_LOCKED);
POPFD
return FALSE;
}
public Bool HeapCtrlWalk(CHeapCtrl *hc)
{//Check integrity of HeapCtrl.
I64 i;
CMemUnused *uum;
PUSHFD
CLI
while (LBts(&hc->locked_flags,HClf_LOCKED))
PAUSE
for (i=0;i<MEM_HEAP_HASH_SIZE>>3;i++) {
uum=hc->heap_hash[i];
while (uum) {
if (!IsInHeapCtrl(uum,hc,FALSE))
goto hc_false;
uum=uum->next;
}
}
uum=hc->malloc_free_lst;
while (uum) {
if (!IsInHeapCtrl(uum,hc,FALSE))
goto hc_false;
uum=uum->next;
}
#if _CFG_HEAP_DBG
CMemUsed *um,*um1;
um1=(&hc->next_um)(U8 *)-offset(CMemUsed.next);
um=um1->next;
while (um!=um1) {
if (!IsInHeapCtrl(um,hc,FALSE))
goto hc_false;
um=um->next;
}
#endif
LBtr(&hc->locked_flags,HClf_LOCKED);
POPFD
return TRUE;
hc_false:
LBtr(&hc->locked_flags,HClf_LOCKED);
POPFD
return FALSE;
}
#help_index "Memory/Task;Debugging/Heap;Memory/Debugging"
public Bool IsInHeap(U8 *a,CTask *task=NULL,Bool lock=TRUE)
{//Check addr if in task's heaps.
if (!task) task=Fs;
if (TaskValidate(task) && (IsInHeapCtrl(a,task->code_heap,lock)||
task->data_heap!=task->code_heap &&
IsInHeapCtrl(a,task->data_heap,lock)))
return TRUE;
else
return FALSE;
}
public Bool HeapWalk(CTask *task=NULL)
{//Check integrity of task's heaps.
if (!task) task=Fs;
if (!TaskValidate(task) || !HeapCtrlWalk(task->code_heap) ||
task->data_heap!=task->code_heap && !HeapCtrlWalk(task->data_heap))
return FALSE;
else
return TRUE;
}
Binary file not shown.
+229
View File
@@ -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.
+263
View File
@@ -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");
+261
View File
@@ -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);
}
+169
View File
@@ -0,0 +1,169 @@
#help_index "AutoComplete/Dictionary"
acd.has_words=FileFind(ACD_WORD_FILENAME);
acd.has_defs =FileFind(ACD_DEF_FILENAME)||FileFind(ACD_DEF_FILENAME_Z);
public U0 ACDWordsLoad()
{//Put words from word list into hash table.
I64 size;
CHashGeneric *tmph;
U8 *in_ptr,*in_start,*st2;
U16 *d;
acd.num_words=0;
if (in_ptr=FileRead(ACD_WORD_FILENAME,&size)) {
in_start=in_ptr;
Free(acd.word_lst);
acd.word_lst=AMAlloc(size);
MemCpy(acd.word_lst,in_start,size);
acd.word_lst_size=size;
while (in_ptr<in_start+size) {
if (*in_ptr==ACD_WORD_CHAR)
in_ptr++;
if (*in_ptr) {
st2=MStrUtil(in_ptr,SUF_TO_UPPER);
tmph=ACAlloc(sizeof(CHashGeneric)+StrLen(st2)+1);
StrCpy(tmph+1,st2);
Free(st2);
in_ptr+=StrLen(in_ptr)+1;
tmph->str=tmph+1;
tmph->use_cnt=1;
tmph->type=HTT_DICT_WORD;
d=in_ptr;
tmph->user_data0=*d;
in_ptr+=2;
HashAdd(tmph,ac.hash_table);
acd.num_words++;
} else
in_ptr+=3;
}
Free(in_start);
}
}
#help_index "AutoComplete"
CHashAC *ACHashAdd(U8 *w)
{
CHashAC *tmpw=HashFind(w,ac.hash_table,HTT_WORD);
if (tmpw) {
tmpw->hits++;
return tmpw;
}
tmpw=ACAlloc(sizeof(CHashAC));
tmpw->str=AStrNew(w);
tmpw->type=HTT_WORD;
tmpw->use_cnt=1;
tmpw->hits=1;
HashAdd(tmpw,ac.hash_table);
ac.num_words++;
return tmpw;
}
U0 ACSingleFileAdd(U8 *buf)
{
I64 ch;
U8 *ptr=buf,*ptr2,*ptr3;
while (TRUE) {
while (TRUE) {
if (ch=*ptr++) {
if (Bt(char_bmp_alpha_numeric,ch))
break;
} else
return;
}
ptr3=ptr;
ptr2=ptr;
ptr--;
while (TRUE) {
if (ch=*ptr2++) {
if (Bt(char_bmp_alpha_numeric,ch))
*ptr3++=ch;
else if (ch!=CH_CURSOR)
break;
} else {
ptr2--;
break;
}
}
*ptr3=0;
ACHashAdd(ptr);
ptr=ptr2;
}
}
U0 ACMainFileLstTraverse(U8 *files_find_mask)
{
U8 *buf;
CDirEntry *tmpde,*tmpde1;
try {
tmpde=tmpde1=FilesFind(files_find_mask,
FUF_RECURSE|FUF_JUST_TXT|FUF_JUST_FILES|FUF_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;
}
+284
View File
@@ -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.
+6
View File
@@ -0,0 +1,6 @@
//See $LK,"::/Doc/AutoComplete.DD"$
Cd(__DIR__);;
#include "ACFill"
#include "ACTask"
#include "ACInit"
Cd("..");;
+72
View File
@@ -0,0 +1,72 @@
#help_index "Info;Time/CPU Cycles;Processor"
class CCPURep
{
Bool mp_start,mp_end;
I64 mp_not_done_flags,
**swaps,
**cycles;
};
U0 MPCPURep(CCPURep *cr)
{
I64 swaps=0,cycles_0,cycles_f;
while (!cr->mp_start)
Yield;
cycles_0=GetTSC;
while (!cr->mp_end) {
swaps++;
Yield;
}
cycles_f=GetTSC;
cr->swaps[Gs->num]=swaps;
cr->cycles[Gs->num]=cycles_f-cycles_0;
LBtr(&cr->mp_not_done_flags,Gs->num);
}
public U0 CPURep(Bool full=FALSE)
{//Report number of cores and clock freq.
I64 i,total_swaps,total_cycles;
F64 t0,tf;
CCPURep cr;
if (!full)
"%03X Cores %6h?nHz\n",mp_cnt,ToF64(cnts.time_stamp_freq);
else {
cr.swaps=CAlloc(sizeof(I64)*mp_cnt);
cr.cycles=CAlloc(sizeof(I64)*mp_cnt);
cr.mp_start=cr.mp_end=FALSE;
cr.mp_not_done_flags=1<<mp_cnt-1;
for (i=0;i<mp_cnt;i++)
Spawn(&MPCPURep,&cr,NULL,i);
t0=tS;
cr.mp_start=TRUE;
Sleep(2000);
cr.mp_end=TRUE;
while (cr.mp_not_done_flags)
Yield;
tf=tS;
"\n%03X Cores %6h?nHz\n",mp_cnt,ToF64(cnts.time_stamp_freq);
"\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);
}
}
+388
View File
@@ -0,0 +1,388 @@
public CCtrl *CtrlFindUnique(CTask *haystack_task,I64 needle_type)
{//Find task ctrl given $LK,"ctrl_type",A="MN:CTRLT_VIEWING_ANGLES"$.
CCtrl *c;
c=haystack_task->next_ctrl;
while (c!=&haystack_task->next_ctrl) {
if (c->type==needle_type)
return c;
c=c->next;
}
return NULL;
}
U0 CtrlsUpdate(CTask *task)
{
CCtrl *c;
c=task->next_ctrl;
while (c!=&task->next_ctrl) {
if (c->update_derived_vals)
(*c->update_derived_vals)(c);
if (c->flags&CTRLF_BORDER) {
c->scrn_left =gr.pan_text_x+task->pix_left+c->left-FONT_WIDTH;
c->scrn_right =gr.pan_text_x+task->pix_left+c->right-FONT_WIDTH;
c->scrn_top =gr.pan_text_y+task->pix_top+c->top-FONT_HEIGHT;
c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom-FONT_HEIGHT;
} else {
c->scrn_left =gr.pan_text_x+task->pix_left+c->left;
c->scrn_right =gr.pan_text_x+task->pix_left+c->right;
c->scrn_top =gr.pan_text_y+task->pix_top+c->top;
c->scrn_bottom=gr.pan_text_y+task->pix_top+c->bottom;
}
c=c->next;
}
}
fp_update_ctrls=&CtrlsUpdate;
Bool CtrlInsideRect(CCtrl *c,I64 x,I64 y)
{//scrn coordinates
if (c->scrn_left<=x<=c->scrn_right &&
c->scrn_top<=y<=c->scrn_bottom)
return TRUE;
else
return FALSE;
}
public Bool CtrlInside(CCtrl *c,I64 x,I64 y)
{//Is x,y inside a ctrl?
if (c->flags&CTRLF_SHOW) {
if (c->inside_ctrl)
return (*c->inside_ctrl)(c,x,y);
else
return CtrlInsideRect(c,x,y);
} else
return FALSE;
}
U0 DrawCtrls(CTask *task)
{
CCtrl *c;
CDC *dc=DCAlias(gr.dc2,task);
c=task->next_ctrl;
while (c!=&task->next_ctrl) {
if (c->flags&CTRLF_SHOW) {
if (c->flags&CTRLF_BORDER) {
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
PUSHFD
CLI
while (LBts(&task->task_flags,TASKf_TASK_LOCK))
PAUSE
task->win_left--; //Allow drawing on border
task->win_right++;
task->win_top--;
task->win_bottom++;
WinDerivedValsUpdate(task);
LBtr(&task->task_flags,TASKf_TASK_LOCK);
POPFD
if (c->draw_it)
(*c->draw_it)(dc,c);
PUSHFD
CLI
while (LBts(&task->task_flags,TASKf_TASK_LOCK))
PAUSE
task->win_left++;
task->win_right--;
task->win_top++;
task->win_bottom--;
WinDerivedValsUpdate(task);
LBtr(&task->task_flags,TASKf_TASK_LOCK);
POPFD
}
} else
if (c->draw_it)
(*c->draw_it)(dc,c);
}
c=c->next;
}
DCDel(dc);
}
#define WIN_SCROLL_SIZE 8
#define WIN_SCROLL_BORDER_BONUS 4
U0 DrawWinScroll(CDC *dc,CCtrl *c)
{
CWinScroll *s=c->state;
if (c->flags&CTRLF_CLICKED)
dc->color=s->color>>4;
else
dc->color=s->color&0xF;
GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);
if (c->flags&CTRLF_CLICKED)
dc->color=s->color&0xF;
else
dc->color=s->color>>4;
GrRect(dc,c->left+2,c->top+2,c->right-c->left+1-4,c->bottom-c->top+1-4);
}
U0 WinDerivedScrollValsUpdate(CCtrl *c)
{
CWinScroll *s=c->state;
I64 range;
if (s->max<s->min) s->max=s->min;
if (s->pos<s->min) s->pos=s->min;
if (s->pos>s->max) s->pos=s->max;
s->color=c->win_task->border_attr&0xF^0xF+
(c->win_task->border_attr&0xF)<<4;
range=s->max-s->min;
if (!range) range=1;
switch (c->type) {
case CTRLT_WIN_HSCROLL:
c->left =gr.pan_text_x+FONT_WIDTH-WIN_SCROLL_BORDER_BONUS+
(s->pos-s->min)*(c->win_task->pix_width+2*WIN_SCROLL_BORDER_BONUS
-WIN_SCROLL_SIZE)/range;
c->right =c->left+WIN_SCROLL_SIZE-1;
c->top =gr.pan_text_y+FONT_HEIGHT+
(FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_height;
c->bottom=c->top+WIN_SCROLL_SIZE-1;
break;
case CTRLT_WIN_VSCROLL:
c->left =gr.pan_text_x+FONT_WIDTH+
(FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->pix_width;
c->right =c->left+WIN_SCROLL_SIZE-1;
c->top =gr.pan_text_y+FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS+
(s->pos-s->min)*(c->win_task->pix_height+
2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE)/range;
c->bottom=c->top+WIN_SCROLL_SIZE-1;
break;
}
}
U0 LeftClickHWinScroll(CCtrl *c,I64 x,I64,Bool down)
{
CTask *task=c->win_task;
CWinScroll *s=c->state;
I64 range=task->pix_width+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;
LBts(&s->flags,WSSf_SET_TO_POS);
s->pos=((x-(FONT_WIDTH-WIN_SCROLL_BORDER_BONUS))
*(s->max-s->min+1)+range/2)/range+s->min;
if (down)
c->flags|=CTRLF_CLICKED;
else
c->flags&=~CTRLF_CLICKED;
if (c->update_derived_vals)
(*c->update_derived_vals)(c);
}
U0 LeftClickVWinScroll(CCtrl *c,I64,I64 y,Bool down)
{
CTask *task=c->win_task;
CWinScroll *s=c->state;
I64 range=task->pix_height+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE;
LBts(&s->flags,WSSf_SET_TO_POS);
s->pos=((y-(FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS))
*(s->max-s->min+1)+range/2)/range+s->min;
if (down)
c->flags|=CTRLF_CLICKED;
else
c->flags&=~CTRLF_CLICKED;
if (c->update_derived_vals)
(*c->update_derived_vals)(c);
}
U0 WheelChangeWinScroll(CCtrl *c,I64 delta)
{
CWinScroll *s=c->state;
LBts(&s->flags,WSSf_SET_TO_POS);
s->pos+=delta;
if (c->update_derived_vals)
(*c->update_derived_vals)(c);
}
U0 WinScrollsInit(CTask *task)
{
CCtrl *c;
if (!CtrlFindUnique(task,CTRLT_WIN_HSCROLL)) {
c=CAlloc(sizeof(CCtrl));
c->win_task=task;
c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;
c->type=CTRLT_WIN_HSCROLL;
c->state=&task->horz_scroll;
c->update_derived_vals=&WinDerivedScrollValsUpdate;
c->draw_it=&DrawWinScroll;
c->left_click=&LeftClickHWinScroll;
QueIns(c,task->last_ctrl);
}
if (!CtrlFindUnique(task,CTRLT_WIN_VSCROLL)) {
c=CAlloc(sizeof(CCtrl));
c->win_task=task;
c->flags=CTRLF_SHOW|CTRLF_BORDER|CTRLF_CAPTURE_LEFT_MS;
c->type=CTRLT_WIN_VSCROLL;
c->state=&task->vert_scroll;
c->update_derived_vals=&WinDerivedScrollValsUpdate;
c->draw_it=&DrawWinScroll;
c->left_click=&LeftClickVWinScroll;
c->wheel_chg=&WheelChangeWinScroll;
QueIns(c,task->last_ctrl);
}
TaskDerivedValsUpdate(task);
}
#define VIEWANGLES_SPACING 22
#define VIEWANGLES_RANGE 48
#define VIEWANGLES_BORDER 2
#define VIEWANGLES_SNAP 2
U0 DrawViewAnglesCtrl(CDC *dc,CCtrl *c)
{
I64 i,j;
CViewAngles *s=c->state;
dc->color=s->cbd;
GrRect(dc, c->left,c->top,VIEWANGLES_SPACING*4+3,
VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
dc->color=s->cbg;
GrRect(dc, c->left+VIEWANGLES_BORDER,c->top+VIEWANGLES_BORDER,
VIEWANGLES_SPACING*4+3-2*VIEWANGLES_BORDER,
VIEWANGLES_SPACING*2+VIEWANGLES_RANGE-2*VIEWANGLES_BORDER);
dc->color=s->cfg;
GrLine(dc,c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING,
c->left+VIEWANGLES_SPACING,c->top+VIEWANGLES_SPACING+
VIEWANGLES_RANGE-1);
GrLine(dc,c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING,
c->left+2*VIEWANGLES_SPACING+1,c->top+VIEWANGLES_SPACING+
VIEWANGLES_RANGE-1);
GrLine(dc,c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING,
c->left+3*VIEWANGLES_SPACING+2,c->top+VIEWANGLES_SPACING+
VIEWANGLES_RANGE-1);
for (i=1;i<VIEWANGLES_RANGE+1;i+=2*VIEWANGLES_SNAP) {
j=2-i/3&1;
GrLine(dc,c->left+VIEWANGLES_SPACING-j,c->bottom-VIEWANGLES_SPACING-i,
c->left+VIEWANGLES_SPACING+j,c->bottom
-VIEWANGLES_SPACING-i);
GrLine(dc,c->left+2*VIEWANGLES_SPACING+1-j,c->bottom-VIEWANGLES_SPACING-i,
c->left+2*VIEWANGLES_SPACING+1+j,c->bottom
-VIEWANGLES_SPACING-i);
GrLine(dc,c->left+3*VIEWANGLES_SPACING+2-j,c->bottom-VIEWANGLES_SPACING-i,
c->left+3*VIEWANGLES_SPACING+2+j,c->bottom
-VIEWANGLES_SPACING-i);
}
dc->color=s->cx;
GrPrint(dc,c->left+VIEWANGLES_SPACING-FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"X");
GrPrint(dc,c->left+VIEWANGLES_SPACING-3*FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
"%3d",s->sx*360/VIEWANGLES_RANGE);
i=c->left+VIEWANGLES_SPACING;
if (s->sx>VIEWANGLES_RANGE/2)
j=-VIEWANGLES_RANGE/2+s->sx;
else
j=s->sx+VIEWANGLES_RANGE/2;
j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
GrRect(dc,i-3,j-2,7,5);
dc->color=s->cx^8;
GrRect(dc,i-2,j-1,5,3);
dc->color=s->cy;
GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Y");
GrPrint(dc,c->left+2*VIEWANGLES_SPACING+1-3*FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
"%3d",s->sy*360/VIEWANGLES_RANGE);
i=c->left+2*VIEWANGLES_SPACING+1;
if (s->sy>VIEWANGLES_RANGE/2)
j=-VIEWANGLES_RANGE/2+s->sy;
else
j=s->sy+VIEWANGLES_RANGE/2;
j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
GrRect(dc,i-3,j-2,7,5);
dc->color=s->cy^8;
GrRect(dc,i-2,j-1,5,3);
dc->color=s->cz;
GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Z");
GrPrint(dc,c->left+3*VIEWANGLES_SPACING+2-3*FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE+3,
"%3d",s->sz*360/VIEWANGLES_RANGE);
i=c->left+3*VIEWANGLES_SPACING+2;
if (s->sz>VIEWANGLES_RANGE/2)
j=-VIEWANGLES_RANGE/2+s->sz;
else
j=s->sz+VIEWANGLES_RANGE/2;
j=c->top+VIEWANGLES_SPACING+VIEWANGLES_RANGE-1-j;
GrRect(dc,i-3,j-2,7,5);
dc->color=s->cz^8;
GrRect(dc,i-2,j-1,5,3);
}
U0 UpdateDerivedViewAnglesCtrl(CCtrl *c)
{
CViewAngles *s=c->state;
c->left=c->win_task->pix_width-(VIEWANGLES_SPACING*4+3);
c->right=c->left+VIEWANGLES_SPACING*4+3;
c->top=c->win_task->pix_height-(VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
c->bottom=c->top+VIEWANGLES_SPACING*2+VIEWANGLES_RANGE;
s->sx=ClampI64(RoundI64(s->sx,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
s->sy=ClampI64(RoundI64(s->sy,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
s->sz=ClampI64(RoundI64(s->sz,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
s->ax=2*ã*s->sx/VIEWANGLES_RANGE;
s->ay=2*ã*s->sy/VIEWANGLES_RANGE;
s->az=2*ã*s->sz/VIEWANGLES_RANGE;
}
U0 LeftClickViewAngles(CCtrl *c,I64 x,I64 y,Bool)
{
CViewAngles *s=c->state;
I64 i;
i=VIEWANGLES_RANGE-1-(y-(c->top+VIEWANGLES_SPACING));
if (i>=VIEWANGLES_RANGE/2)
i-=VIEWANGLES_RANGE/2;
else
i+=VIEWANGLES_RANGE/2;
if (x<c->left+(c->right-c->left)/3)
s->sx=i;
else if (x<c->left+2*(c->right-c->left)/3)
s->sy=i;
else
s->sz=i;
if (c->update_derived_vals)
(*c->update_derived_vals)(c);
}
public CCtrl *ViewAnglesNew(CTask *task=NULL)
{//Create view angle ctrl. See $LK,"::/Demo/Graphics/Shading.HC"$.
CCtrl *c;
CViewAngles *s;
if (!task) task=Fs;
if (!(c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES))) {
s=CAlloc(sizeof(CViewAngles),task);
c=CAlloc(sizeof(CCtrl));
s->cbd=BLUE;
s->cbg=LTBLUE;
s->cfg=BLACK;
s->cx=LTGREEN;
s->cy=GREEN;
s->cz=LTGREEN;
c->win_task=task;
c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
c->type=CTRLT_VIEWING_ANGLES;
c->state=s;
c->draw_it=&DrawViewAnglesCtrl;
c->left_click=&LeftClickViewAngles;
c->update_derived_vals=&UpdateDerivedViewAnglesCtrl;
QueIns(c,task->last_ctrl);
TaskDerivedValsUpdate(task);
}
return c;
}
public U0 ViewAnglesDel(CTask *task=NULL)
{//Free view angle ctrl.
CCtrl *c;
if (!task) task=Fs;
if (c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES)) {
QueRem(c);
Free(c->state);
Free(c);
}
}
+91
View File
@@ -0,0 +1,91 @@
#define BTTN_BORDER 2
#define BTF_DONT_FREE 1
class CCtrlBttnState
{
I64 state,num_states,flags;
U8 *state_texts;
CColorROPU32 *state_colors;
};
U0 DrawCtrlBttn(CDC *dc,CCtrl *c)
{
CCtrlBttnState *s=c->state;
I64 l;
U8 *st;
dc->color=BLACK;
GrRect(dc,c->left,c->top,c->right-c->left+1,c->bottom-c->top+1);
if (!(st=LstSub(s->state,s->state_texts)))
st=s->state_texts;
dc->color=s->state_colors[s->state];
l=StrLen(st);
GrRect(dc,c->left+BTTN_BORDER,c->top+BTTN_BORDER,
c->right-c->left+1-BTTN_BORDER*2,
c->bottom-c->top+1-BTTN_BORDER*2);
dc->color=s->state_colors[s->state]^(WHITE<<16+WHITE);
GrPrint(dc,(c->left+c->right+1-l*FONT_WIDTH)>>1,
(c->top+c->bottom+1-FONT_HEIGHT)>>1,"%s",st);
}
U0 LeftClickCtrlBttn(CCtrl *c,I64,I64,Bool down)
{
CCtrlBttnState *s=c->state;
if (down) {
s->state++;
if (s->state==s->num_states)
s->state=0;
}
}
public CCtrl *CtrlBttnNew(I64 x,I64 y,I64 width=-1,I64 height=-1,
I64 num_states=1,U8 *state_texts,
I32 *state_colors,CCtrlBttnState *_s=NULL)
{//Create bttn ctrl. See $LK,"::/Apps/Strut/Strut.HC"$.
CCtrl *res;
CCtrlBttnState *s;
I64 i,j,l;
U8 *st;
if (width<0) {
l=1;
for (i=0;i<num_states;i++)
if (st=LstSub(i,state_texts)) {
j=StrLen(st);
if (j>l) l=j;
}
width=BTTN_BORDER*4+l*FONT_WIDTH;
}
if (height<0) height=BTTN_BORDER*4+FONT_HEIGHT;
res=CAlloc(sizeof(CCtrl));
if (_s) {
s=_s;
MemSet(s,0,sizeof(CCtrlBttnState));
} else {
s=CAlloc(sizeof(CCtrlBttnState));
s->flags=BTF_DONT_FREE;
}
s->num_states=num_states;
s->state_texts=state_texts;
s->state_colors=state_colors;
res->win_task=Fs;
res->flags=CTRLF_SHOW;
res->type=CTRLT_GENERIC;
res->state=s;
res->draw_it=&DrawCtrlBttn;
res->left_click=&LeftClickCtrlBttn;
res->left=x;
res->top=y;
res->right=res->left+width-1;
res->bottom=res->top+height-1;
QueIns(res,Fs->last_ctrl);
return res;
}
public U0 CtrlBttnDel(CCtrl *c)
{//Free bttn ctrl.
QueRem(c);
if (!(c->flags&BTF_DONT_FREE))
Free(c->state);
Free(c);
}
+214
View File
@@ -0,0 +1,214 @@
class CTemplateCSSlider
{
CTemplateCSSlider *next,*last;
U8 *name;
I64 num;
};
class CTemplateCS
{
CTemplateCSSlider *next_slider,*last_slider;
I64 num_sliders,range,spacing,border;
U8 *glbl_name;
};
CTemplateCS *CtrlSliderGet()
{
CTemplateCSSlider *tmps;
U8 *st,pmt[STR_LEN];
CTemplateCS *res=CAlloc(sizeof(CTemplateCS));
"$$PURPLE$$Ctrl Slider$$FG$$\n\n";
res->glbl_name=GetStr("Glbl Struct Name (ENTER for No Glbl):");
res->range=GetI64 ("Range (%4d):",30);
res->spacing=GetI64("Spacing (%4d):",20);
res->border=GetI64 ("Border (%4d):",2);
res->next_slider=res->last_slider=&res->next_slider;
while (TRUE) {
StrPrint(pmt,"Slider #%d Name:",res->num_sliders+1);
st=GetStr(pmt);
if (!*st) {
Free(st);
break;
}
tmps=CAlloc(sizeof(CTemplateCSSlider));
tmps->name=st;
QueIns(tmps,res->last_slider);
tmps->num=res->num_sliders++;
}
return res;
}
U0 TemplateCtrlSlider(CDoc *doc)
{
CTask *task;
CTemplateCS *m=NULL;
CTemplateCSSlider *tmps;
I64 i;
DocUnlock(doc);
DocRecalc(doc);
DocCaptureUndo(doc,TRUE);
task=User("CTemplateCS **_m=0x%X;*_m=CtrlSliderGet;\n",&m);
while (!m)
Yield;
DocPrint(doc,
"#define SLIDER_RANGE\t%d
#define SLIDER_SPACING\t%d
#define SLIDER_BORDER\t%d
class CSliderState
{
",m->range,m->spacing,m->border);
tmps=m->next_slider;
while (tmps!=&m->next_slider) {
DocPrint(doc," I64 %s;\n",tmps->name);
tmps=tmps->next;
}
if (*m->glbl_name)
DocPrint(doc,"} %s;\n",m->glbl_name);
else
DocPrint(doc,"};\n");
DocPrint(doc,
"
U0 DrawCtrlSlider(CDC *dc,CCtrl *c)
{
CSliderState *s=c->state;
dc->color=LTRED;
GrRect(dc, c->left,c->top,%d*SLIDER_SPACING+%d,SLIDER_SPACING*2+SLIDER_RANGE);
dc->color=BLUE;
GrRect(dc, c->left+SLIDER_BORDER,c->top+SLIDER_BORDER,
%d*SLIDER_SPACING+%d-2*SLIDER_BORDER,SLIDER_SPACING*2
+SLIDER_RANGE-2*SLIDER_BORDER);
dc->color=BLACK;
",m->num_sliders+1,m->num_sliders,m->num_sliders+1,m->num_sliders);
for (i=0;i<m->num_sliders;i++)
DocPrint(doc,
" GrLine(dc,c->left+%d*SLIDER_SPACING+%d,c->top+SLIDER_SPACING,
c->left+%d*SLIDER_SPACING+%d,c->top+SLIDER_SPACING+SLIDER_RANGE-1);
",i+1,i,i+1,i);
DocPrint(doc," dc->color=LTRED;\n");
tmps=m->next_slider;
while (tmps!=&m->next_slider) {
DocPrint(doc,
" GrPrint(dc,c->left+%d*SLIDER_SPACING+%d-FONT_WIDTH/2,
c->top+SLIDER_SPACING+SLIDER_RANGE+3,
\"%%d\",s->%s*10/SLIDER_RANGE);\n",
tmps->num+1,tmps->num,tmps->name);
tmps=tmps->next;
}
tmps=m->next_slider;
while (tmps!=&m->next_slider) {
DocPrint(doc,
" GrRect(dc,c->left+%d*SLIDER_SPACING+%d-3,"
"c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-2,7,5);\n",
tmps->num+1,tmps->num,tmps->name);
tmps=tmps->next;
}
DocPrint(doc," dc->color=YELLOW;\n");
tmps=m->next_slider;
while (tmps!=&m->next_slider) {
DocPrint(doc," GrRect(dc,c->left+%d*SLIDER_SPACING+%d-2,"
"c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-1,5,3);\n",
tmps->num+1,tmps->num,tmps->name);
tmps=tmps->next;
}
DocPrint(doc,
"}
U0 UpdateDerivedCtrlSlider(CCtrl *c)
{
CSliderState *s=c->state;
c->left=c->win_task->pix_width/2-(SLIDER_SPACING*3+2)/2;
c->right=c->left+%d*SLIDER_SPACING+%d;
c->top=c->win_task->pix_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
",m->num_sliders+1,m->num_sliders);
tmps=m->next_slider;
while (tmps!=&m->next_slider) {
DocPrint(doc," s->%s=ClampI64(s->%s,0,SLIDER_RANGE-1);\n",
tmps->name,tmps->name);
tmps=tmps->next;
}
DocPrint(doc,
"}
U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool down)
{
no_warn down;
CSliderState *s=c->state;
");
tmps=m->next_slider;
while (tmps!=&m->next_slider) {
DocPrint(doc," ");
if (tmps!=m->next_slider)
DocPrint(doc,"else ");
if (tmps->next==&m->next_slider)
DocPrint(doc,"\n");
else
DocPrint(doc,"if (x<c->left+%d*SLIDER_SPACING+%d+SLIDER_SPACING/2)\n",
tmps->num+1,tmps->num);
DocPrint(doc," s->%s=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));\n",
tmps->name);
tmps=tmps->next;
}
DocPrint(doc,
" if (c->update_derived_vals)
(*c->update_derived_vals)(c);
}
CCtrl *SliderNew()
{
CCtrl *c=CAlloc(sizeof(CCtrl));
c->win_task=Fs;
c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_MS;
c->type=CTRLT_GENERIC;
");
if (*m->glbl_name)
DocPrint(doc," c->state=&%s;\n"
" MemSet(&%s,0,sizeof(CSliderState));\n",m->glbl_name,m->glbl_name);
else
DocPrint(doc, " c->state=CAlloc(sizeof(CSliderState));\n");
DocPrint(doc,
" c->draw_it=&DrawCtrlSlider;
c->left_click=&LeftClickSlider;
c->update_derived_vals=&UpdateDerivedCtrlSlider;
QueIns(c,Fs->last_ctrl);
TaskDerivedValsUpdate;
return c;
}
U0 SliderDel(CCtrl *c)
{
QueRem(c);
");
if (!*m->glbl_name)
DocPrint(doc," Free(c->state);\n");
DocPrint(doc,
" Free(c);
}
");
Kill(task); //This frees memory.
RegOneTimePopUp(ARf_MANAGE_SLIDER,
"Modify the code to your heart's content.\n"
"The code is no longer managed.\n");
DocLock(doc);
}
+8
View File
@@ -0,0 +1,8 @@
Cd(__DIR__);;
#help_index "Ctrls"
#help_file "::/Doc/Ctrls"
#include "CtrlsA"
#include "CtrlsBttn"
#include "CtrlsSlider"
Cd("..");;
+220
View File
@@ -0,0 +1,220 @@
#help_index "PCI;Processor;Devices;Info"
//The file was downloaded from
//http://www.pcidatabase.com/reports.php?type=tab-delimeted
#define PCI_DEV_FILE "::/Misc/PCIDevices.DD.Z"
/****
//1) Download http://www.pcidatabase.com/reports.php?type=tab-delimeted
//2) Rename to ::/Misc/PCIDevices.DD.Z
//3) ToDolDoc("::/Misc/PCIDevices.DD.Z");
//4) Edit and remove file header and tail
//5) Text find-and-replace "=0A=" with "". (Doesn't seem necessary anmore.)
//6) Run PCIDevFileGen(). (Doesn't seem necessary anmore.)
public U0 PCIDevFileGen()
{
Bool first=TRUE,del=FALSE,del2=FALSE,cont=FALSE;
CDoc *doc=DocRead(PCI_DEV_FILE,
DOCF_PLAIN_TEXT|DOCF_DBL_DOLLARS|DOCF_NO_CURSOR);
CDocEntry *doc_e=doc->head.next,*doc_e2;
while (doc_e!=doc) {
doc_e2=doc_e->next;
if (first) {
if (doc_e->type_u8==DOCT_TEXT) {
if (doc_e->tag[0]==';')
del=TRUE;
}
first=FALSE;
}
if (doc_e->type_u8==DOCT_TEXT && doc_e->tag[StrLen(doc_e->tag)-1]=='=' &&
doc_e2->type_u8==DOCT_NEW_LINE) {
doc_e->tag[StrLen(doc_e->tag)-1]=CH_SPACE;
cont=TRUE;
}
del2=del;
if (doc_e->type_u8==DOCT_NEW_LINE) {
first=TRUE;
del2=FALSE;
if (cont) {
del=TRUE;
cont=FALSE;
}
}
if (del)
DocEntryDel(doc,doc_e);
del=del2;
doc_e=doc_e2;
}
DocWrite(doc);
}
****/
//$LK,"::/Misc/PCIDevices.DD",A="PI:::/Misc/PCIDevices.DD"$
U0 PCILookUpSingle(CDoc *doc,I64 m,I64 d,U8 **_vendor,U8 **_dev)
{
Bool first=TRUE;
U8 buf[8],*vendor=NULL,*dev=NULL;
CDocEntry *doc_e=doc->head.next;
while (doc_e!=doc) {
if (first) {
if (doc_e->type_u8==DOCT_TEXT && doc_e->tag[0]!=';' &&
StrLen(doc_e->tag)>=4) {
buf[0](U16)='0x';
buf[2](U32)=doc_e->tag(U32 *)[0];
buf[6]=0;
if (Str2I64(buf)==m) {
doc_e=doc_e->next->next;
if (doc_e->type_u8==DOCT_TEXT) {
vendor=AStrNew(doc_e->tag);
first=FALSE;
break;
}
}
}
first=FALSE;
}
if (doc_e->type_u8==DOCT_NEW_LINE)
first=TRUE;
doc_e=doc_e->next;
}
if (vendor) {
while (doc_e!=doc) {
if (first) {
if (doc_e->type_u8==DOCT_TAB) {
doc_e=doc_e->next;
if (doc_e->type_u8==DOCT_TEXT && StrLen(doc_e->tag)>=4) {
buf[0](U16)='0x';
buf[2](U32)=doc_e->tag(U32 *)[0];
buf[6]=0;
if (Str2I64(buf)==d) {
doc_e=doc_e->next->next;
if (doc_e->type_u8==DOCT_TEXT) {
dev=AStrNew(doc_e->tag);
break;
}
}
}
} else
break;
first=FALSE;
}
if (doc_e->type_u8==DOCT_NEW_LINE)
first=TRUE;
doc_e=doc_e->next;
}
}
if (vendor)
*_vendor=vendor;
else
*_vendor=AStrNew("Unknown");
if (dev)
*_dev=dev;
else
*_dev=AStrNew("Unknown");
}
U0 PCILookUpDevs()
{
CPCIDev *tmppci;
I64 w1,w2,b,d,f,timeout=32*8*2;
CDoc *doc;
if (dev.pci_head.next!=&dev.pci_head)
return;
doc=DocRead(PCI_DEV_FILE,DOCF_PLAIN_TEXT|DOCF_NO_CURSOR);
for (b=0;b<sys_pci_busses;b++)
for (d=0;d<32;d++)
for (f=0;f<8;f++) {
w1=PCIReadU16(b,d,f,0);
if (w1!=0xFFFF) {
tmppci=ACAlloc(sizeof(CPCIDev));
tmppci->bus=b;
tmppci->dev=d;
tmppci->fun=f;
tmppci->vendor=w1;
tmppci->dev_id=w2=PCIReadU16(b,d,f,2);
tmppci->sub_code=PCIReadU8(b,d,f,0xA);
tmppci->base_code=PCIReadU8(b,d,f,0xB);
PCILookUpSingle(doc,w1,w2,&tmppci->vendor_str,&tmppci->dev_id_str);
QueIns(tmppci,dev.pci_head.last);
timeout=32*8*2;
} else if (sys_pci_busses==256 && --timeout<=0)
goto lud_done;
}
lud_done:
DocDel(doc);
}
public U0 PCIRep()
{//Report description of PCI devices.
CPCIDev *tmppci;
"PCI Busses:%d\n",sys_pci_busses;
if (!FileFind(PCI_DEV_FILE)) {
"You don't have the PCI device file.\n";
return;
}
PCILookUpDevs;
tmppci=dev.pci_head.next;
while (tmppci!=&dev.pci_head) {
"%02X:%02X:%01X %02X%02X $$GREEN$$%s $$CYAN$$%s$$FG$$\n",
tmppci->bus,tmppci->dev,tmppci->fun,
tmppci->base_code,tmppci->sub_code,
tmppci->vendor_str,tmppci->dev_id_str;
tmppci=tmppci->next;
}
}
#help_index "Info;Memory/Info"
public U0 MemBIOSRep()
{//Report the memory ranges reported by the BIOS at boot.
U16 *m01=MEM_E801;
CMemE820 *m20=MEM_E820;
CMemRange *tmpmr;
"Standard Addresses\n"
"000A0000-000BFFFF VGA\n"
"FEE00000-FEE00FFF See $$LK,\"APIC\",A=\"MN:LAPIC_BASE\"$$\n\n"
"32 Bit Device Mem\n";
while (LBts(&sys_semas[SEMA_DEV_MEM],0))
Yield;
tmpmr=dev.mem32_head.next;
while (tmpmr!=&dev.mem32_head) {
"%02X:%016X-%016X\n",
tmpmr->type,tmpmr->base,tmpmr->base+tmpmr->size-1;
tmpmr=tmpmr->next;
}
LBtr(&sys_semas[SEMA_DEV_MEM],0);
"\nBIOS Memory Report 15:E801\n"
"01:0000000000000000-%016X\n",0x100000+m01[0]<<10-1;
"01:0000000001000000-%016X\n",SYS_16MEG_AREA_LIMIT+m01[1]<<16-1;
if (m20->type) {
'\n';
"BIOS Memory Report 15:E820\n";
while (m20->type) {
"%02X:%016X-%016X\n",m20->type,m20->base,m20->base+m20->len-1;
m20++;
}
}
}
public U0 MemPageRep()
{//Page Table Report.
"MAPPED\t :%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;
}
+142
View File
@@ -0,0 +1,142 @@
#help_index "DolDoc/Bin"
CDocBin *DocBinFindNum(CDoc *haystack_doc,I64 needle_num)
{
CDocBin *b=haystack_doc->bin_head.next;
while (b!=&haystack_doc->bin_head) {
if (b->num==needle_num)
return b;
b=b->next;
}
return NULL;
}
CDocBin *DocBinFindTag(CDoc *haystack_doc,U8 *needle_tag)
{
CDocBin *b;
if (needle_tag) {
b=haystack_doc->bin_head.next;
while (b!=&haystack_doc->bin_head) {
if (b->tag && !StrCmp(b->tag,needle_tag))
return b;
b=b->next;
}
}
return NULL;
}
U0 DocBinsValidate(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocBin *b,*b1;
CDocEntry *doc_e,*doc_e2;
I64 renum_num=0;
b=doc->bin_head.next;
while (b!=&doc->bin_head) {
b->use_cnt=0;
b->tmp_use_cnt=0;
b->renum_num=-1;
Free(b->tag);
b->tag=NULL;
b=b->next;
}
doc_e=doc->head.next;
while (doc_e!=doc) {
doc_e2=doc_e->next;
if (doc_e->de_flags & DOCEF_HAS_BIN) {
if (b=doc_e->bin_data=DocBinFindNum(doc,doc_e->bin_num)) {
if (doc_e->de_flags & DOCEF_BIN_PTR_LINK)
b->tmp_use_cnt=I32_MAX;
if (!b->use_cnt++)
b->renum_num=++renum_num;
doc_e->bin_num=b->renum_num;
if (!b->tag && doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
b->tag=StrNew(doc_e->tag,doc->mem_task);
} else {
RawPrint(3000,"Bin Not Found");
doc_e->type=doc_e->de_flags=0;
doc_e->type_u8=DOCT_ERROR;
}
}
doc_e=doc_e2;
}
b=doc->bin_head.next;
doc->cur_bin_num=1;
while (b!=&doc->bin_head) {
b1=b->next;
if (!b->use_cnt) {
QueRem(b);
Free(b->data);
Free(b);
} else {
b->num=b->renum_num;
if (b->num>=doc->cur_bin_num)
doc->cur_bin_num=b->num+1;
}
b=b1;
}
if (unlock)
DocUnlock(doc);
}
U0 DocBinDel(CDoc *doc,CDocBin *b)
{
if (doc && b && b->use_cnt) {
b->use_cnt--;
if (!b->use_cnt) {
QueRem(b);
Free(b->tag);
Free(b->data);
Free(b);
}
} else
RawPrint(3000,"DocBinDel");
}
I64 DocBinPtrRst(CDoc *doc,CDocEntry *doc_e)
{
U8 *st,*st2;
CDoc *doc2;
CDocBin *tmpb,*tmpb2;
I64 i,bin_num=0;
if (doc_e->de_flags&DOCEF_HAS_BIN &&
doc_e->bin_ptr_link && StrLen(doc_e->bin_ptr_link)) {
bin_num=doc_e->bin_num;
st=StrNew(doc_e->bin_ptr_link);
st2=StrNew(st);
StrLastRem(st,",",st2);
i=Str2I64(st2);
if (i>0||*st2) {
doc2=DocRead(st);
if (i>0 && (tmpb2=DocBinFindNum(doc2,i)) ||
i==0 && (tmpb2=DocBinFindTag(doc2,st2))) {
i=1;
if (bin_num>0) {
if (tmpb=DocBinFindNum(doc,bin_num)) {
i=tmpb->use_cnt;
DocBinDel(doc,tmpb);
}
} else
bin_num=doc->cur_bin_num++;
tmpb=MAllocIdent(tmpb2,doc->mem_task);
tmpb->use_cnt=i;
tmpb->data=MAllocIdent(tmpb2->data,doc->mem_task);
tmpb->num=bin_num;
doc_e->bin_data=tmpb;
if (doc_e->de_flags&DOCEF_TAG && doc_e->tag && *doc_e->tag)
tmpb->tag=StrNew(doc_e->tag,doc->mem_task);
else
tmpb->tag=NULL;
QueIns(tmpb,doc->bin_head.last);
} else
bin_num=0;
DocDel(doc2);
} else
bin_num=0;
Free(st2);
Free(st);
doc_e->bin_num=bin_num;
}
return bin_num;
}
+652
View File
@@ -0,0 +1,652 @@
#help_index "DolDoc/Editor"
public I64 EdCurU8(CDoc *doc)
{//Return cur U8. See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
Bool unlock=DocLock(doc);
CDocEntry *doc_ce=doc->cur_entry;
I64 res=-1;
if (doc_ce->type_u8==DOCT_TEXT &&
doc_ce->min_col<=doc->cur_col<doc_ce->max_col)
res=doc_ce->tag[doc->cur_col];
else if (doc_ce->type_u8==DOCT_TAB)
res='\t';
else if (doc_ce->type_u8==DOCT_NEW_LINE ||
doc_ce->type_u8==DOCT_SOFT_NEW_LINE)
res='\n';
if (unlock)
DocUnlock(doc);
return res;
}
public U0 EdCursorLeft(CDoc *doc,I64 sc=I64_MIN)
{//Move cursor left. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
U8 *dst;
Bool unlock=DocLock(doc);
CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
I64 cc=doc->cur_col,y=doc_ce->y;
if (sc!=I64_MIN) sc=sc.u32[0];
if (sc>=0 && sc&SCF_CTRL) {
while (doc_ce->last!=doc && (doc_ce->last->y==y ||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)))
doc_ce=doc_ce->last; //TODO: sel? recurse?
cc=doc_ce->min_col;
} else {
if (cc>doc_ce->min_col) {
if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
}
cc--;
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
cc=doc_ce->min_col;
}
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
} else {
cc=doc_ce->min_col;
while (doc_ce->last!=doc &&
(doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE ||
doc_ce->last->type_u8==DOCT_INDENT ||
doc_ce->last->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
doc_ce=doc_ce->last;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
}
if (doc_ce->last!=doc) {
doc_ce=doc_ce->last;
if (doc_ce->max_col>doc_ce->min_col) {
cc=doc_ce->max_col-1;
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
cc=doc_ce->min_col;
}
} else
cc=doc_ce->max_col;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
}
}
}
doc->cur_col=cc;
doc->cur_entry=doc_ce;
if (doc_ce!=original_ce)
DocFormBwd(doc);
if (unlock)
DocUnlock(doc);
}
public U0 EdCursorRight(CDoc *doc,I64 sc=I64_MIN)
{//Move cursor right. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
Bool unlock=DocLock(doc);
U8 *dst;
CDocEntry *doc_ce=doc->cur_entry,*original_ce=doc_ce,*doc_ne;
I64 cc=doc->cur_col,y=doc_ce->y,old_de_flags,old_color;
if (sc!=I64_MIN) sc=sc.u32[0];
if (sc>=0 && sc&SCF_CTRL) {
while (doc_ce!=doc && doc_ce->next->y==y &&
doc_ce->next->type_u8!=DOCT_SOFT_NEW_LINE && doc_ce->next!=doc &&
(doc_ce->next->type_u8!=DOCT_NEW_LINE || !(doc->flags & DOCF_FORM)) ||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))
doc_ce=doc_ce->next;
if (doc_ce->max_col>doc_ce->min_col)
cc=doc_ce->max_col-1;
else
cc=doc_ce->min_col;
} else {
if (cc<doc_ce->max_col) {
if (IsEditableText(doc_ce) && cc>doc_ce->min_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
cc=doc_ce->min_col;
}
cc++;
old_de_flags=doc_ce->de_flags;
old_color=doc_ce->type;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
if (IsEditableText(doc_ce) && cc<doc_ce->max_col) {
dst=doc_ce->tag+cc;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
doc_ne->type=DOCT_TEXT | old_color & -0x100;
doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
doc_ce->max_col=cc;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
cc=doc_ce->min_col;
} else if (cc>=doc_ce->max_col) {
doc_ce=doc_ce->next;
cc=doc_ce->min_col;
}
} else {
if (doc_ce!=doc) {
if (cc<=doc_ce->min_col && sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
doc_ce=doc_ce->next;
while (doc_ce!=doc && doc_ce->de_flags&(DOCEF_SKIP|DOCEF_FILTER_SKIP)) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
doc_ce=doc_ce->next;
}
cc=doc_ce->min_col;
if (doc_ce->type_u8==DOCT_SOFT_NEW_LINE) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
doc_ce=doc_ce->next;
cc=doc_ce->min_col;
}
}
}
}
doc->cur_col=cc;
doc->cur_entry=doc_ce;
if (doc_ce!=original_ce)
DocFormFwd(doc);
if (unlock)
DocUnlock(doc);
}
public U0 EdLineUp(CDoc *doc,I64 sc=I64_MIN)
{//Move cursor up. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
Bool unlock=DocLock(doc);
U8 *dst;
I64 y,x;
CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
if (sc!=I64_MIN) sc=sc.u32[0];
if (doc_ce->type_u8==DOCT_HEX_ED) {
doc->cur_col=doc->cur_col-doc_ce->hex_ed_width*3;
if (doc->cur_col>=0) {
if (unlock)
DocUnlock(doc);
return;
} else
doc->cur_col=0;
}
x=doc->x; y=doc->y;
if (IsEditableText(doc_ce)) {
if (doc_ce->min_col<doc->cur_col<doc_ce->max_col-1) {
dst=doc_ce->tag+doc->cur_col;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
doc_ne->x=doc_ce->x+doc->cur_col;
doc_ce->max_col=doc->cur_col;
QueIns(doc_ne,doc_ce);
} else if (doc->cur_col==doc_ce->min_col && doc_ce->last!=doc)
doc_ce=doc_ce->last;
} else if (doc_ce->last!=doc)
doc_ce=doc_ce->last;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
doc->cur_entry=doc_ce;
DocFormBwd(doc);
doc_ce=doc->cur_entry;
while (doc_ce->last!=doc && (doc_ce->y>=y ||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
doc_ce=doc_ce->last;
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
}
y=doc_ce->y;
doc->y=y;
while (doc_ce!=doc && (doc_ce->y>=y && doc_ce->x>=x ||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
doc_ce=doc_ce->last;
}
if (doc_ce==doc || doc_ce->y<y)
doc_ce=doc_ce->next;
else {
if (!IsEditableText(doc_ce)) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
} else {
if (doc_ce->next->x==x) {
doc_ce=doc_ce->next;
if (doc->flags & DOCF_FORM)
while (doc_ce->next->x==x &&
(!Bt(doldoc.type_flags_form,doc_ce->type_u8) &&
!(doc_ce->de_flags&DOCEF_LINK)||
doc_ce->de_flags&DOCEF_SKIP_IN_FORM))
doc_ce=doc_ce->next;
}
}
}
if (doc_ce->de_flags&DOCEF_TAG) {
doc->cur_col=x-doc_ce->x;
if (IsEditableText(doc_ce)) {
if (doc->cur_col>doc_ce->max_col)
doc->cur_col=doc_ce->max_col;
} else if (doc->cur_col>=doc_ce->max_col)
doc->cur_col=doc_ce->max_col-1;
if (doc->cur_col<doc_ce->min_col)
doc->cur_col=doc_ce->min_col;
} else {
if (doc_ce->type_u8==DOCT_HEX_ED) {
doc->cur_col=RoundI64((doc_ce->len-1)*3,doc_ce->hex_ed_width*3);
if (doc->cur_col<0)
doc->cur_col=0;
} else
doc->cur_col=doc_ce->min_col;
}
if (IsEditableText(doc_ce) && doc_ce->x<x) {
if (doc->cur_col<doc_ce->max_col-1) {
dst=doc_ce->tag+doc->cur_col;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
if (sc>=0) {
if (sc&SCF_SHIFT)
doc_ne->type=doc_ce->type | DOCET_SEL;
else
doc_ne->type=doc_ce->type & ~DOCET_SEL;
}
doc_ne->x=doc_ce->x+doc->cur_col;
doc_ce->max_col=doc->cur_col;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
doc->cur_col=doc_ce->min_col;
}
}
doc->cur_entry=doc_ce;
DocFormFwd(doc);
doc->x=doc->cur_entry->x+doc->cur_col;
if (unlock)
DocUnlock(doc);
}
public U0 EdLineDown(CDoc *doc,I64 sc=I64_MIN)
{//Move cursor down. Might need a call to $LK,"DocRecalc",A="MN:DocRecalc"$().
//See $LK,"EdRenumAsm",A="MN:EdRenumAsm"$ for an example.
Bool unlock=DocLock(doc);
U8 *dst;
I64 y,x,old_de_flags=0,old_color;
CDocEntry *doc_ce=doc->cur_entry,*doc_ne,*doc_ce2;
if (sc!=I64_MIN) sc=sc.u32[0];
if (doc_ce->type_u8==DOCT_HEX_ED) {
doc->cur_col=doc->cur_col+doc_ce->hex_ed_width*3;
if (doc->cur_col>=doc_ce->len*3) {
doc->cur_entry=doc_ce=doc_ce->next;
doc->cur_col=doc_ce->min_col;
doc->x=doc_ce->x+doc->cur_col;
doc->y=doc_ce->y;
}
if (unlock)
DocUnlock(doc);
return;
}
x=doc->x; y=doc->y;
if (IsEditableText(doc_ce)) {
if (doc->cur_col>doc_ce->min_col && doc->cur_col<doc_ce->max_col-1) {
dst=doc_ce->tag+doc->cur_col;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
if (sc>=0) {
if (sc&SCF_SHIFT)
doc_ne->type=doc_ce->type | DOCET_SEL;
else
doc_ne->type=doc_ce->type & ~DOCET_SEL;
}
doc_ne->x=doc_ce->x+doc->cur_col;
doc_ce->max_col=doc->cur_col;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
doc->cur_col=doc_ce->min_col;
}
}
doc_ce2=doc_ce;
while (doc_ce!=doc && (doc_ce->y<=y ||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP)))
doc_ce=doc_ce->next;
y=doc_ce->y;
doc->y=y;
while (doc_ce!=doc && (doc_ce->y<=y && doc_ce->x<=x ||
doc_ce->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP))) {
old_de_flags=doc_ce->de_flags;
old_color=doc_ce->type;
doc_ce=doc_ce->next;
}
if (doc_ce->last!=doc && (doc_ce->x>x && doc_ce->last->y>=y || doc_ce->y>y)) {
doc_ce=doc_ce->last;
doc->cur_entry=doc_ce;
if (!((doc_ce->type_u8==DOCT_NEW_LINE ||
doc_ce->type_u8==DOCT_SOFT_NEW_LINE ||
doc_ce->type_u8==DOCT_INDENT) &&
(doc_ce->last->type_u8==DOCT_NEW_LINE ||
doc_ce->last->type_u8==DOCT_SOFT_NEW_LINE ||
doc_ce->last->type_u8==DOCT_INDENT)))
DocFormBwd(doc);
doc_ce=doc->cur_entry;
}
while (doc_ce2!=doc && (doc_ce2!=doc_ce || IsEditableText(doc_ce))) {
if ((doc_ce2->y<y || doc_ce2->x<x ||
doc_ce2->de_flags & (DOCEF_SKIP|DOCEF_FILTER_SKIP) ||
doc_ce2->x==x && !doc_ce2->max_col &&
Bt(doldoc.type_flags_nontag_invis,doc_ce2->type_u8)) && sc>=0)
BEqu(&doc_ce2->type,DOCEt_SEL,sc&SCF_SHIFT);
if (doc_ce2==doc_ce) break;
doc_ce2=doc_ce2->next;
}
if (doc_ce->de_flags&DOCEF_TAG) {
doc->cur_col=x-doc_ce->x;
if (IsEditableText(doc_ce)) {
if (doc->cur_col>doc_ce->max_col)
doc->cur_col=doc_ce->max_col;
} else if (doc->cur_col>=doc_ce->max_col)
doc->cur_col=doc_ce->max_col-1;
if (doc->cur_col<doc_ce->min_col)
doc->cur_col=doc_ce->min_col;
} else
doc->cur_col=doc_ce->min_col;
if (IsEditableText(doc_ce)&&doc_ce->min_col<doc->cur_col<doc_ce->max_col-1) {
dst=doc_ce->tag+doc->cur_col;
doc_ne=DocEntryNewTag(doc,doc_ce,dst);
*dst=0;
doc_ne->type=DOCT_TEXT | old_color & -0x100;
doc_ne->de_flags=old_de_flags|doldoc.dft_de_flags[DOCT_TEXT];
doc_ce->max_col=doc->cur_col;
doc_ne->x=doc_ce->x+doc->cur_col;
QueIns(doc_ne,doc_ce);
doc_ce=doc_ne;
doc->cur_col=doc_ce->min_col;
}
doc->cur_entry=doc_ce;
DocFormFwd(doc);
if (!(doc->flags & DOCF_FORM))
while (doc_ce!=doc && doc_ce!=doc->cur_entry) {
if (sc>=0)
BEqu(&doc_ce->type,DOCEt_SEL,sc&SCF_SHIFT);
doc_ce=doc_ce->next;
}
doc->x=doc->cur_entry->x+doc->cur_col;
if (unlock)
DocUnlock(doc);
}
U0 EdCharDel(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocEntry *doc_ce=doc->cur_entry;
if (doc_ce==doc) {
if (unlock)
DocUnlock(doc);
return;
}
if (doc_ce->max_col!=0 &&
(IsEditableText(doc_ce)||doc_ce->type_u8==DOCT_DATA)) {
if (doc_ce->type_u8==DOCT_DATA && doc_ce->de_flags & DOCEF_HAS_TERMINATOR &&
doc->cur_col==doc_ce->max_col-1) {
if (unlock)
DocUnlock(doc);
return;
}
if (doc->cur_col<doc_ce->max_col)
StrCpy(doc_ce->tag+doc->cur_col,doc_ce->tag+doc->cur_col+1);
if (doc->cur_col>=doc_ce->max_col-1) {
doc->cur_entry=doc_ce->next;
doc->cur_col=doc->cur_entry->min_col;
}
DocRemSoftNewLines(doc,doc->cur_entry);
if (unlock)
DocUnlock(doc);
return;
}
doc->cur_entry=doc_ce->next;
doc->cur_col=doc->cur_entry->min_col;
if (!(doc_ce->de_flags&DOCEF_FILTER_SKIP))
DocEntryDel(doc,doc_ce);
DocRemSoftNewLines(doc,doc->cur_entry);
if (unlock)
DocUnlock(doc);
}
U0 ChkDollarBufSize(CDoc *doc)
{
U8 *b;
if (doc->dollar_buf_ptr>=doc->dollar_buf_size-2) {
doc->dollar_buf_size<<=1;
b=MAlloc(doc->dollar_buf_size,doc->mem_task);
MemCpy(b,doc->dollar_buf,doc->dollar_buf_ptr);
Free(doc->dollar_buf);
doc->dollar_buf=b;
}
}
U0 EdCharIns(I64 ch,I64 sc,CDoc *doc)
{
Bool unlock=DocLock(doc);
U8 *st,*src,*dst;
CDocEntry *doc_ce=doc->cur_entry,*doc_ne;
I64 i,j,m,y=doc_ce->y;
if (doc->flags & DOCF_IN_DOLLAR) {
if (!Bt(char_bmp_printable,ch))
goto ic_done;
ChkDollarBufSize(doc);
doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
if (ch=='$$') {
if (doc->dollar_buf_ptr==2) {
doc->flags&=~DOCF_IN_DOLLAR;
doc->dollar_buf_ptr=0;
goto ic_cont;
} else {
doc->dollar_buf[doc->dollar_buf_ptr]=0;
doc->flags&=~DOCF_IN_DOLLAR;
DocPrint(doc,"%s",doc->dollar_buf);
doc->dollar_buf_ptr=0;
goto ic_done;
}
} else
goto ic_done;
}
if (ch=='$$' && !(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_TABS))) {
doc->flags|=DOCF_IN_DOLLAR;
doc->dollar_buf_ptr=0;
doc->dollar_buf[doc->dollar_buf_ptr++]=ch;
goto ic_done;
}
if (ch=='\r') goto ic_done;
ic_cont:
if ((ch==CH_SPACE || ch=='\n') &&
!(sc & (SCF_CTRL|SCF_SHIFT)) &&
doc_ce->de_flags &
(DOCEF_LINK|DOCEF_TREE|DOCEF_LST|DOCEF_CHECK_COLLAPSABLE|
DOCEF_LEFT_MACRO|DOCEF_LEFT_EXP|DOCEF_LEFT_CB|DOCEF_LEFT_IN_STR |
DOCEF_RIGHT_MACRO|DOCEF_RIGHT_EXP|DOCEF_RIGHT_CB|DOCEF_RIGHT_IN_STR)) {
doc->cmd_U8=ch;
DocEntryRun(doc,doc_ce,FALSE);
DocLock(doc);
goto ic_done;
}
if (doc_ce->type_u8==DOCT_HEX_ED) {
if (doc_ce->de_flags&DOCEF_DEREF_DATA &&
!(doc_ce->de_flags&DOCEF_REMALLOC_DATA))
st=doc_ce->data;
else
st=&doc_ce->data;
i=doc->cur_col;
j=i%(doc_ce->hex_ed_width*3);
m=i/(doc_ce->hex_ed_width*3)*doc_ce->hex_ed_width;
if (j>=doc_ce->hex_ed_width<<1)
st[j-doc_ce->hex_ed_width<<1+m]=ch;
else {
ch=ToUpper(ch)-'0';
if (ch>9) {
ch+='0'-'A'+10;
if (!(10<=ch<=15))
goto ic_done;
}
m=j>>1+m;
if (j & 1)
st[m]=st[m] & 0xF0| ch;
else
st[m]=st[m] & 0xF | ch<<4;
}
doc->cur_col++;
goto ic_done;
}
if (doc->flags & DOCF_OVERSTRIKE) {
if (Bt(char_bmp_displayable,ch)) {
ic_overstrike:
if (IsEditableText(doc_ce)) {
if (doc->cur_col<doc_ce->max_col) {
if (doc_ce->tag[doc->cur_col]) {
doc_ce->tag[doc->cur_col++]=ch;
goto ic_done;
}
} else {
doc_ce=doc_ce->next;
doc->cur_entry=doc_ce;
doc->cur_col=doc_ce->min_col;
goto ic_overstrike;
}
} else if (doc_ce->type_u8==DOCT_DATA) {
if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR) {
if (doc_ce->tag[doc->cur_col] &&
doc->cur_col<doc_ce->min_col+doc_ce->len) {
doc_ce->tag[doc->cur_col++]=ch;
if ( ! doc_ce->tag[doc->cur_col]) {
doc_ce->tag[doc->cur_col]='_';
doc_ce->tag[doc->cur_col+1]=0;
}
} else if (doc_ce->de_flags & DOCEF_REMALLOC_DATA)
goto ic_not_overstrike;
} else if (doc_ce->tag[doc->cur_col])
doc_ce->tag[doc->cur_col++]=ch;
goto ic_done;
}
doc_ne=DocEntryNewTag(doc,doc_ce,&ch);
doc_ne->type=DOCT_TEXT | doc->settings_head.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
QueIns(doc_ne,doc_ce->last);
} else if (ch=='\n') {
while (doc->cur_entry->next!=doc && doc->cur_entry->y==y)
doc->cur_entry=doc->cur_entry->next;
doc->cur_col=doc->cur_entry->min_col;
} else if (ch=='\t') {
if (doc->flags&DOCF_FORM)
goto ic_form_tab;
}
goto ic_done;
}
ic_not_overstrike:
if (ch=='\n') {
if (sc&SCF_CTRL && !(sc&SCF_SHIFT)) {
doc_ne=DocEntryNewBase(doc,
DOCT_PAGE_BREAK|doc->settings_head.dft_text_attr<<8);
} else {
doc_ne=DocEntryNewBase(doc,
DOCT_NEW_LINE|doc->settings_head.dft_text_attr<<8);
}
DocInsEntry(doc,doc_ne);
} else if (ch=='\t') {
if (doc->flags&DOCF_FORM &&
(Bt(doldoc.type_flags_form,doc->cur_entry->type_u8) ||
doc->cur_entry->de_flags&DOCEF_LINK) &&
!(doc->cur_entry->de_flags&DOCEF_SKIP_IN_FORM)) {
ic_form_tab:
doc->cur_entry=doc->cur_entry->next;
doc->cur_col=doc->cur_entry->min_col;
DocFormFwd(doc);
goto ic_done;
} else {
doc_ne=DocEntryNewBase(doc,DOCT_TAB|doc->settings_head.dft_text_attr<<8);
DocInsEntry(doc,doc_ne);
}
} else {
if (Bt(char_bmp_displayable,ch)) {
if (doc_ce->type_u8==DOCT_DATA) {
while (TRUE) {
i=doc_ce->len+doc_ce->min_col;
if (doc_ce->de_flags & DOCEF_HAS_TERMINATOR)
i++;
if (doc_ce->max_col<i) {
st=doc_ce->tag;
doc_ce->max_col++;
for (i=doc_ce->max_col;i>doc->cur_col;i--)
st[i]=st[i-1];
st[doc->cur_col++]=ch;
break;
} else if (doc_ce->de_flags & DOCEF_REMALLOC_DATA) {
st=MAlloc(doc_ce->max_col+8,doc->mem_task);
MemCpy(st,doc_ce->tag,doc_ce->max_col+1);
Free(doc_ce->tag);
doc_ce->tag=st;
doc_ce->len=MSize(st)-doc_ce->min_col-2; //See $LK,"DataTagWidth",A="FA:::/Adam/DolDoc/DocPlain.HC,DataTagWidth"$
Free(doc_ce->data);
doc_ce->data=MAlloc(doc_ce->len+2,doc->mem_task);
} else
break;
}
} else if (IsEditableText(doc_ce)) {
dst=st=MAlloc(doc_ce->max_col+2,doc->mem_task);
src=doc_ce->tag;
i=doc->cur_col;
while (i-->0)
*dst++=*src++;
*dst++=ch;
while (*dst++=*src++);
Free(doc_ce->tag);
doc_ce->tag=st;
doc_ce->max_col++;
doc->cur_col++;
} else {
doc_ne=DocEntryNewTag(doc,doc_ce,&ch);
doc_ne->type=DOCT_TEXT | doc->settings_head.dft_text_attr<<8;
doc_ne->de_flags=doldoc.dft_de_flags[DOCT_TEXT];
doc_ne->x=doc_ce->x+1;
QueIns(doc_ne,doc_ce->last);
}
}
}
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;
}
}
+123
View File
@@ -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;
}
+658
View File
@@ -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;
}
}
+110
View File
@@ -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;
}
+250
View File
@@ -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;
}
+13
View File
@@ -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);
+333
View File
@@ -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);
}
+584
View File
@@ -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(&gtl))
DocLineNumGoTo(doc,gtl.line);
}
+344
View File
@@ -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);
}
+224
View File
@@ -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;
}
}
+163
View File
@@ -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);
}
+160
View File
@@ -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;
}
+112
View File
@@ -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;
+358
View File
@@ -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;
}
+211
View File
@@ -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");
}
+385
View File
@@ -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;
}
+611
View File
@@ -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);
}
+323
View File
@@ -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;
}
+729
View File
@@ -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;
}
+336
View File
@@ -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
+213
View File
@@ -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);
}
}
+103
View File
@@ -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;
}
+213
View File
@@ -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;
}
+167
View File
@@ -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
+69
View File
@@ -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("..");;
+348
View File
@@ -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");
+192
View File
@@ -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);
}
}
+26
View File
@@ -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);
+171
View File
@@ -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);
}
+223
View File
@@ -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$
+160
View File
@@ -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);
}
+9
View File
@@ -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
+180
View File
@@ -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;
}
};
+410
View File
@@ -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
+344
View File
@@ -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;
}
+430
View File
@@ -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;
}
+29
View File
@@ -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");
+5
View File
@@ -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);
+55
View File
@@ -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);;;
+21
View File
@@ -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;
+209
View File
@@ -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;
+805
View File
@@ -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;
}
}
}
+93
View File
@@ -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
+423
View File
@@ -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;
}
}
+475
View File
@@ -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;
}
+363
View File
@@ -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);
}
+31
View File
@@ -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("..");;
+677
View File
@@ -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;
}
+603
View File
@@ -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
+189
View File
@@ -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);
}
+70
View File
@@ -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;
}
+140
View File
@@ -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);
}
+64
View File
@@ -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);
}
+32
View File
@@ -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("..");;
+243
View File
@@ -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;
}
+188
View File
@@ -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
}
+33
View File
@@ -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;
}
}
+93
View File
@@ -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
}
+60
View File
@@ -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;
}
}
+107
View File
@@ -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
}
+123
View File
@@ -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