TempleOSTS_130315.ISO

This commit is contained in:
Terry A. Davis authored and minexew committed 2018-09-08 21:45:37 +02:00
1 parent e57428affb
commit 17b71f1a2d
958 files changed
+26043 -15907

No files matched your search

+71
View File
@@ -0,0 +1,71 @@
#exe {OptOn(OPTf_WARN_PAREN);};
#exe {OptOn(OPTf_WARN_DUP_TYPES);};
#help_index "Task/Login"
//Use Dbg("Type 'G;'"); to debug before window mgr is running.
public F64 os_version=1.00;
#include "AdamExt.HPP"
#include "Math2a"
#include "Training"
#include "Utils2a"
#include "MathODE"
Cd("::/TempleOS/Adam/Gr");;
#include "Gr"
Cd("::/TempleOS/Adam/Snd");;
#include "Snd"
Cd("::/TempleOS/Adam/Dsk");;
#include "Dsk2"
Cd("::/TempleOS/Adam");;
#include "Menu"
#include "Window"
#include "Dbg2a"
Cd("::/TempleOS/Adam/Doc");;
#include "Doc"
LBts(&sys_run_level,RLf_DOC);
Cd("::/TempleOS/Adam/Ctrls");;
#include "Ctrls"
Cd("::/TempleOS/Adam");;
#include "AutoFile2a"
#include "LogIn"
Cd("::/TempleOS/Adam/WordStat");;
#include "WordStat"
Cd("::/TempleOS/Adam");;
#include "Profiler"
#include "Hash2a"
#include "TaskSettings"
#include "DevInfo"
#include "DocDefines"
//Dbg("Type 'G;'");
UseTermDoc;
SetWinVert(2,10);
sys_winmgr_task=Spawn(&WinMgrTask,NULL,"Window Mgr");
LBts(&Fs->display_flags,DISPLAYf_CHILDREN_NOT_ON_TOP);
LBts(&Fs->display_flags,DISPLAYf_SHOW);
SysLogin;
LBts(&sys_run_level,RLf_LOGIN);
RegistryInit;
LBts(&sys_run_level,RLf_REGISTRY);
Cd("::/TempleOS/Adam");;
#include "WallPaper"
#exe {OptOff(OPTf_WARN_PAREN);};
#exe {OptOff(OPTf_WARN_DUP_TYPES);};
LBts(&sys_run_level,RLf_ADAM2);
Cd("HOME");;
#include "Adam3"
+109
View File
@@ -0,0 +1,109 @@
extern Bool win_show_menu;
extern Bool SetWinVert(I64 top,I64 bottom,CTask *task=NULL);
extern Bool SetWinHorz(I64 left,I64 right,CTask *task=NULL);
extern Bool WinToTop(CTask *task=NULL,Bool update_z_buf=TRUE);
extern U0 GrPlot0(CDC *dc,I64 x,I64 y);
extern U8 *DC2Sprite(CDC *tempb);
extern CDocEntry *DocPutSprite(CDoc *doc,U8 *elems,U8 *txt=NULL);
extern U0 DrawTaskBorder(CTask *task);
extern U0 DrawCtrls(CTask *task);
extern U0 MgdSliderCtrl(CDoc *doc);
extern U0 WinScrollsInit(CTask *task);
extern Bool BinRep(U8 *filename);
extern I64 doc_tag_types[],doc_nontag_invisible_types[],
doc_form_types[],doc_data_types[];
extern I64 doc_dft_flags1[],doc_dft_flags2[],doc_dft_type_flags[];
extern I64 PopUp(U8 *msg,CTask *parent=NULL,CTask **_pu_task=NULL);
extern CDocEntry *DocPutS(CDoc *doc,U8 *st);
extern Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL);
extern I64 PopUpMenu(CDoc *doc,I64 doc_flags=0);
extern I64 PopUpRangeI64(I64 lo,I64 hi,I64 step=1,U8 *header=NULL,U8 *footer=NULL);
extern I64 PopUpColor(U8 *header=NULL,Bool allow_transpant=TRUE,Bool allow_dft=TRUE);
extern I64 PopUpLightingColor(U8 *header=NULL);
extern I64 PopUpDitherColor(U8 *header=NULL);
extern U8 *PopUpMGetS(U8 *header=NULL);
extern Bool PopUpTransform(I64 *r);
extern U0 PopUpSnap(CSnap *g);
extern CDoc *DocNew(CTask *task=NULL);
extern CDoc *DocRead(U8 *name,I64 flags=0);
extern U0 EdCodeTools(CDoc *doc);
extern U0 DocDel(CDoc *doc);
extern U0 DocMax(I64 i=MAX_I32);
extern CDocEntry *DocPrintF(CDoc *doc,U8 *src,...);
extern U8 *EdSprite(I64 bin_num);
extern Bool View();
extern Bool DocLock(CDoc *doc);
extern Bool DocUnlock(CDoc *doc);
extern U0 DocIns(CDoc *doc,CDocEntry *doc_e);
extern U0 DocDataFmt(CDocEntry *doc_e);
extern U0 DocLineNumGoTo(CDoc *doc,I64 linenum); //one based
extern U0 DocDump(CDoc *doc,I64 uS_delay=0);
extern CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e);
extern U0 DocInsDoc(CDoc *doc,CDoc *doc2);
extern U0 DocD(U8 *buf,I64 cnt=0x80);
extern Bool DocRecalc(CDoc *doc,Bool has_cursor=FALSE,I64 recalc=DOC_RECALC_ALL);
extern Bool DocFormDo(U8 *D,U8 *class_name,I64 doc_flags=0,U8 *header=NULL,U8 *footer=NULL);
extern CDoc *DocCur(CTask *task=NULL);
extern U0 DocClear(CDoc *doc=NULL);
extern Bool DocCursor(Bool show=OFF,CDoc *doc=NULL);
extern U0 DocBottom(CDoc *doc=NULL);
extern U0 DocBinsValidate(CDoc *doc);
extern U0 DocQueRem(CDoc *doc);
extern U0 DocHome(CDoc *doc=NULL);
extern U0 DocCenter(CDoc *doc=NULL,I64 recalc=DOC_RECALC_ALL);
extern U0 DocRst(CDoc *doc,Bool is_old);
extern U0 DocQueIns(CDoc *doc,CDoc *pred);
extern U0 DocUpdateTaskDocs(CTask *task);
extern I64 PmtI64(U8 *msg,I64 dft,I64 lo=MIN_I64,I64 hi=MAX_I64);
extern F64 PmtF64(U8 *msg,F64 dft,F64 lo=MIN_F64,F64 hi=MAX_F64);
extern U0 ClassRep(U8 *class_name,U8 *d,I64 max_depth=2,Bool fun=FALSE,I64 offset=0);
extern U8 *DocLinkFile(U8 *link_st,CTask *mem_task=NULL);
extern Bool Ed(U8 *link_st,I64 ed_flags=0);
extern Bool Plain(U8 *filename);
extern U0 DocPutBMPFile(CDoc *doc=NULL,U8 *fname,Bool use_ms_paint_palette=FALSE);
extern U0 WSFillIn(I64 n);
extern U0 WSMan(I64 n,CTask *parent=NULL);
extern U0 WSDFillin(I64 n);
extern U0 WSDDef(I64 n,CTask *parent=NULL);
extern Bool WordStat(Bool val=ON);
extern U0 WSDDisplayDefs(CDoc *doc,U8 *st,I64 num=-1);
extern U0 WSFindMisspelled(CDoc *doc);
extern U0 DocHelpIndex(CDoc *doc,U8 *index);
extern U0 AcctOneTimePopUp(I64 flag_num,U8 *msg);
extern Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL);
extern Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL);
extern I64 PopUpFile(U8 *filename,Bool warn_ext=TRUE,CTask *parent=NULL,CTask **_pu_task=NULL);
extern I64 AdamFile(U8 *filename,Bool warn_ext=TRUE);
extern CTaskSettings *SettingsPush(CTask *task=NULL,I64 flags=0);
extern U0 SettingsPop(CTask *task=NULL,I64 flags=0);
extern U0 WinScrollNull(CTask *task,CD3I64 *s);
extern U0 WinScrollRestore(CTask *task,CD3I64 *s);
extern F64 win_desired_refresh,win_actual_refresh;
extern Bool WinBorder(Bool val,CTask *task=NULL);
extern U0 WinMgrSync(I64 cnt=1,Bool force=FALSE);
extern U0 WinMax(CTask *task=NULL);
extern Bool SetCursorPos(CTask *task,I64 iptx,I64 ipty,Bool set_cursor=TRUE);
extern F64 refresh_ode_time,last_refresh_ode_time;
extern CMenuEntry *MenuEntryFind(CMenu *m,U8 *full_name);
extern CMenu *MenuPush(U8 *st);
extern U0 MenuPop();
extern CMenu *MenuFilePush(U8 *filename);
extern CTask *Noise(I64 mS,I64 min_freq,I64 max_freq,I64 waveform=WF_NOISE);
extern CCtrl *CtrlFindUnique(CTask *task,I64 type);
extern Bool CtrlInside(CCtrl *c,I64 x,I64 y);
extern CCtrl *ViewAnglesNew(CTask *task=NULL);
extern U0 ViewAnglesDel(CTask *task=NULL);
#define FM_NORMAL 0
#define FM_PICK_FILE 1
#define FM_PICK_DIR 2
extern I64 GrepWiz();
+138
View File
@@ -0,0 +1,138 @@
#help_index "AutoFile;Training"
public U0 AFPmtStr(U8 *st)
{
I64 ch,sc;
U8 buf[136];
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 {
if (*st=='\n')
SPrintF(buf,"Press the '$$FG,GREEN$$<ENTER>$$FG$$' key");
else if (*st==CH_SPACE)
SPrintF(buf,"Press the '$$FG,GREEN$$<SPACE BAR>$$FG$$' key");
else
SPrintF(buf,"Press the '$$FG,GREEN$$%c$$FG$$' key",*st);
PopUpOk(buf);
}
}
}
}
public U0 AFDelayedPutS(U8 *st,I64 mS=100)
{
I64 ch;
while (ch=*st++) {
'' ch;
Sleep(mS);
}
}
public U0 AFGetKey(I64 scancode,I64 sc_mask=0xFF|SCF_SHIFT|SCF_CTRL|SCF_ALT)
{
I64 sc,ch;
U8 buf[128],*st;
do {
ch=GetKey(&sc);
if (sc.u8[0]!=SC_PRTSCRN1 &&
!(sc.u8[0]==SC_SHIFT && scancode&SCF_SHIFT) &&
!(sc.u8[0]==SC_CTRL && scancode&SCF_CTRL) &&
!(sc.u8[0]==SC_ALT && scancode&SCF_ALT) ) {
if (sc&sc_mask!=scancode&sc_mask) {
st=ScanCode2KeyName(scancode);
SPrintF(buf,"Press the '$$FG,GREEN$$%s$$FG$$' key",st);
Free(st);
PopUpOk(buf);
}
}
} while (sc&sc_mask!=scancode&sc_mask);
Msg(MSG_KEY_DOWN,ch,sc);
}
public U0 AFGetChar(I64 ch1,I64 ch2=0)
{
I64 sc,ch;
U8 buf[256],*st1,*st2;
while (TRUE) {
ch=GetKey(&sc);
if (sc.u8[0]!=SC_SHIFT &&
sc.u8[0]!=SC_ALT &&
sc.u8[0]!=SC_CTRL) {
if (ch!=ch1 && (!ch2 || ch!=ch2)) {
if (!ch2) {
st1=A2KeyName(ch1);
SPrintF(buf,"Press the '$$FG,GREEN$$%s$$FG$$' key",st1);
Free(st1);
} else {
st1=A2KeyName(ch1);
st2=A2KeyName(ch2);
SPrintF(buf,"Press the '$$FG,GREEN$$%s$$FG$$' key or\n"
"the '$$FG,GREEN$$%s$$FG$$' key.",st1,st2);
Free(st1);
Free(st2);
}
PopUpOk(buf);
} else
break;
}
}
Msg(MSG_KEY_DOWN,ch,sc);
}
public U0 AFUntilKey(I64 scancode,I64 sc_mask=0xFF|SCF_SHIFT|SCF_CTRL|SCF_ALT)
{
I64 sc,ch;
do {
ch=GetKey(&sc);
Msg(MSG_KEY_DOWN,ch,sc);
} while (sc&sc_mask!=scancode&sc_mask);
}
public U0 AFUntilChar(I64 ch1,I64 ch2=0)
{
I64 sc,ch;
do {
ch=GetKey(&sc);
Msg(MSG_KEY_DOWN,ch,sc);
} while (ch!=ch1 && (!ch2 || ch!=ch2));
}
I64 af_l,af_r,af_c;
U0 AFSetIPPlot(I64 mS,I64 x,I64 y,I64 z)
{
SetIP(x,y,z,af_l,af_r,af_c);
Sleep(mS);
}
public U0 AFSetIP(I64 mS=7,I64 x=MAX_I64,I64 y=MAX_I64,I64 z=MAX_I64,I64 l=MAX_I64,I64 r=MAX_I64,I64 c=MAX_I64)
{
if (!(0<=x<gr_width))
x=ipx;
if (!(0<=y<gr_height))
y=ipy;
if (z==MAX_I64)
z=ipz;
if (!(FALSE<=l<=TRUE))
l=ip_lb;
if (!(FALSE<=c<=TRUE))
c=ip_cb;
if (!(FALSE<=r<=TRUE))
r=ip_rb;
af_l=l; af_r=r; af_c=c;
Line(mS,ipx,ipy,ipz,x,y,z,&AFSetIPPlot);
}
public Bool AFView()
{
Bool result=View;
DocBottom;
return result;
}
#help_index ""
+83
View File
@@ -0,0 +1,83 @@
#help_index "Compiler"
DefineLstLoad("ST_BIN_FILE_TYPES",
"END\0 \0"
"REL_EXPORT\0"
"LIT_EXPORT\0"
"REL_U8\0"
"LIT_U8\0"
"REL_U16\0"
"LIT_U16\0"
"REL_U32\0"
"LIT_U32\0"
"REL_U64\0"
"LIT_U64\0"
" \0 \0 \0 \0"
"MAIN\0"
"MODULE_ALIGN\0MODULE_ORG\0"
" \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0 \0"
"ABS_ADDR\0"
"HEAP_GLBL\0"
);
public Bool BinRep(U8 *filename)
{//This reports imports, exports, etc
//for a .BI? file.
//See $LK,"Loader Patch Table Generation","FF:::/TempleOS/Compiler/CmpMain.CPP,EIE_MODULE_ALIGNMENT"$ and $LK,"Load","MN:Load"$().
U8 *fbuf,*ptr,etype,*sptr,*absname;
I64 i,j,size;
CBinFile *bfh,*bfh2;
CHashExport *saved_hash_ptr=NULL;
fbuf=DftExt(filename,"BIN.Z");
if (!(bfh2=FileRead(fbuf,&size))) {
Free(fbuf);
return FALSE;
}
bfh=bfh2;
if (ArcXSum(bfh,bfh->file_size)!=NATIVE_XSUM) {
"Bad XSum\n\n";
return FALSE;
}
absname=FileNameAbs(fbuf);
Free(fbuf);
fbuf=StrNew(absname);
FileExtRem(fbuf);
if (fbuf[1]==':' && StrLen(fbuf)>2)
"Module Name:%s\n",fbuf+2;
else
"No Module Name\n";
Free(fbuf);
ptr=bfh(U8 *)+bfh->loader_patch_table_offset;
while (etype=*ptr++) {
i=*ptr(U32 *)++;
sptr=ptr;
ptr+=StrLen(sptr)+1;
"%16Z:$$FG,GREEN$$%s$$FG$$:%X ",etype,"ST_BIN_FILE_TYPES",sptr,i;
switch (etype) {
case EIE_REL_U8...EIE_LIT_U64:
if (*sptr)
saved_hash_ptr=HashFind(sptr,Fs->hash_table,HTG_ALL);
if (!saved_hash_ptr)
"%S%s\n","ST_UNRESOLVED_REFERENCE",sptr;
break;
case EIE_ABS_ADDR:
NewLine;
for (j=0;j<i;j++)
"%X ",*ptr(U32 *)++;
break;
case EIE_HEAP_GLBL:
"Size:%X ",*ptr(I64 *)++;
for (j=0;j<i;j++)
"%X ",*ptr(U32 *)++;
break;
}
NewLine;
}
Free(absname);
Free(bfh);
return TRUE;
}
#help_index ""
+157
View File
@@ -0,0 +1,157 @@
asm {
#define MODULE_SIZE CD_BOOT_LOADER_SIZE
#define BOOT_HIGH_LOC ((BOOT_RAM_LIMIT-(BOOT_STK_SIZE+MODULE_SIZE))>>4)
USE16
BCD_START::
//DL is supposed to have the BIOS drive number
CLD
MOV AX,BOOT_HIGH_LOC
MOV ES,AX
CLI
MOV SS,AX
MOV SP,BOOT_STK_SIZE+MODULE_SIZE
STI
CALL BCD_GET_IP
BCD_GET_IP:
POP BX
SUB BX,BCD_GET_IP-BCD_START
SHR BX,4
//Copy this bootloader code to just under 0x80000
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
MOV DS,AX
//My assembler doesn't support 16-bit very well.
DU8 0xEA; //JMP BOOT_HIGH_LOC:BCD_MAIN
DU16 BCD_MAIN-BCD_START,BOOT_HIGH_LOC;
BCD_BIOS_DRV_NUM: DU8 0;
BCD_PAGE: DU8 0;
BCD_DAP: DU8 16,0,1,0; //One blk at a time
BCD_DAP_BUF: DU16 0,0;
BCD_DAP_BLK: DU64 0;
BCD_TEMPLEOS_MSG:
DU8 "Loading TempleOS",0;
BCD_NOT64_MSG:
DU8 "TempleOS requires a 64-bit capable processor.\n\r",0;
//These get patched by $LK,"CDBootFileCreate","MN:CDBootFileCreate"$
BCD_BLK_LO:: DU16 0;
BCD_BLK_HI:: DU16 0;
BCD_BLK_CNT:: DU16 0;
BCD_PROGRESS_STEP:: DU32 0;
BCD_PROGRESS_VAL:: DU32 0;
BCD_PUTCHAR::
MOV AH,0xE
MOV BL,7 //Might be foreground color on some BIOS's
MOV BH,U8 [BCD_PAGE-BCD_START]
INT 0x10
BCD_RET::
RET
BCD_PUTS::
@@1: LODSB
OR AL,AL
JZ BCD_RET
CALL BCD_PUTCHAR
JMP @@1
BCD_MAIN::
MOV U8 [BCD_BIOS_DRV_NUM-BCD_START],DL //Passed in by BIOS
MOV AH,0xF
INT 0x10
MOV U8 [BCD_PAGE-BCD_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,BCD_NOT64_MSG-BCD_START
CALL BCD_PUTS
@@10: JMP @@10
@@15: MOV SI,BCD_TEMPLEOS_MSG-BCD_START
CALL BCD_PUTS
MOV AX,BOOT_RAM_BASE/16
MOV ES,AX
XOR ECX,ECX
MOV CX,U16 [BCD_BLK_CNT-BCD_START]
MOV EAX,(80-7-9)*65536 //80 columns
XOR EDX,EDX
DIV ECX
MOV U32 [BCD_PROGRESS_STEP-BCD_START],EAX
MOV U32 [BCD_PROGRESS_VAL-BCD_START],0
MOV AX,U16 [BCD_BLK_LO-BCD_START]
MOV DX,U16 [BCD_BLK_HI-BCD_START]
@@20: PUSH CX //Blk cnt
//READ BLK
PUSH AX //Blk lo
PUSH DX //Blk hi
PUSH ES //Buf seg
MOV U16 [BCD_DAP_BLK-BCD_START],AX
MOV U16 [BCD_DAP_BLK+2-BCD_START],DX
MOV AX,ES
MOV U16 [BCD_DAP_BUF+2-BCD_START],AX //ES:0000
MOV SI,BCD_DAP-BCD_START //DS:SI=DAP
MOV AH,0x42
MOV DL,U8 [BCD_BIOS_DRV_NUM-BCD_START]
INT 0x13
POP AX //ES
ADD AX,CD_BLK_SIZE/16
MOV ES,AX
POP DX
POP AX
INC AX
JNZ @@25
INC DX
@@25: PUSH AX
MOV BX,U16 [BCD_PROGRESS_VAL+2-BCD_START]
MOV EAX,U32 [BCD_PROGRESS_STEP-BCD_START]
ADD U32 [BCD_PROGRESS_VAL-BCD_START],EAX
CMP U16 [BCD_PROGRESS_VAL+2-BCD_START],BX
JE @@30
MOV AL,'.'
CALL BCD_PUTCHAR
@@30: POP AX
POP CX
LOOP @@20
//See $LK,"BootCdProbe","MN:BootCdProbe"$().
MOV EBX,U32 [BCD_BLK_LO-BCD_START]
SHL EBX,16
MOV BX,BOOT_CODE_CDROM //$MA+A-X+PU,"See sys_boot_code","Grep(\"sys_boot_code\",\"/TempleOS/\"FILENAME_MASK_TXT);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,"::/TempleOS/Kernel/KStart.CPP","FL:::/TempleOS/Kernel/KStart.CPP,1"$
BCD_END::
#assert BCD_END-BCD_START<MODULE_SIZE
}
+92
View File
@@ -0,0 +1,92 @@
asm {
#define MODULE_SIZE 1*BLK_SIZE
#define BOOT_HIGH_LOC ((BOOT_RAM_LIMIT-(BOOT_STK_SIZE+MODULE_SIZE))>>4)
USE16
BHD_START::
DU8 0x5A DUP(0); //See $LK,"CFAT32Boot","MN:CFAT32Boot"$.code[]
BHD_CODE::
CLD
MOV AX,VGA_TEXT_MEM_BASE/16
MOV FS,AX
MOV U32 FS:[4],0
MOV U32 FS:[0],'B'+0x2000+('3'+0x2000)<<16
MOV AX,BOOT_HIGH_LOC
MOV ES,AX
CLI
MOV SS,AX
MOV SP,BOOT_STK_SIZE+MODULE_SIZE
STI
CALL BHD_GET_IP
BHD_GET_IP:
POP BX
SUB BX,BHD_GET_IP-BHD_START
SHR BX,4
//Copy this bootloader code to just under 0x80000
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
MOV DS,AX
//My assembler doesn't support 16-bit very well.
DU8 0xEA; //JMP BOOT_HIGH_LOC:BHD_HISTART
DU16 BHD_HISTART-BHD_START,BOOT_HIGH_LOC;
BHD_BIOS_DRV_NUM: DU8 0;
//Gets patched by $LK,"MakeOSInstallPrtBootLoader","MN:MakeOSInstallPrtBootLoader"$().
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,"MakeOSInstallPrtBootLoader","MN:MakeOSInstallPrtBootLoader"$().
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
MOV EBX,BOOT_CODE_HARDDRV //$MA+A-X+PU,"See sys_boot_code","Grep(\"sys_boot_code\",\"/TempleOS/\"FILENAME_MASK_TXT);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,"::/TempleOS/Kernel/KStart.CPP","FL:::/TempleOS/Kernel/KStart.CPP,1"$
BHD_END::
#assert BHD_END-BHD_START<MODULE_SIZE-2
}
+105
View File
@@ -0,0 +1,105 @@
asm {
#define MODULE_SIZE 1*BLK_SIZE
#define BOOT_HIGH_LOC ((BOOT_RAM_LIMIT-(BOOT_STK_SIZE+MODULE_SIZE))>>4)
USE16
BMHD_START::
BMHD_CODE::
CLD
MOV AX,BOOT_HIGH_LOC
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
MOV AX,VGA_TEXT_MEM_BASE/16
MOV FS,AX
MOV U32 FS:[0],'B'+0x2000+('1'+0x2000)<<16
CALL BMHD_GET_IP
BMHD_GET_IP:
POP BX
SUB BX,BMHD_GET_IP-BMHD_START
MOV CX,BX
SHR BX,4
//Copy this bootloader code to just under 0x80000
MOV AX,CS
PUSH AX
ADD AX,BX
MOV DS,AX
MOV U16 [BMHD_OLD_CS_IP-BMHD_START],CX
POP U16 [BMHD_OLD_CS_IP+2-BMHD_START]
MOV CX,MODULE_SIZE
XOR SI,SI
XOR DI,DI
REP_MOVSB
MOV AX,BOOT_HIGH_LOC
MOV DS,AX
//My assembler doesn't support 16-bit very well.
DU8 0xEA; //JMP BOOT_HIGH_LOC:BMHD_HISTART
DU16 BMHD_HISTART-BMHD_START,BOOT_HIGH_LOC;
BMHD_BIOS_DRV_NUM: DU8 0;
BMHD_OLD_CS_IP: DU16 0,0;
//Gets patched by $LK,"MakeOSInstallPrtBootLoader","MN:MakeOSInstallPrtBootLoader"$().
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,"MakeOSInstallPrtBootLoader","MN:MakeOSInstallPrtBootLoader"$().
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_IP-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","FF:::/TempleOS/Adam/Boot/BootMHD2.CPP,BMHD2_START"$
BMHD_END::
#assert BMHD_END-BMHD_START<=440
}
+119
View File
@@ -0,0 +1,119 @@
asm {
#define MODULE_SIZE 2*BLK_SIZE
#define BOOT_HIGH_LOC ((BOOT_RAM_LIMIT-(BOOT_STK_SIZE+MODULE_SIZE))>>4)
USE16
BMHD2_START::
MOV U32 FS:[0],'B'+0x2000+('2'+0x2000)<<16
MOV AX,BOOT_HIGH_LOC
MOV ES,AX
//Copy this bootloader code to just under 0x80000
MOV AX,CS
MOV DS,AX
MOV U32 [BMHD2_OLD_CS_IP-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
MOV DS,AX
//My assembler doesn't support 16-bit very well.
DU8 0xEA; //JMP BOOT_HIGH_LOC:BMHD2_HISTART
DU16 BMHD2_HISTART-BMHD2_START,BOOT_HIGH_LOC;
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_PUTCHAR::
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
OR AL,AL
JZ BMHD2_RET
CALL BMHD2_PUTCHAR
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]
OR EBX,EBX
JNZ @@10
OR 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_IP-BMHD2_START]
SHR AX,4
ADD AX,U16 [BMHD2_OLD_CS_IP+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_IP:
DU16 0,0;
BMHD2_END::
//Continues here $LK,"::/TempleOS/Adam/Boot/BootHD.CPP","FF:::/TempleOS/Adam/Boot/BootHD.CPP,START"$
#assert BMHD2_END-BMHD2_START<MODULE_SIZE
}
+384
View File
@@ -0,0 +1,384 @@
#help_index "Install"
//See $LK,"Install Documentation","FI:::/TempleOS/Doc/Install.TXT"$ or $LK,"Upgrading Documentation","FI:::/TempleOS/Doc/Upgrade.TXT"$.
//Kernel module: Kernel.BIN.Z
#define KERNEL_BIN_C "Kernel.BIN.C"
//Must be first dir on CD.
#define BOOT_DIR "/0000Boot"
//Must be first file on CD.
#define BOOT_DIR_KERNEL_BIN_C BOOT_DIR "/0000" KERNEL_BIN_C
//Stage 2 of master boot loader
#define BOOTMHD2_BIN_C "/0000Boot/BootMHD2.BIN.C"
//Old master boot record
#define OLDMBR_BIN_C "/0000Boot/OldMBR.BIN.C"
//CD-ROM patched Boot Loader
#define BOOTCD_BIN_Z "/0000Boot/BootCD.BIN.Z"
if (IsDrvWritable)
MkDir("/Temp"); //Good to have a Temp
#include "BootCD"
#include "BootHD"
#include "BootMHD"
#include "BootMHD2"
#help_index "Install;File/Install Related;File/CD DVD"
public Bool CDBootFileCreate()
{
U8 *br;
I64 size=FileSize(BOOT_DIR_KERNEL_BIN_C);
br=CAlloc(CD_BOOT_LOADER_SIZE);
*BCD_BLK_CNT(U16 *)=(size+CD_BLK_SIZE-1)/CD_BLK_SIZE;
//$LK,"CDBOOT","FA:::/TempleOS/Adam/Dsk/DskCDDVD.CPP,CDBOOT"$ writes the following blocks:
//0x14 Preboot
//0x15 Boot-loader ($LK,"BootCD.BIN.C","FI:::/TempleOS/Adam/Boot/BootCD.CPP"$ stored uncompressed in a non-file block)
//0x16 0000Kernel.BIN.C.
//No emulation
//This trick assumes 0000Kernel is first file in first dir.
*BCD_BLK_LO(U32 *)=1+(CD_FILE_OFFSET+CD_BOOT_LOADER_SIZE/BLK_SIZE)/(CD_BLK_SIZE>>BLK_SIZE_BITS);
MemCpy(br,BCD_START,BCD_END-BCD_START);
FileWrite(BOOTCD_BIN_Z,br,CD_BOOT_LOADER_SIZE);
Free(br);
return TRUE;
}
#help_index "Call"
asm {
USE64
_HI_CALL::
ENTER 0
MOV RAX,U64 16[RBP]
OR RAX,RAX
JZ @@05
CALL RAX
@@05: LEAVE
RET1 8
}
_extern _HI_CALL I64 HiCall(U8 *s);
#help_index "Boot"
public U0 SoftBoot(U8 *filename) //No hardware rst
//Specify the Kernel binary file you
//wish to boot.
{
I64 size;
CKernel *hi_image,*lo_image=sys_boot_base-sizeof(CBinFile),
reg *shutdown,*hi_image2;
if (!(hi_image2=FileRead(filename,&size))) return;
switch (snd_dev) {
case SD_PC_SPEAKER:
break;
case SD_HD_AUDIO:
CallExtStr("HDAudioEnd",TRUE);
break;
}
shutdown=MAlloc(SYS_RESTART_KERNEL_END-SYS_RESTART_KERNEL,Fs->code_heap);
hi_image=MAlloc(size,Fs->code_heap);
MemCpy(hi_image,hi_image2,size);
Free(hi_image2);
hi_image->boot_base=lo_image(U8 *)+sizeof(CBinFile);
hi_image->boot_patch_table_base=lo_image(U8 *)+hi_image->h.loader_patch_table_offset;
MemCpy(&hi_image->sys_mem_E801,&lo_image->sys_mem_E801,2*2);
MemCpy(&hi_image->sys_mem_E820,&lo_image->sys_mem_E820,NUM_MEM_E820_ENTRIES*MEM_E820_ENTRY_SIZE);
hi_image->sys_gr_mode=lo_image->sys_gr_mode;
hi_image->sys_pci_busses=lo_image->sys_pci_busses;
hi_image->boot_code=BOOT_CODE_RAM;
Cli;
if (mp_cnt>1)
MPHalt;
MemCpy(shutdown,SYS_RESTART_KERNEL,SYS_RESTART_KERNEL_END-SYS_RESTART_KERNEL);
MemCpy(&hi_image->sys_gdttab,&lo_image->sys_gdttab,GDT_SIZE);
MemCpy(lo_image,hi_image,size);
HiCall(shutdown);
}
#help_index "Install"
U0 InstallCDir(U8 src,U8 dst)
{
U8 buf_s[136],buf_d[136];
if (src==dst) return;
SPrintF(buf_s,"%c:/TempleOS",src);
SPrintF(buf_d,"%c:/TempleOS",dst);
DelTree(buf_d);
CopyTree(buf_s,buf_d);
}
U8 ChkWritable(U8 drv_let=0)
{
Bool cont=TRUE;
U8 writable_drv=drv_let;
CPrt *p;
CBlkDev *bdev;
if (!IsDrvWritable(drv_let)) {
'' drv_let;
": Drive is read-only.\n";
do {
"Enter RAM drive (usually 'B') for temporary files:";
writable_drv=ToUpper(GetChar);
NewLine;
p=Drv2Prt(writable_drv);
bdev=p->bdev;
if (bdev->type!=BDT_RAM ||
!IsDrvWritable(writable_drv))
"Not A RAM Drive\n";
else
cont=FALSE;
} while (cont);
Fmt(writable_drv,FALSE,FALSE);
InstallCDir(drv_let,writable_drv);
}
return writable_drv;
}
#help_index "Install"
public U0 MakeAll()
//Call from $LK,"MakeOSInstallPrtBootLoader","MN:MakeOSInstallPrtBootLoader"$() because loader must be patched with block address.
//These 2 modules (and bootloaders at top) are the only AOT
//compiled code in TempleOS. Everything else is JIT.
//You are doing it wrong if you make AOT compiled code.
{
Cd("/TempleOS/Compiler");
if (Cmp("Compiler","Compiler",,':'))
throw;
Cd("/TempleOS/Kernel");
if (Cmp("Kernel","Kernel",,':'))
throw;
}
public Bool MakeOSInstallPrtBootLoader(U8 src_drv=0,U8 dst_drv=0)
{//Make All and install new boot-loader.
//Normally, you just supply a src_drv. It will compile
//the code on that drive and update the boot sect.
//If you are making a bootable CD-ROM you supply a dst_drv.
//See $LK-A,"::/TempleOS/Demo/MakeDistro.CPP.Z"$
//See $LK,"Install Documentation","FI:::/TempleOS/Doc/Install.TXT"$
//Study my account examples my technique $LK,"Cfg Strs","FL:::/TempleOS/Demo/AcctExample/TSAdam.CPP,1"$ $LK,"Update Funs","FL:::/TempleOS/Demo/AcctExample/TSDistro.CPP,1"$
CBlkDev *bdev;
CPrt *p;
CFAT32Boot br;
CDirEntry de;
I64 i;
Bool result=FALSE;
try {
if (!src_drv) src_drv=Fs->cur_prt->drv_let;
if (!dst_drv) dst_drv=src_drv;
//This passes a cfg arg for
//compilation of Kernel which is accessed
//within a #exe {} statement.
//See $LK,"InsBootDstDrv","FF:::/TempleOS/Kernel/KCfg.CPP,InsBootDstDrv"$
//(There is no way to set compiler options.)
NamedFramePtrAdd("InsBootDstDrv",dst_drv);
src_drv=ChkWritable(src_drv);
if (!Drv(src_drv))
throw;
MakeAll;
Cd("/");
bdev=Drv2BlkDev(dst_drv);
p =Drv2Prt (dst_drv);
switch (bdev->type) {
case BDT_ATAPI:
Move("/TempleOS/Kernel/Kernel.BIN.Z",BOOT_DIR_KERNEL_BIN_C);
CDBootFileCreate;
result=TRUE;
break;
case BDT_RAM:
case BDT_ATA:
Move("/TempleOS/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(p,&br,p->offset,1);
br.jump_and_nop[0]=0xEB;
br.jump_and_nop[1]=0x58;
br.jump_and_nop[2]=0x90;
*BHD_BLK_CNT(U16 *)=(de.size+BLK_SIZE-1)>>BLK_SIZE_BITS;
*BHD_DAP_BLK(I64 *)=p->data+de.cluster*p->spc;
for (i=0;i<BHD_END-BHD_CODE;i++)
br.code[i]=BHD_CODE(U8 *)[i];
for (;i<420;i++)
br.code[i]=0;
WBlks(p,&br,p->offset,1);
result=TRUE;
}
break;
}
} catch
CatchAll;
NamedFramePtrDel("InsBootDstDrv");
return result;
}
public U0 OldMasterBootRead(U8 src_drv,U8 dst_drv)
{//Reads MBR from disk drive containing src partition.
//Writes a single blk file to dst /0000Boot directory.
CBlkDev *bdev=Drv2BlkDev(src_drv);
CPrt *p;
CMasterBoot mbr;
Drv(dst_drv);
p=Fs->cur_prt;
if (p->type!=PT_NATIVE && p->type!=PT_FAT32)
PutDefineErr("ST_NOT_NATIVE");
else {
//Bypass partition bounds-checking
BlkDevLock(bdev);
ATAReadBlks(bdev,&mbr,0,1);
BlkDevUnlock(bdev);
Drv(dst_drv);
MkDir(BOOT_DIR);
FileWrite(OLDMBR_BIN_C,&mbr,BLK_SIZE);
}
}
public U0 OldMasterBootWrite(U8 src_drv,U8 dst_drv)
{ //Reads OldMBR from src drive /0000Boot directory
//writes it to the MBR of the drive with dst partition.
CBlkDev *bdev=Drv2BlkDev(dst_drv);
CMasterBoot *mbr;
Drv(src_drv);
if (mbr=FileRead(OLDMBR_BIN_C)) {
//Bypass partition bounds-checking
BlkDevLock(bdev);
ATAWriteBlks(bdev,mbr,0,1);
BlkDevUnlock(bdev);
}
Free(mbr);
}
public U0 MasterBootZero(U8 dst_drv)
{ //Set MBR of disk with dst partition to zero.
//This is dangerous!!
//The TempleOS partitioner doesn't play well
//with other operating systems at this time and you need
//to do this on a drive partitioned by TempleOS
//if you wish to partition with another operating system.
CBlkDev *bdev=Drv2BlkDev(dst_drv);
CMasterBoot mbr;
MemSet(&mbr,0,BLK_SIZE);
//Bypass partition bounds-checking
BlkDevLock(bdev);
ATAWriteBlks(bdev,&mbr,0,1);
BlkDevUnlock(bdev);
}
public Bool InstallMasterBootLoader(U8 drv_let,U8 *drv_lst=NULL)
{ //Create new MBR on the disk that has drv_let as a partition.
//Puts stage 2 in /0000Boot dir of drv_let.
CBlkDev *bdev,*bdev1;
CPrt *p,*p1;
CMasterBoot mbr;
CDirEntry de;
I64 i,j,size,*_q;
U8 *menu_ptr,*ptr,ch,buf[128],buf2[128];
Bool result=FALSE;
try {
if (drv_lst)
StrCpy(buf2,drv_lst);
else {
j=0;
for (i='A';i<='Z';i++)
buf2[j++]=i;
buf2[j++]=0;
}
Drv(drv_let);
p=Fs->cur_prt;
if (p->type!=PT_NATIVE && p->type!=PT_FAT32)
PutDefineErr("ST_NOT_NATIVE");
else {
bdev=Drv2BlkDev(drv_let);
if (!FileFind(OLDMBR_BIN_C,,FUF_JUST_FILES))
OldMasterBootRead(drv_let,drv_let);
_q=BMHD2_BLK_ARRAY;
MemSet(_q,0,sizeof(I64)*8);
menu_ptr=BMHD2_BOOT_MSG;
SPrintF(menu_ptr,"\n\r\n\rTempleOS Boot Loader\n\r\n\r");
j=0;
if (FileFind(OLDMBR_BIN_C,&de,FUF_JUST_FILES)) {
Free(de.full_name);
*_q++=p->data+de.cluster*p->spc;
StrCat(menu_ptr,"0. Old Boot Record\n\r");
j++;
}
ptr=buf2;
while (ch=*ptr++) {
try {
p1 =Drv2Prt(ch);
bdev1=Drv2BlkDev(ch);
} catch {
Fs->catch_except=TRUE;
p1 =NULL;
bdev1=NULL;
}
if (p1 && bdev1==bdev) {
*_q=p1->offset;
"Drive %C:%16X\n",Prt2Drv(p1),*_q;
SPrintF(buf,"%d. Drive %C\n\r",j++,Prt2Drv(p1));
StrCat(menu_ptr,buf);
_q++;
}
}
StrCat(menu_ptr,"\n\rSelection:");
size=BMHD2_END-BMHD2_START;
FileWrite(BOOTMHD2_BIN_C,BMHD2_START,size);
if (!FileFind(BOOTMHD2_BIN_C,&de,FUF_JUST_FILES))
"No Boot Loader Image\n";
else {
Free(de.full_name);
*BMHD_BLK_CNT(U16 *)=(size+BLK_SIZE-1)>>BLK_SIZE_BITS;
*BMHD_DAP_BLK(I64 *)=p->data+de.cluster*p->spc;
//Bypass partition bounds-checking
BlkDevLock(bdev);
ATAReadBlks(bdev,&mbr,0,1);
for (i=0;i<BMHD_END-BMHD_CODE;i++)
mbr.boot_code[i]=BMHD_CODE(U8 *)[i];
for (;i<440;i++)
mbr.boot_code[i]=0;
if (!mbr.media_id)
mbr.media_id=RandU32;
mbr.zero=0;
mbr.signature=0xAA55;
ATAWriteBlks(bdev,&mbr,0,1);
BlkDevUnlock(bdev);
result=TRUE;
}
}
} catch
CatchAll;
return result;
}
#help_index ""
+8
View File
@@ -0,0 +1,8 @@
#help_index "Ctrls"
#help_file "::/TempleOS/Doc/Ctrls"
#include "Ctrls2a"
#include "CtrlsButton"
#include "CtrlsSlider"
#help_index ""
+393
View File
@@ -0,0 +1,393 @@
public CCtrl *CtrlFindUnique(CTask *task,I64 type)
{
CCtrl *c;
Bool old_preempt=Preempt(OFF);
c=task->next_ctrl;
while (c!=&task->next_ctrl) {
if (c->type==type) {
Preempt(old_preempt);
return c;
}
c=c->next;
}
Preempt(old_preempt);
return NULL;
}
U0 CtrlsUpdate(CTask *task)
{
CCtrl *c;
Bool old_preempt=Preempt(OFF);
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->screen_left =task->win_pixel_left+c->left-FONT_WIDTH;
c->screen_right =task->win_pixel_left+c->right-FONT_WIDTH;
c->screen_top =task->win_pixel_top+c->top-FONT_HEIGHT;
c->screen_bottom=task->win_pixel_top+c->bottom-FONT_HEIGHT;
} else {
c->screen_left =task->win_pixel_left+c->left;
c->screen_right =task->win_pixel_left+c->right;
c->screen_top =task->win_pixel_top+c->top;
c->screen_bottom=task->win_pixel_top+c->bottom;
}
c=c->next;
}
Preempt(old_preempt);
}
fp_update_ctrls=&CtrlsUpdate;
Bool CtrlInsideRect(CCtrl *c,I64 x,I64 y)
{//screen coordinates
if (c->screen_left<=x<=c->screen_right &&
c->screen_top<=y<=c->screen_bottom)
return TRUE;
else
return FALSE;
}
public Bool CtrlInside(CCtrl *c,I64 x,I64 y)
{
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_dc,task);
Bool old_preempt=Preempt(OFF);
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->locked_flags,TASKLf_TASK_LOCK))
Pause;
task->win_left--; //Allow drawing on border
task->win_right++;
task->win_top--;
task->win_bottom++;
WinDerivedValsUpdate(task);
LBtr(&task->locked_flags,TASKLf_TASK_LOCK);
PopFD;
if (c->draw_it)
(*c->draw_it)(dc,c);
PushFD;
Cli;
while (LBts(&task->locked_flags,TASKLf_TASK_LOCK))
Pause;
task->win_left++;
task->win_right--;
task->win_top++;
task->win_bottom--;
WinDerivedValsUpdate(task);
LBtr(&task->locked_flags,TASKLf_TASK_LOCK);
PopFD;
}
} else
if (c->draw_it)
(*c->draw_it)(dc,c);
}
c=c->next;
}
Preempt(old_preempt);
DCDel(dc);
}
#define WIN_SCROLL_SIZE 8
#define WIN_SCROLL_BORDER_BONUS 4
U0 DrawWinScroll(CDC *dc,CCtrl *c)
{
CWinScroll *s=c->state;
Bool old_preempt=Preempt(OFF);
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);
Preempt(old_preempt);
}
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=FONT_WIDTH-WIN_SCROLL_BORDER_BONUS+(s->pos-s->min)*(c->win_task->win_pixel_width+2*WIN_SCROLL_BORDER_BONUS-WIN_SCROLL_SIZE)/range;
c->right=c->left+WIN_SCROLL_SIZE-1;
c->top=FONT_HEIGHT+(FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->win_pixel_height;
c->bottom=c->top+WIN_SCROLL_SIZE-1;
break;
case CTRLT_WIN_VSCROLL:
c->left=FONT_WIDTH+(FONT_WIDTH-WIN_SCROLL_SIZE)/2+c->win_task->win_pixel_width;
c->right=c->left+WIN_SCROLL_SIZE-1;
c->top=FONT_HEIGHT-WIN_SCROLL_BORDER_BONUS+(s->pos-s->min)*(c->win_task->win_pixel_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->win_pixel_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->win_pixel_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)
{
Bool old_preempt=Preempt(OFF);
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_IP;
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_IP;
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);
Preempt(old_preempt);
}
#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;
GrPrintF(dc,c->left+VIEWANGLES_SPACING-FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"X");
GrPrintF(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;
GrPrintF(dc,c->left+2*VIEWANGLES_SPACING+1-FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Y");
GrPrintF(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;
GrPrintF(dc,c->left+3*VIEWANGLES_SPACING+2-FONT_WIDTH/2,
c->top+VIEWANGLES_SPACING-(1+FONT_HEIGHT),"Z");
GrPrintF(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->win_pixel_width-(VIEWANGLES_SPACING*4+3);
c->right=c->left+VIEWANGLES_SPACING*4+3;
c->top=c->win_task->win_pixel_height-(VIEWANGLES_SPACING*2+VIEWANGLES_RANGE);
c->bottom=c->top+VIEWANGLES_SPACING*2+VIEWANGLES_RANGE;
s->sx=LimitI64(RoundI64(s->sx,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
s->sy=LimitI64(RoundI64(s->sy,VIEWANGLES_SNAP),0,VIEWANGLES_RANGE-1);
s->sz=LimitI64(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)
{
Bool old_preempt;
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_IP;
c->type=CTRLT_VIEWING_ANGLES;
c->state=s;
c->draw_it=&DrawViewAnglesCtrl;
c->left_click=&LeftClickViewAngles;
c->update_derived_vals=&UpdateDerivedViewAnglesCtrl;
old_preempt=Preempt(OFF);
QueIns(c,task->last_ctrl);
TaskDerivedValsUpdate(task);
Preempt(old_preempt);
}
return c;
}
public U0 ViewAnglesDel(CTask *task=NULL)
{
CCtrl *c;
Bool old_preempt=Preempt(OFF);
if (!task) task=Fs;
if (c=CtrlFindUnique(task,CTRLT_VIEWING_ANGLES)) {
QueRem(c);
Free(c->state);
Free(c);
}
Preempt(old_preempt);
}
+94
View File
@@ -0,0 +1,94 @@
#define BUTTON_BORDER 2
#define BTF_DONT_FREE 1
class CCtrlButtonState
{
I64 state,num_states,flags;
U8 *state_texts;
CColorROPU32 *state_colors;
};
U0 DrawCtrlButton(CDC *dc,CCtrl *c)
{
CCtrlButtonState *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=LstEntryPt(s->state,s->state_texts)))
st=s->state_texts;
dc->color=s->state_colors[s->state];
l=StrLen(st);
GrRect(dc,c->left+BUTTON_BORDER,c->top+BUTTON_BORDER,
c->right-c->left+1-BUTTON_BORDER*2,c->bottom-c->top+1-BUTTON_BORDER*2);
dc->color=s->state_colors[s->state]^(WHITE<<16+WHITE);
GrPutS(dc,(c->left+c->right+1-l*FONT_WIDTH)>>1,
(c->top+c->bottom+1-FONT_HEIGHT)>>1,st);
}
U0 LeftClickCtrlButton(CCtrl *c,I64,I64,Bool down)
{
CCtrlButtonState *s=c->state;
if (down) {
s->state++;
if (s->state==s->num_states)
s->state=0;
}
}
public CCtrl *CtrlButtonNew(I64 x,I64 y,I64 width=-1,I64 height=-1,
I64 num_states=1,U8 *state_texts,I32 state_colors[],CCtrlButtonState *_s=NULL)
{
Bool old_preempt;
CCtrl *result;
CCtrlButtonState *s;
I64 i,j,l;
U8 *st;
if (width<0) {
l=1;
for (i=0;i<num_states;i++)
if (st=LstEntryPt(i,state_texts)) {
j=StrLen(st);
if (j>l) l=j;
}
width=BUTTON_BORDER*4+l*FONT_WIDTH;
}
if (height<0) height=BUTTON_BORDER*4+FONT_HEIGHT;
result=CAlloc(sizeof(CCtrl));
if (_s) {
s=_s;
MemSet(s,0,sizeof(CCtrlButtonState));
} else {
s=CAlloc(sizeof(CCtrlButtonState));
s->flags=BTF_DONT_FREE;
}
s->num_states=num_states;
s->state_texts=state_texts;
s->state_colors=state_colors;
result->win_task=Fs;
result->flags=CTRLF_SHOW;
result->type=CTRLT_GENERIC;
result->state=s;
result->draw_it=&DrawCtrlButton;
result->left_click=&LeftClickCtrlButton;
result->left=x;
result->top=y;
result->right=result->left+width-1;
result->bottom=result->top+height-1;
old_preempt=Preempt(OFF);
QueIns(result,Fs->last_ctrl);
Preempt(old_preempt);
return result;
}
public U0 CtrlButtonDel(CCtrl *c)
{
Bool old_preempt=Preempt(OFF);
QueRem(c);
Preempt(old_preempt);
if (!(c->flags&BTF_DONT_FREE))
Free(c->state);
Free(c);
}
+217
View File
@@ -0,0 +1,217 @@
class CMgdSCSlider
{
CMgdSCSlider *next,*last;
U8 *name;
I64 num;
};
class CMgdSC
{
CMgdSCSlider *next_slider,*last_slider;
I64 num_sliders,range,spacing,border;
U8 *glbl_name;
};
CMgdSC *PmtSliderCtrl()
{
CMgdSCSlider *temps;
U8 *st,pmt[136];
CMgdSC *result=CAlloc(sizeof(CMgdSC));
"$$FG,PURPLE$$Slider Ctrl$$FG$$\n\n";
result->glbl_name=PmtStr("Glbl Struct Name (ENTER for No Glbl):");
result->range=PmtI64 ("Range (%4d):",30);
result->spacing=PmtI64("Spacing (%4d):",20);
result->border=PmtI64 ("Border (%4d):",2);
result->next_slider=result->last_slider=&result->next_slider;
while (TRUE) {
SPrintF(pmt,"Slider #%d Name:",result->num_sliders+1);
st=PmtStr(pmt);
if (!*st) {
Free(st);
break;
}
temps=CAlloc(sizeof(CMgdSCSlider));
temps->name=st;
QueIns(temps,result->last_slider);
temps->num=result->num_sliders++;
}
return result;
}
U0 MgdSliderCtrl(CDoc *doc)
{
CTask *task;
CMgdSC *m=NULL;
CMgdSCSlider *temps;
I64 i;
DocUnlock(doc);
DocRecalc(doc);
DocCaptureUndo(doc,TRUE);
task=SpawnUser("CMgdSC **_m=0x%X;*_m=PmtSliderCtrl;\n",&m);
while (!m)
Yield;
DocPrintF(doc,
"#define SLIDER_RANGE %d
#define SLIDER_SPACING %d
#define SLIDER_BORDER %d
class CSliderState
{
",m->range,m->spacing,m->border);
temps=m->next_slider;
while (temps!=&m->next_slider) {
DocPrintF(doc," I64 %s;\n",temps->name);
temps=temps->next;
}
if (*m->glbl_name)
DocPrintF(doc,"} %s;\n",m->glbl_name);
else
DocPutS(doc,"};\n");
DocPrintF(doc,
"
U0 DrawSliderCtrl(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++)
DocPrintF(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);
DocPutS(doc," dc->color=LTRED;\n");
temps=m->next_slider;
while (temps!=&m->next_slider) {
DocPrintF(doc,
" GrPrintF(dc,c->left+%d*SLIDER_SPACING+%d-FONT_WIDTH/2,
c->top+SLIDER_SPACING+SLIDER_RANGE+3,
\"%%d\",s->%s*10/SLIDER_RANGE);\n",
temps->num+1,temps->num,temps->name);
temps=temps->next;
}
temps=m->next_slider;
while (temps!=&m->next_slider) {
DocPrintF(doc," GrRect(dc,c->left+%d*SLIDER_SPACING+%d-3,c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-2,7,5);\n",
temps->num+1,temps->num,temps->name);
temps=temps->next;
}
DocPutS(doc," dc->color=YELLOW;\n");
temps=m->next_slider;
while (temps!=&m->next_slider) {
DocPrintF(doc," GrRect(dc,c->left+%d*SLIDER_SPACING+%d-2,c->top+SLIDER_SPACING+SLIDER_RANGE-1-s->%s-1,5,3);\n",
temps->num+1,temps->num,temps->name);
temps=temps->next;
}
DocPrintF(doc,
"}
U0 UpdateDerivedSliderCtrl(CCtrl *c)
{
CSliderState *s=c->state;
c->left=c->win_task->win_pixel_width/2-(SLIDER_SPACING*3+2)/2;
c->right=c->left+%d*SLIDER_SPACING+%d;
c->top=c->win_task->win_pixel_height/2-(SLIDER_SPACING*2+SLIDER_RANGE)/2;
c->bottom=c->top+SLIDER_SPACING*2+SLIDER_RANGE;
",m->num_sliders+1,m->num_sliders);
temps=m->next_slider;
while (temps!=&m->next_slider) {
DocPrintF(doc," s->%s=LimitI64(s->%s,0,SLIDER_RANGE-1);\n",temps->name,temps->name);
temps=temps->next;
}
DocPutS(doc,
"}
U0 LeftClickSlider(CCtrl *c,I64 x,I64 y,Bool down)
{
nounusedwarn down;
CSliderState *s=c->state;
");
temps=m->next_slider;
while (temps!=&m->next_slider) {
DocPutS(doc," ");
if (temps!=m->next_slider)
DocPutS(doc,"else ");
if (temps->next==&m->next_slider)
DocPutS(doc,"\n");
else
DocPrintF(doc,"if (x<c->left+%d*SLIDER_SPACING+%d+SLIDER_SPACING/2)\n",
temps->num+1,temps->num);
DocPrintF(doc," s->%s=SLIDER_RANGE-1-(y-(c->top+SLIDER_SPACING));\n",
temps->name);
temps=temps->next;
}
DocPutS(doc,
" if (c->update_derived_vals)
(*c->update_derived_vals)(c);
}
CCtrl *SliderNew()
{
Bool old_preempt;
CCtrl *c=CAlloc(sizeof(CCtrl));
c->win_task=Fs;
c->flags=CTRLF_SHOW|CTRLF_CAPTURE_LEFT_IP;
c->type=CTRLT_GENERIC;
");
if (*m->glbl_name)
DocPrintF(doc," c->state=&%s;\n"
" MemSet(&%s,0,sizeof(CSliderState));\n",m->glbl_name,m->glbl_name);
else
DocPutS(doc, " c->state=CAlloc(sizeof(CSliderState));\n");
DocPutS(doc,
" c->draw_it=&DrawSliderCtrl;
c->left_click=&LeftClickSlider;
c->update_derived_vals=&UpdateDerivedSliderCtrl;
old_preempt=Preempt(OFF);
QueIns(c,Fs->last_ctrl);
TaskDerivedValsUpdate;
Preempt(old_preempt);
return c;
}
U0 SliderDel(CCtrl *c)
{
Bool old_preempt=Preempt(OFF);
QueRem(c);
Preempt(old_preempt);
");
if (!*m->glbl_name)
DocPutS(doc," Free(c->state);\n");
DocPutS(doc,
" Free(c);
}
");
Kill(task); //This frees memory.
AcctOneTimePopUp(ARf_MANAGE_SLIDER,
"Modify the code to your heart's content.\n"
"The code is no longer managed.\n");
DocLock(doc);
}
+255
View File
@@ -0,0 +1,255 @@
#help_index "Debugging/Dump"
Bool ClassRep2(CDoc *doc,U8 *class_name,U8 *_b,I64 depth,I64 max_depth,Bool dynamic,I64 types=HTT_CLASS,I64 offset=0)
{
I64 i,j,*ptr;
CMemberLst *ml;
CDocEntry *doc_e;
Bool unlock;
CHashClass *tempc,*tempc2;
if (depth>=max_depth) return TRUE;
if (!(tempc=HashFind(class_name,Fs->hash_table,types))) {
DocPutS(doc,"Class Not Found.\n");
return FALSE;
}
if (!ChkPtr(_b) || !ChkPtr(_b(U8 *)+tempc->size)) {
DocPrintF(doc,"Bad Ptr:%016X\n",_b);
return FALSE;
}
if (tempc->base_class && !ClassRep2(doc,tempc->base_class->str,_b,depth,max_depth,dynamic,types,offset))
return FALSE;
unlock=DocLock(doc);
DocPrintF(doc,"Class:\"%s\"\n",class_name);
ml=tempc->member_lst;
while (ml) {
tempc2=ml->member_class;
ptr=_b(U8 *)+ml->offset;
DocPrintF(doc,"%08X ",ptr(U8 *)+offset);
j=tempc2->ptr_cnt;
while (tempc2->fwd_class)
tempc2=tempc2->fwd_class;
tempc2-=tempc2->ptr_cnt;
if (tempc2->type & HTT_INTERNAL_TYPE) {
DocPrintF(doc,"$$FG,GREEN$$%-20ts:$$FG$$",ml->str);
if (j==1 && (tempc2->sub_type==IT_I8 || tempc2->sub_type==IT_U8)) {
ptr=*ptr;
if (ChkPtr(ptr)) {
if (dynamic) {
doc_e=DocPutS(doc,"$$DA-T-P+RD,64,\"%40ts\"$$\n");
doc_e->data=ptr;
DocDataFmt(doc_e);
} else
DocPrintF(doc,"%40ts\n",ptr);
}
} else if (!j) {
j=MinI64(ml->dim.total_cnt,32);
if (tempc2->sub_type==IT_I8 || tempc2->sub_type==IT_U8) {
if (j==1) {
if (dynamic) {
doc_e=DocPutS(doc,"$$DA-T+RD+UD-I64+U8,32,\"%c\"$$\n");
doc_e->data=ptr;
} else
DocPrintF(doc,"%c\n",*ptr(U8 *));
} else {
if (dynamic) {
doc_e=DocPutS(doc,"$$DA-T-P+RD,64,\"%40ts\"$$\n");
doc_e->data=ptr;
DocDataFmt(doc_e);
} else
DocPrintF(doc,"%40ts\n",ptr);
}
}
for (i=0;i<j;i++) {
switch (tempc2->sub_type) {
case IT_I0:
case IT_U0:
break;
case IT_I8:
case IT_U8:
if (dynamic) {
doc_e=DocPutS(doc,"$$DA-T+RD+UD-I64+U8,32,\"%02X\"$$ ");
doc_e->data=ptr(U8 *)++;
} else
DocPrintF(doc,"%02X ",*ptr(U8 *)++);
break;
case IT_I16:
case IT_U16:
if (dynamic) {
doc_e=DocPutS(doc,"$$DA-T+RD+UD-I64+U16,32,\"%04X\"$$ ");
doc_e->data=ptr(U16 *)++;
} else
DocPrintF(doc,"%04X ",*ptr(U16 *)++);
break;
case IT_I32:
case IT_U32:
if (dynamic) {
doc_e=DocPutS(doc,"$$DA-T+RD+UD-I64+U32,32,\"%08X\"$$ ");
doc_e->data=ptr(U32 *)++;
} else
DocPrintF(doc,"%08X ",*ptr(U32 *)++);
break;
case IT_F64:
if (dynamic) {
doc_e=DocPutS(doc,"$$DA-T+RD+UD,32,\"%16g\"$$ ");
doc_e->data=ptr(I64 *)++;
} else
DocPrintF(doc,"%16g ",*ptr(I64 *)++);
break;
default:
if (dynamic) {
doc_e=DocPutS(doc,"$$DA-T+RD+UD,32,\"%016X\"$$ ");
doc_e->data=ptr(I64 *)++;
} else
DocPrintF(doc,"%016X ",*ptr(I64 *)++);
}
if (dynamic)
DocDataFmt(doc_e);
}
if (j<ml->dim.total_cnt)
DocPutS(doc,"...");
} else
DocPrintF(doc,"%016X",*ptr);
DocPutS(doc,"\n");
} else {
if (depth<2) {
if (j==1 && !ChkPtr(*ptr))
DocPrintF(doc,"%-20ts:%016X\n",ml->str,*ptr);
else {
DocPrintF(doc,"$$TR,\"%s\"$$\n",ml->str);
DocPutS(doc,"$$ID,2$$");
if (!j)
ClassRep2(doc,tempc2->str,ptr,depth+1,max_depth,dynamic);
else if (j==1)
ClassRep2(doc,tempc2->str,*ptr,depth+1,max_depth,dynamic);
DocPutS(doc,"$$ID,-2$$");
}
} else
DocPrintF(doc,"%-20ts\n",ml->str);
}
ml=ml->next;
}
if (unlock)
DocUnlock(doc);
return TRUE;
}
public U0 ClassRep(U8 *class_name,U8 *_b,I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
//Displays members of a record
//by using the compiler's info.
{
CDoc *doc;
Bool old_preempt;
if (IsRaw) {
doc=DocNew;
} else {
DocMax;
old_preempt=Preempt(OFF);
doc=DocCur;
}
if (fun)
ClassRep2(doc,class_name,_b,0,max_depth,FALSE,HTT_FUN,offset);
else
ClassRep2(doc,class_name,_b,0,max_depth,FALSE,HTT_CLASS,offset);
DocPutS(doc,"\n");
DocRecalc(doc);
if (IsRaw) {
DocDump(doc,100000);
DocDel(doc);
} else
Preempt(old_preempt);
}
public U0 ClassRepD(U8 *class_name,U8 *_b,I64 max_depth=2,Bool fun=FALSE,I64 offset=0)
//Dynamic classrep (uses hex_ed widgit for live changes)
{
CDoc *doc;
Bool old_preempt;
if (IsRaw) {
doc=DocNew;
} else {
DocMax;
old_preempt=Preempt(OFF);
doc=DocCur;
}
if (fun)
ClassRep2(doc,class_name,_b,0,max_depth,TRUE,HTT_FUN,offset);
else
ClassRep2(doc,class_name,_b,0,max_depth,TRUE,HTT_CLASS,offset);
DocPutS(doc,"\n");
DocRecalc(doc);
if (IsRaw) {
DocDump(doc,100000);
DocDel(doc);
} else
Preempt(old_preempt);
}
U0 UpdateRegVarImg(CHashFun *tempf,U8 *_b,CTask *task)
{
CMemberLst *ml;
CHashClass *tempc;
ml=tempf->member_lst;
while (ml) {
if (ml->register!=CREG_NONE) {
tempc=ml->member_class;
while (tempc->fwd_class)
tempc=tempc->fwd_class;
MemCpy(_b+ml->offset,TaskRegAdd(task,ml->register),tempc->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 info the compiler
//has.
{
I64 size;
U8 *img;
CHashFun *tempf=HashFind(st,Fs->hash_table,HTT_FUN);
CMemberLst *tempm;
if (tempf) {
if (rbp) {
if (task) {
//tempf->size is negative. It's the bottom
//of the fun local var space relative to RBP .
size=tempf->arg_cnt*8-tempf->size+16;
img=MAlloc(size);
MemCpy(img,rbp+tempf->size,size);
UpdateRegVarImg(tempf,img-tempf->size,task);
ClassRep(st,img-tempf->size,max_depth,TRUE,rbp-img+tempf->size);
Free(img);
} else
ClassRep(st,rbp,max_depth,TRUE);
} else {
tempm=tempf->member_lst;
while (tempm) {
if (0<=tempm->register<NUM_REGS)
"%08Z %s\n",tempm->register,"ST_U64_REGS",tempm->str;
else
"%08tX %s\n",tempm->offset,tempm->str;
tempm=tempm->next;
}
"%08tX Stk Size\n",tempf->size;
}
}
}
public U0 Uf(U8 *st)
{//Unassemble named fun
I64 i;
CHashFun *tempf=HashFind(st,Fs->hash_table,HTT_FUN);
CDbgInfo *dbg;
if (tempf) {
FunRep(st);
if (dbg=tempf->debug) {
i=dbg->body[dbg->max_line-dbg->min_line+1]-tempf->executable_addr;
Un(tempf->executable_addr,i);
"Code Size:%04X\n",i;
} else
U(tempf->executable_addr);
}
}
#help_index ""
+217
View File
@@ -0,0 +1,217 @@
#help_index "PCI;Processor;Device;Info"
//The file was downloaded from
//http://www.pcidatabase.com/reports.php?type=tab-delimeted
#define PCI_DEV_FILE "::/TempleOS/Misc/PCIDevices.TXT.Z"
/****
//1) Plain text edit and remove file header and tail
//2) Text find-and-replace "=0A=" with "".
//3) Run PCIDevFileGen().
public U0 PCIDevFileGen()
{
Bool first=TRUE,del=FALSE,del2=FALSE,cont=FALSE;
CDoc *doc=DocRead(PCI_DEV_FILE,DOCF_PLAIN_TEXT|DOCF_DBL_DOLLARS);
CDocEntry *doc_e=doc->root.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,"::/TempleOS/Misc/PCIDevices.TXT","PI:::/TempleOS/Misc/PCIDevices.TXT"$
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->root.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]='0';
buf[1]='x';
buf[2]=doc_e->tag[0];
buf[3]=doc_e->tag[1];
buf[4]=doc_e->tag[2];
buf[5]=doc_e->tag[3];
buf[6]=0;
if (A2I(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]='0';
buf[1]='x';
buf[2]=doc_e->tag[0];
buf[3]=doc_e->tag[1];
buf[4]=doc_e->tag[2];
buf[5]=doc_e->tag[3];
buf[6]=0;
if (A2I(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 *temppci;
U16 w1,w2;
I64 b,d,f,timeout=32*8*2;
CDoc *doc;
if (sys_pci_dev_root.next!=&sys_pci_dev_root)
return;
doc=DocRead(PCI_DEV_FILE,DOCF_PLAIN_TEXT);
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) {
temppci=ACAlloc(sizeof(CPCIDev));
temppci->bus=b;
temppci->dev=d;
temppci->fun=f;
temppci->vendor=w1;
temppci->dev_id=w2=PCIReadU16(b,d,f,2);
temppci->sub_code=PCIReadU8(b,d,f,0xA);
temppci->base_code=PCIReadU8(b,d,f,0xB);
PCILookUpSingle(doc,w1,w2,&temppci->vendor_str,&temppci->dev_id_str);
QueIns(temppci,sys_pci_dev_root.last);
timeout=32*8*2;
} else if (sys_pci_busses==256 && --timeout<=0)
goto lud_done;
}
lud_done:
DocDel(doc);
}
public U0 PCIRep()
{
CPCIDev *temppci;
"PCI Busses:%d\n",sys_pci_busses;
if (!FileFind(PCI_DEV_FILE)) {
"You don't have the PCI device file.\n";
return;
}
PCILookUpDevs;
temppci=sys_pci_dev_root.next;
while (temppci!=&sys_pci_dev_root) {
"%02X:%02X:%01X %02X%02X $$FG,GREEN$$%s $$FG,CYAN$$%s$$FG$$\n",
temppci->bus,temppci->dev,temppci->fun,
temppci->base_code,temppci->sub_code,
temppci->vendor_str,temppci->dev_id_str;
temppci=temppci->next;
}
}
#help_index "Info;Time/CPU Cycles"
public U0 CPURep()
{
"%d Cores %6h?nHz\n",mp_cnt,ToF64(time_stamp_freq);
}
#help_index "Info;Memory/Info"
public U0 MemBIOSRep()
{
U16 *m01=SYS_MEM_E801;
CMemE820 *m20=SYS_MEM_E820;
CMemRange *tempmr;
"Standard Addresses\n"
"0x000A0000-0x000BFFFF VGA\n"
"0xFEE00000-0xFEE00FFF See $$LK,\"APIC\",\"MN:LAPIC_BASE\"$$\n\n"
"32 Bit Device Mem\n";
while (LBts(&sys_semas[SYS_SEMA_DEV_MEM],0))
Yield;
tempmr=sys_mem32_dev_root.next;
while (tempmr!=&sys_mem32_dev_root) {
"%02X:0x%016X-0x%016X\n",tempmr->type,tempmr->base,tempmr->base+tempmr->size-1;
tempmr=tempmr->next;
}
LBtr(&sys_semas[SYS_SEMA_DEV_MEM],0);
"\nBIOS Memory Report 15:E801\n"
"01:0x0000000000000000-0x%016X\n",0x100000+m01[0]<<10-1;
"01:0x0000000001000000-0x%016X\n",0x1000000+m01[1]<<16-1;
if (m20->type) {
NewLine;
"BIOS Memory Report 15:E820\n";
while (m20->type) {
"%02X:0x%016X-0x%016X\n",m20->type,m20->base,m20->base+m20->len-1;
m20++;
}
}
}
#help_index ""
+297
View File
@@ -0,0 +1,297 @@
#help_index "Utils;Cmd Line (Typically)"
#define DS_USE_FILE1 0
#define DS_USE_FILE2 1
#define DS_REMAINDER_1 2
#define DS_REMAINDER_2 3
#define DS_ABORT_FILE 4
I64 PopUpDiffOptions()
{
I64 i;
CDoc *doc=DocNew;
DocPutS(doc,"$$CM+LX,2,4$$$$FG$$$$BT,\"USE FILE1\",DS_USE_FILE1$$"
"$$CM+LX,24,0$$$$FG,CYAN$$$$BT,\"USE FILE2\",DS_USE_FILE2$$"
"$$CM+LX,2,4$$$$FG$$$$BT,\"REMAINDER ALL FILE1\",DS_REMAINDER_1$$"
"$$CM+LX,24,0$$$$FG,CYAN$$$$BT,\"REMAINDER ALL FILE2\",DS_REMAINDER_2$$"
"$$CM+LX,2,4$$$$FG$$$$BT,\"ABORT FILE\",DS_ABORT_FILE$$"
"$$CM+LX,24,0$$$$FG$$$$BT,\"ABORT ALL FILES\",DOCM_CANCEL$$\n");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
I64 DiffEntriesCompare(CDocEntry *doc_e1,CDocEntry *doc_e2)
{
return StrCmp(doc_e1->tag,doc_e2->tag);
}
#define DF_MODIFIED 1
#define DF_DONT_MODIFIED 2
#define DF_REMAINDER_ALL_FILE1 4
#define DF_REMAINDER_ALL_FILE2 8
#define DF_ABORT_FILE 16
#define DF_ABORT_ALL_FILES 32
#define DF_NO_MORE_PMTS_THIS_FILE 64
U0 DiffSelect(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,
I64 j2_lo,I64 j2_hi,I64 cnt1,I64 cnt2,CDocEntry **doc_us1,CDocEntry **doc_us2)
{
CDocEntry *doc_e,*doc_e1,*doc_e2;
Bool use_file1;
I64 i,old_flags;
CDoc *cur_l;
if (!(*_df_flags & (DF_ABORT_FILE|DF_ABORT_ALL_FILES))) {
"$$FG,RED$$";
if (0<=j1_lo<cnt1)
"%d,",doc_us1[j1_lo]->y+1;
else if (0<=j1_hi-1<cnt1)
"%d,",doc_us1[j1_hi-1]->y+1;
else
"***,";
if (0<=j2_lo<cnt2)
"%d",doc_us2[j2_lo]->y+1;
else if (0<=j2_hi-1<cnt2)
"%d",doc_us2[j2_hi-1]->y+1;
else
"***";
"---------------------$$FG$$\n";
i= j1_lo<=0 ? 0:j1_lo-1;
while (i<j1_hi) {
if (cur_l=DocCur) {
old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
cur_l->flags|=DOCF_PLAIN_TEXT;
}
"" doc_us1[i++]->tag;
if (cur_l)
cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
NewLine;
}
"$$FG,CYAN$$";
i= j2_lo<=0 ? 0:j2_lo-1;
while (i<j2_hi) {
if (cur_l=DocCur) {
old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
cur_l->flags|=DOCF_PLAIN_TEXT;
}
"" doc_us2[i++]->tag;
if (cur_l)
cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
NewLine;
}
"$$FG$$";
use_file1=TRUE;
if (!(*_df_flags & DF_NO_MORE_PMTS_THIS_FILE)) {
switch (PopUpDiffOptions) {
case DS_USE_FILE1:
break;
case DS_USE_FILE2:
use_file1=FALSE;
break;
case DS_REMAINDER_1:
*_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE2|DF_REMAINDER_ALL_FILE1|DF_NO_MORE_PMTS_THIS_FILE;
break;
case DS_REMAINDER_2:
*_df_flags=*_df_flags&~DF_REMAINDER_ALL_FILE1|DF_REMAINDER_ALL_FILE2|DF_NO_MORE_PMTS_THIS_FILE;
break;
case DS_ABORT_FILE:
*_df_flags|=DF_DONT_MODIFIED|DF_ABORT_FILE|DF_NO_MORE_PMTS_THIS_FILE;
break;
default:
*_df_flags|=DF_DONT_MODIFIED|DF_ABORT_ALL_FILES|DF_NO_MORE_PMTS_THIS_FILE;
}
}
if (*_df_flags & DF_REMAINDER_ALL_FILE2 &&
!(*_df_flags & (DF_DONT_MODIFIED|DF_REMAINDER_ALL_FILE1)))
use_file1=FALSE;
if (!use_file1) {
*_df_flags|=DF_MODIFIED;
doc_e1=doc_us1[j1_lo]->last;
if (j1_lo<j1_hi) {
doc_e=doc_us1[j1_lo];
while (doc_e!=doc_us1[j1_hi]) {
doc_e2=doc_e->next;
DocEntryDel(doc,doc_e);
doc_e=doc_e2;
}
}
if (j2_lo<j2_hi) {
doc_e=doc_us2[j2_lo];
while (doc_e!=doc_us2[j2_hi]) {
doc_e2=DocEntryCopy(doc,doc_e);
QueIns(doc_e2,doc_e1);
doc_e1=doc_e2;
doc_e=doc_e->next;
}
}
}
}
}
Bool DiffSub(CDoc *doc,I64 *_df_flags,I64 j1_lo,I64 j1_hi,I64 j2_lo,I64 j2_hi,
I64 cnt1,I64 cnt2,CDocEntry **doc_s1,CDocEntry **doc_s2,CDocEntry **doc_us1,CDocEntry **doc_us2)
{
I64 i,i1=0,i2=0,i2b,j1,j2,n,
best_j1,best_j2,best_score=0,score;
Bool result=FALSE;
if (j1_lo>=j1_hi || j2_lo>=j2_hi) {
if (j1_lo<j1_hi || j2_lo<j2_hi) {
DiffSelect(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,cnt1,cnt2,doc_us1,doc_us2);
return TRUE;
} else
return FALSE;
}
//Locate longest matching str in intervals
while (i1<cnt1 && i2<cnt2) {
if (!(j1_lo<=doc_s1[i1]->x<j1_hi)) //x is the new y
i1++;
else if (!(j2_lo<=doc_s2[i2]->x<j2_hi)) //x is the new y
i2++;
else {
i=StrCmp(doc_s1[i1]->tag,doc_s2[i2]->tag);
if (i>0)
i2++;
else if (i<0)
i1++;
else {
i2b=i2;
while (!StrCmp(doc_s1[i1]->tag,doc_s2[i2]->tag)) {
if (j2_lo<=doc_s2[i2]->x<j2_hi) { //x is the new y
score=0;
j1=doc_s1[i1]->x; //x is the new y
j2=doc_s2[i2]->x; //x is the new y
n=j1_hi-j1;
if (j2_hi-j2<n)
n=j2_hi-j2;
while (score<n) {
if (!StrCmp(doc_us1[j1+score]->tag,doc_us2[j2+score]->tag))
score++;
else
break;
}
if (score>best_score) {
best_score=score;
best_j1=j1;
best_j2=j2;
}
}
i2++;
if (i2>=cnt2)
break;
}
i2=i2b;
i1++;
}
}
}
if (!best_score) {
DiffSelect(doc,_df_flags,j1_lo,j1_hi,j2_lo,j2_hi,cnt1,cnt2,doc_us1,doc_us2);
return TRUE;
} else {
if (DiffSub(doc,_df_flags,j1_lo,best_j1,j2_lo,best_j2,cnt1,cnt2,doc_s1,doc_s2,doc_us1,doc_us2))
result=TRUE;
if (DiffSub(doc,_df_flags,best_j1+best_score,j1_hi,best_j2+best_score,j2_hi,cnt1,cnt2,
doc_s1,doc_s2,doc_us1,doc_us2))
result=TRUE;
return result;
}
}
Bool DiffBins(CDoc *doc1,CDoc *doc2)
{
CDocBin *tempb1=doc1->bin_root.next,
*tempb2=doc2->bin_root.next;
if (tempb1->last->last->num!=
tempb2->last->last->num)
return TRUE;
while (tempb1!=&doc1->bin_root) {
if (tempb1->type!=tempb2->type ||
tempb1->size!=tempb2->size ||
MemCmp(tempb1->data,tempb2->data,tempb1->size))
return TRUE;
tempb1=tempb1->next;
tempb2=tempb2->next;
}
return FALSE;
}
public Bool Diff(U8 *dst_file,U8 *src_file,I64 *_df_flags=NULL)
{ //The _df_flags arg is used when this is called by $LK,"MergeChk","MN:MergeChk"$().
CDoc *doc1=DocRead(dst_file,DOCF_PLAIN_TEXT_WITH_TABS|DOCF_NO_CURSOR),
*doc2=DocRead(src_file,DOCF_PLAIN_TEXT_WITH_TABS|DOCF_NO_CURSOR);
CDocEntry *doc_e,**doc_s1,**doc_s2,**doc_us1,**doc_us2;
I64 i,cnt1=0,cnt2=0,df_flags;
Bool result=FALSE;
if (_df_flags)
df_flags=*_df_flags;
else
df_flags=0;
df_flags&=DF_ABORT_ALL_FILES;
doc_e=doc1->root.next;
while (doc_e!=doc1) {
if (doc_e->type_u8==DOCT_TEXT)
doc_e->x=cnt1++; //x is the new y
doc_e=doc_e->next;
}
doc_e=doc2->root.next;
while (doc_e!=doc2) {
if (doc_e->type_u8==DOCT_TEXT)
doc_e->x=cnt2++; //x is the new y
doc_e=doc_e->next;
}
doc_s1=MAlloc(cnt1*sizeof(CDocEntry *));
doc_us1=MAlloc((cnt1+1)*sizeof(CDocEntry *));
i=0;
doc_e=doc1->root.next;
while (doc_e!=doc1) {
if (doc_e->type_u8==DOCT_TEXT) {
doc_s1[i]=doc_e;
doc_us1[i++]=doc_e;
}
doc_e=doc_e->next;
}
doc_us1[i]=doc1;
QSortI64(doc_s1,cnt1,&DiffEntriesCompare);
doc_s2=MAlloc(cnt2*sizeof(CDocEntry *));
doc_us2=MAlloc((cnt2+1)*sizeof(CDocEntry *));
i=0;
doc_e=doc2->root.next;
while (doc_e!=doc2) {
if (doc_e->type_u8==DOCT_TEXT) {
doc_s2[i]=doc_e;
doc_us2[i++]=doc_e;
}
doc_e=doc_e->next;
}
doc_us2[i]=doc2;
QSortI64(doc_s2,cnt2,&DiffEntriesCompare);
result=DiffSub(doc1,&df_flags,0,cnt1,0,cnt2,cnt1,cnt2,doc_s1,doc_s2,doc_us1,doc_us2);
if (df_flags&DF_MODIFIED && !(df_flags&DF_DONT_MODIFIED))
DocWrite(doc1);
if (DiffBins(doc1,doc2)) {
"$$FG,RED$$Bin Data is Different$$FG$$\n";
result=TRUE;
}
DocDel(doc1);
DocDel(doc2);
Free(doc_s1);
Free(doc_s2);
Free(doc_us1);
Free(doc_us2);
if (_df_flags)
*_df_flags=df_flags;
return result;
}
#help_index ""
+90
View File
@@ -0,0 +1,90 @@
#help_index "Doc"
#help_file "::/TempleOS/Doc/Doc"
//See $LK-A,"::/TempleOS/Doc/Doc.TXT"$
extern I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e);
extern I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e);
extern U0 DocPutSPartial(CDoc *doc,U8 *st);
extern U0 DocFormBackward(CDoc *doc,Bool giveup=FALSE);
extern U0 EdUndoFilter(CDoc *doc);
U0 DocInit()
{
DefineLstLoad("ST_DOC_CMDS","TX\0CR\0SR\0CU\0TB\0CL\0PB\0DA\0PL\0LM\0RM\0HD\0FO\0ID\0"
"FG\0BG\0FD\0BD\0F2\0FL\0FM\0FA\0FH\0FE\0FU\0FB\0FY\0FR\0FC\0FQ\0"
"WW\0UL\0IV\0BK\0SX\0SY\0CM\0AN\0LK\0BT\0"
"CB\0MA\0MU\0HX\0HS\0HE\0TR\0SP\0IB\0IT\0IS\0BP\0SO\0HL\0LP\0CC\0HI\0HV\0HC\0ER\0");
DefineLstLoad("ST_DOC_FLAGS",
//flags1
"A\0L\0"
"LC\0LE\0LM\0LA\0RC\0RE\0RM\0RA\0"
"TC\0BI\0X\0Q\0LX\0CX\0RX\0TY\0CY\0BY\0SX\0SY\0SCX\0SCY\0"
"HL\0LP\0CC\0WW\0BK\0IV\0SEL\0UL\0"
"B\0S\0BD\0C\0CA\0RD\0P\0T\0"
"Z\0H\0TR\0SK\0AL\0PU\0PRY\0MRX\0"
"FST\0SIF\0WD\0HT\0HS\0FS\0NC\0DD\0UD\0U8\0U16\0U32\0U64\0D\0WR\0HTML\0"
//flags2
"BP\0"
);
DefineLstLoad("ST_LINK_TYPES","FI\0FA\0FF\0FL\0MN\0PI\0PF\0PL\0BF\0DF\0HI\0AD\0");
}
DocInit;
//--TEMPLEOS LINK TYPES--
// "filename"
// "FI:filename"
// "FA:filename,anchor"
// "FF:filename,pattern"
// "FF:filename,pattern:occurnum"
// "FL:filename,linenum"
#define LK_FILE 0
#define LK_FILE_ANCHOR 1
#define LK_FILE_FIND 2
#define LK_FILE_LINE 3
// "MN:SymName"
#define LK_MAN_PAGE 4
// "PI:filename"
// "PF:filename,pattern"
// "PF:filename,pattern:occurnum"
// "PL:filename,linenum"
#define LK_PLAIN 5
#define LK_PLAIN_FIND 6
#define LK_PLAIN_LINE 7
// "BF:book,pattern"
#define LK_BIBLE_FIND 8
// "DF:word"
// "DF:word,defnum"
#define LK_DEF 9
// "HI:index"
#define LK_HELP_INDEX 10
// "AD:address_number"
#define LK_ADDR 11
#define LK_PLACE_ANCHOR 12
#include "DocNew"
#include "DocHighlight"
#include "DocRecalc"
#include "DocPlain"
#include "DocFile"
#include "DocOpt"
#include "DocPopUp"
#include "DocCtrlL"
#include "DocMacro"
#include "DocIDE"
#include "DocEd"
#include "DocCodeTools"
#include "DocBible"
#include "DocTree"
#include "DocMain"
#help_index ""
$WW,1$/*$AN,"","Doc"$
TempleOS Doc's can have "cursor movement" cmds which can move the cursor up the screen and layer on existing text. It can also have call-back funs which supply live, changing text. For these reasons, you can't assume you know where the visible portion of the document is and must process an extensive portion of the document each time it is placed on the screen, becoming CPU intensive on big documents. The doc->recalc_start member attempts to limit what is recalculated. This is tricky, howeve, and optimizations create minor glitches. Similarly, an optimization to only refresh the entire document 1 in 10 times it is drawn to the screen creates minor glitches. Since the Doc handles the cmd line, it must also be fast when adding text output from programs. doc->recalc_start comes into play here.
*/
+192
View File
@@ -0,0 +1,192 @@
#help_index "Doc/Bible"
DefineLoad("ST_BIBLE_FILE","::/TempleOS/Misc/Bible.TXT.Z");
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"
"Tobit\0"
"Judith\0"
"Esther\0"
"1 Maccabees\0"
"2 Maccabees\0"
"Job\0"
"Psalms\0"
"Proverbs\0"
"Ecclesiastes\0"
"Song of Songs\0"
"Wisdom\0"
"Sirach\0"
"Isaiah\0"
"Jeremiah\0"
"Lamentations\0"
"Baruch\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"
"\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"
"Tobit\0"
"Judith\0"
"42963\0"
"1 Maccabees\0"
"2 Maccabees\0"
"43605\0"
"46190\0"
"53793\0"
"56267\0"
"56966\0"
"Wisdom\0"
"Sirach\0"
"57332\0"
"61806\0"
"66736\0"
"Baruch\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"
"\0");
public U0 PutBibleVerse(U8 *verse,I64 lines)
{
I64 i;
CDoc *doc;
CDocEntry *doc_e;
U8 *st=StrNew(verse),
*st2=StrNew(verse);
if (StrOcc(st,','))
StrLastRem(st,",",st2);
else
*st2=0;
i=DefineMatch(st,"ST_BIBLE_BOOKS",LEF_IGNORE_CASE);
if (i>=0) {
i=A2I(DefineSub(i,"ST_BIBLE_BOOK_LINES"));
doc=DocRead(Define("ST_BIBLE_FILE"),DOCF_PLAIN_TEXT);
DocLineNumGoTo(doc,i); //one based
if (*st2) {
StrCpy(doc->find_replace->find_text,st2);
EdFindNext(doc);
}
doc_e=doc->cur_entry;
while (lines) {
if (doc_e->type_u8==DOCT_TEXT)
"" doc_e->tag;
else if (doc_e->type_u8==DOCT_NEW_LINE) {
NewLine;
lines--;
}
doc_e=doc_e->next;
}
DocDel(doc);
}
Free(st);
Free(st2);
}
+428
View File
@@ -0,0 +1,428 @@
#define EF_DONT_RECOMPILE 0
#define EF_RECOMPILE 1
#define EF_RENUM_ASM 2
#define EF_SLIDER_CTRL 3
#define EF_CH_SC 4
I64 PopUpEdFmt()
{
I64 i;
CDoc *doc=DocNew;
DocPutS(doc,"$$FG,PURPLE$$Reformat Function$$FG$$\n"
"If you enter $$FG,GREEN$$DONT RECOMPILE$$FG$$ the stored\n"
"source line indentation information will\n"
"be used. $$BK,1$$Be sure it is up-to-date!$$BK,0$$\n"
"For $$FG,GREEN$$#exe$$FG$$ config'ed projects, enter $$FG,GREEN$$DONT RECOMPILE$$FG$$.\n"
"$$MU,\"Recompile and autoindent CPP.Z Fun\",EF_RECOMPILE$$\n"
"$$MU,\"Don't Recompile but autoindent CPP.Z Fun\",EF_DONT_RECOMPILE$$\n\n"
"$$MU,\"Renum Asm Local @@ Labels for Fun\",EF_RENUM_ASM$$\n\n"
"$$FG,PURPLE$$Insert Managed Code$$FG$$\n"
"$$MU,\"Slider Ctrl\",EF_SLIDER_CTRL$$\n\n"
"$$FG,PURPLE$$Misc$$FG$$\n"
"$$MU,\"Insert ASCII/Scan Code Hex Codes for key pressed\",EF_CH_SC$$\n\n"
"$$MU,\"CANCEL\",DOCM_CANCEL$$\n"
"$$FG,GREEN$$<ALT-BACKSPACE>$$FG$$ to undo if not happy\n"
"with the results.\n");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
#define C_INDENT_SPACES 2
#define ASM_RENUM_SPACING 5
U0 EdRemFunLeadingSpace(CDoc *doc)
{
Bool unlock=DocLock(doc),
start_of_line=TRUE;
U8 ch,*ptr;
I64 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->flags1&(DOCEG1_DONT_EDIT-DOCEF1_SCROLLING_X)) &&
!(doc_e->flags2&DOCEG2_DONT_EDIT))
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 result=-1;
while (doc->cur_entry!=doc && doc->cur_entry->type&DOCET_SELECTED && result<0) {
result=EdCurU8(doc);
EdCursorRight(doc);
}
return result;
}
U0 EdRACollect(CDoc *doc,CRenum *root)
{
I64 ch,i;
CRenum *tempr;
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(alpha_numeric_bitmap,ch))
buf[i++]=ch;
else
break;
ch=EdRAGetU8(doc);
}
if (i<sizeof(CEdFindText.find_text)) {
buf[i++]=0;
while (ch>=0 && Bt(white_space_bitmap,ch))
ch=EdRAGetU8(doc);
if (ch==':') {
ch=EdRAGetU8(doc);
tempr=MAlloc(sizeof(CRenum));
StrCpy(tempr->label,buf);
QueIns(tempr,root->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 root,*tempr,*tempr1;
U8 buf[sizeof(CEdFindText.find_text)],
buf2[sizeof(CEdFindText.find_text)];
QueInit(&root);
EdSelectFun(doc,TRUE);
EdRACollect(doc,&root);
tempr=root.next;
while (tempr!=&root) {
tempr1=tempr->next;
num+=ASM_RENUM_SPACING;
SPrintF(buf,"@#%02d",num);
EdReplace(doc,tempr->label,buf,TRUE,TRUE,TRUE);
Free(tempr);
tempr=tempr1;
}
while (num) {
SPrintF(buf, "@#%02d",num);
SPrintF(buf2,"@@%02d",num);
EdReplace(doc,buf,buf2,TRUE,TRUE,TRUE);
num-=ASM_RENUM_SPACING;
}
EdSelectAll(doc,FALSE);
DocRecalc(doc);
DocCenter(doc);
if (unlock)
DocUnlock(doc);
}
#define AC_ABORT -1
#define AC_REINDENT 0
#define AC_RENUM_ASM 1
U0 EdRefmtFun(CDoc *doc,I64 fmt_type)
{
Bool unlock=DocLock(doc),start_of_line=TRUE;
CDocEntry *doc_e,*doc_ne;
I64 i,x,r,action=AC_ABORT,old_line_num;
U8 *b,*st,*st2,*prj_file;
CHashSrcSym *temph;
CIndentInfo *indent;
CTask *task=NULL;
CTaskCmd *tempc;
DocRecalc(doc);
old_line_num=doc->cur_entry->y+1;
DocCaptureUndo(doc,TRUE);
switch (fmt_type) {
case EF_RECOMPILE:
if (EdGoToFun(doc,FALSE,FALSE)) {
if (doc->flags&DOCF_PLAIN_TEXT)
DocFlagsToggle(doc,DOCF_PLAIN_TEXT);
DocWrite(doc);
task=Spawn(&ServantUserCmdLine,NULL,"Servant",Fs);
st2=CurDir;
st=MSPrintF("Cd(\"%s\");",st2);
tempc=TaskRqstQue(task,Fs,st,1<<TASKCf_WAKE_MASTER|1<<TASKCf_FOCUS_MASTER);
Free(st2);
Free(st);
SetWinHorz(Fs->win_left,Fs->win_right, task);
SetWinVert(Fs->win_top, Fs->win_bottom,task);
if (GetRqstResult(tempc,&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=MSPrintF("Cd(\"%s\");",st2);
Free(st2);
tempc=TaskRqstQue(task,Fs,st,1<<TASKCf_WAKE_MASTER|1<<TASKCf_FOCUS_MASTER);
Free(st);
st=MSPrintF("\"$$WW,1$$\";Cmp(\"%s\",\"SysTemp\",\"SysTemp\");",prj_file);
tempc=TaskRqstQue(task,Fs,st,1<<TASKCf_WAKE_MASTER|1<<TASKCf_FOCUS_MASTER);
Free(st);
if (GetRqstResult(tempc,&r))
if (!r) {
tempc=TaskRqstQue(task,Fs,
"Load(\"SysTemp\",LDF_JUST_LOAD);"
"MapFileLoad(\"SysTemp\");",1<<TASKCf_WAKE_MASTER|1<<TASKCf_FOCUS_MASTER);
if (GetRqstResult(tempc,&r))
action=AC_REINDENT;
}
tempc=TaskRqstQue(task,Fs,"Del(\"SysTemp.*\");",1<<TASKCf_WAKE_MASTER|1<<TASKCf_FOCUS_MASTER);
GetRqstResult(tempc,&r);
} else {
Free(prj_file);
st=DirFile(doc->filename.name,"Load","CPP.Z");
prj_file=FileNameAbs(st,FUF_Z_OR_NOT_Z);
Free(st);
if (FileFind(prj_file))
st=MSPrintF("\"$$WW,1$$\";ExeFile(\"%s\",TRUE);",prj_file);
else
st=MSPrintF("\"$$WW,1$$\";ExeFile(\"%s\",TRUE);",doc->filename.name);
tempc=TaskRqstQue(task,Fs,st,1<<TASKCf_WAKE_MASTER|1<<TASKCf_FOCUS_MASTER);
Free(st);
if (GetRqstResult(tempc,&r) && r)
action=AC_REINDENT;
}
Free(prj_file);
}
if (action==AC_REINDENT) {
DocUnlock(doc);
st=MSPrintF("DbgFunFind(0x%X,0);",doc);
tempc=TaskRqstQue(task,Fs,st,1<<TASKCf_WAKE_MASTER|1<<TASKCf_FOCUS_MASTER);
Free(st);
if (GetRqstResult(tempc,&r))
temph=r;
else
action=AC_ABORT;
DocLock(doc);
} else
PopUpOk("Has Errors");
}
break;
case EF_DONT_RECOMPILE:
if (EdGoToFun(doc,FALSE,FALSE)) {
if (temph=DbgFunFind(doc,0))
action=AC_REINDENT;
}
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);
}
action=AC_RENUM_ASM;
}
break;
}
switch (action) {
case AC_RENUM_ASM:
DocUnlock(doc);
Snd(2000); Sleep(150); Snd(0);
Sleep(100);
Snd(2000); Sleep(150); Snd(0);
DocLock(doc);
EdRenumAsm(doc);
break;
case AC_REINDENT:
if (temph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM))
indent=temph->indent;
else
indent=NULL;
if (indent && indent->min_line<=indent->max_line) {
DocUnlock(doc);
Snd(2000); Sleep(150); Snd(0);
Sleep(100);
Snd(2000); Sleep(150); Snd(0);
DocLock(doc);
EdRemFunLeadingSpace(doc);
DocLineNumGoTo(doc,indent->min_line);
doc_e=doc->cur_entry;
while (indent->min_line<=doc_e->y+1<=indent->max_line) {
if (doc_e!=doc && doc_e!=doc->cur_entry &&
!(doc_e->flags1&(DOCEG1_DONT_EDIT-DOCEF1_SCROLLING_X)) &&
!(doc_e->flags2&DOCEG2_DONT_EDIT)) {
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=indent->body[doc_e->y+1-indent->min_line]*C_INDENT_SPACES;
x=doc_e->x+1;
while (i>8) {
doc_ne=CAlloc(sizeof(CDocEntryBase),doc->mem_task);
doc_ne->type=DOCT_TAB | doc->settings_root.dft_text_attr << 8;
doc_ne->x=x;
doc_ne->y=doc_e->y;
doc_ne->page_line_num=doc_e->page_line_num;
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=CAlloc(sizeof(CDocEntryBase)+sizeof(U8 *),doc->mem_task);
doc_ne->type=DOCT_TEXT | doc->settings_root.dft_text_attr << 8;
doc_ne->tag=b;
doc_ne->max_col=1;
doc_ne->x=x;
doc_ne->y=doc_e->y;
doc_ne->page_line_num=doc_e->page_line_num;
QueIns(doc_ne,doc_e->last);
}
}
start_of_line=FALSE;
}
}
doc_e=doc_e->next;
}
break;
}
}
DocRecalc(doc);
DocLineNumGoTo(doc,old_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";
DocCur->flags|=DOCF_MIN_SIZE;
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[136];
SPrintF(buf,"EdPopUpChSC(%d,%d);",&ch,&sc);
PopUp(buf,Fs);
if (ch==CH_BACKSPACE)
DocPrintF(doc,"CH_BACKSPACE,0x%X",sc);
else if (ch=='\n')
DocPrintF(doc,"'\n',0x%X",sc);
else if (CH_CTRLA<=ch<=CH_CTRLZ)
DocPrintF(doc,"CH_CTRL%C,0x%X",ch+'@',sc);
else if (ch=='$$')
DocPrintF(doc,"'$$$$',0x%X",sc);
else if (ch=='\\')
DocPrintF(doc,"'\\\\',0x%X",sc);
else if (ch=='\'')
DocPrintF(doc,"'\\\'',0x%X",sc);
else if (ch==CH_ESC)
DocPrintF(doc,"CH_ESC,0x%X",sc);
else if (ch==CH_SHIFT_ESC)
DocPrintF(doc,"CH_SHIFT_ESC,0x%X",sc);
else if (ch==CH_SPACE)
DocPrintF(doc,"CH_SPACE,0x%X",sc);
else if (ch==CH_SHIFT_SPACE)
DocPrintF(doc,"CH_SHIFT_SPACE,0x%X",sc);
else if (Bt(displayable_chars_bitmap,ch))
DocPrintF(doc,"'%c',0x%X",ch,sc);
else
DocPrintF(doc,"0x%X,0x%X",ch,sc);
}
U0 EdCodeTools(CDoc *doc)
{
I64 fmt_type=PopUpEdFmt;
switch (fmt_type) {
case EF_DONT_RECOMPILE:
case EF_RECOMPILE:
case EF_RENUM_ASM:
EdRefmtFun(doc,fmt_type);
break;
case EF_SLIDER_CTRL:
MgdSliderCtrl(doc);
break;
case EF_CH_SC:
EdChSC(doc);
break;
}
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+455
View File
@@ -0,0 +1,455 @@
#help_index "Doc/File"
public U0 DocLoad(CDoc *doc,U8 *src2,I64 size)
{
I64 i;
U8 *src;
Bool unlock=DocLock(doc);
CDocBin *tempb;
doc->find_replace->filter_lines=0;
if (src2) {
DocPutS(doc,src2);
src=src2+StrLen(src2)+1;
i=size-(offset(CDocBin.data)-offset(CDocBin.start));
while (src<=src2+i) {
tempb=CAlloc(sizeof(CDocBin),doc->mem_task);
MemCpy(&tempb->start,src,offset(CDocBin.data)-offset(CDocBin.start));
src+=offset(CDocBin.data)-offset(CDocBin.start);
tempb->data=MAlloc(tempb->size,doc->mem_task);
if (tempb->size) {
MemCpy(tempb->data,src,tempb->size);
src+=tempb->size;
}
QueIns(tempb,doc->bin_root.last);
if (tempb->num>=doc->cur_bin_num)
doc->cur_bin_num=tempb->num+1;
}
}
if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_WITH_TABS)))
DocBinsValidate(doc);
DocHome(doc); //DOCT_CURSOR will set it in recalc
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
public CDoc *DocRead(U8 *name,I64 flags=0)
{
CDoc *doc=DocNew;
U8 *src,*name2;
I64 size=0;
doc->flags|=flags;
name2=FileNameAbs(name);
StrCpy(doc->filename.name,name2);
src=FileRead(name2,&size,&doc->file_attr);
Free(name2);
if (src) {
DocLoad(doc,src,size);
Free(src);
}
return doc;
}
public U8 *DocSave(CDoc *doc,I64 *_size=NULL)
{
CDocEntry *doc_e;
CDocBin *b;
Bool unlock=DocLock(doc);
I64 i,cnt;
U8 *st,*result,*dst,*src,ch;
if (doc->flags&DOCF_NO_CURSOR)
cnt=1; //terminator
else
cnt=2; //cursor + terminator
if (!(doc->flags & (DOCF_PLAIN_TEXT|DOCF_PLAIN_TEXT_WITH_TABS)))
DocBinsValidate(doc);
DocRecalc(doc);
for (doc_e=doc->root.next;doc_e!=doc;doc_e=doc_e->next) {
if (!Bt(doc_data_types,doc_e->type_u8)) {
switch (doc_e->type_u8) {
case DOCT_TAB:
case DOCT_PAGE_BREAK:
cnt++;
break;
case DOCT_NEW_LINE:
if (doc->flags&DOCF_CARRIAGE_RETURN)
cnt+=2;
else
cnt++;
break;
case DOCT_TEXT://$BK,1$Update $LK,"DOCT_TEXT","FF:D:/TempleOS/Compiler/Lex.CPP,DOCT_TEXT"$$BK,0$
if (!(doc_e->flags1 & ~(DOCG_BL_IV_UL|DOCEF1_WORD_WRAP|DOCEF1_HIGHLIGHT|DOCEF1_LOCK_TO_PAGE|DOCEF1_LOCK_TO_CENTER|DOCEF1_SKIP|DOCEF1_HARD_SKIP|DOCEF1_FILTER_SKIP))) {
cnt+=StrLen(doc_e->tag);
if (!(doc->flags & (DOCF_PLAIN_TEXT | DOCF_PLAIN_TEXT_WITH_TABS)) ||
doc->flags&DOCF_DBL_DOLLARS)
cnt+=StrOcc(doc_e->tag,'$$');
} else {
st=Doc2PlainText(doc,doc_e);
cnt+=StrLen(st)+2;
Free(st);
}
break;
default:
if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE &&
doc_e->type_u8!=DOCT_CURSOR &&
doc_e->type_u8!=DOCT_BPT) {
st=Doc2PlainText(doc,doc_e);
cnt+=StrLen(st)+2;
Free(st);
}
}
}
}
for (b=doc->bin_root.next;b!=&doc->bin_root;b=b->next) {
if (b->use_cnt>b->temp_use_cnt)
cnt+=offset(CDocBin.data)-
offset(CDocBin.start)+b->size;
}
result=MAlloc(cnt);
dst=result;
for (doc_e=doc->root.next;doc_e!=doc;doc_e=doc_e->next) {
if (!Bt(doc_data_types,doc_e->type_u8)) {
if (doc_e->type_u8==DOCT_TEXT &&
!(doc_e->flags1 & ~(DOCG_BL_IV_UL|DOCEF1_WORD_WRAP|DOCEF1_HIGHLIGHT|DOCEF1_LOCK_TO_PAGE|DOCEF1_LOCK_TO_CENTER|DOCEF1_SKIP|DOCEF1_HARD_SKIP|DOCEF1_FILTER_SKIP))) {
src=doc_e->tag;
i=0;
while (ch=*src++) {
if (doc_e==doc->cur_entry && i++==doc->cur_data_col && !(doc->flags&DOCF_NO_CURSOR))
*dst++=CH_CURSOR;
*dst++=ch;
if (ch=='$$') {
if (!(doc->flags & (DOCF_PLAIN_TEXT | DOCF_PLAIN_TEXT_WITH_TABS)) ||
doc->flags&DOCF_DBL_DOLLARS)
*dst++=ch;
}
}
if (doc_e==doc->cur_entry && i++==doc->cur_data_col && !(doc->flags&DOCF_NO_CURSOR))
*dst++=CH_CURSOR;
} else {
if (doc_e==doc->cur_entry && !(doc->flags&DOCF_NO_CURSOR))
*dst++=CH_CURSOR;
switch (doc_e->type_u8) {
case DOCT_TAB:
*dst++='\t';
break;
case DOCT_PAGE_BREAK:
*dst++=CH_FORM_FEED;
break;
case DOCT_NEW_LINE:
if (doc->flags&DOCF_CARRIAGE_RETURN)
*dst++=CH_CARRIAGE_RETURN;
*dst++='\n';
break;
default:
if (doc_e->type_u8!=DOCT_SOFT_NEW_LINE &&
doc_e->type_u8!=DOCT_CURSOR &&
doc_e->type_u8!=DOCT_BPT) {
*dst++='$$';
st=Doc2PlainText(doc,doc_e);
StrCpy(dst,st);
dst+=StrLen(st);
*dst++='$$';
Free(st);
}
break;
}
}
}
}
*dst++=0;
b=doc->bin_root.next;
if (b!=&doc->bin_root) {
do {
if (b->use_cnt>b->temp_use_cnt) {
MemCpy(dst,&b->type,offset(CDocBin.data)-offset(CDocBin.start));
dst+=offset(CDocBin.data)-offset(CDocBin.start);
MemCpy(dst,b->data,b->size);
dst+=b->size;
}
b=b->next;
} while (b!=&doc->bin_root);
} else
cnt--;
if (_size) *_size=cnt;
if (unlock)
DocUnlock(doc);
return result;
}
public U0 DocWrite(CDoc *doc,Bool prompt=FALSE)
{
I64 size;
U8 *buf=DocSave(doc,&size);
if (prompt) {
if (DocFormDo(&doc->filename,"CEdFileName"))
FileWrite(doc->filename.name,buf,size,0,doc->file_attr);
} else
FileWrite(doc->filename.name,buf,size,0,doc->file_attr);
Free(buf);
}
#help_index "Doc"
public U0 DocInsDoc(CDoc *doc,CDoc *doc2)
{ //TODO: $LK,"DocRst","MN:DocRst"$
U8 *dst;
Bool unlock_doc=DocLock(doc),
unlock_doc2=DocLock(doc2);
CDocEntry *doc_ne,*doc_e=doc2->root.next;
DocRemSoftNewLines(doc,NULL);
if (doc->cur_entry->type_u8==DOCT_TEXT &&
doc->cur_data_col>doc->cur_entry->min_col) {
if (doc->cur_data_col<doc->cur_entry->max_col) {
doc_ne=CAlloc(sizeof(CDocEntryBase)+sizeof(U8 *),doc->mem_task);
doc_ne->type=DOCT_TEXT | doc->cur_entry->type & 0xFFFFFF00;
doc_ne->flags1=doc->cur_entry->flags1;
doc_ne->flags2=doc->cur_entry->flags2;
doc_ne->x=doc->cur_entry->x;
doc_ne->y=doc->cur_entry->y;
doc_ne->page_line_num=doc->cur_entry->page_line_num;
dst=doc->cur_entry->tag+doc->cur_data_col;
doc_ne->tag=StrNew(dst,doc->mem_task);
doc_ne->max_col=StrLen(dst);
*dst=0;
doc->cur_entry->max_col=doc->cur_data_col;
QueIns(doc_ne,doc->cur_entry);
doc->cur_entry=doc_ne;
doc->cur_data_col=doc_ne->min_col;
} else
if (doc->cur_entry!=doc)
doc->cur_entry=doc->cur_entry->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 "Doc/Clipboard"
public U0 ClipBoardDel()
{
DocRst(sys_clipboard_doc,TRUE);
}
public U0 EdCopyToClipboard(CDoc *doc)
{
CDoc *doc2=sys_clipboard_doc;
Bool unlock_doc=DocLock(doc),
unlock_doc2=DocLock(doc2);
CDocEntry *doc_e=doc->root.next,*doc_ne;
ClipBoardDel;
while (doc_e!=doc) {
if (doc_e->type & DOCET_SELECTED) {
doc_e->type&=~DOCET_SELECTED;
if (!Bt(doc_data_types,doc_e->type_u8)) {
doc_ne=DocEntryCopy(doc2,doc_e);
QueIns(doc_ne,doc2->root.last);
}
}
doc_e=doc_e->next;
}
if (unlock_doc2)
DocUnlock(doc2);
if (unlock_doc)
DocUnlock(doc);
}
public U0 EdCutToClipboard(CDoc *doc)
{
CDoc *doc2=sys_clipboard_doc;
Bool unlock_doc=DocLock(doc),
unlock_doc2=DocLock(doc2);
CDocEntry *doc_e=doc->root.next,*doc_e1,*doc_ne,*doc_e2=NULL;
ClipBoardDel;
while (doc_e!=doc) {
doc_e1=doc_e->next;
if (doc_e->type & DOCET_SELECTED) {
doc_e->type&=~DOCET_SELECTED;
if (!Bt(doc_data_types,doc_e->type_u8)) {
doc_ne=DocEntryCopy(doc2,doc_e);
QueIns(doc_ne,doc2->root.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_data_col=doc_e2->min_col;
}
doc->recalc_start=doc;
DocRemSoftNewLines(doc,NULL);
if (unlock_doc2)
DocUnlock(doc2);
if (unlock_doc)
DocUnlock(doc);
}
public U0 EdPasteClipboard(CDoc *doc)
{
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->root.next;
while (doc_e!=doc2) {
if (Bt(doc_tag_types,doc_e->type_u8))
DocPutSPartial(doc,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)
{ //deletes 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_data_col=doc->cur_entry->min_col;
}
DocEntryDel(doc,start);
if (start==end)
break;
start=doc_e1;
}
doc->recalc_start=doc;
DocRemSoftNewLines(doc,NULL);
if (unlock_doc)
DocUnlock(doc);
}
public CDoc *DocCopy(CDoc *doc,CDocEntry *start,CDocEntry *end)
{ //copies including end points
CDoc *doc2=DocNew;
Bool unlock_doc=DocLock(doc);
CDocEntry *doc_ne;
while (start!=doc) {
if (!Bt(doc_data_types,start->type_u8)) {
doc_ne=DocEntryCopy(doc2,start);
QueIns(doc_ne,doc2->root.last);
}
if (start==end)
break;
start=start->next;
}
if (unlock_doc)
DocUnlock(doc);
return doc2;
}
#help_index "Doc;Compiler/Directive"
public U0 StreamDoc(CDoc *doc)
{ //TODO: $LK,"DocRst","MN:DocRst"$
Bool unlock_doc=DocLock(doc);
CDocEntry *doc_e=doc->root.next;
while (doc_e!=doc) {
if (doc_e->type_u8==DOCT_TEXT)
StreamPutS(doc_e->tag);
else if (doc_e->type_u8==DOCT_NEW_LINE)
StreamPutS("\n");
else if (doc_e->type_u8==DOCT_TAB)
StreamPutS("\t");
doc_e=doc_e->next;
}
if (unlock_doc)
DocUnlock(doc);
}
#help_index "Doc"
Bool DocCaptureUndo(CDoc *doc,Bool force=FALSE)
{
Bool result=FALSE,unlock;
I64 time_stamp;
CDocUndo *u;
if (doc->flags&DOCF_ALLOW_UNDO) {
unlock=DocLock(doc);
time_stamp=GetTimeStamp;
if (doc->flags&DOCF_UNDO_DIRTY &&
time_stamp>doc->undo_root.last->time_stamp+time_stamp_freq<<4 || force) {
u=CAlloc(sizeof(CDocUndo),doc->mem_task);
u->time_stamp=time_stamp;
u->body=DocSave(doc,&u->size);
QueIns(u,doc->undo_root.last);
doc->flags&=~DOCF_UNDO_DIRTY;
doc->undo_cnt++;
u->doc_flags=doc->flags;
result=TRUE;
}
if (unlock)
DocUnlock(doc);
}
return result;
}
U0 DocUndoRestore(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocUndo *u=doc->undo_root.last,*u_next,*u_last;
if (u!=&doc->undo_root) {
QueRem(u);
u_next=doc->undo_root.next;
u_last=doc->undo_root.last;
QueInit(&doc->undo_root);
DocRst(doc,TRUE);
doc->flags=u->doc_flags;
DocLoad(doc,u->body,u->size);
DocUndoDel(doc,u);
doc->undo_root.next=u_next;
doc->undo_root.last=u_last;
}
DocUndoCntSet(doc);
doc->flags&=~DOCF_UNDO_DIRTY;
if (unlock)
DocUnlock(doc);
}
#help_index "File/Cmd Line (Typically);Doc/Cmd Line (Typically);Cmd Line (Typically)"
public Bool Type(U8 *fname)
//Output a file to the cmd line.
//Even graphics and macros will be sent.
{
CDoc *doc,*doc2;
if (doc=DocCur) {
if (FilesFindMatch(FILENAME_MASK_TXT,fname)) {
doc2=DocRead(fname);
DocInsDoc(doc,doc2);
DocDel(doc2);
return TRUE;
} else if (FilesFindMatch("*.BMP.Z",fname)) {
DocPutBMPFile(doc,fname,FALSE);
return TRUE;
} else if (FilesFindMatch("*.BMP;*.bmp",fname)) {
DocPutBMPFile(doc,fname,TRUE);
return TRUE;
} else if (FilesFindMatch("*.GRA*",fname)) {
DocPutGRAFile(doc,fname);
return TRUE;
}
}
return FALSE;
}
#help_index "Doc"
+385
View File
@@ -0,0 +1,385 @@
CHashTable *doc_hash;
U0 DocHighlightInit()
{
doc_hash=MAllocIdentical(asm_hash);
doc_hash->next=NULL;
}
DocHighlightInit;
U32 *DocHighlight(CDoc *doc,Bool full_refresh,CDocEntry *doc_e,CDocSettings **_s,
U8 *src,I64 len,I64 _temp_u32_attr)
{ //Be aware of $LK-A,"::/TempleOS/Adam/ToHtml.CPP"$.
U32 *result=MAlloc((len+1)*sizeof(U32)),*dst=result;
U8 *ptr,ch,ch1,last_ch;
CDocSettings *s=*_s;
I64 temp_u32_attr,mask_temp_u32_attr=_temp_u32_attr&0xFFFFF000,
comment_depth,brace_depth=s->brace_depth,paren_depth=s->paren_depth;
CHash *temph;
nobound_switch (s->state) {
case DOCSS_NORMAL:
hl_normal:
while (len) {
while (len && !Bt(alpha_numeric_bitmap,*src)) {
temp_u32_attr=_temp_u32_attr;
ch1=*src++;
switch (ch1) {
case '/':
if (len>=2) {
if (*src=='/') {
temp_u32_attr=(s->comment_attr&15)<<8|mask_temp_u32_attr;
*dst++=ch1+temp_u32_attr;
*dst++=*src++ +temp_u32_attr;
len-=2;
goto hl_cpp_comment;
} else if (*src=='*') {
temp_u32_attr=(s->comment_attr&15)<<8|mask_temp_u32_attr;
*dst++=ch1+temp_u32_attr;
*dst++=*src++ +temp_u32_attr;
len-=2;
comment_depth=1;
goto hl_comment;
}
}
break;
case '\'':
temp_u32_attr=(s->quote_attr&15)<<8|mask_temp_u32_attr;
*dst++=ch1+temp_u32_attr;
len--;
goto hl_single_quote;
case '\"':
temp_u32_attr=(s->quote_attr&15)<<8|mask_temp_u32_attr;
*dst++=ch1+temp_u32_attr;
len--;
goto hl_dbl_quote;
case '(':
if (paren_depth++&1)
temp_u32_attr=(s->alt_text_attr&15)<<8|mask_temp_u32_attr;
break;
case ')':
if (--paren_depth&1)
temp_u32_attr=(s->alt_text_attr&15)<<8|mask_temp_u32_attr;
break;
case '{':
if (brace_depth++&1)
temp_u32_attr=(s->alt_text_attr&15)<<8|mask_temp_u32_attr;
break;
case '}':
if (--brace_depth&1)
temp_u32_attr=(s->alt_text_attr&15)<<8|mask_temp_u32_attr;
break;
}
*dst++=ch1+temp_u32_attr;
if (!--len) goto hl_normal_done;
}
ptr=src;
while (len && Bt(alpha_numeric_bitmap,*src)) {
src++;
len--;
}
ch=*src;
*src=0;
if (temph=HashFind(ptr,doc_hash,HTT_KEYWORD|HTT_ASM_KEYWORD|HTT_OPCODE|HTT_REG)) {
if (temph->type&(HTT_KEYWORD|HTT_ASM_KEYWORD|HTT_OPCODE))
temp_u32_attr=(s->keyword_attr&15) <<8|mask_temp_u32_attr;
else
temp_u32_attr=(s->keyword2_attr&15)<<8|mask_temp_u32_attr;
} else
temp_u32_attr=_temp_u32_attr;
while (ch1=*ptr++)
*dst++=ch1+temp_u32_attr;
*src=ch;
}
hl_normal_done:
if (s->state!=DOCSS_NORMAL||s->comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_NORMAL;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=0;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_SINGLE_QUOTE:
temp_u32_attr=(s->quote_attr&15)<<8|mask_temp_u32_attr;
hl_single_quote:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch!='\\' && ch1=='\'')
goto hl_normal;
if (last_ch=='\\' && ch1=='\\')
last_ch=0;
else
last_ch=ch1;
}
if (s->state!=DOCSS_SINGLE_QUOTE||s->comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_SINGLE_QUOTE;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=0;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_DBL_QUOTE:
temp_u32_attr=(s->quote_attr&15)<<8|mask_temp_u32_attr;
hl_dbl_quote:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch!='\\' && ch1=='\"')
goto hl_normal;
if (last_ch=='\\' && ch1=='\\')
last_ch=0;
else
last_ch=ch1;
}
if (s->state!=DOCSS_DBL_QUOTE||s->comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_DBL_QUOTE;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=0;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_COMMENT:
temp_u32_attr=(s->comment_attr&15)<<8|mask_temp_u32_attr;
comment_depth=s->comment_depth;
hl_comment:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch=='*' && ch1=='/') {
if (!--comment_depth)
goto hl_normal;
} else if (last_ch=='/' && ch1=='*')
comment_depth++;
last_ch=ch1;
}
if (s->state!=DOCSS_COMMENT||s->comment_depth!=comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_COMMENT;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=comment_depth;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_CPP_Z_COMMENT:
temp_u32_attr=(s->comment_attr&15)<<8|mask_temp_u32_attr;
hl_cpp_comment:
while (len--)
*dst++=*src++ +temp_u32_attr;
if (s->state!=DOCSS_CPP_Z_COMMENT||s->comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_CPP_Z_COMMENT;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=0;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_NORMAL+DOCSSF_BPT:
temp_u32_attr=_temp_u32_attr & 0xFFFFF000 | RED<<8;
hl_bpt_normal:
while (len) {
while (len && !Bt(alpha_numeric_bitmap,*src)) {
ch1=*src++;
switch (ch1) {
case '/':
if (len>=2) {
if (*src=='/') {
*dst++=ch1+temp_u32_attr;
*dst++=*src++ +temp_u32_attr;
len-=2;
goto hl_bpt_cpp_comment;
} else if (*src=='*') {
*dst++=ch1+temp_u32_attr;
*dst++=*src++ +temp_u32_attr;
len-=2;
comment_depth=1;
goto hl_bpt_comment;
}
}
break;
case '\'':
*dst++=ch1+temp_u32_attr;
len--;
goto hl_bpt_single_quote;
case '\"':
*dst++=ch1+temp_u32_attr;
len--;
goto hl_bpt_dbl_quote;
case '(':
paren_depth++;
break;
case ')':
paren_depth--;
break;
case '{':
brace_depth++;
break;
case '}':
brace_depth--;
break;
}
*dst++=ch1+temp_u32_attr;
if (!--len) goto hl_bpt_normal_done;
}
ptr=src;
while (len && Bt(alpha_numeric_bitmap,*src)) {
src++;
len--;
}
ch=*src;
*src=0;
while (ch1=*ptr++)
*dst++=ch1+temp_u32_attr;
*src=ch;
}
hl_bpt_normal_done:
if (s->state!=DOCSS_NORMAL+DOCSSF_BPT||s->comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_NORMAL+DOCSSF_BPT;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=0;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_SINGLE_QUOTE+DOCSSF_BPT:
temp_u32_attr=_temp_u32_attr & 0xFFFFF000 | RED<<8;
hl_bpt_single_quote:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch!='\\' && ch1=='\'')
goto hl_bpt_normal;
if (last_ch=='\\' && ch1=='\\')
last_ch=0;
else
last_ch=ch1;
}
if (s->state!=DOCSS_SINGLE_QUOTE+DOCSSF_BPT||s->comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_SINGLE_QUOTE+DOCSSF_BPT;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=0;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_DBL_QUOTE+DOCSSF_BPT:
temp_u32_attr=_temp_u32_attr & 0xFFFFF000 | RED<<8;
hl_bpt_dbl_quote:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch!='\\' && ch1=='\"')
goto hl_bpt_normal;
if (last_ch=='\\' && ch1=='\\')
last_ch=0;
else
last_ch=ch1;
}
if (s->state!=DOCSS_DBL_QUOTE+DOCSSF_BPT||s->comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_DBL_QUOTE+DOCSSF_BPT;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=0;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_COMMENT+DOCSSF_BPT:
temp_u32_attr=_temp_u32_attr & 0xFFFFF000 | RED<<8;
comment_depth=s->comment_depth;
hl_bpt_comment:
last_ch=0;
while (len--) {
ch1=*src++;
*dst++=ch1+temp_u32_attr;
if (last_ch=='*' && ch1=='/') {
if (!--comment_depth)
goto hl_bpt_normal;
} else if (last_ch=='/' && ch1=='*')
comment_depth++;
last_ch=ch1;
}
if (s->state!=DOCSS_COMMENT+DOCSSF_BPT||s->comment_depth!=comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_COMMENT+DOCSSF_BPT;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=comment_depth;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
case DOCSS_CPP_Z_COMMENT+DOCSSF_BPT:
temp_u32_attr=_temp_u32_attr & 0xFFFFF000 | RED<<8;
hl_bpt_cpp_comment:
while (len--)
*dst++=*src++ +temp_u32_attr;
if (s->state!=DOCSS_CPP_Z_COMMENT+DOCSSF_BPT||s->comment_depth||
s->paren_depth!=paren_depth||s->brace_depth!=brace_depth) {
if (full_refresh) {
s=DocSettingsIdentical(doc,s);
s->state=DOCSS_CPP_Z_COMMENT+DOCSSF_BPT;
s->paren_depth=paren_depth;
s->brace_depth=brace_depth;
s->comment_depth=0;
QueIns(s,doc->settings_root.last);
} else
s=DocSettingsNext(doc_e->next);
}
break;
}
*dst=0;
*_s=s;
return result;
}
+506
View File
@@ -0,0 +1,506 @@
#help_index "Debugging/IDE"
#define IDET_GO 1
#define IDET_STEP_INTO 2
#define IDET_STEP_OVER 3
class CIDE
{
I64 type;
U8 *cur_line,*next_line;
U8 *call_bpt;
Bool existing_bpt;
};
U0 IDEWaitParent()
{
CTask *task=Fs->parent_task;
while (!IsSuspended(task) &&
!Bt(&task->task_flags,TASKf_IDLE) &&
!Bt(&task->rflags,RFLAGf_TRAP))
Yield;
}
public CHashFun *DbgFunFind(CDoc *doc,I64 line_offset=0)
{
U8 st[256],*filename=doc->filename.name;
I64 line=doc->cur_entry->y+1+line_offset;
CHashTable *h=Fs->hash_table;
CHashSrcSym *temph;
CDbgInfo *dbg;
while (h) {
temph=h->next_added;
while (temph!=h) {
if (temph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM))
dbg=temph->debug;
else
dbg=NULL;
if (dbg) {
StrCpy(st,temph->src_link);
StrFirstRem(st,":");
StrLastRem(st,",");
if (!StrCmp(st,filename)) {
if (dbg->min_line<=line<=dbg->max_line)
return temph;
}
}
temph=temph->next_added;
}
h=h->next;
}
return NULL;
}
U0 WatchLocals()
{
Bool old_preempt=Preempt(OFF);
CTask *task=Fs->parent_task,*dbg_task;
CDoc *doc;
CHashFun *tempf,*tempf1;
I64 sc,ch,offset,ip;
F64 timeout;
U8 **rbp,**ptr;
while (TRUE) {
IDEWaitParent;
if (!TaskValidate(dbg_task=task->dbg_task))
Exit;
if (ScanKey(&ch,&sc,TRUE)) {
timeout=tS+4.0;
do {
if (ch==CH_SHIFT_ESC || ch==CH_ESC)
Exit;
if (ScanKey(&ch,&sc,TRUE))
timeout=tS+4.0;
WinMgrSync;
} while (tS<timeout);
} else {
IDEWaitParent;
if (!TaskValidate(dbg_task=task->dbg_task))
Exit;
DocDblBufStart;
if (doc=DocCur(dbg_task)) {
if (tempf=DbgFunFind(doc,0)) {
"$$WW,1$$";
rbp=task->rbp;
ip=task->rip;
while (TRUE) {
tempf1=PSectFind(ip,&offset);
break; //TODO: load reg vars for higher level subroutines
if (tempf==tempf1)
break;
else {
if (rbp>=*rbp)
break;
ptr=rbp+1;
rbp=*rbp;
ip=*ptr;
if (!ChkOnStk(rbp,task))
break;
}
}
if (tempf==tempf1)
FunRep(tempf->str,rbp,1,task);
}
}
DocDblBufEnd;
WinMgrSync;
}
}
Preempt(old_preempt);
}
public U0 IDE(U8 *filename)
//Spawns a child process which has
//access to parents syms. Can be used
//to debug parent.
{
CTask *task;
U8 *fn1=DftExt(filename,"CPP.Z"),
*fn2=FileNameAbs(fn1);
if (PopUpCancelOk("$$BK,1$$$$FG,RED$$TempleOS IDE Debugger$$FG$$$$BK,0$$\n"
"Do not use this on files that run when included.\n"
"\nTo use:\n"
" 1) Set a break-point in the editor window.\n"
" 2) Run program from cmd line.\n\n"
"$$FG,GREEN$$F5$$FG$$\t\tGo\n"
"$$FG,GREEN$$F10$$FG$$\t\tStep Over\n"
"$$FG,GREEN$$F11$$FG$$\t\tStep Into\n"
"$$FG,GREEN$$F9$$FG$$\t\tToggle Break Point\n"
"$$FG,GREEN$$SHIFT-F9$$FG$$\tClear All Break Points\n",
"\n\n\nNote: I don't use this debugger because\n"
"I'm always doing multitasking stuff, \n"
"kernel stuff and multicore stuff. Also,\n"
"you can't debug code in the window\n"
"mgr callbacks. It works on really\n"
"simple stuff, sort-of.\n\n"
"I recommend making use of:\n"
"$$LK,\"progress1\",\"MN:progress1\"$$-$$LK,\"progress4\",\"MN:progress4\"$$, -- glbl I64 vars shown on wallpaper\n"
"$$LK,\"DbgI64\",\"MN:DbgI64\"$$() $$LK,\"DbgStr\",\"MN:DbgStr\"$$() $$LK,\"DbgAdd\",\"MN:DbgAdd\"$$() -- raw text output for a time\n"
"$$LK,\"Beep\",\"MN:Beep\"$$() $$LK,\"Snd\",\"MN:Snd\"$$() -- sound\n"
"$$LK,\"AdamLog\",\"MN:AdamLog\"$$() $$LK,\"AdamErr\",\"MN:AdamErr\"$$() -- printf to adam task's window\n"
"$$LK,\"SysDbg\",\"MN:SysDbg\"$$() and $$LK,\"IsSysDbg\",\"MN:IsSysDbg\"$$() -- just a flag\n\n")) {
SetWinHorz(1,TEXT_COLS>>1-1);
SetWinVert(2,TEXT_ROWS-2);
LBts(&Fs->display_flags,DISPLAYf_CHILDREN_NOT_ON_TOP);
task=Spawn(&UserCmdLine,NULL,"Debug",Fs);
TaskWait(task);
SetWinHorz(TEXT_COLS>>1+1,TEXT_COLS-2,task);
SetWinVert(12,TEXT_ROWS-2,task);
XTalk(task,"Ed(\"%s\");\n",fn2);
Fs->dbg_task=task;
task=Spawn(&UserCmdLine,NULL,"Watch",Fs);
TaskWait(task);
SetWinHorz(TEXT_COLS>>1+1,TEXT_COLS-2,task);
SetWinVert(2,10,task);
XTalk(task,"WatchLocals;\n");
ExeFile(fn2);
Free(fn1);
Free(fn2);
}
}
I64 IDELineAdd(CDbgInfo *dbg,I64 line)
{
I64 max=dbg->max_line-dbg->min_line;
line-=dbg->min_line;
if (line<0)
return IDELineAdd(dbg,dbg->min_line);
while (!dbg->body[line] && line<=max)
line++;
return dbg->body[line];
}
I64 IDERIPLineNum(CDoc *doc,U8 *rip)
{
U8 st[256],*filename=doc->filename.name;
I64 line;
CHashTable *h=Fs->hash_table;
CHashFun *tempf;
CDbgInfo *dbg;
while (h) {
tempf=h->next_added;
while (tempf!=h) {
if (tempf->type&HTT_FUN) {
if (dbg=tempf->debug) {
StrCpy(st,tempf->src_link);
StrFirstRem(st,":");
StrLastRem(st,",");
if (!StrCmp(st,filename)) {
for (line=dbg->min_line;line<=dbg->max_line;line++)
if (rip>=IDELineAdd(dbg,line) &&
rip<IDELineAdd(dbg,line+1))
return line;
}
}
}
tempf=tempf->next_added;
}
h=h->next;
}
return -1;
}
U0 IDESetStepRange(CDoc *doc)
{
U8 st[256],*filename=doc->filename.name;
I64 line=doc->cur_entry->y+1;
CHashTable *h=Fs->hash_table;
CHashFun *tempf;
CIDE *tempi=NamedFramePtr("IDEFrame");
CDbgInfo *dbg;
while (h) {
tempf=h->next_added;
while (tempf!=h) {
if (tempf->type&HTT_FUN) {
if (dbg=tempf->debug) {
StrCpy(st,tempf->src_link);
StrFirstRem(st,":");
StrLastRem(st,",");
if (!StrCmp(st,filename)) {
if (dbg->min_line<=line<=dbg->max_line) {
tempi->cur_line =IDELineAdd(dbg,line);
tempi->next_line=IDELineAdd(dbg,line+1);
return;
}
}
}
}
tempf=tempf->next_added;
}
h=h->next;
}
}
U0 IDEToggleBpt(CDoc *doc)
{ //F9
U8 st[512],*filename=doc->filename.name;
I64 a,line=doc->cur_entry->y+1;
Bool unlock;
CHashTable *h=Fs->hash_table;
CHashFun *tempf;
CDbgInfo *dbg;
CDocEntry *doc_e;
while (h) {
tempf=h->next_added;
while (tempf!=h) {
if (tempf->type&HTT_FUN) {
if (dbg=tempf->debug) {
StrCpy(st,tempf->src_link);
StrFirstRem(st,":");
StrLastRem(st,",");
if (!StrCmp(st,filename)) {
if (dbg->min_line<=line<=dbg->max_line) {
a=IDELineAdd(dbg,line);
unlock=DocLock(doc);
doc_e=doc->cur_entry;
while (doc_e->last->type_u8!=DOCT_NEW_LINE &&
doc_e->last->type_u8!=DOCT_SOFT_NEW_LINE &&
doc_e->last!=doc)
doc_e=doc_e->last;
doc->cur_entry=doc_e;
doc->cur_data_col=doc_e->min_col;
if (!BptR(a,Fs->parent_task)) {
BptS(a,Fs->parent_task);
DocPutS(doc,"$$BP$$");
} else {
if (doc_e->type_u8==DOCT_BPT) {
doc->cur_entry=doc_e->next;
doc->cur_data_col=doc->cur_entry->min_col;
DocEntryDel(doc,doc_e);
}
}
if (unlock)
DocUnlock(doc);
DocLineNumGoTo(doc,line);
return;
}
}
}
}
tempf=tempf->next_added;
}
h=h->next;
}
}
U0 IDEClearAllBpts(CDoc *doc)
{ //SHIFT-F9
CDocEntry *doc_e,*doc_e2;
Bool unlock;
IDEWaitParent;
B2(Fs->parent_task);
unlock=DocLock(doc);
doc_e=doc->root.next;
while (doc_e!=doc) {
doc_e2=doc_e->next;
if (doc_e->type_u8==DOCT_BPT) {
if (doc->cur_entry==doc_e) {
doc->cur_entry=doc_e->next;
doc->cur_data_col=doc->cur_entry->min_col;
}
DocEntryDel(doc,doc_e);
}
doc_e=doc_e2;
}
if (unlock)
DocUnlock(doc);
}
U0 IDEGo() //Continue after breakpoint
{ //F5
CTask *task=Fs->parent_task;
CIDE *tempi=NamedFramePtr("IDEFrame");
if (!tempi) {
tempi=CAlloc(sizeof(CIDE));
NamedFramePtrAdd("IDEFrame",tempi);
}
IDEWaitParent;
LBts(&task->task_flags,TASKf_DISABLE_BPTS);
tempi->cur_line=task->rip;
tempi->type=IDET_GO;
LBts(&task->rflags,RFLAGf_TRAP);
Suspend(task,FALSE);
}
U0 IDEStepOver(CDoc *doc)
{ //F10
CTask *task=Fs->parent_task;
I64 line;
U8 *opcode;
CIDE *tempi=NamedFramePtr("IDEFrame");
if (!tempi) {
tempi=CAlloc(sizeof(CIDE));
NamedFramePtrAdd("IDEFrame",tempi);
}
IDEWaitParent;
line=IDERIPLineNum(doc,task->rip);
LBts(&task->task_flags,TASKf_DISABLE_BPTS);
if (line>0) {
DocLineNumGoTo(doc,line);
IDESetStepRange(doc);
} else {
tempi->cur_line=NULL;
tempi->next_line=NULL;
}
tempi->type=IDET_STEP_OVER;
tempi->call_bpt=NULL;
LBts(&task->rflags,RFLAGf_TRAP);
Suspend(task,FALSE);
opcode=task->rip;
if (*opcode==OC_CALL) {
if (BptS(opcode+5,task)) {
if (tempi->call_bpt!=opcode+5)
tempi->existing_bpt=TRUE;
} else
tempi->existing_bpt=FALSE;
tempi->call_bpt=opcode+5;
LBtr(&task->task_flags,TASKf_DISABLE_BPTS);
LBtr(&task->rflags,RFLAGf_TRAP);
}
}
U0 IDEStepInto(CDoc *doc)
{ //F11
CTask *task=Fs->parent_task;
I64 line;
CIDE *tempi=NamedFramePtr("IDEFrame");
if (!tempi) {
tempi=CAlloc(sizeof(CIDE));
NamedFramePtrAdd("IDEFrame",tempi);
}
IDEWaitParent;
line=IDERIPLineNum(doc,task->rip);
LBts(&task->task_flags,TASKf_DISABLE_BPTS);
if (line>0) {
DocLineNumGoTo(doc,line);
IDESetStepRange(doc);
} else {
tempi->cur_line=NULL;
tempi->next_line=NULL;
}
tempi->type=IDET_STEP_INTO;
LBts(&task->rflags,RFLAGf_TRAP);
Suspend(task,FALSE);
}
U0 IDEEdTask(I64)
{
CTask *task=Fs->parent_task,
*ed_task=NULL,*dbg_task;
U8 *rip=task->rip,
*st,*rip_filename,*bpt_filename;
CIDE *tempi,*tempi1;
CDoc *doc;
CBpt *tempb;
if (rip_filename=SrcFileName(rip)) {
ed_task=Spawn(&UserCmdLine,NULL,"Debug",task);
TaskWait(ed_task);
st=MSPrintF("Preempt(OFF);Ed(\"%s\");\n",rip_filename);
XTalkWait(ed_task,st);
Free(st);
doc=DocCur(ed_task);
if (TaskValidate(dbg_task=task->dbg_task)) {
SetWinHorz(dbg_task->win_left,dbg_task->win_right, ed_task);
SetWinVert(dbg_task->win_top, dbg_task->win_bottom,ed_task);
if (tempi=NamedFramePtr("IDEFrame",dbg_task)) {
tempi1=MAllocIdentical(tempi,ed_task);
NamedFramePtrAdd("IDEFrame",tempi1);
}
Kill(dbg_task);
}
task->dbg_task=ed_task;
tempb=task->bpt_lst;
while (tempb) {
if (bpt_filename=SrcFileName(tempb->addr)) {
if (!StrCmp(rip_filename,bpt_filename)) {
DocLineNumGoTo(doc,SrcLineNum(tempb->addr));
DocPutS(doc,"$$BP$$");
}
Free(bpt_filename);
}
tempb=tempb->next;
}
DocLineNumGoTo(doc,SrcLineNum(rip));
Free(rip_filename);
StrCpy(ed_task->task_title,"Debug Task");
}
}
U0 IDEResumeDbg()
{
CTask *dbg_task=Fs->dbg_task;
CIDE *tempi=NamedFramePtr("IDEFrame",dbg_task);
U8 *opcode;
if (!tempi) {
Spawn(&IDEEdTask,NULL,"Resume Dbg",Fs);
Suspend(Fs);
} else
switch (tempi->type) {
case IDET_GO:
if (tempi->cur_line) {
LBtr(&Fs->task_flags,TASKf_DISABLE_BPTS);
LBtr(&Fs->rflags,RFLAGf_TRAP);
if (Fs->rip==tempi->cur_line) {//Jmp to self
tempi->cur_line=NULL;
Spawn(&IDEEdTask,NULL,"Resume Dbg",Fs);
Suspend(Fs);
} else
tempi->cur_line=NULL;
} else {
Spawn(&IDEEdTask,NULL,"Resume Dbg",Fs);
Suspend(Fs);
}
break;
case IDET_STEP_INTO:
if (!tempi->cur_line ||
Fs->rip<tempi->cur_line || Fs->rip>=tempi->next_line) {
Spawn(&IDEEdTask,NULL,"Resume Dbg",Fs);
Suspend(Fs);
} else
Suspend(Fs,FALSE);
break;
case IDET_STEP_OVER:
LBts(&Fs->rflags,RFLAGf_TRAP);
LBts(&Fs->task_flags,TASKf_DISABLE_BPTS);
if (Fs->rip==tempi->call_bpt) {
if (!tempi->existing_bpt)
BptR(Fs->rip,Fs,FALSE);
tempi->call_bpt=NULL;
}
if (!tempi->cur_line ||
Fs->rip<tempi->cur_line || Fs->rip>=tempi->next_line) {
Spawn(&IDEEdTask,NULL,"Resume Dbg",Fs);
Suspend(Fs);
} else {
opcode=Fs->rip;
if (*opcode==OC_CALL) {
if (BptS(opcode+5,Fs,FALSE)) {
if (tempi->call_bpt!=opcode+5)
tempi->existing_bpt=TRUE;
} else
tempi->existing_bpt=FALSE;
tempi->call_bpt=opcode+5;
LBtr(&Fs->task_flags,TASKf_DISABLE_BPTS);
LBtr(&Fs->rflags,RFLAGf_TRAP);
}
Suspend(Fs,FALSE);
}
break;
}
}
ext[EXT_RESUME_DBG]=&IDEResumeDbg;
#help_index ""
+219
View File
@@ -0,0 +1,219 @@
U8 captured_macro_name[136];
StrCpy(captured_macro_name,"Test");
I64 sys_macro_repeat_n=1;
U0 SysMacroStripKey(CTaskCmd *macro_root,I64 p1,I64 p2)
{
CTaskCmd *tempc,*tempc1;
tempc=macro_root->next;
while (tempc!=macro_root) {
tempc1=tempc->next;
if (tempc->cmd_code==TASKCT_MSG &&
(tempc->msg_code==MSG_KEY_DOWN ||
tempc->msg_code==MSG_KEY_UP ||
tempc->msg_code==MSG_KEY_DOWN_UP) &&
p1 && tempc->p1==p1 ||
!p1 && tempc->p2==p2) {
QueRem(tempc);
Free(tempc);
}
tempc=tempc1;
}
}
#define MT_NULL 0
#define MT_MSG 1
#define MT_CHAR 2
class CMacroTemp
{
CMacroTemp *next,*last;
I64 type;
U8 buf[136];
};
CMacroTemp *Cmd2MT(CTaskCmd *tempc)
{
U8 buf[8];
CMacroTemp *tempmt=CAlloc(sizeof(CMacroTemp));
if (Bt(getkey_chars_bitmap,tempc->p1) && tempc->msg_code==MSG_KEY_DOWN) {
tempmt->type=MT_CHAR;
buf[0]=tempc->p1;
buf[1]=0;
SPrintF(tempmt->buf,"%Q",buf);
} else {
tempmt->type=MT_MSG;
SPrintF(tempmt->buf,"Msg(0x%X,0x%X,0x%X);",
tempc->msg_code,tempc->p1,tempc->p2);
}
return tempmt;
}
U8 *SysMacro2Str(CTaskCmd *macro_root)
{
CTaskCmd *tempc;
I64 cnt=1; //terminating zero
U8 *ptr,*m;
CMacroTemp *tempmt,*tempmt1,root;
Bool old_preempt=Preempt(OFF);
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
QueInit(&root);
root.type=MT_NULL;
tempc=macro_root->next;
while (tempc!=macro_root) {
tempmt=Cmd2MT(tempc);
QueIns(tempmt,root.last);
cnt+=StrLen(tempmt->buf);
if (tempmt->type==MT_CHAR) {
if (tempmt->last->type!=MT_CHAR)
cnt+=StrLen("\"");
if (tempmt->next->type!=MT_CHAR)
cnt+=StrLen("\";");
}
tempc=tempc->next;
}
m=MAlloc(cnt);
ptr=m;
tempmt=root.next;
while (tempmt!=&root) {
tempmt1=tempmt->next;
if (tempmt->type==MT_MSG) {
StrCpy(ptr, tempmt->buf);
ptr+=StrLen(tempmt->buf);
} else {
if (tempmt->last->type!=MT_CHAR) {
StrCpy(ptr, "\"");
ptr+=StrLen("\"");
}
StrCpy(ptr,tempmt->buf);
ptr+=StrLen(tempmt->buf);
if (tempmt->next->type!=MT_CHAR) {
StrCpy(ptr, "\";");
ptr+=StrLen("\";");
}
}
Free(tempmt);
tempmt=tempmt1;
}
*ptr=0;
Preempt(old_preempt);
return m;
}
U0 PlaySysMacro(I64 n=1)
{
CTask *task=sys_focus_task;
Bool old_preempt;
U8 *m;
if (TaskValidate(task)) {
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
old_preempt=Preempt(OFF);
m=SysMacro2Str(&sys_macro_root);
while (n-- && TaskValidate(task)) {
if (task==Fs)
AutoStr("%s",m);
else
XTalkStrWait(task,"%s",m);
}
Free(m);
Preempt(old_preempt);
}
}
U0 EdInsCapturedMacro()
{
Bool old_preempt=Preempt(OFF);
U8 *st=SysMacro2Str(&sys_macro_root);
if (sys_focus_task) {
XTalk(sys_focus_task,"$$MA+A+LM+LA,\"%s\",\"%Q\"$$",
captured_macro_name,st);
Free(st);
}
Preempt(old_preempt);
}
#define SM_CANCEL -1
#define SM_RECORD 0
#define SM_INS 1
#define SM_PLAY 2
#define SM_REPEAT_N 3
#define SM_STOP 4
I64 PopUpExitRecordPlayStopIns()
{
U8 buf[136];
CTaskCmd *tempc;
CDoc *doc=DocNew;
CDocEntry *doc_e=DocPutS(doc,"$$DA-P,135,\"Name:%s\"$$");
I64 result=0;
doc_e->data=captured_macro_name;
DocDataFmt(doc_e);
doc_e=DocPutS(doc,"\n$$DA,32,\"Repeat N:%d\"$$");
doc_e->data=&sys_macro_repeat_n;
DocDataFmt(doc_e);
DocPutS(doc,"\n"
"$$CM+LX,1,3$$$$BT,\"RECORD\",SM_RECORD$$"
"$$CM+LX,17,0$$$$BT,\"INSERT\",SM_INS$$"
"$$CM+LX,1,3$$$$BT,\"PLAY\",SM_PLAY$$"
"$$CM+LX,17,0$$$$BT,\"REPEAT N\",SM_REPEAT_N$$"
"$$CM+LX,1,3$$$$BT,\"STOP\",SM_STOP$$"
"$$CM+LX,17,0$$$$BT,\"CANCEL\",SM_CANCEL$$"
"\n\n\n$$FG,GREEN$$SHIFT-F2$$FG$$ will play macro.\n");
doc->flags|=DOCF_MIN_SIZE | DOCF_FORM;
SPrintF(buf,"DocMenuDo(0x%X);",doc);
sys_macro_util_task=Spawn(&ServantUserCmdLine,NULL,"Macro Popup",Fs);
Fs->popup_task=sys_macro_util_task;
LBts(&sys_macro_util_task->display_flags,DISPLAYf_WIN_ON_TOP);
tempc=TaskRqstQue(sys_macro_util_task,Fs,buf,
1<<TASKCf_WAKE_MASTER | 1<<TASKCf_FOCUS_MASTER);
GetRqstResult(tempc,&result);
Fs->popup_task=NULL;
Kill(sys_macro_util_task);
sys_macro_util_task=NULL;
DocDataGet(doc_e);
DocDel(doc);
return result;
}
U0 MacroTask(I64)
{
I64 i;
StrCpy(captured_macro_name,"Click Here");
sys_macro_repeat_n=1;
do {
i=PopUpExitRecordPlayStopIns;
WinRefocus;
switch (i) {
case SM_RECORD:
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
QueDel(&sys_macro_root,TRUE);
LBts(&sys_semas[SYS_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[SYS_SEMA_RECORD_MACRO],0);
break;
case SM_INS:
LBtr(&sys_semas[SYS_SEMA_RECORD_MACRO],0);
EdInsCapturedMacro;
break;
}
} while (i>=0);
}
U0 EdMacroUtil()
{
if (!sys_macro_util_task)
Spawn(&MacroTask,NULL,"Macro");
}
+690
View File
@@ -0,0 +1,690 @@
#help_index "Doc/Cmd Line (Typically);Cmd Line (Typically)"
Bool Ed(U8 *link_st,I64 ed_flags=0)
{
U8 *filename,*pattern;
I64 i,num;
Bool cont,result=FALSE;
CDoc *doc;
switch (i=EdLinkCvt(link_st,&filename,&pattern,&num,ed_flags)) {
case -1:
break;
case LK_DEF:
doc=DocNew;
StrCpy(doc->desc,"DictDef");
WSDDisplayDefs(doc,filename,num);
goto ej_doc;
case LK_HELP_INDEX:
doc=DocNew;
StrCpy(doc->desc,"HelpIdx");
DocHelpIndex(doc,filename);
ej_doc:
if (!(ed_flags&EDF_BAIL)) {
DocDo(doc);
DocDel(doc);
}
result=TRUE;
break;
default:
if (IsRaw)
EdLite(filename,num);
else {
cont=TRUE;
if (!(ed_flags&EDF_BAIL) && !FilesFindMatch(FILENAME_MASK_TXT,filename) &&
!PopUpCancelOk(ST_WARN_ST "Not Text File\n\n"))
cont=FALSE;
if (cont)
result=DocFileEd(i,filename,pattern,&num,ed_flags);
}
}
Free(filename);
Free(pattern);
return result;
}
public Bool Plain(U8 *filename)
//Open a document in plain text mode,
//so that dollar signs are not special.
{
Bool result;
U8 *st=MSPrintF("PI:%s",filename);
result=Ed(st);
Free(st);
return result;
}
#help_index "Doc"
public Bool DocLinkChk(U8 *link_st)
{
U8 *filename;
I64 num;
Bool result=FALSE;
if (link_st) {
switch (EdLinkCvt(link_st,&filename,,&num)) {
case -1:
break;
case LK_FILE_LINE:
case LK_PLAIN_LINE:
case LK_FILE:
//We don't check line number
result=FileFind(filename,,FUF_JUST_FILES|FUF_Z_OR_NOT_Z|FUF_SCAN_PARENTS);
break;
case LK_BIBLE_FIND:
result=TRUE; //We don't check verse string
break;
default://TODO: Need to validate HI: and DF:
if (Ed(link_st,EDF_BAIL))
result=TRUE;
}
Free(filename);
}
return result;
}
public U8 *DocLinkFile(U8 *link_st,CTask *mem_task=NULL)
{
U8 *filename=NULL,*st,*result=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);
result=StrNew(st);
Free(st);
break;
case LK_BIBLE_FIND:
result=StrNew(Define("ST_BIBLE_FILE"),mem_task);
break;
}
Free(filename);
}
return result;
}
#help_index "Doc/Task"
public CDoc *SysAuxDocInit()
{
CDocEntry *doc_e;
CDoc *aux,*doc=DocCur;
aux=DocNew;
aux->flags|=DOCF_AUX_DOC;
if (doc) {
DocPutS(aux,"$$CM+H+BY+RX+NC,-7,1$$");
doc_e=DocPutS(aux,"$$TX+H+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdFilterCB;
doc_e=DocPutS(aux,"$$TX+H+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdOverStrikeCB;
doc_e=DocPutS(aux,"$$TX+H+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdDollarCB;
}
DocPutS(aux,"$$CM+H+BY+RX+NC,-4,1$$");
doc_e=DocPutS(aux,"$$TX+H+BD+TC,\" \"$$");
doc_e->tag_cb=&EdQuotesCB;
doc_e=DocPutS(aux,"$$TX+H+BD+TC,\" \"$$");
doc_e->tag_cb=&EdBracesCB;
doc_e=DocPutS(aux,"$$TX+H+BD+TC,\" \"$$");
doc_e->tag_cb=&EdSemicolonCB;
if (doc) {
DocPutS(aux,"$$CM+H+BY+RX+NC,-18,1$$");
doc_e=DocPutS(aux,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdMoreCB;
doc_e=DocPutS(aux,"$$TX+H+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdDollarTypeCB;
}
if (Fs->user_num)
DocPrintF(aux,"$$CM+H+TY+LX+NC,5,-1$$$$TX+H+BD,\"#%d\"$$",Fs->user_num);
DocPutS(aux,"$$CM+H+TY+NC,0,-1$$");
doc_e=DocPutS(aux,"$$DA+H-T-P+BD+RD+CX+SCX+IV,140,\"%s...\",16$$");
doc_e->data=&Fs->task_title;
DocDataFmt(doc_e);
DocPrintF(aux,"$$CM+H+NC,1,0$$$$TX+H+BD+IV,\"%X\"$$",Fs);
aux->settings_root.dft_text_attr=Fs->border_attr;
if (Bt(&Fs->display_flags,DISPLAYf_HAS_CLOSE_WIN))
DocPutS(aux,"$$TX+H+RX+BD,\"[X]\"$$");
DocPutS(aux,"$$BK,1$$$$TX+H+LX+BD,\"MENU\"$$$$BK,0$$");
return aux;
}
public U0 UseTermDoc()
{
Bool old_preempt=Preempt(OFF);
CDoc *doc=DocNew;
doc->start_text_attr=WHITE<<4+BLUE;
DocQueIns(doc,Fs->last_doc);
doc->right_click_link=&TermRightClickLink;
doc->max_entries=4096;
doc->flags|=DOCF_ATTR_BY_PRT;
StrCpy(doc->desc,"Term");
DocQueInsRev(SysAuxDocInit,Fs->next_doc);
Fs->cur_menu=MenuFile("::/TempleOS/Doc/EdPullDown.TXT");
WinScrollsInit(Fs);
Preempt(old_preempt);
Raw(OFF);
}
#help_index "Doc/Input"
public U8 *DocGetLine(CDoc *doc,CDocEntry *doc_e,I64 *cur_col=NULL,CDocEntry **_do_e_end=NULL)
{
CDocEntry *doc_e2=doc_e;
Bool unlock=DocLock(doc);
U8 *dst,*src,*start,*result;
I64 i=0;
if (cur_col)
*cur_col=-1;
while (doc_e2!=doc && doc_e2->type_u8!=DOCT_NEW_LINE) {
if (Bt(doc_tag_types,doc_e2->type_u8)) {
src=doc_e2->tag;
i+=StrLen(src);
} else if (doc_e2->type_u8==DOCT_TAB)
i++;
doc_e2=doc_e2->next;
}
result=MAlloc(i+1);
dst=result;
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE) {
start=dst;
if (Bt(doc_tag_types,doc_e->type_u8)) {
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-result+doc->cur_data_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_data_col)
*cur_col=dst-result;
if (unlock)
DocUnlock(doc);
return result;
}
#help_index "Doc/Output"
public U0 DocDump(CDoc *doc,I64 uS_delay=0)
{
U8 *st;
CDocEntry *doc_e,*doc_e2;
Bool unlock=DocLock(doc);
doc_e=doc->root.next;
while (doc_e!=doc) {
st=DocGetLine(doc,doc_e,NULL,&doc_e2);
"" st;
Free(st);
doc_e=doc_e2;
if (doc_e->type_u8==DOCT_NEW_LINE) {
NewLine;
BusyWait(uS_delay);
doc_e=doc_e->next;
}
}
if (unlock)
DocUnlock(doc);
}
public CDocEntry *DocPutLine(CDocEntry *doc_e)
{
U8 ch,*ptr,*ptr2;
while (doc_e->type_u8!=DOCT_ERROR && doc_e->type_u8!=DOCT_NEW_LINE) {
if (Bt(doc_tag_types,doc_e->type_u8)) {
ptr=doc_e->tag;
do {
ptr2=ptr;
while (ch=*ptr)
if (ch=='$$')
break;
else
ptr++;
*ptr=0;
"" ptr2;
*ptr=ch;
if (ch=='$$') {
"$$$$";
ptr++;
}
} while (ch);
} else if (doc_e->type_u8==DOCT_TAB)
'\t';
doc_e=doc_e->next;
}
NewLine;
return doc_e->type_u8==DOCT_ERROR ? doc_e:doc_e->next;
}
#help_index "Doc/Input"
public U8 *DocMGetS(I64 flags=0)
//$LK,"Flags","MN:GETSF_SHIFT_ESC_EXIT"$
{
CDoc *doc;
CDocEntry *doc_e,*doc_e_end;
Bool old_preempt=IsPreempt;
U8 *st,*result;
I64 ch,sc;
"$$FU$$";
do {
ch=DocGetKey(&sc);
if (ch==CH_ESC) {
doc=Fs->next_doc;
while (doc!=(&Fs->next_doc)(U8 *)-offset(CDoc.next_doc) &&
doc->doc_in_que_signature==DOC_IN_QUE_SIGNATURE_VAL) {
DocLock(doc);
if (!(doc->flags&DOCF_DONT_SHOW) &&
(!doc->best_d || !(doc->flags&DOCF_AUX_DOC)) &&
doc->doc_in_que_signature==DOC_IN_QUE_SIGNATURE_VAL && doc->cur_entry!=doc) {
doc_e=DocEntryCopy(doc,doc->cur_entry);
if (doc->flags&DOCF_AUX_DOC && DocCur)
DocBottom;
else
DocBottom(doc);
DocEntryRun(doc,doc_e,TRUE);
DocEntryDel(doc,doc_e);
DocUnlock(doc);
break;
}
DocUnlock(doc);
doc=doc->next_doc;
}
if (flags&GETSF_WITH_NEW_LINE)
break;
} if (ch==CH_SHIFT_ESC) {
if (flags&GETSF_SHIFT_ESC_EXIT)
Exit;
else {
result=StrNew("");
goto mgets_done;
}
}
//<CTRL-SHIFT-CR> is a blank line without entry
} while (flags&GETSF_WITH_NEW_LINE || ch!='\n' || sc & SCF_CTRL && sc & SCF_SHIFT);
Preempt(OFF);
doc=DocCur;
DocLock(doc);
if (flags&GETSF_WITH_NEW_LINE) {
doc_e=doc->cur_entry;
do doc_e=doc_e->last;
while (doc_e!=doc && doc_e->type_u8!=DOCT_USER_FOREGROUND);
doc_e=doc_e->next;
if (result=DocGetLine(doc,doc_e,NULL,&doc_e_end)) {
while (doc_e_end!=doc && doc_e_end->type_u8==DOCT_NEW_LINE) {
result=StrAdd(result,"\n");
if (st=DocGetLine(doc,doc_e_end->next,NULL,&doc_e_end)) {
result=StrAdd(result,st);
Free(st);
}
}
}
} 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_USER_FOREGROUND);
if (doc_e!=doc && doc_e->type_u8!=DOCT_USER_FOREGROUND) {
do doc_e=doc_e->last;
while (doc_e!=doc && doc_e->type_u8!=DOCT_NEW_LINE &&
doc_e->type_u8!=DOCT_USER_FOREGROUND);
}
doc_e=doc_e->next;
result=DocGetLine(doc,doc_e,NULL);
}
DocUnlock(doc);
mgets_done:
"$$FU$$$$FG$$$$BG$$";
Preempt(old_preempt);
return result;
}
#help_index "Char/Input"
public I64 PmtI64(U8 *msg,I64 dft,I64 lo=MIN_I64,I64 hi=MAX_I64)
{
Bool okay;
U8 *st;
I64 result;
while (TRUE) {
"" msg,dft;
st=MGetS;
if (!*st) {
Free(st);
return dft;
}
try {
okay=FALSE;
result=ExePrintF3("ToI64(%s);",st);
okay=TRUE;
} catch
Fs->catch_except=TRUE;
Free(st);
if (okay && lo<=result<=hi)
return result;
}
}
public F64 PmtF64(U8 *msg,F64 dft,F64 lo=MIN_F64,F64 hi=MAX_F64)
{
Bool okay;
U8 *st;
F64 result;
while (TRUE) {
"" msg,dft;
st=MGetS;
if (!*st) {
Free(st);
return dft;
}
try {
okay=FALSE;
result=ExePrintF3("ToF64(%s);",st)(F64);
okay=TRUE;
} catch
Fs->catch_except=TRUE;
Free(st);
if (okay && lo<=result<=hi)
return result;
}
}
public U8 *PmtStr(U8 *msg=NULL,U8 *dft=NULL)
{
U8 *st;
if (msg) {
if (dft)
"" msg,dft;
else
"" msg;
}
st=MGetS;
if (!*st) {
Free(st);
if (dft)
return StrNew(dft);
else
return StrNew("");
}
return st;
}
public CDate PmtCDate(U8 *msg,CDate dft,CDate lo=MIN_I64,CDate hi=MAX_I64)
{
U8 *st;
CDate result;
while (TRUE) {
"" msg,dft,dft;
st=MGetS;
if (!*st) {
Free(st);
return dft;
}
result=A2CDate(st);
Free(st);
if (result>=lo && result<=hi)
return result;
}
}
#help_index "Doc"
#define RIGHT_INCLUDE 0
#define RIGHT_DEBUG 1
#define RIGHT_COMPILE 2
#define RIGHT_LOAD 3
#define RIGHT_AINCLUDE 4
#define RIGHT_AUTOFILE 5
#define RIGHT_COPY 6
#define RIGHT_MOVE 7
#define RIGHT_DELETE 8
#define RIGHT_TYPE 9
#define RIGHT_ED 10
#define RIGHT_PLAIN 11
#define RIGHT_BINREP 12
I64 PopUpCancelIncludeDelAuto(U8 *header=NULL,U8 *footer=NULL)
{
I64 i;
CDoc *doc=DocNew;
if (header) DocPutS(doc,header);
DocPrintF(doc,"\n\n"
"TXT=%s\n"
"SRC=%s\n"
"AOT=%s\n"
"JIT=%s\n"
"GRA=%s"
"$$CM+LX,1,3 $$$$BT,\"INCLUDE JIT\",RIGHT_INCLUDE$$"
"$$CM+LX,26,0$$$$BT,\"DEBUG JIT\",RIGHT_DEBUG$$"
"$$CM+LX,1,3 $$$$BT,\"AOT COMPILE AOT\",RIGHT_COMPILE$$"
"$$CM+LX,26,0$$$$BT,\"LOAD BIN\",RIGHT_LOAD$$"
"$$CM+LX,1,3 $$$$BT,\"ADAM_INCLUDE JIT\",RIGHT_AINCLUDE$$"
"$$CM+LX,26,0$$$$BT,\"AUTOFILE AUT\",RIGHT_AUTOFILE$$"
"$$CM+LX,1,3 $$$$BT,\"COPY \",RIGHT_COPY$$"
"$$CM+LX,26,0$$$$BT,\"MOVE \",RIGHT_MOVE$$"
"$$CM+LX,1,3 $$$$BT,\"DELETE \",RIGHT_DELETE$$"
"$$CM+LX,26,0$$$$BT,\"TYPE TXT;GRA\",RIGHT_TYPE$$"
"$$CM+LX,1,3 $$$$BT,\"ED TXT\",RIGHT_ED$$"
"$$CM+LX,26,0$$$$BT,\"PLAIN ED TXT\",RIGHT_PLAIN$$"
"$$CM+LX,1,3 $$$$BT,\"CANCEL \",DOCM_CANCEL$$"
"$$CM+LX,26,0$$$$BT,\"BINREP BIN\",RIGHT_BINREP$$\n",
FILENAME_MASK_TXT,
FILENAME_MASK_SRC,
FILENAME_MASK_AOT,
FILENAME_MASK_JIT,
FILENAME_MASK_GRA);
if (footer) DocPutS(doc,footer);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
I64 EdLeftClickLink(CDoc *doc,CDocEntry *doc_e)
{ //called with doc locked, exit unlocked
Bool result;
U8 *st;
if (st=DocEntryLink(doc,doc_e)) {
DocUnlock(doc);
result=Ed(st);
Free(st);
return result;
}
}
I64 TermRightClickLink(CDoc *doc,CDocEntry *doc_e)
{ //called with doc locked, exit unlocked
Bool send_new_line=FALSE,result=FALSE;
U8 *st,*st2;
I64 i;
CEdFileName fn;
if (st2=DocEntryLink(doc,doc_e)) {
if (st=DocLinkFile(st2)) {
DocUnlock(doc);
if ((i=PopUpCancelIncludeDelAuto(st))>=0) {
DocBottom(doc);
switch (i) {
case RIGHT_INCLUDE:
if (FileExtDot(st) && !FilesFindMatch(FILENAME_MASK_JIT,st)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n")) {
send_new_line=TRUE;
break;
}
}
"#include \"%s\";\n$$FU$$$$FG$$$$BG$$",st;
WinZBufUpdate;
ExeFile(st);
result=TRUE;
break;
case RIGHT_DELETE:
result=ToBool(Del(st));
break;
case RIGHT_TYPE:
result=Type(st);
break;
case RIGHT_ED:
"Ed(\"%s\");\n$$FU$$$$FG$$$$BG$$",st;
result=Ed(st);
break;
case RIGHT_PLAIN:
"Plain(\"%s\");\n$$FU$$$$FG$$$$BG$$",st;
result=Plain(st);
break;
case RIGHT_AUTOFILE:
if (FileExtDot(st) && !FilesFindMatch("*.AUT*",st)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .AUT File\n\n")) {
send_new_line=TRUE;
break;
}
}
"AutoFile(\"%s\");\n$$FU$$$$FG$$$$BG$$",st;
WinZBufUpdate;
AutoStr("%F\n",st);
result=TRUE;
break;
case RIGHT_AINCLUDE:
if (FileExtDot(st) && !FilesFindMatch(FILENAME_MASK_JIT,st)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n")) {
send_new_line=TRUE;
break;
}
}
"Adam(\"#include \\\"%s\\\"\" );\n$$FU$$$$FG$$$$BG$$",st;
WinZBufUpdate;
AdamFile(st,FALSE);
result=TRUE;
break;
case RIGHT_COMPILE:
if (FileExtDot(st) && !FilesFindMatch(FILENAME_MASK_AOT,st)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .PRJ File\n\n")) {
send_new_line=TRUE;
break;
}
}
"Cmp(\"%s\");\n$$FU$$$$FG$$$$BG$$",st;
WinZBufUpdate;
result=!ToBool(Cmp(st));
break;
case RIGHT_LOAD:
if (FileExtDot(st) && !FilesFindMatch("*.BIN*",st)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .BIN File\n\n")) {
send_new_line=TRUE;
break;
}
}
"Load(\"%s\");\n$$FU$$$$FG$$$$BG$$",st;
WinZBufUpdate;
result=ToBool(Load(st));
break;
case RIGHT_BINREP:
if (FileExtDot(st) && !FilesFindMatch("*.BIN*",st)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .BIN File\n\n")) {
send_new_line=TRUE;
break;
}
}
"BinRep(\"%s\");\n$$FU$$$$FG$$$$BG$$",st;
WinZBufUpdate;
result=BinRep(st);
break;
case RIGHT_COPY:
StrCpy(fn.name,st);
if (DocFormDo(fn.name,"CEdFileName")) {
result=ToBool(Copy(st,fn.name));
} else
send_new_line=TRUE;
break;
case RIGHT_MOVE:
StrCpy(fn.name,st);
if (DocFormDo(fn.name,"CEdFileName"))
result=Move(st,fn.name);
else
send_new_line=TRUE;
break;
case RIGHT_DEBUG:
if (FileExtDot(st) && !FilesFindMatch(FILENAME_MASK_JIT,st)) {
if (!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n")) {
send_new_line=TRUE;
break;
}
}
"IDE(\"%s\");\n$$FU$$$$FG$$$$BG$$",st;
WinZBufUpdate;
IDE(st);
result=TRUE;
break;
}
} else
send_new_line=TRUE;
Free(st);
} else
send_new_line=TRUE;
Free(st2);
} else
send_new_line=TRUE;
DocBottom(doc);
"$$FU$$$$FG$$$$BG$$";
if (send_new_line)
'\n';
return result;
}
#help_index "Debugging/Dump;Doc/Cmd Line (Typically);Cmd Line (Typically);Doc/Output"
public U0 DocDm(U8 *buf,I64 cnt=0x80)
//Dumps a chunk of mem, showing
//addresses. It is live and can be
//edited.
{
CDocEntry *doc_e;
CDoc *doc=DocCur;
Bool unlock=DocLock(doc);
doc_e=DocPrintF(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)
//Dumps a chunk of mem, showing
//offsets. It is live and can be
//edited.
{
CDocEntry *doc_e;
CDoc *doc=DocCur;
Bool unlock=DocLock(doc);
doc_e=DocPrintF(doc,"$$HX,%d,16$$",cnt);
doc_e->data=buf;
doc->cur_entry=doc_e->next;
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
}
#help_index "Doc/Output"
Bool AKDDocPutS(U8 *st)
{
CDoc *doc;
if (doc=DocCur)
DocPutSPartial(doc,st);
return FALSE;
}
KeyDevAdd(&AKDDocPutKey,&AKDDocPutS,0x80000000,TRUE);
fp_mgets=&DocMGetS;
fp_doc_cur=&DocCur;
#help_index "Doc"
+908
View File
@@ -0,0 +1,908 @@
I64 doc_tag_types[(DOCT_NUM_TYPES+63)/64],
doc_nontag_invisible_types[(DOCT_NUM_TYPES+63)/64],
doc_form_types[(DOCT_NUM_TYPES+63)/64],
doc_data_types[(DOCT_NUM_TYPES+63)/64];
I64 doc_clean_scancodes[4]={0,0,0,0};
//Don't forget $LK,"doc_stop_btypes","FF:::/TempleOS/Compiler/Lex.CPP,doc_stop_btypes"$
U0 DocTablesInit()
{
doc_tag_types[0]=
1<<DOCT_TEXT|
1<<DOCT_DATA|
1<<DOCT_MENU_VAL|
1<<DOCT_HIDE_START |
1<<DOCT_TREE|
1<<DOCT_HIDE_END|
1<<DOCT_MACRO|
1<<DOCT_BUTTON|
1<<DOCT_CHECK_BOX|
1<<DOCT_LINK|
1<<DOCT_ANCHOR|
1<<DOCT_SPRITE|
1<<DOCT_INS_BINARY|
1<<DOCT_INS_BINARY_TYPE|
1<<DOCT_INS_BINARY_SIZE|
1<<DOCT_SONG|
1<<DOCT_HTML_IMG|
1<<DOCT_HTML_VIDEO|
1<<DOCT_HTML_CODE;
//Don't forget $LK,"doc_stop_btypes","FF:::/TempleOS/Compiler/Lex.CPP,doc_stop_btypes"$
doc_nontag_invisible_types[0]=
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_ALT_FOREGROUND|
1<<DOCT_LINK_FOREGROUND|
1<<DOCT_MACRO_FOREGROUND|
1<<DOCT_ANCHOR_FOREGROUND|
1<<DOCT_HIDDEN_FOREGROUND|
1<<DOCT_TREE_FOREGROUND|
1<<DOCT_USER_FOREGROUND|
1<<DOCT_BINARY_FOREGROUND|
1<<DOCT_KEYWORD_FOREGROUND|
1<<DOCT_KEYWORD2_FOREGROUND|
1<<DOCT_COMMENT_FOREGROUND|
1<<DOCT_QUOTE_FOREGROUND|
1<<DOCT_WORD_WRAP|
1<<DOCT_UNDERLINE|
1<<DOCT_INVERT|
1<<DOCT_BLINK|
1<<DOCT_SHIFTED_X|
1<<DOCT_SHIFTED_Y|
1<<DOCT_SPRITE|
1<<DOCT_BPT|
1<<DOCT_HIGHLIGHT|
1<<DOCT_LOCK_TO_PAGE|
1<<DOCT_LOCK_TO_CENTER;
doc_form_types[0]=doc_tag_types[0]&~(1<<DOCT_TEXT)|1<<DOCT_HEX_ED;
doc_data_types[0]=
1<<DOCT_DATA|
1<<DOCT_HEX_ED|
1<<DOCT_CHECK_BOX;
Bts(doc_clean_scancodes,SC_CURSOR_RIGHT);
Bts(doc_clean_scancodes,SC_CURSOR_LEFT);
Bts(doc_clean_scancodes,SC_CURSOR_UP);
Bts(doc_clean_scancodes,SC_CURSOR_DOWN);
Bts(doc_clean_scancodes,SC_PAGE_UP);
Bts(doc_clean_scancodes,SC_PAGE_DOWN);
Bts(doc_clean_scancodes,SC_ALT);
Bts(doc_clean_scancodes,SC_CTRL);
Bts(doc_clean_scancodes,SC_SHIFT);
Bts(doc_clean_scancodes,SC_CAPS);
Bts(doc_clean_scancodes,SC_NUM);
Bts(doc_clean_scancodes,SC_SCROLL);
Bts(doc_clean_scancodes,SC_HOME);
Bts(doc_clean_scancodes,SC_END);
Bts(doc_clean_scancodes,SC_GUI);
Bts(doc_clean_scancodes,SC_BACKSPACE); //Handled specially
}
DocTablesInit;
public Bool DocLock(CDoc *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)
{
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;
}
CDocBin *DocBinFindNum(CDoc *doc,I64 num)
{
CDocBin *b=doc->bin_root.next;
while (b!=&doc->bin_root) {
if (b->num==num)
return b;
b=b->next;
}
return NULL;
}
CDocBin *DocBinFindTag(CDoc *doc,U8 *tag)
{
CDocBin *b;
if (tag) {
b=doc->bin_root.next;
while (b!=&doc->bin_root) {
if (b->tag && !StrCmp(b->tag,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_root.next;
while (b!=&doc->bin_root) {
b->use_cnt=0;
b->temp_use_cnt=0;
b->renum_num=-1;
Free(b->tag);
b->tag=NULL;
b=b->next;
}
doc_e=doc->root.next;
while (doc_e!=doc) {
doc_e2=doc_e->next;
if (doc_e->flags1 & DOCEF1_HAS_BIN) {
if (b=doc_e->bin_data=DocBinFindNum(doc,doc_e->bin_num)) {
if (doc_e->flags2 & DOCEF2_BIN_PTR_LINK)
b->temp_use_cnt=MAX_I32;
if (!b->use_cnt++)
b->renum_num=++renum_num;
doc_e->bin_num=b->renum_num;
if (!b->tag && Bt(doc_tag_types,doc_e->type_u8) &&
doc_e->tag && *doc_e->tag)
b->tag=StrNew(doc_e->tag,doc->mem_task);
} else {
DbgStr("Bin Not Found",3000);
doc_e->type=doc_e->flags2=doc_e->flags1=0;
doc_e->type_u8=DOCT_ERROR;
}
}
doc_e=doc_e2;
}
b=doc->bin_root.next;
doc->cur_bin_num=1;
while (b!=&doc->bin_root) {
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
DbgStr("DocBinDel",3000);
}
public U0 DocEntryDel(CDoc *doc,CDocEntry *doc_e)
{
if (!doc || doc==doc_e)
DbgStr("DocEntryDel",3000);
else {
if (doc->cur_entry==doc_e)
doc->cur_entry=doc_e->next;
QueRem(doc_e);
if (Bt(doc_tag_types,doc_e->type_u8))
Free(doc_e->tag);
if (doc_e->flags1 & DOCEF1_LEFT_MACRO)
Free(doc_e->left_macro);
if (doc_e->flags1 & DOCEF1_RIGHT_MACRO)
Free(doc_e->right_macro);
if (doc_e->flags1 & DOCEF1_AUX_STR)
Free(doc_e->aux_str);
if (doc_e->flags1 & DOCEF1_DEFINE)
Free(doc_e->define_str);
if (doc_e->flags1 & DOCEF1_HTML_LINK)
Free(doc_e->html_link);
if (doc_e->flags2 & DOCEF2_BIN_PTR_LINK)
Free(doc_e->bin_ptr_link);
if (doc_e->flags1 & DOCEF1_HAS_BIN)
DocBinDel(doc,doc_e->bin_data);
Free(doc_e);
}
}
public I64 DocEntrySize(CDoc *,CDocEntry *doc_e)
{
I64 result;
if (!doc_e) return 0;
result=MSize2(doc_e);
if (Bt(doc_tag_types,doc_e->type_u8))
result+=MSize2(doc_e->tag);
if (doc_e->flags1 & DOCEF1_AUX_STR)
result+=MSize2(doc_e->aux_str);
if (doc_e->flags1 & DOCEF1_DEFINE)
result+=MSize2(doc_e->define_str);
if (doc_e->flags1 & DOCEF1_HTML_LINK)
result+=MSize2(doc_e->html_link);
if (doc_e->flags2 & DOCEF2_BIN_PTR_LINK)
result+=MSize2(doc_e->bin_ptr_link);
if (doc_e->flags1 & DOCEF1_LEFT_MACRO)
result+=MSize2(doc_e->left_macro);
if (doc_e->flags1 & DOCEF1_RIGHT_MACRO)
result+=MSize2(doc_e->right_macro);
return result;
}
U0 DocUndoDel(CDoc *,CDocUndo *u)
{
Free(u->body);
Free(u);
}
U0 DocUndoCntSet(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocUndo *u=doc->undo_root.next;
doc->undo_cnt=0;
while (u!=&doc->undo_root) {
doc->undo_cnt++;
u=u->next;
}
if (unlock)
DocUnlock(doc);
}
public CDocEntry *DocEntryCopy(CDoc *doc,CDocEntry *doc_e)
{
CDocEntry *doc_ne;
CDocBin *tempb;
CTask *task=doc->mem_task;
doc_ne=MAllocIdentical(doc_e,task);
doc_ne->next=doc_ne;
doc_ne->last=doc_ne;
doc_ne->settings=NULL;
if (Bt(doc_tag_types,doc_e->type_u8))
doc_ne->tag=MAllocIdentical(doc_e->tag,task);
if (doc_e->flags1 & DOCEF1_AUX_STR)
doc_ne->aux_str=MAllocIdentical(doc_e->aux_str,task);
if (doc_e->flags1 & DOCEF1_DEFINE)
doc_ne->define_str=MAllocIdentical(doc_e->define_str,task);
if (doc_e->flags1 & DOCEF1_HTML_LINK)
doc_ne->html_link=MAllocIdentical(doc_e->html_link,task);
if (doc_e->flags2 & DOCEF2_BIN_PTR_LINK)
doc_ne->bin_ptr_link=MAllocIdentical(doc_e->bin_ptr_link,task);
if (doc_e->flags1 & DOCEF1_LEFT_MACRO)
doc_ne->left_macro=MAllocIdentical(doc_e->left_macro,task);
if (doc_e->flags1 & DOCEF1_RIGHT_MACRO)
doc_ne->right_macro=MAllocIdentical(doc_e->right_macro,task);
if (doc_e->flags1 & DOCEF1_HAS_BIN) {
tempb=MAllocIdentical(doc_e->bin_data,task);
tempb->data=MAllocIdentical(doc_e->bin_data->data,task);
doc_ne->bin_num=doc->cur_bin_num;
tempb->num=doc->cur_bin_num++;
doc_ne->bin_data=tempb;
if (Bt(doc_tag_types,doc_e->type_u8) && doc_e->tag && *doc_e->tag)
tempb->tag=StrNew(doc_e->tag,task);
else
tempb->tag=NULL;
QueIns(tempb,doc->bin_root.last);
}
return doc_ne;
}
public U8 *DocEntryLink(CDoc *doc,CDocEntry *doc_e)
{
if (doc_e->flags1&DOCEF1_LINK) {
if (doc_e->flags1 & DOCEF1_AUX_STR)
return StrNew(doc_e->aux_str,doc->mem_task);
else
return StrNew(doc_e->tag,doc->mem_task);
}
return NULL;
}
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 recover;
while (!Bt(doc_form_types,doc_e->type_u8) ||
doc_e->flags1&DOCEF1_SKIP_IN_FORM) {
doc_e=doc_e->next;
if (doc_e==doc) {
recover:
doc->cur_data_col=0;
if (!giveup) {
doc->cur_entry=doc_e->last;
DocFormBackward(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_data_col=doc_e->min_col;
doc->cur_entry=doc_e;
}
}
U0 DocFormBackward(CDoc *doc,Bool giveup=FALSE)
{
CDocEntry *doc_e=doc->cur_entry,*doc_e2=doc_e;
if (doc->flags & DOCF_FORM) {
while (!Bt(doc_form_types,doc_e->type_u8) ||
doc_e->flags1&DOCEF1_SKIP_IN_FORM) {
doc_e=doc_e->last;
if (doc_e==doc) {
doc->cur_data_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_data_col=doc_e->min_col;
doc->cur_entry=doc_e;
}
}
public U0 DocHome(CDoc *doc=NULL)
{
Bool unlock;
if (!doc) {
doc=DocCur;
if (!doc) return;
}
unlock=DocLock(doc);
doc->cur_entry=doc->root.next;
doc->cur_data_col=doc->cur_entry->min_col;
doc->x=0;
doc->y=0;
doc->line_start_col=0;
doc->cur_top_line_num=0;
DocFormFwd(doc);
if (unlock)
DocUnlock(doc);
}
U0 DocSettlingsRemainingDel(CDoc *doc,CDocEntry *doc_e,CDocSettings *s)
{
CDocSettings *s1;
if (doc_e) {
while (doc_e!=doc) {
doc_e->settings=NULL;
doc_e=doc_e->next;
}
}
if (!s) return;
while (s!=&doc->settings_root) {
s1=s->next;
QueRem(s);
Free(s);
s=s1;
}
}
CDocSettings *DocSettingsIdentical(CDoc *doc,CDocSettings *s1)
{
CDocSettings *s=MAlloc(sizeof(CDocSettings),doc->mem_task);
MemCpy(&s->start,&s1->start,sizeof(CDocSettings)-offset(CDocSettings.start));
return s;
}
CDocSettings *DocSettingsLast(CDocEntry *doc_e)
{
while (!doc_e->settings)
doc_e=doc_e->last;
return doc_e->settings;
}
CDocSettings *DocSettingsNext(CDocEntry *doc_e)
{
while (!doc_e->settings)
doc_e=doc_e->next;
return doc_e->settings;
}
public U0 DocRst(CDoc *doc,Bool is_old)
{
Bool unlock;
CDocEntry *doc_e,*doc_e2;
CDocUndo *u,*u8;
CDocSettings *s;
CDocBin *b,*b1;
if (!doc) {
doc=DocCur;
if (!doc) return;
}
unlock=DocLock(doc);
if (is_old) {
doc_e=doc->root.next;
while (doc_e!=doc) {
doc_e2=doc_e->next;
DocEntryDel(doc,doc_e);
doc_e=doc_e2;
}
DocSettlingsRemainingDel(doc,NULL,doc->settings_root.next);
u=doc->undo_root.next;
while (u!=&doc->undo_root) {
u8=u->next;
DocUndoDel(doc,u);
u=u8;
}
b=doc->bin_root.next;
while (b!=&doc->bin_root) {
b1=b->next;
QueRem(b);
Free(b->data);
Free(b);
b=b1;
}
}
//Check $LK,"DocInsDoc","MN:DocInsDoc"$
doc->flags&=DOCF_BREAK_UNLOCKED;
doc->root.next=doc->root.last=doc;
QueInit(&doc->bin_root);
QueInit(&doc->undo_root);
doc->undo_root.time_stamp=0;
doc->undo_cnt=0;
doc->cur_bin_num=1;
doc->recalc_start=doc;
doc->dollar_buf_ptr=0;
doc->ext_ascii_cnt=doc->ext_ascii_val=0;
doc->cmd_U8=CH_SPACE;
doc->page_line_num=0;
doc->best_d=MAX_I64;
s=&doc->settings_root;
s->next=s->last=s;
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->start_text_attr=WHITE<<4+BLACK;
s->alt_text_attr =LTGRAY;
s->link_attr =RED;
s->macro_attr =LTBLUE;
s->anchor_attr =DKGRAY;
s->hidden_attr =DKGRAY;
s->tree_attr =PURPLE;
s->user_attr =GREEN;
s->bin_attr =CYAN;
s->keyword_attr =BLUE;
s->keyword2_attr =LTRED;
s->comment_attr =GREEN;
s->quote_attr =BROWN;
doc_e=&doc->root;
doc_e->type=DOCT_ERROR;
doc_e->flags1=0;
doc_e->flags2=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;
doc_e->settings=s;
DocHome(doc);
if (unlock)
DocUnlock(doc);
}
public U0 DocDel(CDoc *doc)
{
if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return;
DocLock(doc);
doc->doc_signature=0;
doc->doc_in_que_signature=0;
DocRst(doc,TRUE);
Free(doc->find_replace);
Free(doc->dollar_buf);
DocUnlock(doc);
Free(doc);
}
public I64 DocSize(CDoc *doc)
{
Bool unlock;
CDocEntry *doc_e;
CDocUndo *u;
CDocSettings *s;
CDocBin *b;
I64 result=0;
if (!doc || doc->doc_signature!=DOC_SIGNATURE_VAL) return 0;
unlock=DocLock(doc);
doc_e=doc->root.next;
while (doc_e!=doc) {
result+=DocEntrySize(doc,doc_e);
doc_e=doc_e->next;
}
s=doc->settings_root.next;
while (s!=&doc->settings_root) {
result+=MSize2(s);
s=s->next;
}
u=doc->undo_root.next;
while (u!=&doc->undo_root) {
result+=MSize2(u->body);
result+=MSize2(u);
u=u->next;
}
b=doc->bin_root.next;
while (b!=&doc->bin_root) {
result+=MSize2(b->data);
result+=MSize2(b);
b=b->next;
}
result+=MSize2(doc->find_replace);
result+=MSize2(doc->dollar_buf);
result+=MSize2(doc);
if (unlock)
DocUnlock(doc);
return result;
}
U0 DocDataFmt(CDocEntry *doc_e)
{
I64 i,d;
U8 *ptr;
if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX) {
if (doc_e->flags1 & DOCEF1_DATA_IS_PTR) {
if (!(ptr=doc_e->data)) return;
} else
ptr=&doc_e->data;
if (doc_e->flags1&DOCEF1_U8)
d=*ptr;
else if (doc_e->flags1&DOCEF1_U16)
d=*ptr(U16 *);
else if (doc_e->flags1&DOCEF1_U32)
d=*ptr(U32 *);
else
d=*ptr(I64 *);
if (doc_e->type_u8==DOCT_DATA) {
SPrintF(doc_e->tag,doc_e->aux_str,d,doc_e->my_fmt_data);
if (doc_e->flags1 & DOCEF1_HAS_TERMINATOR) {
i=StrLen(doc_e->tag);
doc_e->tag[i++]='_';
doc_e->tag[i]=0;
}
doc_e->max_col=StrLen(doc_e->tag);
} else {
if (d)
doc_e->flags1|=DOCEF1_CHECKED_COLLAPSED;
else
doc_e->flags1&=~DOCEF1_CHECKED_COLLAPSED;
}
}
}
U0 DocDataGet(CDocEntry *doc_e)
{
I64 i,d;
U8 *ptr;
if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX) {
if (doc_e->flags1 & DOCEF1_DATA_IS_PTR) {
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->flags1 & DOCEF1_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 (doc_e->flags1&(DOCEF1_U8|DOCEF1_U16|DOCEF1_U32)) {
GetF(doc_e->tag,doc_e->aux_str,&d,doc_e->my_fmt_data);
if (doc_e->flags1 & DOCEF1_HAS_TERMINATOR)
doc_e->tag[i]='_';
} else {
GetF(doc_e->tag,doc_e->aux_str,ptr,doc_e->my_fmt_data);
if (doc_e->flags1 & DOCEF1_HAS_TERMINATOR)
doc_e->tag[i]='_';
return;
}
} else {
if (doc_e->flags1 & DOCEF1_CHECKED_COLLAPSED)
d=TRUE;
else
d=FALSE;
}
if (doc_e->flags1&DOCEF1_U8)
*ptr=d;
else if (doc_e->flags1&DOCEF1_U16)
*ptr(U16 *)=d;
else if (doc_e->flags1&DOCEF1_U32)
*ptr(U32 *)=d;
else
*ptr(I64 *)=d;
}
}
U0 DocRemSoftNewLines(CDoc *doc=NULL,CDocEntry *doc_e=NULL)
{
CDocEntry *doc_e2,*saved_ll=doc_e;
Bool unlock;
if (!doc) {
doc=DocCur;
if (!doc) return;
}
unlock=DocLock(doc);
if (!doc_e) doc_e=doc->root.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_data_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);
}
#help_index "Doc/Cmd Line (Typically);Cmd Line (Typically)"
public I64 DocMax(I64 i=MAX_I32)
//Adjusts the size of the Doc buf.
//Normally, the cmd line deletes
//entries after a while.
{
I64 result;
CDoc *doc=DocCur;
if (doc) {
result=doc->max_entries;
doc->max_entries=i;
return result;
} else
return 0;
}
#help_index "Doc"
public CDoc *DocNew(CTask *task=NULL)
{
CDoc *doc;
if (!task) task=Fs;
doc=CAlloc(sizeof(CDoc),task);
StrCpy(doc->filename.name,sys_temp_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=MAX_I32;
doc->ww_lines_back=32;
doc->win_task=task;
doc->mem_task=task;
DocRst(doc,FALSE);
doc->doc_signature=DOC_SIGNATURE_VAL;
return doc;
}
sys_clipboard_doc=DocNew;
#help_index "Doc/Task"
public U0 DocQueIns(CDoc *doc,CDoc *pred)
{
CDoc *succ;
Bool *old_preempt;
if (!doc) return;
old_preempt=Preempt(OFF);
succ=pred->next_doc;
doc->last_doc=pred;
doc->next_doc=succ;
pred->next_doc=doc;
succ->last_doc=doc;
doc->doc_in_que_signature=DOC_IN_QUE_SIGNATURE_VAL;
Preempt(old_preempt);
}
public U0 DocQueInsRev(CDoc *doc,CDoc *succ)
{
CDoc *pred;
Bool *old_preempt;
if (!doc) return;
old_preempt=Preempt(OFF);
pred=succ->last_doc;
doc->last_doc=pred;
doc->next_doc=succ;
pred->next_doc=doc;
succ->last_doc=doc;
doc->doc_in_que_signature=DOC_IN_QUE_SIGNATURE_VAL;
Preempt(old_preempt);
}
public U0 DocQueRem(CDoc *doc)
{
CDoc *succ,*pred;
Bool *old_preempt;
if (!doc) return;
old_preempt=Preempt(OFF);
doc->doc_in_que_signature=0;
succ=doc->next_doc;
pred=doc->last_doc;
pred->next_doc=succ;
succ->last_doc=pred;
Preempt(old_preempt);
}
public CDoc *DocCur(CTask *task=NULL)
{
CDoc *result;
if (!task) task=Fs;
result=task->last_doc;
if (result==(&task->next_doc)(U8 *)-offset(CDoc.next_doc) ||
result->flags&DOCF_AUX_DOC ||
result->doc_in_que_signature!=DOC_IN_QUE_SIGNATURE_VAL)
result=NULL;
return result;
}
public CDoc *DocAux(CTask *task=NULL)
{
CDoc *result;
if (!task) task=Fs;
result=task->next_doc;
if (result==(&task->next_doc)(U8 *)-offset(CDoc.next_doc) ||
!(result->flags&DOCF_AUX_DOC) ||
result->doc_in_que_signature!=DOC_IN_QUE_SIGNATURE_VAL)
result=NULL;
return result;
}
public CDoc *DocDblBufStart(CTask *task=NULL)
{ //See $LK-A,"::/TempleOS/Demo/Spy.CPP"$
CDoc *doc,*doc2;
Bool unlock_doc2,old_preempt=Preempt(OFF);
if (!task) task=Fs;
doc2=task->last_doc;
unlock_doc2=DocLock(doc2); //dont want change during winupdate, so lock DocCur$WW,0$
doc=DocNew(task);
doc->win_task =doc2->win_task;
doc->start_text_attr=doc2->start_text_attr;
doc->max_entries=doc2->max_entries;
MemCpy(doc->find_replace,doc2->find_replace,sizeof(CEdFindText));
doc->start_x =doc2->start_x;
doc->start_y =doc2->start_y;
MemCpy(&doc->filename,&doc2->filename,sizeof(CEdFileName));
doc->left_click_link =doc2->left_click_link;
doc->right_click_link=doc2->right_click_link;
doc->user_put_data=doc2->user_put_data;
doc->user_put_key =doc2->user_put_key;
doc->user_put_s =doc2->user_put_s;
doc->parent_doc =doc2->parent_doc;
doc->desc[0](I64)=doc2->desc[0](I64);
doc->user_data =doc2->user_data;
doc->flags|=doc2->flags&DOCG_DBL_BUF_FLAGS | DOCF_DONT_SHOW;
DocQueIns(doc,task->last_doc);
if (unlock_doc2)
DocUnlock(doc2);
Preempt(old_preempt);
return doc;
}
public Bool DocDblBufEnd(CTask *task=NULL)
{ //See $LK-A,"::/TempleOS/Demo/Spy.CPP"$
Bool okay=FALSE,old_preempt=Preempt(OFF);
CDoc *doc1,*doc2;
if (!task) task=Fs;
if (doc1=DocCur(task)) {
doc2=doc1->last_doc;
if (doc2!=(&task->next_doc)(U8 *)-offset(CDoc.next_doc) &&
!(doc2->flags&DOCF_AUX_DOC) &&
doc2->doc_in_que_signature==DOC_IN_QUE_SIGNATURE_VAL) {
doc2->flags|=DOCF_DONT_SHOW;
doc1->flags&=~DOCF_DONT_SHOW;
DocLock(doc2);
DocQueRem(doc2);
DocUnlock(doc2);
DocDel(doc2);
okay=TRUE;
}
}
Preempt(old_preempt);
return okay;
}
public Bool DocDblBufSwap(CTask *task=NULL)
{ //See $LK-A,"::/TempleOS/Demo/Spy.CPP"$
Bool okay=FALSE,old_preempt=Preempt(OFF);
CDoc *doc1,*doc2;
if (!task) task=Fs;
if (doc1=DocCur(task)) {
doc2=doc1->last_doc;
if (doc2!=(&task->next_doc)(U8 *)-offset(CDoc.next_doc) &&
!(doc2->flags&DOCF_AUX_DOC) &&
doc2->doc_in_que_signature==DOC_IN_QUE_SIGNATURE_VAL) {
doc2->flags|=DOCF_DONT_SHOW;
doc1->flags&=~DOCF_DONT_SHOW;
DocLock(doc2);
DocQueRem(doc2);
DocUnlock(doc2);
DocRst(doc2,TRUE);
MemCpy(doc2->find_replace,doc1->find_replace,sizeof(CEdFindText));
MemCpy(&doc2->filename,&doc1->filename,sizeof(CEdFileName));
doc2->start_text_attr=doc1->start_text_attr;
doc2->max_entries =doc1->max_entries;
doc2->flags =doc1->flags&DOCG_DBL_BUF_FLAGS | doc2->flags&~DOCG_DBL_BUF_FLAGS;
doc2->left_click_link =doc1->left_click_link;
doc2->right_click_link=doc1->right_click_link;
doc2->user_put_data=doc1->user_put_data;
doc2->user_put_key =doc1->user_put_key;
doc2->user_put_s =doc1->user_put_s;
doc2->desc[0](I64)=doc1->desc[0](I64);
doc2->user_data =doc1->user_data;
DocQueIns(doc2,task->last_doc);
okay=TRUE;
}
}
Preempt(old_preempt);
return okay;
}
#help_index "Doc"
+115
View File
@@ -0,0 +1,115 @@
#help_index "Doc"
I64 DocOptEntry(CDoc *,CDocEntry *doc_e)
{
U8 *st,*st2,**dst;
I64 i,result=0;
if (doc_e->flags1&DOCEF1_LINK) {
if (doc_e->flags1 & DOCEF1_AUX_STR &&
Bt(doc_tag_types,doc_e->type_u8) &&
!MemCmp(doc_e->aux_str,"FI:",3) &&
!StrCmp(doc_e->aux_str+3,doc_e->tag)) {
Free(doc_e->aux_str);
doc_e->aux_str=NULL;
doc_e->flags1&=~DOCEF1_AUX_STR;
result++;
}
if (doc_e->flags1 & DOCEF1_AUX_STR)
dst=&doc_e->aux_str;
else
dst=&doc_e->tag;
if (StrStr(*dst,".Z")) {
st=DocLinkFile(*dst);
if (FileFind(st)) {
if (IsDotZ(st))
st[StrLen(st)-2]=0;
i=StrLen(st);
if ((st2=StrStr(*dst,st)) && st2[i]=='.' && st2[i+1]=='Z') {
StrCpy(st2+i,st2+i+2);
result++;
}
}
Free(st);
}
/* !!! Dangerous, but handy !!!
if (doc_e->flags1 & DOCEF1_AUX_STR) {
if (st=StrStr(doc_e->aux_str,".Z")) {
StrCpy(st,st+2);
result++;
}
}
if (Bt(doc_tag_types,doc_e->type_u8)) {
if (st=StrStr(doc_e->tag,".Z")) {
StrCpy(st,st+2);
result++;
}
}
*/
}
if (doc_e->type_u8==DOCT_MACRO && doc_e->flags1&DOCEF1_AUX_STR &&
doc_e->flags1&DOCEF1_LEFT_MACRO && !StrCmp(doc_e->tag,doc_e->left_macro) ||
doc_e->flags1&DOCEF1_RIGHT_MACRO && !StrCmp(doc_e->tag,doc_e->right_macro)) {
doc_e->flags1&=~DOCEF1_AUX_STR;
Free(doc_e->aux_str);
doc_e->aux_str=NULL;
result++;
}
return result;
}
public I64 DocOptDoc(CDoc *doc)
{//Optimize Doc
Bool unlock=DocLock(doc);
I64 result=0;
CDocEntry *doc_e;
DocRecalc(doc);
doc_e=doc->root.next;
while (doc_e!=doc) {
if (result+=DocOptEntry(doc,doc_e))
result+=DocOptEntry(doc,doc_e);
doc_e=doc_e->next;
}
DocRecalc(doc);
if (unlock)
DocUnlock(doc);
return result;
}
public I64 DocOptFile(U8 *filename)
{//Optimize File
I64 result;
CDoc *doc=DocRead(filename);
if (result=DocOptDoc(doc)) {
"-%d:%s\n",result,doc->filename.name;
DocWrite(doc);
}
DocDel(doc);
return result;
}
I64 DocOptLst(CDirEntry *tempm1)
{
I64 result=0;
CDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub) {
"%S %s\n","ST_SCANNING_DIR",tempm1->full_name;
result+=DocOptLst(tempm1->sub);
}
} else
result+=DocOptFile(tempm1->full_name);
CDirEntryDel(tempm1);
tempm1=tempm2;
}
return result;
}
public I64 DocOpt(U8 *files_find_mask="*",U8 *fu_flags=NULL)
{//Optimize Files
I64 f=0;
GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r+T");
GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
return DocOptLst(FilesFind(files_find_mask,f));
}
File diff suppressed because it is too large. Load diff
+879
View File
@@ -0,0 +1,879 @@
public I64 DocEntryRun(CDoc *doc,CDocEntry *doc_e,Bool exited)
{ //sometimes returns locked, sometimes unlocked
U8 ch=doc->cmd_U8,*st;
I64 result=-1;
DocLock(doc);
if (!exited) {
if (doc_e->flags1 & DOCEF1_ESC) {
Msg(MSG_KEY_DOWN,CH_ESC,0,1<<TASKCf_DONT_FILTER);
return 0;
} if (doc_e->flags1 & DOCEF1_QUIT) {
Msg(MSG_KEY_DOWN,CH_SHIFT_ESC,0,1<<TASKCf_DONT_FILTER);
return 0;
} else if (doc_e->flags1 & DOCEF1_CHECK_COLLAPSABLE)
doc_e->flags1^=DOCEF1_CHECKED_COLLAPSED;
}
doc->best_d=MAX_I64;
try {
if (ch==CH_SPACE) {
if (doc_e->flags1 & DOCEF1_LINK && doc->left_click_link)
result=(*doc->left_click_link)(doc,doc_e);
if (doc_e->flags1 & DOCEF1_LEFT_EXP) {
result=doc_e->left_exp;
Msg(MSG_CMD,result,0,1<<TASKCf_DONT_FILTER);
}
if (doc_e->flags1 & DOCEF1_LEFT_CB && doc_e->left_cb) {
DocUnlock(doc);
result=(*doc_e->left_cb)(doc,doc_e);
Msg(MSG_CMD,result,0,1<<TASKCf_DONT_FILTER);
}
if (doc_e->flags1 & DOCEF1_LEFT_MACRO) {
if (doc_e->flags1 & DOCEF1_POPUP) {
st=StrNew(doc_e->left_macro);
DocUnlock(doc);
PopUp(st,Fs);
Free(st);
} else {
if (doc_e->flags1 & DOCEF1_LEFT_AUTO)
AutoStr("%s",doc_e->left_macro);
else
Auto("%s",doc_e->left_macro);
}
}
} else if (ch=='\n') {
if (doc_e->flags1 & DOCEF1_LINK && doc->right_click_link)
result=(*doc->right_click_link)(doc,doc_e);
if (doc_e->flags1 & DOCEF1_RIGHT_EXP) {
result=doc_e->right_exp;
Msg(MSG_CMD,result,0,1<<TASKCf_DONT_FILTER);
}
if (doc_e->flags1 & DOCEF1_RIGHT_CB && doc_e->right_cb) {
DocUnlock(doc);
result=(*doc_e->right_cb)(doc,doc_e);
Msg(MSG_CMD,result,0,1<<TASKCf_DONT_FILTER);
}
if (doc_e->flags1 & DOCEF1_RIGHT_MACRO) {
if (doc_e->flags1 & DOCEF1_POPUP) {
st=StrNew(doc_e->right_macro);
DocUnlock(doc);
PopUp(st,Fs);
Free(st);
} else {
if (doc_e->flags1 & DOCEF1_RIGHT_AUTO)
AutoStr("%s",doc_e->right_macro);
else
Auto("%s",doc_e->right_macro);
}
}
}
}
catch
DocBottom(doc);
doc->cmd_U8=CH_SPACE;
return result;
}
U8 *EdOverStrikeCB(CDoc *,CDocEntry *doc_e,CTask *mem_task)
{
CDoc *doc=doc_e->user_data;
U8 *st=MAlloc(8,mem_task);
*st=doc->flags & DOCF_OVERSTRIKE ? 'O':'Ä';
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);
*st=doc->find_replace->filter_lines ? 'F':'Ä';
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);
*st=doc->flags & DOCF_IN_DOLLAR ? '$$':'Ä';
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 *EdQuotesCB(CDoc *,CDocEntry *,CTask *mem_task)
{
CLex *lx=mem_task->last_lex;
U8 *st=MAlloc(8,mem_task);
*st=lx->flags & LF_IN_QUOTES ? '"':'Ä';
st[1]=0;
return st;
}
U8 *EdBracesCB(CDoc *,CDocEntry *,CTask *mem_task)
{
CLex *lx=mem_task->last_lex;
U8 *st=MAlloc(8,mem_task);
*st=lx->braces_cnt ? '}':'Ä';
st[1]=0;
return st;
}
U8 *EdSemicolonCB(CDoc *,CDocEntry *,CTask *mem_task)
{
CLex *lx=mem_task->last_lex;
U8 *st=MAlloc(8,mem_task);
*st=lx->statement_cnt ? ';':'Ä';
st[1]=0;
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";
SPrintF(st,"%-3ts",src);
return st;
}
public I64 DocGetKey(I64 *_sc=NULL)
{
I64 ch,sc;
Bool cont,old_preempt=IsPreempt;
do {
ch=GetKey(&sc,TRUE);
DocRecalc(DocCur);
cont=FALSE;
if (ch==CH_ESC || ch==CH_SHIFT_ESC) { //Check for exit filter mode
Preempt(OFF);
if (DocCur && DocCur->find_replace->filter_lines) {
EdUndoFilter(DocCur);
cont=TRUE;
}
Preempt(old_preempt);
}
} while (cont);
if (_sc) *_sc=sc;
return ch;
}
#help_index "Doc/Output"
public Bool View()
{
I64 ch;
do ch=DocGetKey;
while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
return ch==CH_ESC;
}
#help_index "Doc"
public Bool DocDo(CDoc *doc,I64 doc_flags=0)
{
CDoc *old_doc=DocCur,*old_aux_doc=DocAux,*aux;
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;
Bool result,unlock,old_preempt;
if (doc_flags&DOF_WIN_MAX)
WinMax;
unlock=DocLock(doc);
doc->win_task=Fs;
aux=DocNew;
aux->flags|=DOCF_AUX_DOC;
aux->settings_root.dft_text_attr=Fs->border_attr;
DocPutS(aux,"$$CM+TY+LX+NC,0,-1$$");
if (Bt(&Fs->display_flags,DISPLAYf_HAS_CLOSE_WIN))
DocPutS(aux,"$$TX+RX+BD,\"[X]\"$$");
DocPutS(aux,"$$BK,1$$$$TX+LX+BD,\"MENU\"$$$$BK,0$$");
doc_e=DocPutS(aux,"$$DA-T-P+BD+RD+CX+SCX+IV,256,\"%s...\",16$$");
doc_e->data=&doc->filename.name;
DocDataFmt(doc_e);
if (doc->flags & DOCF_ALLOW_UNDO) {
DocPutS(aux,"$$CM+BY+LX+NC,1,1$$");
doc_e=DocPutS(aux,"$$DA+BD+RD-T,32,\"Undo:%03d\"$$\n");
doc_e->data=&doc->undo_cnt;
DocDataFmt(doc_e);
}
DocPutS(aux,"$$CM+BY+RX+NC,-30,1$$");
doc_e=DocPutS(aux,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdMoreCB;
doc_e=DocPutS(aux,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdDollarTypeCB;
doc_e=DocPutS(aux,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdFilterCB;
doc_e=DocPutS(aux,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdOverStrikeCB;
doc_e=DocPutS(aux,"$$TX+BD+TC,\" \"$$");
doc_e->user_data=doc;
doc_e->tag_cb=&EdDollarCB;
doc_e=DocPutS(aux,"$$DA+BD+RD-T,32,\"Line:%04d \"$$");
doc_e->data=&doc->line;
DocDataFmt(doc_e);
doc_e=DocPutS(aux,"$$DA+BD+RD-T,32,\"Col:%04d\"$$\n");
doc_e->data=&doc->col;
DocDataFmt(doc_e);
DocRecalc(aux);
DocRecalc(doc);
if (!(doc_flags&DOF_DONT_HOME))
DocHome(doc);
old_preempt=Preempt(OFF);
DocQueRem(old_aux_doc);
DocQueInsRev(aux,Fs->next_doc);
if (doc!=old_doc)
doc->parent_doc=old_doc;
DocQueRem(old_doc);
DocQueIns(doc,Fs->last_doc);
Fs->text_attr=doc->settings_root.dft_text_attr;
LBts(&Fs->display_flags,DISPLAYf_SHOW);
WinZBufUpdate;
if (doc_flags&DOF_MIN_SIZE)
doc->flags|=DOCF_MIN_SIZE;
Preempt(old_preempt);
DocUnlock(doc);
WinMgrSync(2,TRUE);
if (doc->flags&DOCF_MIN_SIZE)
WinMgrSync(2,TRUE);
result=View;
Preempt(OFF);
DocLock(doc);
if (result) {
doc_e=doc->root.next;
while (doc_e!=doc) {
if (doc_e->type_u8==DOCT_DATA || doc_e->type_u8==DOCT_CHECK_BOX)
DocDataGet(doc_e);
doc_e=doc_e->next;
}
}
if (unlock)
DocUnlock(doc);
DocQueRem(aux);
DocQueInsRev(old_aux_doc,Fs->next_doc);
DocDel(aux);
DocQueRem(doc);
DocQueIns(old_doc,Fs->last_doc);
Fs->text_attr=old_attr;
if (doc_flags&DOF_MIN_SIZE) {
SetWinHorz(old_left,old_right);
SetWinVert(old_top,old_bottom);
}
Preempt(old_preempt);
return result;
}
#help_index "Doc/Input"
public Bool DocFormDo(U8 *D,U8 *class_name,
I64 doc_flags=0,U8 *header=NULL,U8 *footer=NULL)
//Supply a class name that has fmtstr definitions
//and this routine will allow user input.
{
CMemberLst *ml;
CDocEntry *doc_e;
U8 *fmtstr;
CHashClass *tempc;
CDoc *doc;
Bool result=FALSE;
if (!(tempc=HashFind(class_name,Fs->hash_table,HTT_CLASS)))
return FALSE;
doc=DocNew;
StrCpy(doc->desc,"Form");
if (header) DocPutS(doc,header);
doc->flags|=DOCF_OVERSTRIKE|DOCF_FORM;
if (doc_flags&DOF_MIN_SIZE)
doc->flags|=DOCF_MIN_SIZE;
ml=tempc->member_lst;
while (ml) {
if (fmtstr=MemberMetaData("fmtstr",ml)) {
doc_e=DocPutS(doc,fmtstr);
doc_e->data=D+ml->offset;
doc_e->my_fmt_data=MemberMetaData("fmtdata",ml);
DocDataFmt(doc_e);
}
ml=ml->next;
}
if (footer) DocPutS(doc,footer);
if (doc->root.next!=doc) {
doc->flags&=~(DOCF_ATTR_BY_PRT | DOCF_ATTR_BY_FILENAME);
DocRecalc(doc);
if (DocDo(doc,doc_flags)) {
doc_e=doc->cur_entry;
if (doc_e!=doc) {
DocEntryRun(doc,doc_e,TRUE);
DocUnlock(doc);
}
result=TRUE;
}
}
DocDel(doc);
return result;
}
U0 DocMenuDoEndTaskCB()
{
WinToTop;
throw(EXCEPT_LOCAL);
}
public I64 DocMenuDo(CDoc *m,I64 doc_flags=0)
{ //returns m 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_doc_flags=m->flags,result=DOCM_CANCEL;
Fs->task_end_cb=&DocMenuDoEndTaskCB;
try {
if (m) {
StrCpy(m->desc,"Menu");
m->flags&=~(DOCF_ATTR_BY_PRT | DOCF_ATTR_BY_FILENAME);
if (DocDo(m,doc_flags)) {
doc_e=m->cur_entry;
if (doc_e!=m) {
result=DocEntryRun(m,doc_e,TRUE);
DocUnlock(m);
}
}
}
} catch {
if (Fs->except_argc==1 && Fs->except_argv[0]==EXCEPT_LOCAL) {
if (!(doc_flags & DOF_INTERCEPT_TASK_END))
Exit;
Fs->catch_except=TRUE;
}
}
m->flags|=old_doc_flags&(DOCF_ATTR_BY_PRT | DOCF_ATTR_BY_FILENAME);
LBEqu(&Fs->task_flags,TASKf_BREAK_TO_SHIFT_ESC,old_break_shift_esc);
Fs->task_end_cb=old_end_cb;
return result;
}
#help_index "Doc"
public I64 PopUp(U8 *msg,CTask *parent=NULL,CTask **_pu_task=NULL)
{
I64 result=0;
Bool old_preempt=Preempt(OFF);
CTaskCmd *tempc;
CTask *task=Spawn(&ServantUserCmdLine,NULL,"System",parent);
if (!parent) {
TaskRqstQue(task,parent,msg,1<<TASKCf_EXIT_ON_COMPLETE);
if (_pu_task) *_pu_task=task;
Preempt(old_preempt);
return 0;
} else {
Fs->popup_task=task;
tempc=TaskRqstQue(task,parent,msg,
1<<TASKCf_WAKE_MASTER | 1<<TASKCf_FOCUS_MASTER);
if (_pu_task) *_pu_task=task;
GetRqstResult(tempc,&result);
Fs->popup_task=NULL;
Kill(task);
if (_pu_task) *_pu_task=NULL;
Preempt(old_preempt);
return result;
}
}
#help_index "Doc/Output"
public CTask *PopUpViewDoc(CDoc *doc,I64 doc_flags=0)
{
U8 *buf=MSPrintF("if (!IsSysDeterministic) Preempt(ON);DocDo(0x%X,0x%X);",doc,doc_flags);
CTask *task=Spawn(&ServantUserCmdLine,NULL,"View",Fs);
TaskRqstQue(task,NULL,buf,1<<TASKCf_EXIT_ON_COMPLETE);
Free(buf);
return task;
}
U0 PopUpViewStrTaskEndCB()
{
DocDel(NamedFramePtr("ViewStrFrame"));
Exit;
}
public CTask *PopUpViewStr(U8 *msg)
{
CTask *task;
CDoc *doc=DocNew;
DocPrintF(doc,msg);
task=PopUpViewDoc(doc);
NamedFramePtrAdd("ViewStrFrame",doc,task);
task->task_end_cb=&PopUpViewStrTaskEndCB;
return task;
}
#help_index "Doc/Input"
public I64 PopUpMenu(CDoc *doc,I64 doc_flags=0)
{
doc->flags|=DOCF_MIN_SIZE | DOCF_FORM;
return ServantUser("DocMenuDo(0x%X,0x%X);",doc,doc_flags);
}
public Bool PopUpForm(U8 *D,U8 *class_name,I64 doc_flags=DOF_MIN_SIZE,
U8 *header=NULL,U8 *footer=NULL)
{
return ServantUser("DocFormDo(0x%X,0x%X,0x%X,0x%X,0x%X);",D,class_name,
doc_flags,header,footer);
}
#help_index "Doc/Input;File/FileNames"
public U8 *PopUpPickFile(U8 *dir=NULL)
{
U8 *result,*st,*st2;
if (dir)
st=MSPrintF("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",dir);
else {
st2=CurDir;
st=MSPrintF("Cd(\"%Q\");FileMgr(FM_PICK_FILE,Fs->parent_task);",st2);
Free(st2);
}
result=PopUp(st,Fs);
Free(st);
return result;
}
public U8 *PopUpPickDir(U8 *dir=NULL)
{
U8 *result,*st,*st2;
if (dir)
st=MSPrintF("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",dir);
else {
st2=CurDir;
st=MSPrintF("Cd(\"%Q\");FileMgr(FM_PICK_DIR,Fs->parent_task);",st2);
Free(st2);
}
result=PopUp(st,Fs);
Free(st);
return result;
}
public U8 *FileNameForm(U8 *dft=NULL,I64 doc_flags=0,CTask *mem_task=NULL)
{
CEdFileName fn;
if (dft)
StrCpy(fn.name,dft);
else
*fn.name=0;
if (DocFormDo(fn.name,"CEdFileName",doc_flags))
return StrNew(fn.name,mem_task);
else
return NULL;
}
public U8 *PopUpFileName(U8 *dft=NULL,I64 doc_flags=0)
{
U8 *st=MSPrintF("FileNameForm(\"%Q\",0x%X,Fs->parent_task);",dft,doc_flags|DOF_MIN_SIZE),
*result=PopUp(st,Fs);
Free(st);
return result;
}
#help_index "Doc"
public Bool PopUpCd()
{
Bool result;
U8 *st=PopUpPickDir;
if (st) {
result=Cd(st);
Free(st);
} else
result=FALSE;
return result;
}
#help_index "Doc/Input"
public U8 *PopUpPickLstEntry(U8 *lst)
{
I64 i=0;
CDoc *doc=DocNew;
while (*lst) {
if (*lst=='@') { //Check for '@' alias lst entry
i--;
lst++;
}
DocPrintF(doc,"$$MU,\"%s\",0x%08X$$\n",
lst,i++);
lst+=StrLen(lst)+1;
}
DocPutS(doc,"\n$$MU,\"CANCEL\",DOCM_CANCEL$$\n");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
public U8 *PopUpPickDefineSub(U8 *st)
{
return PopUpPickLstEntry(Define(st));
}
public I64 PopUp1(U8 *b1,I64 n1,U8 *header=NULL,U8 *footer=NULL)
{
I64 i,l1=StrLen(b1);
CDoc *doc=DocNew;
if (header) DocPutS(doc,header);
DocPrintF(doc,"$$CM+CX,%d,4$$$$BT,\"%s\",%d$$\n",-l1/2,b1,n1);
if (footer) DocPutS(doc,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)
{
I64 i,l1=StrLen(b1),l2=StrLen(b2),y;
CDoc *doc=DocNew;
if (header) {
DocPutS(doc,header);
y=4;
} else {
DocPrintF(doc,"%*s\n",l1+l2+10,"");
y=3;
}
DocPrintF(doc,"$$CM+CX,%d,%d$$$$BT,\"%s\",%d$$",-(l1+l2+3)>>1,y,b1,n1);
DocPrintF(doc,"$$CM+CX,%d,0$$$$BT,\"%s\",%d$$\n" ,-(l1+l2+3)>>1+l1+6,b2,n2);
if (footer) DocPutS(doc,footer);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
public Bool PopUpOk(U8 *header=NULL,U8 *footer=NULL)
{
return PopUp1("OKAY",1,header,footer)>0;
}
public Bool PopUpNoYes(U8 *header=NULL,U8 *footer=NULL)
{
return $WW,0$PopUp2("YES",1,"NO",0,header,footer)>0;
}
public Bool PopUpCancelOk(U8 *header=NULL,U8 *footer=NULL)
{
return PopUp2("OKAY",1,"CANCEL",0,header,footer)>0;
}
#define RSAC_REPLACE 0
#define RSAC_SKIP 1
#define RSAC_ALL 2
public I64 PopUpReplaceSkipAllCancel(U8 *header=NULL,U8 *footer=NULL)
{
I64 i;
CDoc *doc=DocNew;
if (header) DocPutS(doc,header);
DocPutS(doc,"$$CM+LX,1,4$$$$BT,\"REPLACE\",RSAC_REPLACE$$"
"$$CM+LX,17,0$$$$BT,\"SKIP\",RSAC_SKIP$$"
"$$CM+LX,1,3$$$$BT,\"ALL\",RSAC_ALL$$"
"$$CM+LX,17,0$$$$BT,\"CANCEL\",DOCM_CANCEL$$\n");
if (footer) DocPutS(doc,footer);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
U8 *DoPopUpMGetS(U8 *header,CTask *mem_task)
{
U8 *result,*st;
if (header)
"" header;
st=MGetS(GETSF_WITH_NEW_LINE);
result=StrNew(st,mem_task);
Free(st);
return result;
}
public U8 *PopUpMGetS(U8 *header=NULL)
{
U8 *st=MSPrintF("DoPopUpMGetS(0x%X,0x%X);",header,Fs),
*result=PopUp(st,Fs);
Free(st);
return result;
}
public I64 PopUpRangeI64(I64 lo,I64 hi,I64 step=1,U8 *header=NULL,U8 *footer=NULL)
{
I64 i;
CDoc *doc=DocNew;
if (header)
DocPutS(doc,header);
for (i=lo;i<=hi;i+=step)
DocPrintF(doc,"$$MU,\"%d\",%d$$\n",i,i);
if (footer)
DocPutS(doc,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)
{
F64 d;
I64 i;
U8 buf[136];
CDoc *doc=DocNew;
if (header)
DocPutS(doc,header);
for (d=lo;d<=hi;d+=step) {
SPrintF(buf,fmt,d);
DocPrintF(doc,"$$MU,\"%s\",0x%X$$\n",buf,d);
}
if (footer)
DocPutS(doc,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)
{
F64 d;
I64 i;
U8 buf[136];
CDoc *doc=DocNew;
if (header)
DocPutS(doc,header);
for (d=lo;d<=hi;d*=factor) {
SPrintF(buf,fmt,d);
DocPrintF(doc,"$$MU,\"%s\",0x%X$$\n",buf,d);
}
if (footer)
DocPutS(doc,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)
{
return PopUpRangeF64Exp(lo,hi,Exp(Ln(hi/lo)/(steps-1)),fmt,header,footer);
}
#help_index "Task/Rqsts"
public I64 AdamFile(U8 *filename,Bool warn_ext=TRUE)
{
Bool okay=TRUE;
U8 *name=FileNameAbs(filename),
*name2=DftExt(name,"CPP.Z");
I64 result=0;
if (warn_ext &&
!FilesFindMatch(FILENAME_MASK_JIT,name2) &&
!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n"))
okay=FALSE;
if (okay)
result=Adam("#include \"%s\";",name2);
Free(name2);
Free(name);
return result;
}
#help_index "Doc"
public I64 PopUpFile(U8 *filename,Bool warn_ext=TRUE,CTask *parent=NULL,CTask **_pu_task=NULL)
{
Bool okay=TRUE;
U8 *st,*name=FileNameAbs(filename),
*name2=DftExt(name,"CPP.Z");
I64 result=0;
if (warn_ext &&
!FilesFindMatch(FILENAME_MASK_JIT,name2) &&
!PopUpCancelOk(ST_WARN_ST "Not .CPP File\n\n"))
okay=FALSE;
if (okay) {
st=MSPrintF("\"$$$$WW+H,1$$$$\";Auto(\"ExeFile(\\\"%s\\\");\\n\");UserTaskCont;",name2);
result=PopUp(st,parent,_pu_task);
Free(st);
}
Free(name2);
Free(name);
return result;
}
#help_index "Graphics/Input"
public I64 PopUpColor(U8 *header=NULL,Bool allow_transparent=TRUE,Bool allow_dft=TRUE)
{
I64 i;
CDoc *doc=DocNew;
if (header)
DocPutS(doc,header);
if (allow_transparent)
DocPutS(doc,"$$BG,WHITE$$$$MU,\"TRANSPARENT\",COLOR_TRANSPARENT$$$$BG$$\n");
DocPutS(doc,"$$FM,BLACK$$");
for (i=0;i<16;i++)
DocPrintF(doc,"$$BG,%d$$$$MU,\"__%-8Z__\",%d$$$$BG$$\n",i,i,"ST_COLORS",i);
if (allow_dft)
DocPutS(doc,"$$BG,WHITE$$$$MU,\"DEFAULT\",DOC_DFT$$$$BG$$");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
public I64 PopUpLightingColor(U8 *header=NULL)
{
I64 i;
CDoc *doc=DocNew;
if (header)
DocPutS(doc,header);
DocPutS(doc,"\n$$FM,BLACK$$Single-Sided Full-Range Double-Sided Full-Range\n");
for (i=0;i<8;i++) {
DocPrintF(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",%d$$$$BG$$ ",i,i,"ST_COLORS",i);
DocPrintF(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",%d$$$$BG$$\n",i,i,"ST_COLORS",ROPF_TWO_SIDED+i);
}
DocPutS(doc,"\nSingle-Sided Half-Range Double-Sided Half-Range\n");
for (i=0;i<16;i++) {
DocPrintF(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",%d$$$$BG$$ ",i,i,"ST_COLORS",ROPF_HALF_RANGE_COLOR+i);
DocPrintF(doc,"$$BG,%d$$$$MU,\"__%-19Z__\",%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-T,32,\"X Scale :%12.6f\"$$\n";
F64 y_scale fmtstr "$$DA-T,32,\"Y Scale :%12.6f\"$$\n";
F64 z_scale fmtstr "$$DA-T,32,\"Z Scale :%12.6f\"$$\n";
F64 é_z fmtstr "\nAngles are in degrees\n$$DA-T,32,\"Z-Axis :%12.6f\"$$\n";
F64 é_y fmtstr "$$DA-T,32,\"Y-Axis :%12.6f\"$$\n";
F64 é_x fmtstr "$$DA-T,32,\"X-Axis :%12.6f\"$$\n";
F64 x_offset fmtstr "\n$$DA-T,32,\"X Offset:%12.6f\"$$\n";
F64 y_offset fmtstr "$$DA-T,32,\"Y Offset:%12.6f\"$$\n";
F64 z_offset fmtstr "$$DA-T,32,\"Z Offset:%12.6f\"$$\n";
};
Bool PopUpTransform(I64 *r)
{
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,"CTransformForm")) {
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;
GrRotZEqu(r,tf->é_z*ã/180.0);
GrRotYEqu(r,tf->é_y*ã/180.0);
GrRotXEqu(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;
}
#define PU_SPACING 10
U0 DrawIt(CTask *task,CDC *dc)
{
I64 i,j,i1,j1;
CDoc *doc=DocCur(task);
for (j=0;j<17;j++)
for (i=0;i<17;i++) {
if (j<16)
j1=j;
else
j1=COLOR_TRANSPARENT;
if (i<16)
i1=i;
else
i1=COLOR_TRANSPARENT;
dc->color=j1+i1<<16+ROPF_DITHER;
GrRect(dc,i*PU_SPACING,j*PU_SPACING+NamedFramePtr("DitherDoFrame",task),PU_SPACING,PU_SPACING);
}
i=(17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH;
if (doc->max_x>i) i=doc->max_x;
SetWinHorz(task->win_left,task->win_left+i,task);
SetWinVert(task->win_top,task->win_top+doc->max_y+(17*PU_SPACING+FONT_WIDTH-1)/FONT_WIDTH,task);
}
I64 DitherColorDo(U8 *header=NULL)
{
I64 msg_code,p1,p2,result=-1,i,j;
DocClear;
"" header;
DocRecalc(DocCur);
NamedFramePtrAdd("DitherDoFrame",(DocCur->max_y+1)*FONT_HEIGHT);
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
Fs->draw_it=&DrawIt;
do {
msg_code=GetMsg(&p1,&p2,1<<MSG_IP_L_DOWN|1<<MSG_KEY_DOWN);
if (msg_code==MSG_IP_L_DOWN) {
msg_code=GetMsg(&p1,&p2,1<<MSG_IP_L_UP);
i=p1/PU_SPACING;
j=(p2-NamedFramePtr("DitherDoFrame"))/PU_SPACING;
if (p1>=0 && p2>=0 && 0<=j<17 && 0<=i<17) {
if (j==16) j=COLOR_TRANSPARENT;
if (i==16) i=COLOR_TRANSPARENT;
result=j+i<<16+ROPF_DITHER;
goto dcd_done;
}
}
} while (!(msg_code==MSG_KEY_DOWN && (p1==CH_ESC || p1==CH_SHIFT_ESC)));
do GetMsg(&p1,&p2,1<<MSG_KEY_UP);
while (!p1);
dcd_done:
SettingsPop;
NamedFramePtrDel("DitherDoFrame");
return result;
}
public I64 PopUpDitherColor(U8 *header=NULL)
{
U8 buf[136];
SPrintF(buf,"DitherColorDo(0x%X);",header);
return PopUp(buf,Fs);
}
U0 PopUpSnap(CSnap *g)
{
F64 d;
I64 i=PopUpRangeI64(1,16,1,"Snap\n");
if (i>=1) {
d=PopUpRangeF64Exp(1.0/16.0,4.0,2.0,"%5.3f","Pointer Speed Scaler\n");
if (d>0)
SetSnap(g,i,d);
}
}
#help_index "Doc"
File diff suppressed because it is too large. Load diff
+175
View File
@@ -0,0 +1,175 @@
#help_index "Doc"
public Bool DocTreeFind(CDoc *doc,U8 *path,
CDocEntry **_tree_entry=NULL,
CDocEntry **_start_indent=NULL, CDocEntry **_end_indent=NULL)
{
I64 i=0,k=0;
U8 *st1=StrNew(path),*st2=MAlloc(StrLen(path)+1);
Bool result=FALSE,unlock_doc=DocLock(doc);
CDocEntry *doc_e=doc->root.next;
if (_tree_entry) *_tree_entry=doc;
if (_start_indent) *_start_indent=doc;
if (_end_indent) *_end_indent=doc;
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;
else if (i==k && doc_e->flags1&DOCEF1_TREE && !StrCmp(doc_e->tag+3,st2)) {
if (*st1)
break;
else {
if (_tree_entry) *_tree_entry=doc_e;
i=0;
while (doc_e!=doc && doc_e->type_u8!=DOCT_INDENT)
doc_e=doc_e->next;
if (doc_e!=doc) {
i=doc_e->attr;
if (_start_indent) *_start_indent=doc_e;
doc_e=doc_e->next;
while (doc_e!=doc && i>0) {
if (doc_e->type_u8==DOCT_INDENT) {
i+=doc_e->attr;
if (i<=0) {
if (_end_indent) *_end_indent=doc_e;
result=TRUE;
break;
}
}
doc_e=doc_e->next;
}
}
goto ft_done;
}
}
doc_e=doc_e->next;
}
k+=2;
}
}
ft_done:
if (unlock_doc)
DocUnlock(doc);
Free(st1);
Free(st2);
return result;
}
public Bool DocTreeMake(CDoc *doc,U8 *path)
{
I64 i=0,j=MIN_I64,k=0;
U8 *st1=StrNew(path),
*st2=MAlloc(StrLen(path)+1),
*st3=StrNew(path);
Bool result=TRUE,unlock_doc=DocLock(doc);
CDocEntry *doc_e=doc->root.next;
doc->cur_entry=doc;
doc->cur_data_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_data_col=0;
goto mt_done;
}
} else if (i==k && doc_e->flags1&DOCEF1_TREE && !StrCmp(doc_e->tag+3,st2)) {
Free(st3);
st3=StrNew(st1);
j=i;
if (!*st1)
result=FALSE;
else
break;
}
doc_e=doc_e->next;
}
k+=2;
}
}
mt_done:
if (result) {
while (*st3) {
StrFirstRem(st3,"/",st2);
if (*st2) {
DocPrintF(doc,"$$TR+C,\"%s\"$$\n$$ID,2$$",st2);
doc->cur_entry=DocPutS(doc,"$$ID,-2$$");
doc->cur_data_col=0;
}
}
}
if (unlock_doc)
DocUnlock(doc);
Free(st1);
Free(st2);
Free(st3);
return result;
}
#help_index "Doc/Compiler;Compiler"
public I64 ExeDoc(CDoc *doc,Bool just_load=FALSE)
{
I64 result;
Bool okay=TRUE,unlock_doc=DocLock(doc);
CLex *lx;
lx=LexNew("",LF_DONT_FREE_BUF,FileNameAbs(sys_temp_filename));
if (just_load)
lx->flags|=LF_JUST_LOAD;
if (Fs->last_lex!=&Fs->next_lex)
lx->opts=Fs->last_lex->opts;
QueIns(lx,Fs->last_lex);
LexIncludeDoc(lx,NULL,doc);
try {
Lex(lx);
result=ExeCmdLine(lx);
} catch {
if (Fs->except_argc>0) {
if (Fs->except_argv[0]==EXCEPT_COMPILER ||
Fs->except_argv[0]==EXCEPT_BREAK) {
Fs->catch_except=TRUE;
okay=FALSE;
result=0;
}
}
}
QueRem(lx);
if (okay)
LexDel(lx); //TODO: can crash
if (unlock_doc)
DocUnlock(doc);
return result;
}
public I64 DocTreeBranchExe(CDoc *doc,U8 *path)
{
CDoc *doc2;
Bool unlock_doc=DocLock(doc);
CDocEntry *tree_branch,*start_indent,*end_indent;
I64 result=0;
if (DocTreeFind(doc,path,&tree_branch,&start_indent,&end_indent)) {
doc2=DocCopy(doc,tree_branch,end_indent);
result=ExeDoc(doc2);
DocDel(doc2);
}
if (unlock_doc)
DocUnlock(doc);
return result;
}
public I64 ExeTreeBranch(U8 *registry_file,U8 *path)
{
I64 result;
CDoc *doc=DocRead(registry_file);
result=DocTreeBranchExe(doc,path);
DocDel(doc);
return result;
}
#help_index "Doc"
+55
View File
@@ -0,0 +1,55 @@
#help_index "Char/Define"
U0 LoadDocDefines()
{
//These are used in documents such as $LK-A,"::/TempleOS/Doc/TrivialSolutions.TXT"$
//The $LK,"CDoc","MN:CDoc"$ framework will search the sym table for define string
//constants if you specify that.
CBinFile *bfh=sys_boot_base-sizeof(CBinFile);
DefinePrintF(
"DD_KERNEL","%08X",bfh);
DefinePrintF(
"DD_KERNEL2","%09,X",bfh);
bfh(I64)+=bfh->file_size-1;
DefinePrintF(
"DD_KERNEL_END","%08X",bfh);
DefinePrintF(
"DD_KERNEL_END2","%09,X",bfh);
DefinePrintF(
"DD_MP_VECT","%08X",MP_VECT_ADDR);
DefinePrintF(
"DD_MP_VECT_END","%08X",MP_VECT_ADDR+SYS_MP_INIT_END-SYS_MP_INIT_START-1);
DefinePrintF(
"DD_TEMPLEOS_AGE","%h56D",GetCurTimeCDate-A2CDate("8/1/2003"));
//This is cut and replaced when I generate a distro.
//See $LK,"DD_TEMPLEOS_LOC","FF:::/TempleOS/Demo/AcctExample/TSDistro.CPP,DD_TEMPLEOS_LOC"$.
$TR-C,"LineCnt"$
$ID,4$DefinePrintF("DD_TEMPLEOS_LOC","139,640");
$ID,-4$
DefinePrintF(
"DD_PAGE_TABLE_BASE","%08X",PAGE_TABLE_BASE);
DefinePrintF(
"DD_PAGE_TABLE_BASE2","%09,X",PAGE_TABLE_BASE);
DefinePrintF(
"DD_PAGE_TABLE_END","%08X",PAGE_TABLE_BASE+PAGE_TABLE_SIZE-1);
DefinePrintF(
"DD_SYS_HEAP_BASE","%08X",sys_heap_base);
DefinePrintF(
"DD_SYS_HEAP_BASE2","%09,X",sys_heap_base);
DefinePrintF(
"DD_MAPPED_MEM_SPACE_GIG","%d Gig",MAPPED_MEM_SPACE/0x40000000);
DefinePrintF(
"DD_MAPPED_MEM_SPACE_END","%010X",MAPPED_MEM_SPACE-1);
DefinePrintF(
"DD_MAPPED_MEM_SPACE_END2","%014,X",MAPPED_MEM_SPACE-1);
}
LoadDocDefines;
#help_index ""
+232
View File
@@ -0,0 +1,232 @@
#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 NativeFSChkDskLst(CDirEntry *tempm1,U8 *bits,U8 *bits2,I64 size,I64 bpc)
{
CDirEntry *tempm2;
I64 i,j,errs=0;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub)
errs+=NativeFSChkDskLst(tempm1->sub,bits,bits2,size,bpc);
}
j=(tempm1->size+bpc-1)/bpc;
for (i=0;i<j;i++) {
if (i+tempm1->cluster>size) {
PrintFErr("Invalid Cluster:%s Cluster:%X\n",tempm1->full_name,
i+tempm1->cluster);
errs++;
break;
}
if (LBts(bits,i+tempm1->cluster)) {
PrintFErr("Dbl Alloc:%s Cluster:%X\n",tempm1->full_name,
i+tempm1->cluster);
errs++;
}
if (!LBtr(bits2,i+tempm1->cluster)) {
PrintFErr("UnAlloc:%s Cluster:%X\n",tempm1->full_name,
i+tempm1->cluster);
errs++;
}
}
CDirEntryDel(tempm1);
tempm1=tempm2;
}
return errs;
}
I64 NativeFSChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)
{
I64 i,j,bpc,size,errs=0;
CPrt *p=Drv2Prt(drv_let),*old_prt=Fs->cur_prt;
U8 *files_find_mask=MSPrintF("%c:/*",Prt2Drv(p)),
*old_dir=StrNew(Fs->cur_dir),
*bits,*bits2;
CDirEntry *ptr,*ptr2;
Drv(drv_let);
"Scanning...\n";
size=(p->size-(p->data-p->offset))/p->spc;
bpc=p->spc<<BLK_SIZE_BITS;
bits=CAlloc((size+7)>>3);
bits2=CAlloc((size+7)>>3+BLK_SIZE);
RBlks(p,bits2,p->map1,((size+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS);
//Get Root Dir size
ptr2=MAlloc(bpc);
RClusters(p,ptr2,p->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+p->root_cluster>size) {
PrintFErr("Invalid Cluster: RootDir Cluster:%X\n",i+p->root_cluster);
errs++;
break;
}
if (LBts(bits,i+p->root_cluster)) {
PrintFErr("Dbl Alloc: RootDir Cluster:%X\n",i+p->root_cluster);
errs++;
}
if (!LBtr(bits2,i+p->root_cluster)) {
PrintFErr("UnAlloc: RootDir Cluster:%X\n",i+p->root_cluster);
errs++;
}
}
errs+=NativeFSChkDskLst(FilesFind(files_find_mask,FUF_RECURSE),bits,bits2,size,bpc);
for (i=1;i<size;i++)
if (Bt(bits2,i)) {
PrintFWarn("Shouldn't Alloc Cluster:%0X\n",i);
errs++;
if (ChkDskConfirm(_fix,_confirm))
NativeFSFreeClusters(p,i,1);
}
Free(files_find_mask);
Free(bits);
Free(bits2);
Drv(Prt2Drv(old_prt));
Cd(old_dir);
Free(old_dir);
return errs;
}
I64 FAT32ChkDskLst(CPrt *p,CDirEntry *tempm1,U8 *bits,U32 *bits2,I64 size,I64 bpc)
{
CDirEntry *tempm2;
I64 i,c,errs=0;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub)
errs+=FAT32ChkDskLst(p,tempm1->sub,bits,bits2,size,bpc);
}
i=0;
c=tempm1->cluster;
while (0<c<0x0FFFFFF8) {
if (c>size) {
PrintFErr("Invalid Cluster:%s Cluster:%X\n",tempm1->full_name,c);
errs++;
break;
}
if (LBts(bits,c)) {
PrintFErr("Dbl Alloc:%s Cluster:%X\n",tempm1->full_name,c);
errs++;
}
if (!bits2[c]) {
PrintFErr("UnAlloc:%s Cluster:%X\n",tempm1->full_name,c);
errs++;
} else
bits2[c]=0;
c=ClusterNumNext(p,c);
i++;
}
if (!(tempm1->attr & _ATTR_DIR)) {
i*=bpc;
if (tempm1->size>i) {
PrintFErr("Allocated File Too Short:%s\n",tempm1->full_name);
errs++;
}
if (i>tempm1->size+bpc-1) {
PrintFWarn("Allocated File Too Long:%s\n",tempm1->full_name);
errs++;
}
}
CDirEntryDel(tempm1);
tempm1=tempm2;
}
return errs;
}
I64 FAT32ChkDsk(U8 drv_let,Bool *_fix,Bool *_confirm)
{
I64 i,bpc,size,c,errs=0;
CPrt *p=Drv2Prt(drv_let),*old_prt=Fs->cur_prt;
U8 *files_find_mask=MSPrintF("%c:/*",Prt2Drv(p)),
*old_dir=StrNew(Fs->cur_dir),
*bits;
U32 *bits2;
Drv(drv_let);
"Scanning...\n";
size=(p->size-(p->data-p->offset))/p->spc;
bpc=p->spc<<BLK_SIZE_BITS;
bits=CAlloc((size+7)>>3);
bits2=CAlloc(size*4+BLK_SIZE);
RBlks(p,bits2,p->map1,(size*4+BLK_SIZE-1)>>BLK_SIZE_BITS);
c=p->root_cluster;
while (0<c<0x0FFFFFF8) {
if (c>size) {
PrintFErr("Invalid Cluster: RootDir Cluster:%X\n",c);
errs++;
break;
}
if (LBts(bits,c)) {
PrintFErr("Dbl Alloc: RootDir Cluster:%X\n",c);
errs++;
}
if (!bits2[c]) {
PrintFErr("UnAlloc: RootDir Cluster:%X\n",c);
errs++;
} else
bits2[c]=0;
c=ClusterNumNext(p,c);
}
errs+=FAT32ChkDskLst(p,FilesFind(files_find_mask,FUF_RECURSE),bits,bits2,size,bpc);
bits2[1]=0; //See $LK,"FAT32Fmt","MN:FAT32Fmt"$()
for (i=1;i<size;i++)
if (bits2[i]) {
PrintFWarn("Shouldn't Alloc Cluster:%0X\n",i);
errs++;
if (ChkDskConfirm(_fix,_confirm))
FAT32FreeClusters(p,i);
}
Free(files_find_mask);
Free(bits);
Free(bits2);
Drv(Prt2Drv(old_prt));
Cd(old_dir);
Free(old_dir);
return errs;
}
public I64 ChkDsk(U8 drv_let=0,Bool fix=FALSE,Bool confirm=TRUE)
{ //Check for allocation errors.
I64 errs=0;
CPrt *p=Drv2Prt(drv_let);
switch (p->type) {
case PT_NATIVE:
errs=NativeFSChkDsk(drv_let,&fix,&confirm);
break;
case PT_FAT32:
errs=FAT32ChkDsk(drv_let,&fix,&confirm);
break;
default:
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
}
if (errs) {
if (fix)
"It might be a little better. ";
"Copy files to another partition or CD-ROM, "
"reformat, and copy back. "
"Or, copy from a back-up.\n";
}
return errs;
}
#help_index ""
+5
View File
@@ -0,0 +1,5 @@
#include "Dsk2a"
#include "Dsk2b"
#include "DskCDDVD"
#include "ChkDsk"
#include "FileMgr"
+429
View File
@@ -0,0 +1,429 @@
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
public U8 *DBlk(I64 blk,Bool write=FALSE)
{//Dump Disk Blk.
//If you set write to TRUE, it will be written when you press <ESC>.
//See $LK-A,"::/TempleOS/Demo/Dsk/Raw.CPP"$.
U8 *buf=MAlloc(BLK_SIZE);
RBlks(Fs->cur_prt,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_prt,buf,blk,1);
}
}
return buf;
}
public U8 *DCluster(I64 c,Bool write=FALSE,I64 num=0)
{//Dump Disk Cluster.
//If you set write to TRUE, it will be written when you press <ESC>.
//See $LK-A,"::/TempleOS/Demo/Dsk/Raw.CPP"$.
//Do $LK,"Dir","MN:Dir"$("*",TRUE); to get cluster numbers of files.
U8 *buf=MAlloc(Fs->cur_prt->spc<<BLK_SIZE_BITS);
c=ClusterNumNext(Fs->cur_prt,c,num);
RClusters(Fs->cur_prt,buf,c,1);
"Cluster:%X\n",c;
DocD(buf,Fs->cur_prt->spc<<BLK_SIZE_BITS);
if (write) {
"Edit and press <ESC> to write or <SHIFT-ESC>\n";
if (View) {
"Write\n";
WClusters(Fs->cur_prt,buf,c,1);
}
}
return buf;
}
#help_index "File/Program Routines"
U0 OFFlatten(CDirEntry *tempm,CDirEntry **a,I64 *i)
{
CDirEntry *tempm1;
while (tempm) {
tempm1=tempm->next;
if (tempm->attr&_ATTR_DIR) {
OFFlatten(tempm->sub,a,i);
CDirEntryDel(tempm);
} else {
a[*i]=tempm;
*i=*i+1;
}
tempm=tempm1;
}
}
public I64 CFileCnt(CDirEntry *tempm)
{
I64 cnt=0;
while (tempm) {
if (tempm->attr&_ATTR_DIR)
cnt+=CFileCnt(tempm->sub);
else
cnt++;
tempm=tempm->next;
}
return cnt;
}
I64 OFCompare(CDirEntry *e1,CDirEntry *e2)
{
return e1->cluster-e2->cluster;
}
public CDirEntry **FilesOrder(CDirEntry *tempm,I64 *_cnt=NULL)
{ //See $LK-A,"::/TempleOS/Demo/Dsk/OrderedIO.CPP"$.
I64 cnt=CFileCnt(tempm),i=0;
CDirEntry **a=MAlloc(sizeof(CDirEntry *)*cnt);
OFFlatten(tempm,a,&i);
QSortI64(a,cnt,&OFCompare);
if (_cnt) *_cnt=cnt;
return a;
}
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
public Bool Copy(U8 *src_files_find_mask,U8 *dst_files_find_mask=".")
{
Bool result=TRUE;
CFileAccess *fa;
CDirEntry *tempm,*tempm1;
U8 *st;
if (!(tempm=FilesFind(src_files_find_mask)))
return FALSE;
if (IsDir(dst_files_find_mask)) {
if (fa=FileAccessNew(dst_files_find_mask,TRUE)) {
while (tempm) {
tempm1=tempm->next;
if (!(tempm->attr & _ATTR_DIR)) {
st=FileNameAbs(tempm->name);
if (!CopySingle(tempm->full_name,st))
result=FALSE;
Free(st);
}
CDirEntryDel(tempm);
tempm=tempm1;
}
FileAccessDel(fa);
}
return result;
} else
return CopySingle(src_files_find_mask,dst_files_find_mask);
}
public Bool Move(U8 *f1,U8 *f2)
{
if (Copy(f1,f2)) {
Del(f1);
return TRUE;
}
return FALSE;
}
I64 PutCopyTree(CDirEntry *tempm,I64 src_dir_len,I64 dst_dir_len,U8 *dst_dir)
{
U8 *st;
I64 result=1;
while (tempm) {
st=MAlloc(StrLen(tempm->full_name)+dst_dir_len+2);
MemCpy(st,dst_dir,dst_dir_len);
StrCpy(st+dst_dir_len,tempm->full_name+src_dir_len);
if (tempm->attr & _ATTR_DIR) {
MkDir(st);
result+=PutCopyTree(tempm->sub,src_dir_len,dst_dir_len,dst_dir);
} else
if (CopySingle(tempm->full_name,st))
result++;
Free(st);
tempm=tempm->next;
}
return result;
}
public I64 CopyTree(U8 *src_files_find_mask,U8 *dst_files_find_mask)
{ //returns count of copied files (not dirs)
CFileAccess *fa;
CDirEntry *tempm=NULL;
I64 result=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 (fa=FileAccessNew(src_files_find_mask,TRUE)) {
tempm=SysFilesFind(fa->mask,FUF_RECURSE);
st1=CurDir;
FileAccessDel(fa);
i1=StrLen(st1);
if (i1==3) i1--;
if (fa=FileAccessNew(dst_files_find_mask,TRUE,TRUE)) {
st2=CurDir;
i2=StrLen(st2);
if (i2==3) i2--;
result=PutCopyTree(tempm,i1,i2,st2);
FileAccessDel(fa);
Free(st2);
}
CDirLstDel(tempm);
Free(st1);
}
return result;
}
I64 DelTreeDirs(CDirEntry *tempm1)
{
I64 result=0;
CDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub)
result+=DelTreeDirs(tempm1->sub);
result+=SysDel(tempm1->full_name,TRUE);
}
CDirEntryDel(tempm1);
tempm1=tempm2;
}
return result;
}
I64 DelTreeFiles(CDirEntry *tempm1)
{
I64 result=0;
CDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub)
result+=DelTreeFiles(tempm1->sub);
} else
result+=SysDel(tempm1->full_name,FALSE);
CDirEntryDel(tempm1);
tempm1=tempm2;
}
return result;
}
public I64 DelTree(U8 *files_find_mask,U8 *fu_flags=NULL)
{
I64 result=0,fuf_flags=0;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (IsDir(files_find_mask)) {
result=DelTreeDirs(FilesFind(files_find_mask,fuf_flags));
result+=SysDel(files_find_mask,TRUE);
result+=SysDel(files_find_mask,FALSE);
} else
result=DelTreeFiles(FilesFind(files_find_mask,fuf_flags));
return result;
}
U0 TouchFile(U8 *filename,U8 *attr,CDate spdt=0) //Just one file
{
CPrt *p=Drv2Prt(*filename);
CDirEntry de;
U8 *cur_dir=StrNew(filename),
buf[136];
if (FileFind(filename,&de,FUF_JUST_FILES)) {
Free(de.full_name);
if (!StrCmp(attr,"+?"))
"%-48ts %s\n",filename,SPrintFFlags(buf,Define("ST_FILE_ATTRS"),de.attr);
else {
StrFirstRem(cur_dir,":");
StrLastRem(cur_dir,"/");
if (!*cur_dir)
StrCpy(cur_dir,"/");
GetFFlags(&de.attr,Define("ST_FILE_ATTRS"),attr);
if (spdt)
de.datetime=spdt;
else
de.datetime=GetCurTimeCDate;
CDirNew(p,cur_dir,&de,FALSE);
}
} else PutDefineErr("ST_FILE_NOT_FOUND");
}
U0 TouchLst(CDirEntry *tempm1,U8 *attr,CDate spdt=0)
{
CDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub) {
"%S%s\n","ST_SCANNING_DIR",tempm1->full_name;
TouchLst(tempm1->sub,attr,spdt);
}
} else
TouchFile(tempm1->full_name,attr,spdt);
CDirEntryDel(tempm1);
tempm1=tempm2;
}
}
public U0 Touch(U8 *files_find_mask,U8 *attr="+?",U8 *fu_flags=NULL,CDate spdt=0)
{
//Attr "+?" =show
// "+T" =resident
//To Set Date
// Touch(filename,"",,datetime);
I64 fuf_flags=0;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
TouchLst(FilesFind(files_find_mask,fuf_flags),attr,spdt);
}
I64 FFLst(CDirEntry *tempm1)
{
I64 cnt=0;
CDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub)
cnt+=FFLst(tempm1->sub);
} else {
PutFileLink(tempm1->full_name);
NewLine;
cnt++;
}
CDirEntryDel(tempm1);
tempm1=tempm2;
}
return cnt;
}
public I64 FF(U8 *files_find_mask,U8 *fu_flags=NULL)
//Files Find
{
I64 cnt=0,fuf_flags=0;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
cnt+=FFLst(FilesFind(files_find_mask,fuf_flags));
return cnt;
}
public U0 SetDrvTextAttr(U8 drv_let,U8 attr)
{ //This is to color the border text according to the current drive
CPrt *p;
try {
p=Drv2Prt(drv_let);
p->text_attr=attr;
} catch
Fs->catch_except=TRUE;
}
U0 PrintFDrvTextAttr(U8 drv_let=0)
{
CPrt *p=Drv2Prt(drv_let);
U8 fg=p->text_attr&0xF,bg=p->text_attr>>4;
if (fg!=bg)
"$$FG,%d$$$$BG,%d$$",fg,bg;
}
I64 NativeFSUnusedDrvSpace(U8 drv_let=0)
{
CPrt *p=Drv2Prt(drv_let);
I64 result=0,i,l;
U8 *bitmap;
try {
l=(p->size+p->spc-1)/p->spc;
i=((l+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
bitmap=MAlloc(i<<BLK_SIZE_BITS);
RBlks(p,bitmap,p->map1,i);
for (i=0;i<l;i++)
if (!Bt(bitmap,i))
result++;
Free(bitmap);
} catch
PrtUnlock(p);
return result*BLK_SIZE*p->spc;
}
I64 FAT32UnusedDrvSpace(U8 drv_let=0)
{
CPrt *p=Drv2Prt(drv_let);
I64 result=0,i,l;
U32 *bitmap;
try {
l=(p->size+p->spc-1)/p->spc;
i=(l*4+BLK_SIZE-1)>>BLK_SIZE_BITS;
bitmap=MAlloc(i<<BLK_SIZE_BITS);
RBlks(p,bitmap,p->map1,i);
for (i=0;i<l;i++)
if (!bitmap[i])
result++;
Free(bitmap);
} catch
PrtUnlock(p);
return result*BLK_SIZE*p->spc;
}
public I64 UnusedDrvSpace(U8 drv_let=0)
{ //returns size in bytes
CPrt *p=Drv2Prt(drv_let),*p_old=Fs->cur_prt;
U8 *old_dir=StrNew(Fs->cur_dir);
I64 result=0;
Drv(drv_let);
switch (p->type) {
case PT_NATIVE:
result=NativeFSUnusedDrvSpace(drv_let);
break;
case PT_FAT32:
result=FAT32UnusedDrvSpace(drv_let);
break;
default:
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
}
Drv(Prt2Drv(p_old));
Cd(old_dir);
Free(old_dir);
return result;
}
#help_index "File/Program Routines"
I64 TreeSizeFiles(CDirEntry *tempm,I64 round_to)
{
I64 result=0,i;
while (tempm) {
if (round_to)
i=CeilU64(tempm->size,round_to);
else
i=tempm->size;
if (tempm->attr&_ATTR_DIR)
i+=TreeSizeFiles(tempm->sub,round_to);
tempm->user_data=i;
result+=i;
tempm=tempm->next;
}
return result;
}
public I64 TreeSize(U8 *files_find_mask="/TempleOS/*",U8 *fu_flags=NULL,I64 round_to=0)
{
//Does not include directory size of base directory, but
//does include size of sub directories.
I64 fuf_flags=0,result=0;
CDirEntry *tempm1=NULL;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (tempm1=FilesFind(files_find_mask,fuf_flags)) {
result=TreeSizeFiles(tempm1,round_to);
CDirLstDel(tempm1);
}
return result;
}
#help_index ""
+410
View File
@@ -0,0 +1,410 @@
#help_index "File/Program Routines/Utils"
I64 CDirTreeFlattenSize(CDirEntry *tempm)
{
I64 result=0;
while (tempm) {
result+=CDIR_SIZE+1;
if (tempm->attr & _ATTR_DIR)
result+=CDirTreeFlattenSize(tempm->sub);
tempm=tempm->next;
}
return result+1;
}
I64 CDirTreeFlattenFill(CDirEntry *tempm,U8 *dst)
{
I64 result=0,i;
while (tempm) {
*dst++=1;
result++;
i=CDIR_SIZE;
MemCpy(dst,&tempm->start,i);
dst+=i;
result+=i;
if (tempm->attr & _ATTR_DIR) {
i=CDirTreeFlattenFill(tempm->sub,dst);
dst+=i;
result+=i;
}
tempm=tempm->next;
}
*dst=0;
return result+1;
}
public U8 *CDirTreeFlatten(CDirEntry *tempm,I64 *_size=NULL)
{
I64 size=CDirTreeFlattenSize(tempm);
U8 *buf=MAlloc(size);
CDirTreeFlattenFill(tempm,buf);
if (_size) *_size=size;
return buf;
}
U8 *CDirTreeDoUnflatten(U8 *src,CDirEntry **tempm)
{
I64 i;
CDirEntry *tempm1;
if (*src++) {
tempm1=CAlloc(sizeof(CDirEntry));
*tempm=tempm1;
i=CDIR_SIZE;
MemCpy(&tempm1->start,src,i);
src+=i;
if (tempm1->attr & _ATTR_DIR)
src=CDirTreeDoUnflatten(src,&tempm1->sub);
src=CDirTreeDoUnflatten(src,&tempm1->next);
} else
*tempm=NULL;
return src;
}
public CDirEntry *CDirTreeUnflatten(U8 *src)
{
CDirEntry *tempm=NULL;
CDirTreeDoUnflatten(src,&tempm);
return tempm;
}
#help_index "Install;File/Install Related"
#help_file "::/TempleOS/Doc/Install"
#define ROUND_PRT_TO (63*255)
#define PRT_HEADER 63
class CPlannedPrt
{
CPlannedPrt *next,*last;
I64 size;
Bool pri;
};
//This is available to assist in writing scripts.
I64 prt_dsk_dsk_size;
public U0 PrtDsk(U8 drv_let=0)
//Partition Disk containing partition drv_let.
//or drv_let=0 means add new drv that is not already mounted.
{
CBlkDev *bdev;
CPlannedPrt root,*temppp;
CMasterBoot mbr;
Bool pri=TRUE;
I64 ext_base,drv_let2,pri_cnt=0,
i,start_offset,offset,remaining;
"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,\"MasterBootZero\",\"MN:MasterBootZero\"$$()\n\n\n"
"Continue";
if (!YorN) return;
if (drv_let)
try
Drv2BlkDev(drv_let);
catch {
drv_let=0;
Fs->catch_except=TRUE;
}
if (!drv_let) {
Mount(TRUE);
return;
}
bdev=Drv2BlkDev(drv_let);
if (!bdev || bdev->type!=BDT_ATA)
return;
prt_dsk_dsk_size=bdev->max_blk+1;
QueInit(&root);
drv_let2=bdev->first_drv_let;
remaining=FloorU64(bdev->max_blk+1,ROUND_PRT_TO);
while (FloorU64(remaining,ROUND_PRT_TO)>=ROUND_PRT_TO) {
temppp=MAlloc(sizeof(CPlannedPrt));
do {
"$$FG,RED$$Partition %C$$FG$$\n",drv_let2;
temppp->pri=FALSE;
if (pri) {
"Primary Partition";
if (YorN) {
pri_cnt++;
temppp->pri=TRUE;
if (pri_cnt==3)
pri=FALSE;
} else
pri=FALSE;
}
"Blocks Remaining:%d (0x%X)\n",
remaining-PRT_HEADER,remaining-PRT_HEADER;
temppp->size=CeilU64(PmtI64("Size in Blocks :",
remaining-PRT_HEADER)+PRT_HEADER,ROUND_PRT_TO);
} while (!(ROUND_PRT_TO<=temppp->size<=FloorU64(remaining,ROUND_PRT_TO)));
QueIns(temppp,root.last);
remaining-=temppp->size;
drv_let2++;
}
"\n\n!!! Repartition Drive !!!\n\n";
temppp=root.next;
drv_let2=bdev->first_drv_let;
while (temppp!=&root) {
"Drive %C:%08X %s\n",drv_let2,temppp->size,
temppp->pri ? "Primary":"Logical";
temppp=temppp->next;
drv_let2++;
}
if (!AreYouSure)
goto pd_done;
remaining=FloorU64(bdev->max_blk+1,ROUND_PRT_TO)-ROUND_PRT_TO;
temppp=root.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 to MBR_PT_NATIVE
mbr.p[i].end_head=0xFE;
mbr.p[i].end_cyl=0xFFFF;
mbr.p[i].offset=PRT_HEADER+offset;
mbr.p[i].size=temppp->size-PRT_HEADER;
offset+=temppp->size;
remaining-=temppp->size;
temppp=temppp->next;
}
if (!i) i++;
if (temppp!=&root) {
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(bdev,&mbr,0,1);
while (temppp!=&root) {
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 to MBR_PT_NATIVE
mbr.p[0].end_head=0xFE;
mbr.p[0].end_cyl=0xFFFF;
mbr.p[0].offset=PRT_HEADER;
mbr.p[0].size=temppp->size-PRT_HEADER;
offset+=temppp->size;
temppp=temppp->next;
if (temppp!=&root) {
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=temppp->size;
}
ATAWriteBlks(bdev,&mbr,start_offset,1);
}
bdev->flags&=~(BDF_INITIALIZED | BDF_INIT_IN_PROGRESS);
BlkDevAdd(bdev,FALSE,TRUE);
for (i=bdev->first_drv_let;i<drv_let2;i++)
Fmt(i,TRUE,FALSE);
pd_done:
while (root.next!=&root) {
temppp=root.next;
QueRem(temppp);
Free(temppp);
}
}
#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically)"
U0 NativeFSDrvView(U8 drv_let=0)
{
CPrt *p=Drv2Prt(drv_let);
I64 lohi,c1,i,x,y,l,s;
U8 *bitmap;
CDC *dc=DCAlias;
l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
s=(p->size+p->spc-1)/p->spc;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
WinMax;
DocCursor;
DocClear;
DCFill;
try {
i=((s+7)>>3+BLK_SIZE-1)>>BLK_SIZE_BITS;
bitmap=MAlloc(i<<BLK_SIZE_BITS);
RBlks(p,bitmap,p->map1,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^COLOR_TRANSPARENT;
else
dc->color=ROP_XOR+WHITE^COLOR_TRANSPARENT;
GrPlot(dc,x,y);
i++;
}
}
Free(bitmap);
} catch
PrtUnlock(p);
GetChar;
SettingsPop;
DCFill;
DCDel(dc);
}
U0 FAT32DrvView(U8 drv_let=0)
{
CPrt *p=Drv2Prt(drv_let);
I64 lohi,c1,i,x,y,l,s;
U32 *bitmap;
CDC *dc=DCAlias;
l=(GR_HEIGHT-3*FONT_HEIGHT)*(GR_WIDTH-FONT_WIDTH<<1),
s=(p->size+p->spc-1)/p->spc;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
WinMax;
DocCursor;
DocClear;
DCFill;
try {
i=(s*4+BLK_SIZE-1)>>BLK_SIZE_BITS;
bitmap=MAlloc(i<<BLK_SIZE_BITS);
RBlks(p,bitmap,p->map1,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^COLOR_TRANSPARENT;
else
dc->color=ROP_XOR+WHITE^COLOR_TRANSPARENT;
GrPlot(dc,x,y);
i++;
}
}
Free(bitmap);
} catch
PrtUnlock(p);
GetChar;
SettingsPop;
DCFill;
DCDel(dc);
}
public U0 DrvView(U8 drv_let=0)
{
CPrt *p=Drv2Prt(drv_let),*p_old=Fs->cur_prt;
Drv(drv_let);
switch (p->type) {
case PT_NATIVE:
NativeFSDrvView(drv_let);
break;
case PT_FAT32:
FAT32DrvView(drv_let);
break;
default:
PutDefineErr("ST_UNSUPPORTED_FILE_SYSTEM");
}
Drv(Prt2Drv(p_old));
}
public U0 DskView(U8 drv_let=0)
{
I64 i,j,
h=Fs->win_pixel_width,
v=Fs->win_pixel_height,
radius;
CPrt *p;
CBlkDev *bdev=Drv2BlkDev(drv_let);
CDC *dc=DCAlias;
F64 sect_start,sect_end;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
DocCursor;
DocClear;
DCFill;
if (h<v)
radius=0.4*h;
else
radius=0.4*v;
dc->color=ROP_EQU+BLACK;
GrCircle(dc,h>>1,v>>1,radius);
j=1;
for (i=0;i<NUM_PRTS;i++) {
p=&sys_prts[i];
if (bdev==p->bdev && p->type) {
sect_start=-(p->offset*2*ã/(bdev->max_blk+1));
sect_end =-((p->offset+p->size)*2*ã/(bdev->max_blk+1));
dc->color=ROP_EQU+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));
dc->color=ROP_EQU+j;
GrPrintF(dc,0,v-FONT_HEIGHT*j,"%C %-8Z",Prt2Drv(p),
p->type.u16[0],"ST_PRT_TYPES");
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(NULL,FALSE);
SettingsPop;
DCFill;
DCDel(dc);
}
#help_index "Info;File/Cmd Line (Typically);Cmd Line (Typically);File/Install Related;Install"
public U0 BlkDevRep()
{
I64 i;
for (i=0;i<NUM_BLKDEVS;i++)
if (sys_blkdevs[i].bd_signature==BD_SIGNATURE_VAL)
ClassRep("CBlkDev",&sys_blkdevs[i]);
}
#help_index ""
+549
View File
@@ -0,0 +1,549 @@
#help_index "File/CD DVD"
U0 FillU16Palindrome(CPalindromeU16 *dst,U16 w)
{
dst->big=EndianU16(w);
dst->little=w;
}
U0 FillU32Palindrome(CPalindromeU32 *dst,I64 d)
{
dst->big=EndianU32(d);
dst->little=d;
}
class CCCDUserData //Create CD
{
I64 loc,path_entry_num,
short_dir_blks,long_dir_blks;
};
I64 CDFileCreate2(CFile *out_file,CDirEntry *tempm,
CISO1DirEntry *tempi,CISO1DirEntry *tempi2,
I64 *_cur_blk,
CDirEntry *parent,Bool write)
{
CCCDUserData *tempc;
CDirEntry *tempm1,*tempm2;
CFile *in_file;
U8 *buf=MAlloc(CD_BLK_SIZE),*ptr1,*ptr2;
CISO1DirEntry *dir_blk_buf =CAlloc(CD_BLK_SIZE*128),
*de =dir_blk_buf, *de1,
*dir_blk_buf2=CAlloc(CD_BLK_SIZE*128),
*de2=dir_blk_buf2,*de12;
I64 i,n;
tempc=parent->user_data;
de->len=sizeof(CISO1DirEntry)-1;
de->ext_attr_len=0;
FillU16Palindrome(&de->vol_seq_num,1);
CDate2ISO1(&de->date,tempm->datetime);
de->flags=ISO1_ATTR_DIR;
de->name_len=1;
de->name=0;
de->len+=de->name_len;
de(U8 *)+=de->len;
de->len=sizeof(CISO1DirEntry)-1;
de->ext_attr_len=0;
FillU32Palindrome(&de->loc,tempc->loc);
FillU32Palindrome(&de->size,tempc->short_dir_blks*CD_BLK_SIZE);
FillU16Palindrome(&de->vol_seq_num,1);
CDate2ISO1(&de->date,parent->datetime);
de->flags=ISO1_ATTR_DIR;
de->name_len=1;
de->name=1;
de->len+=de->name_len;
de(U8 *)+=de->len;
de2->len=sizeof(CISO1DirEntry)-1;
de2->ext_attr_len=0;
FillU16Palindrome(&de2->vol_seq_num,1);
CDate2ISO1(&de2->date,tempm->datetime);
de2->flags=ISO1_ATTR_DIR;
de2->name_len=1;
de2->name=0;
de2->len=de2->len+de2->name_len;
de2(U8 *)+=de2->len;
de2->len=sizeof(CISO1DirEntry)-1;
de2->ext_attr_len=0;
FillU32Palindrome(&de2->loc,tempc->loc+tempc->short_dir_blks);
FillU32Palindrome(&de2->size,tempc->long_dir_blks*CD_BLK_SIZE);
FillU16Palindrome(&de2->vol_seq_num,1);
CDate2ISO1(&de2->date,parent->datetime);
de2->flags=ISO1_ATTR_DIR;
de2->name_len=1;
de2->name=1;
de2->len+=de2->name_len;
de2(U8 *)+=de2->len;
tempm1=tempm->sub;
while (tempm1) {
tempm2=tempm1->next;
if (!write) tempm1->user_data=CAlloc(sizeof(CCCDUserData));
de1=de;
de12=de2;
if (tempm1->attr & _ATTR_DIR) {
n=CDFileCreate2(out_file,tempm1,de,de2,_cur_blk,tempm,write);
de(U8 *)+=sizeof(CISO1DirEntry)-1+n;
de2(U8 *)+=sizeof(CISO1DirEntry)-1+n<<1;
} else {
tempc=tempm1->user_data;
de->len=sizeof(CISO1DirEntry)-1;
de->ext_attr_len=0;
FillU32Palindrome(&de->loc,*_cur_blk);
tempc->loc=*_cur_blk;
if (write)
"%X:%s\n",*_cur_blk,tempm1->full_name;
FillU32Palindrome(&de->size,tempm1->size);
FillU16Palindrome(&de->vol_seq_num,1);
CDate2ISO1(&de->date,tempm1->datetime);
de->flags=0;
de->name_len=StrLen(tempm1->name);
StrCpy(&de->name,tempm1->name);
de->len=de->len+de->name_len;
de(U8 *)+=de->len;
de2->len=sizeof(CISO1DirEntry)-1;
de2->ext_attr_len=0;
FillU32Palindrome(&de2->loc,*_cur_blk);
FillU32Palindrome(&de2->size,tempm1->size);
FillU16Palindrome(&de2->vol_seq_num,1);
CDate2ISO1(&de2->date,tempm1->datetime);
de2->flags=0;
de2->name_len=StrLen(tempm1->name)<<1;
ptr1=&de2->name;
ptr2=&tempm1->name;
for (i=0;i<de2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
de2->len+=de2->name_len;
de2(U8 *)+=de2->len;
in_file=FOpen(tempm1->full_name,"r");
for (i=0;i<(FSize(in_file)+CD_BLK_SIZE-1)/CD_BLK_SIZE;i++) {
n=4;
if ((i+1)<<2>(FSize(in_file)+BLK_SIZE-1)>>BLK_SIZE_BITS) {
n=(FSize(in_file)+BLK_SIZE-1)>>BLK_SIZE_BITS&3;
MemSet(buf,0,CD_BLK_SIZE);
}
if (write) {
FRBlks(in_file,buf,i<<2,n);
FWBlks(out_file,buf,*_cur_blk<<2,n);
}
*_cur_blk+=1;
}
FClose(in_file);
}
if ((de1(U8 *)-dir_blk_buf(U8 *))/CD_BLK_SIZE!=
(de(U8 *) -dir_blk_buf(U8 *))/CD_BLK_SIZE) {
i=de1->len;
MemCpy(buf,de1,i);
MemSet(de1,0,i);
de=dir_blk_buf(U8 *)+(de(U8 *)-dir_blk_buf(U8 *))/CD_BLK_SIZE*CD_BLK_SIZE;
MemCpy(de,buf,i);
de(U8 *)+=i;
}
if ((de12(U8 *)-dir_blk_buf2(U8 *))/CD_BLK_SIZE!=
(de2(U8 *) -dir_blk_buf2(U8 *))/CD_BLK_SIZE) {
i=de12->len;
MemCpy(buf,de12,i);
MemSet(de12,0,i);
de2(U8 *)=dir_blk_buf2(U8 *)+(de2(U8 *)-dir_blk_buf2(U8 *))/CD_BLK_SIZE*CD_BLK_SIZE;
MemCpy(de2,buf,i);
de2(U8 *)+=i;
}
tempm1=tempm2;
}
tempc=tempm->user_data;
tempi->len=sizeof(CISO1DirEntry)-1;
tempi->ext_attr_len=0;
tempi->flags=ISO1_ATTR_DIR;
if (!tempm->name[0]) {
tempi->name_len=1;
tempi->name=1;
} else {
tempi->name_len=StrLen(tempm->name);
StrCpy(&tempi->name,tempm->name);
}
tempi->len+=tempi->name_len;
n=de(U8 *)+1-dir_blk_buf(U8 *);
n=(n+CD_BLK_SIZE-1)/CD_BLK_SIZE;
FillU32Palindrome(&tempi->size,n*CD_BLK_SIZE);
FillU32Palindrome(&tempi->loc,*_cur_blk);
tempc->short_dir_blks=n;
tempc->loc=*_cur_blk;
FillU32Palindrome(&dir_blk_buf->size,n*CD_BLK_SIZE);
FillU32Palindrome(&dir_blk_buf->loc,*_cur_blk);
FillU16Palindrome(&tempi->vol_seq_num,1);
CDate2ISO1(&tempi->date,tempm->datetime);
if (write)
"%X:%s\n",*_cur_blk,tempm->full_name;
if (write)
FWBlks(out_file,dir_blk_buf,*_cur_blk<<2,n<<2);
*_cur_blk+=n;
tempi2->len=sizeof(CISO1DirEntry)-1;
tempi2->ext_attr_len=0;
tempi2->flags=ISO1_ATTR_DIR;
if (!tempm->name[0]) {
tempi2->name_len=1;
tempi->name=1;
} else {
tempi2->name_len=StrLen(tempm->name)<<1;
ptr1=&tempi2->name;
ptr2=&tempm->name;
for (i=0;i<tempi2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
}
tempi2->len+=tempi2->name_len;
n=de2(U8 *)+1-dir_blk_buf2(U8 *);
n=(n+CD_BLK_SIZE-1)/CD_BLK_SIZE;
FillU32Palindrome(&tempi2->size,n*CD_BLK_SIZE);
FillU32Palindrome(&tempi2->loc,*_cur_blk);
tempc->long_dir_blks=n;
FillU32Palindrome(&dir_blk_buf2->size,n*CD_BLK_SIZE);
FillU32Palindrome(&dir_blk_buf2->loc,*_cur_blk);
FillU16Palindrome(&tempi2->vol_seq_num,1);
CDate2ISO1(&tempi2->date,tempm->datetime);
if (write)
"%X:%s\n",*_cur_blk,tempm->full_name;
if (write)
FWBlks(out_file,dir_blk_buf2,*_cur_blk<<2,n<<2);
*_cur_blk+=n;
Free(dir_blk_buf);
Free(dir_blk_buf2);
Free(buf);
return tempi->name_len;
}
I64 CDTableLen(CDirEntry *tempm,I64 *size1,I64 *size2,I64 cur_depth)
//returns depth
{
CDirEntry *tempm1=tempm->sub;
I64 max_depth=cur_depth,i;
while (tempm1) {
if (tempm1->attr & _ATTR_DIR) {
*size1+=sizeof(CISO1PathEntry)-2+ (StrLen(tempm1->name)+1)&-0x2;
*size2+=sizeof(CISO1PathEntry)-2+StrLen(tempm1->name)<<1;
i=CDTableLen(tempm1,size1,size2,cur_depth+1);
if (i>max_depth) max_depth=i;
}
tempm1=tempm1->next;
}
return max_depth;
}
U0 CDFillPathTable(CDirEntry *tempm,
CISO1PathEntry **_itabbuf,CISO1PathEntry **_itabbuf2,
I64 parent_entry_num,Bool big_endian,I64 *first_free,I64 cur_level,I64 output_level)
{
U8 *ptr1,*ptr2;
I64 i;
CISO1PathEntry *tabbuf =*_itabbuf,
*tabbuf2=*_itabbuf2;
CDirEntry *tempm1=tempm->sub,*tempm2;
CCCDUserData *tempc;
if (cur_level==output_level) {
while (tempm1) {
if (tempm1->attr & _ATTR_DIR) {
tempc=tempm1->user_data;
tempc->path_entry_num=*first_free;
tabbuf->name_len=StrLen(tempm1->name);
if (big_endian) {
tabbuf->blk=EndianU32(tempc->loc);
tabbuf->parent_entry_num=EndianU16(parent_entry_num);
} else {
tabbuf->blk=tempc->loc;
tabbuf->parent_entry_num=parent_entry_num;
}
StrCpy(&tabbuf->name,tempm1->name);
tabbuf(U8 *)+=sizeof(CISO1PathEntry)-2+
(StrLen(tempm1->name)+1) & -0x2;
tabbuf2->name_len=StrLen(tempm1->name)<<1;
if (big_endian) {
tabbuf2->blk=EndianU32(tempc->loc+tempc->short_dir_blks);
tabbuf2->parent_entry_num=EndianU16(parent_entry_num);
} else {
tabbuf2->blk=tempc->loc+tempc->short_dir_blks;
tabbuf2->parent_entry_num=parent_entry_num;
}
ptr1=&tabbuf2->name;
ptr2=&tempm1->name;
for (i=0;i<tabbuf2->name_len;i=i+2) {
ptr1++;
*ptr1++=*ptr2++;
}
tabbuf2(U8 *)+=sizeof(CISO1PathEntry)-2+
StrLen(tempm1->name)<<1;
*first_free+=1;
}
tempm1=tempm1->next;
}
*_itabbuf=tabbuf;
*_itabbuf2=tabbuf2;
}
tempm1=tempm->sub;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
tempc=tempm1->user_data;
CDFillPathTable(tempm1,_itabbuf,_itabbuf2,tempc->path_entry_num,
big_endian,first_free,cur_level+1,output_level);
}
tempm1=tempm2;
}
}
class CElTorito
{
U16 w[16];
U8 bootable; //88=bootable 00=not bootable
U8 media_type; //0=no emulation 4=hard disk
U16 load_seg; //0000->07C0
U8 sys_type;
U8 zero;
U16 sect_cnt;
U32 load_rba; //start addr of virtual disk
U8 zero2[20];
};
public I64 CDFileCreate(U8 *filename=NULL,U8 *src_files_find_mask,U8 *fu_flags=NULL,
U8 *bootfile=NULL,I64 emulation=0)
//See $LK-A,"::/TempleOS/Demo/MakeDistro.CPP.Z"$
//NULL filename uses sys_dft_iso_name.
//See the above sample code
//0=no emu 2=1.44meg 4=hard drive
//Use "C:/*" if you want all files on the C: drive.
//Default flags are "+r" recurse.
{
CISO1PriDesc *iso =CAlloc(CD_BLK_SIZE),
*iso1=CAlloc(CD_BLK_SIZE),
*iso2=CAlloc(CD_BLK_SIZE),
*iso3=CAlloc(CD_BLK_SIZE);
CDirEntry *rootdir=CAlloc(sizeof(CDirEntry));
I64 i,j,
cur_blk=0,bootfile_cd_blks=0,tabsize,tabsize2,first_free,max_depth,
fuf_flags=0;
U32 *d;
CElTorito *et=CAlloc(CD_BLK_SIZE);
U8 *filename2,
*zero_buf=CAlloc(CD_BLK_SIZE),
*bootfile_buf=NULL;
CISO1PathEntry *tabbuf=NULL,*tabbuf2=NULL,*itabbuf,*itabbuf2;
Bool okay=TRUE;
CFile *out_file=NULL;
CISO1DirEntry *tempi;
CCCDUserData *tempc;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (!filename)
filename=sys_dft_iso_name;
filename2=DftExt(filename,"ISO");
if (bootfile) {
bootfile_buf=FileRead(bootfile,&bootfile_cd_blks);
if (bootfile_cd_blks>CD_BLK_SIZE*4) {
ST_ERR_ST "Boot files limited to 0x2000 bytes\n";
goto done1;
}
bootfile_cd_blks=(bootfile_cd_blks+CD_BLK_SIZE-1)/CD_BLK_SIZE;
}
rootdir->attr=_ATTR_DIR;
rootdir->sub=FilesFind(src_files_find_mask,fuf_flags);
rootdir->datetime=GetCurTimeCDate;
rootdir->user_data=CAlloc(sizeof(CCCDUserData));
tempc=rootdir->user_data;
tempc->path_entry_num=1;
if (okay) {
cur_blk=CD_FILE_OFFSET>>2;
if (bootfile_buf)
//preboot and bootloader
cur_blk+=1+bootfile_cd_blks;
CDFileCreate2(out_file,rootdir,
&iso->root_dir_record,
&iso2->root_dir_record,
&cur_blk,rootdir,FALSE);
tabsize=sizeof(CISO1PathEntry);
tabsize2=sizeof(CISO1PathEntry);
max_depth=CDTableLen(rootdir,&tabsize,&tabsize2,1);
FillU32Palindrome(&iso->path_table_size,tabsize);
FillU32Palindrome(&iso2->path_table_size,tabsize2);
tabsize=(tabsize+CD_BLK_SIZE-1)/CD_BLK_SIZE;
cur_blk+=tabsize<<1;
tabsize2=(tabsize2+CD_BLK_SIZE-1)/CD_BLK_SIZE;
cur_blk+=tabsize2<<1;
}
if (okay) {
if (FileAttr(filename2) & _ATTR_CONTIGUOUS)
out_file=FOpen(filename2,"wc",cur_blk<<2);
else
out_file=FOpen(filename2,"w",cur_blk<<2);
if (!out_file)
okay=FALSE;
}
if (okay) {
cur_blk=0;
while (cur_blk<CD_FILE_OFFSET>>2) {
FWBlks(out_file,zero_buf,cur_blk<<2,4);
cur_blk++;
}
iso->type=ISO1T_PRI_VOL_DESC;
StrCpy(iso->id,"CD001");
iso->version=1;
FillU16Palindrome(&iso->vol_set_size,1);
FillU16Palindrome(&iso->vol_seq_num,1);
FillU16Palindrome(&iso->log_block_size,CD_BLK_SIZE);
iso->file_structure_version=1;
iso2->type=ISO1T_SUPPLEMENTARY_DESC;
StrCpy(iso2->id,"CD001");
iso2->version=1;
FillU16Palindrome(&iso2->vol_set_size,1);
FillU16Palindrome(&iso2->vol_seq_num,1);
FillU16Palindrome(&iso2->log_block_size,CD_BLK_SIZE);
iso2->file_structure_version=1;
iso1->type=ISO1T_BOOT_RECORD;
StrCpy(iso1->id,"CD001");
iso1->version=1;
StrCpy(iso1(U8 *)+7,"EL TORITO SPECIFICATION");
cur_blk=CD_FILE_OFFSET>>2;
if (bootfile_buf) {
d=iso1(U8 *)+0x47;
*d=cur_blk;
et->w[0]=1;
StrCpy(&et->w[2],"TempleOS");
et->w[15]=0xAA55;
j=0;
for (i=0;i<16;i++) //Checksum
j+=et->w[i];
et->w[14]=-j;
if (bootfile_buf)
et->bootable=0x88;
//0=no emu 2=1.44meg 4=hard drive
et->media_type=emulation;
et->sect_cnt=4; //5 seems like the limit, 4 is safer
et->load_rba=cur_blk+1;
//$AN,"CDBOOT","CDBOOT"$ See $LK,"CDBootFileCreate","MN:CDBootFileCreate"$
//See $LK,"BootCdProbe","MN:BootCdProbe"$().
"%X: Pre Boot Blk\n",cur_blk;
FWBlks(out_file,et,cur_blk<<2,4);
cur_blk++;
"%X: Boot Loader Blks\n",cur_blk;
FWBlks(out_file,bootfile_buf,cur_blk<<2,bootfile_cd_blks<<2);
cur_blk+=bootfile_cd_blks;
}
CDFileCreate2(out_file,rootdir,
&iso->root_dir_record,
&iso2->root_dir_record,
&cur_blk,rootdir,TRUE);
tabbuf=CAlloc(tabsize*CD_BLK_SIZE);
iso->type_l_path_table=cur_blk;
tabbuf->name_len=2; //Fill-in adam entry
tempi=&iso->root_dir_record;
tabbuf->blk=tempi->loc.little;
tabbuf->parent_entry_num=1;
tabbuf2=CAlloc(tabsize2*CD_BLK_SIZE);
iso2->type_l_path_table=cur_blk+tabsize;
tabbuf2->name_len=2; //Fill-in adam entry
tempi=&iso2->root_dir_record;
tabbuf2->blk=tempi->loc.little;
tabbuf2->parent_entry_num=1;
itabbuf=tabbuf+1;
itabbuf2=tabbuf2+1;
first_free=2;
for (i=1;i<=max_depth;i++)
CDFillPathTable(rootdir,&itabbuf,&itabbuf2,
1,FALSE,&first_free,1,i);
"%X: Path Table 0\n",cur_blk;
FWBlks(out_file,tabbuf,cur_blk<<2,tabsize<<2);
cur_blk+=tabsize;
"%X: Path Table 1\n",cur_blk;
FWBlks(out_file,tabbuf2,cur_blk<<2,tabsize2<<2);
cur_blk+=tabsize2;
MemSet(tabbuf,0,tabsize*CD_BLK_SIZE);
iso->type_m_path_table=EndianU32(cur_blk);
tabbuf->name_len=2; //Fill-in adam entry
tempi=&iso->root_dir_record;
tabbuf->blk=tempi->loc.big;
tabbuf->parent_entry_num=EndianU16(1);
MemSet(tabbuf2,0,tabsize2*CD_BLK_SIZE);
iso2->type_m_path_table=EndianU32(cur_blk+tabsize);
tabbuf2->name_len=2; //Fill-in adam entry
tempi=&iso2->root_dir_record;
tabbuf2->blk=tempi->loc.big;
tabbuf2->parent_entry_num=EndianU16(1);
itabbuf=tabbuf+1;
itabbuf2=tabbuf2+1;
first_free=2;
for (i=1;i<=max_depth;i++)
CDFillPathTable(rootdir,&itabbuf,&itabbuf2,
1,TRUE,&first_free,1,i);
"%X: Path Table 2\n",cur_blk;
FWBlks(out_file,tabbuf,cur_blk<<2,tabsize<<2);
cur_blk+=tabsize;
"%X: Path Table 3\n",cur_blk;
FWBlks(out_file,tabbuf2,cur_blk<<2,tabsize2<<2);
cur_blk+=tabsize2;
CDirLstDel2(rootdir);
FillU32Palindrome(&iso->vol_space_size,cur_blk);
FillU32Palindrome(&iso2->vol_space_size,cur_blk);
FWBlks(out_file,iso,16<<2,4);
iso3->type=ISO1T_TERMINATOR;
StrCpy(iso3->id,"CD001");
iso3->version=1;
if (bootfile_buf) {
FWBlks(out_file,iso1,17<<2,4);
FWBlks(out_file,iso2,18<<2,4);
FWBlks(out_file,iso3,19<<2,4);
} else {
FWBlks(out_file,iso2,17<<2,4);
FWBlks(out_file,iso3,18<<2,4);
}
} else
cur_blk=0;
FClose(out_file);
Free(tabbuf);
Free(tabbuf2);
done1:
Free(bootfile_buf);
Free(filename2);
Free(et);
Free(zero_buf);
Free(iso);
Free(iso1);
Free(iso2);
Free(iso3);
return cur_blk;
}
#help_index ""
+765
View File
@@ -0,0 +1,765 @@
#help_index "Doc/Output"
U0 CDirFileDoc(CDoc *doc,CDirEntry *tempm)
{
CDocEntry *doc_e;
while (tempm) {
if (tempm->attr & _ATTR_DIR) {
doc_e=DocPrintF(doc,"$$TR,\"%s\"$$",tempm->name);
doc_e->user_data=tempm;
tempm->user_data=doc_e;
DocPutS(doc,"\n$$ID,+2$$");
if (tempm->sub)
CDirFileDoc(doc,tempm->sub);
DocPutS(doc,"$$ID,-2$$");
} else {
doc_e=DocPrintF(doc,"$$MU-LE,\"%s\"$$",
tempm->name);
doc_e->user_data=tempm;
tempm->user_data=doc_e;
DocPutS(doc,"\n");
}
tempm=tempm->next;
}
}
#help_index "File/Cmd Line (Typically);Cmd Line (Typically)"
class CFMUncollapsedLst
{
CFMUncollapsedLst *next;
U8 *name;
};
CFMUncollapsedLst *FMCollectUncollapsedLst(CDoc *doc)
{
CDocEntry *doc_e=doc->root.next;
CFMUncollapsedLst *result=NULL,*tempc;
CDirEntry *tempm;
while (doc_e!=doc) {
if (doc_e->type_u8==DOCT_TREE) {
if (!(doc_e->flags1&DOCEF1_CHECKED_COLLAPSED)) {
if (tempm=doc_e->user_data) {
tempc=MAlloc(sizeof(CFMUncollapsedLst));
tempc->next=result;
result=tempc;
tempc->name=StrNew(tempm->full_name);
}
}
}
doc_e=doc_e->next;
}
return result;
}
U0 FMMarkUncollapsed(CDoc *doc,CFMUncollapsedLst *tempc,U8 *cur_entry,U8 *next_entry)
{
CDocEntry *doc_e=doc->root.next;
CFMUncollapsedLst *tempc1;
CDirEntry *tempm;
while (doc_e!=doc) {
if (doc_e->type_u8==DOCT_TREE) {
tempm=doc_e->user_data;
tempc1=tempc;
while (tempc1) {
if (!StrCmp(tempc1->name,tempm->full_name)) {
doc_e->flags1&=~DOCEF1_CHECKED_COLLAPSED;
break;
}
tempc1=tempc1->next;
}
if (cur_entry) {
if (!StrNCmp(cur_entry,tempm->full_name,StrLen(tempm->full_name))) {
doc->cur_entry=doc_e;
if (StrLen(tempm->full_name)==StrLen(cur_entry))
cur_entry=NULL;
} else if (next_entry) {
if (!StrNCmp(next_entry,tempm->full_name,StrLen(tempm->full_name))) {
doc->cur_entry=doc_e;
if (StrLen(tempm->full_name)==StrLen(next_entry))
cur_entry=NULL;
}
}
}
} else if (doc_e->type_u8==DOCT_MENU_VAL) {
tempm=doc_e->user_data;
if (cur_entry) {
if (!StrNCmp(cur_entry,tempm->full_name,StrLen(tempm->full_name))) {
doc->cur_entry=doc_e;
if (StrLen(tempm->full_name)==StrLen(cur_entry))
cur_entry=NULL;
} else if (next_entry) {
if (!StrNCmp(next_entry,tempm->full_name,StrLen(tempm->full_name))) {
doc->cur_entry=doc_e;
if (StrLen(tempm->full_name)==StrLen(next_entry))
cur_entry=NULL;
}
}
}
}
doc_e=doc_e->next;
}
}
U0 FMDelUncollapsedLst(CFMUncollapsedLst *tempc)
{
CFMUncollapsedLst *tempc1;
while (tempc) {
tempc1=tempc->next;
Free(tempc->name);
Free(tempc);
tempc=tempc1;
}
}
CDirEntry *FMRebuildDocDrv(U8 drv_let,CDoc *doc,CDirEntry **_root,Bool init)
{
CDocEntry *doc_e;
CDirEntry *tempm,*tempm1;
U8 *st;
tempm=CAlloc(sizeof(CDirEntry));
tempm->full_name=MSPrintF("%C:/",drv_let);
tempm->attr=_ATTR_DIR;
st=MSPrintF("%c:/*",drv_let);
if (init)
tempm->sub=tempm1=FilesFind(st,FUF_RECURSE);
else
tempm1=NULL;
Free(st);
doc_e=DocPrintF(doc,"$$TR,\"%s\"$$",tempm->full_name);
doc_e->user_data=tempm;
tempm->user_data=doc_e;
tempm->next=*_root;
*_root=tempm;
DocPutS(doc,"\n$$ID,+2$$");
DocBottom(doc);
if (init) {
CDirFileDoc(doc,tempm1);
while (tempm1) {
tempm1->parent=tempm;
tempm1=tempm1->next;
}
}
DocPutS(doc,"$$ID,-2$$");
return tempm;
}
U0 FMRebuildDoc(CDoc **_doc,CDirEntry **_root,I64 mode)
{
CPrt *p;
I64 i;
CDoc *doc=*_doc,*doc2=sys_clipboard_doc,*parent_doc;
CFMUncollapsedLst *tempc=NULL;
U8 *cur_entry=NULL,*next_entry=NULL;
CDocEntry *doc_ce;
CDirEntry *tempm,*tempm1,*cur_tree_entry;
if (!doc)
parent_doc=DocCur;
else {
parent_doc=doc->parent_doc;
DocQueRem(doc);
DocUnlock(doc);
WinMgrSync;
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);
tempm=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)
tempm=doc_ce->user_data;
else
tempm=NULL;
if (tempm) {
tempm1=tempm->parent;
while (tempm1) {
if (tempm1==cur_tree_entry) {
tempm=NULL;
break;
} else
tempm1=tempm1->parent;
}
if (tempm)
break;
}
doc_ce=doc_ce->next;
}
if (tempm)
next_entry=StrNew(tempm->full_name);
tempc=FMCollectUncollapsedLst(doc);
DocDel(doc);
}
if (*_root) {
CDirLstDel(*_root);
*_root=NULL;
}
doc=DocNew;
StrCpy(doc->desc,"FileMan");
doc->parent_doc=parent_doc;
doc->flags|=DOCF_FORM;
switch (mode) {
case FM_NORMAL:
DocPutS(doc,"$$FG,PURPLE$$File Manager$$FG$$\n\n$$LK,\"Click for Help\",\"FI:::/TempleOS/Doc/FileMgr.TXT\"$$\n\n");
break;
case FM_PICK_FILE:
DocPutS(doc,"$$FG,PURPLE$$Pick file and press <ESC>$$FG$$\n\n");
doc->flags|=DOCF_MIN_SIZE;
break;
case FM_PICK_DIR:
DocPutS(doc,"$$FG,PURPLE$$Pick directory and press <ESC>$$FG$$\n\n");
doc->flags|=DOCF_MIN_SIZE;
break;
}
for (i=0;i<NUM_PRTS;i++) {
p=&sys_prts[i];
if (p->type==PT_NATIVE||p->type==PT_FAT32)
FMRebuildDocDrv(Prt2Drv(p),doc,_root,TRUE);
else if (p->type==PT_ISO9660) {
if (p->bdev->flags&BDF_INITIALIZED)
tempm=FMRebuildDocDrv(Prt2Drv(p),doc,_root,TRUE);
else {
tempm=FMRebuildDocDrv(Prt2Drv(p),doc,_root,FALSE);
tempm->flags|=DEF_NOT_INITIALIZED;
}
tempm->flags|=DEF_REMOVABLE;
}
}
DocHome(doc);
FMMarkUncollapsed(doc,tempc,cur_entry,next_entry);
DocCenter(doc);
DocRst(doc2,TRUE);
FMDelUncollapsedLst(tempc);
Free(cur_entry);
Free(next_entry);
*_doc=doc;
DocLock(doc);
DocQueRem(DocCur);
DocQueIns(doc,Fs->last_doc);
}
U0 FMRename(CDoc *doc)
{
CEdFileName fn;
CDocEntry *doc_e=doc->cur_entry;
CDirEntry *tempm=NULL,*parent;
if (doc_e->type_u8==DOCT_MENU_VAL) {
tempm=doc_e->user_data;
if (parent=tempm->parent) {
Cd(parent->full_name);
StrCpy(fn.name,tempm->name);
if (DocFormDo(fn.name,"CEdFileName")) {
Silent(ON);
Move(tempm->name,fn.name);
Silent(OFF);
}
}
} else if (doc_e->type_u8==DOCT_TREE) {
tempm=doc_e->user_data;
if (parent=tempm->parent) {
Cd(parent->full_name);
StrCpy(fn.name,tempm->name);
if (DocFormDo(fn.name,"CEdFileName")) {
if (StrCmp(tempm->name,fn.name)) {
Silent(ON);
if (CopyTree(tempm->name,fn.name))
DelTree(tempm->name);
Silent(OFF);
}
}
}
}
}
U0 FMMkDir(CDoc *doc)
{
CEdFileName fn;
CDocEntry *doc_e=doc->cur_entry;
CDirEntry *tempm=NULL,*parent;
*fn.name=0;
if (doc_e->type_u8==DOCT_MENU_VAL) {
tempm=doc_e->user_data;
if (parent=tempm->parent) {
Cd(parent->full_name);
if (DocFormDo(fn.name,"CEdFileName")) {
Silent(ON);
MkDir(fn.name);
Silent(OFF);
}
}
} else if (doc_e->type_u8==DOCT_TREE) {
tempm=doc_e->user_data;
Cd(tempm->full_name);
if (DocFormDo(fn.name,"CEdFileName")) {
Silent(ON);
MkDir(fn.name);
Silent(OFF);
}
}
}
U0 FMDelete(CDoc *doc)
{
U8 *st;
CDocEntry *doc_ce=doc->cur_entry;
CDirEntry *tempm;
if (doc_ce->type_u8==DOCT_MENU_VAL) {
tempm=doc_ce->user_data;
Silent(ON);
st=MSPrintF("Delete: %s",tempm->full_name);
if (PopUpCancelOk(st))
Del(tempm->full_name);
Free(st);
Silent(OFF);
} else if (doc_ce->type_u8==DOCT_TREE) {
tempm=doc_ce->user_data;
Silent(ON);
st=MSPrintF("Delete: %s",tempm->full_name);
if (PopUpCancelOk(st))
DelTree(tempm->full_name);
Free(st);
Silent(OFF);
}
}
U0 FMMount(CDoc *doc)
{
CDocEntry *doc_ce=doc->cur_entry;
CDirEntry *tempm;
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
tempm=doc_ce->user_data;
else
tempm=NULL;
if (tempm) {
while (tempm->parent)
tempm=tempm->parent;
Silent(ON);
ChgDsk(*tempm->full_name);
Silent(OFF);
}
}
U0 FMFmtDrv(CDoc *doc)
{
CDocEntry *doc_ce=doc->cur_entry;
CDirEntry *tempm;
U8 *st=NULL;
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
tempm=doc_ce->user_data;
else
tempm=NULL;
if (tempm) {
while (tempm->parent)
tempm=tempm->parent;
st=MSPrintF("Format Drive '%c'?\nAre You Sure?\n",*tempm->full_name);
if (PopUpCancelOk(st)) {
Silent(ON);
Fmt(*tempm->full_name,TRUE,FALSE);
Silent(OFF);
}
}
Free(st);
}
U0 FMMakeISO(CDoc *doc)
{
CDocEntry *doc_ce=doc->cur_entry;
CDirEntry *tempm;
U8 *st;
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
tempm=doc_ce->user_data;
else
tempm=NULL;
if (tempm) {
if (doc_ce->type_u8==DOCT_MENU_VAL)
tempm=tempm->parent;
if (tempm && *tempm->full_name) {
Silent(ON);
if (tempm->full_name[StrLen(tempm->full_name)-1]=='/')
st=MSPrintF("%s*",tempm->full_name);
else
st=MSPrintF("%s/*",tempm->full_name);
CDFileCreate(,st);
Free(st);
Silent(OFF);
}
}
}
U0 FMBurnISO(CDoc *doc)
{
CDocEntry *doc_ce=doc->cur_entry;
CDirEntry *tempm;
if (doc_ce->type_u8==DOCT_TREE || doc_ce->type_u8==DOCT_MENU_VAL)
tempm=doc_ce->user_data;
else
tempm=NULL;
if (tempm) {
while (tempm->parent)
tempm=tempm->parent;
Silent(ON);
CDImageWrite(*tempm->full_name);
Silent(OFF);
}
}
U0 FMCopy(CDoc *doc)
{
CDoc *doc2=sys_clipboard_doc;
U8 *st;
CDocEntry *doc_ce=doc->cur_entry,*doc_e;
CDirEntry *tempm,*tempm1=NULL,*tempm2;
Bool unlock_doc2=DocLock(doc2);
doc_e=doc2->root.next;
tempm1=doc_ce->user_data;
if (doc_ce->type_u8==DOCT_MENU_VAL)
tempm1=tempm1->parent;
else if (doc_ce->type_u8!=DOCT_TREE)
tempm1=NULL;
if (tempm1) {
while (doc_e!=doc2) {
if (doc_e->type_u8==DOCT_MENU_VAL) {
tempm=doc_e->user_data;
tempm->flags|=DEF_PROCESSED;
tempm2=tempm->parent;
if (!tempm2 || !(tempm2->flags&DEF_PROCESSED)) {
Silent(ON);
Copy(tempm->full_name,tempm1->full_name);
Silent(OFF);
}
} else if (doc_e->type_u8==DOCT_TREE) {
tempm=doc_e->user_data;
tempm->flags|=DEF_PROCESSED;
tempm2=tempm->parent;
if (!tempm2 || !(tempm2->flags&DEF_PROCESSED)) {
Silent(ON);
if (*tempm1->name)
st=MSPrintF("%s/%s",tempm1->full_name,tempm->name);
else
st=MSPrintF("%s%s",tempm1->full_name,tempm->name);
CopyTree(tempm->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_MAKE_ISO 9
#define FMR_BURN_ISO 10
#define FMR_HELP 11
I64 PopUpCancelPasteDel(U8 *header=NULL,U8 *footer=NULL)
{
I64 i;
CDoc *doc=DocNew;
if (header) DocPutS(doc,header);
DocPutS(doc,"$$CM+LX,1,1 $$$$BT,\"INCLUDE \",FMR_INCLUDE$$"
"$$CM+LX,27,0$$$$BT,\"ADAM INCLUDE \",FMR_ADAM_INCLUDE$$"
"$$CM+LX,1,3 $$$$BT,\"DELETE \",FMR_DELETE$$"
"$$CM+LX,27,0$$$$BT,\"RENAME \",FMR_RENAME$$"
"$$CM+LX,1,3 $$$$BT,\"MAKE DIRECTORY \",FMR_MKDIR$$"
"$$CM+LX,27,0$$$$BT,\"PLAIN-TEXT EDIT \",FMR_PLAIN$$"
"$$CM+LX,1,3 $$$$BT,\"PASTE CLIPBOARD FILES \",FMR_PASTE$$"
"$$CM+LX,27,0$$$$BT,\"CHANGE DISK(MOUNT IT) \",FMR_CHG_DSK$$"
"$$CM+LX,1,3 $$$$BT,\"FORMAT \",FMR_FORMAT$$"
"$$CM+LX,1,3 $$$$BT,\"MAKE ISO (CD-ROM) FILE\",FMR_MAKE_ISO$$"
"$$CM+LX,27,0$$$$BT,\"BURN ISO (CD-ROM) FILE\",FMR_BURN_ISO$$"
"$$CM+LX,1,3 $$$$BT,\"HELP \",FMR_HELP$$"
"$$CM+LX,27,0$$$$BT,\"CANCEL \",DOCM_CANCEL$$\n");
if (footer) DocPutS(doc,footer);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
U0 FMRightClick()
{
switch (PopUpCancelPasteDel) {
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,'m',0);
break;
case FMR_FORMAT:
Msg(MSG_KEY_DOWN,'f',0);
break;
case FMR_MAKE_ISO:
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_ip_str=NULL;
U0 (*fp_old_final_screen_update)(CDC *dc);
U0 FMFinalScreenUpdate(CDC *dc)
{
if (fm_ip_str) {
dc->color=LTRED;
GrPutS(dc,ipx,ipy,fm_ip_str);
}
(*fp_old_final_screen_update)(dc);
}
public U8 *FileMgr(I64 mode=FM_NORMAL,CTask *mem_task=NULL)
{
CDirEntry *root=NULL,*tempm,*tempm1,*tempm2;
I64 sc,ch,p1,p2,msg_code;
CDoc *doc=NULL,*old_doc=DocCur;
U8 *result=NULL,*st,*st2,*old_cur_dir=CurDir;
CDocEntry *doc_ce=NULL,*doc_e;
Bool okay;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
fp_old_final_screen_update=fp_final_screen_update;
MenuFilePush("::/TempleOS/Doc/FileMgrPullDown.TXT");
FMRebuildDoc(&doc,&root,mode);
if (tempm1=CdDir(root,old_cur_dir))
doc->cur_entry=tempm1->user_data;
while (tempm1) {
if (tempm1->attr&_ATTR_DIR)
tempm1->user_data(CDocEntry *)->flags1&=~DOCEF1_CHECKED_COLLAPSED;
tempm1=tempm1->parent;
}
do {
DocUnlock(doc);
do msg_code=GetMsg(&p1,&p2,
1<<MSG_KEY_DOWN|1<<MSG_IP_L_DOWN|1<<MSG_IP_L_UP|
1<<MSG_IP_R_UP);
while (Fs!=sys_focus_task);
DocLock(doc);
switch (msg_code) {
case MSG_IP_R_UP:
DocUnlock(doc);
FMRightClick;
DocLock(doc);
break;
case MSG_IP_L_DOWN:
doc_ce=doc->cur_entry;
fm_ip_str=doc_ce->tag;
fp_final_screen_update=&FMFinalScreenUpdate;
break;
case MSG_IP_L_UP:
if (doc_ce) {
fp_final_screen_update=fp_old_final_screen_update;
if (SetCursorPos(Fs,p1/FONT_WIDTH+Fs->win_left+Fs->win_scroll_x/FONT_WIDTH,p2/FONT_HEIGHT+Fs->win_top+Fs->win_scroll_y/FONT_HEIGHT,TRUE)) {
doc_e=doc->cur_entry;
if (doc_e!=doc_ce) {
st2=NULL;
if (doc_e->type_u8==DOCT_MENU_VAL) {
tempm1=doc_e->user_data;
if (tempm1=tempm1->parent)
st2=StrNew(tempm1->full_name);
} else if (doc_e->type_u8==DOCT_TREE) {
tempm1=doc_e->user_data;
st2=StrNew(tempm1->full_name);
}
if (st2 && doc_ce->type_u8==DOCT_MENU_VAL) {
tempm=doc_ce->user_data;
Silent(ON);
Move(tempm->full_name,st2);
Silent(OFF);
FMRebuildDoc(&doc,&root,mode);
} else if (st2 && doc_ce->type_u8==DOCT_TREE) {
tempm=doc_ce->user_data;
okay=TRUE;
tempm2=tempm1;
while (tempm2) {
if (tempm2!=tempm)
tempm2=tempm2->parent;
else {
okay=FALSE;
break;
}
}
if (okay) {
if (*tempm1->name)
st=MSPrintF("%s/%s",tempm1->full_name,tempm->name);
else
st=MSPrintF("%s%s",tempm1->full_name,tempm->name);
if (StrCmp(tempm->full_name,st)) {
Silent(ON);
CopyTree(tempm->full_name,st);
DelTree(tempm->full_name);
Silent(OFF);
FMRebuildDoc(&doc,&root,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=p1; sc=p2;
if (sc.u8[0]==SC_DELETE && !(sc&(SCF_SHIFT|SCF_CTRL)))
ch=CH_CTRLY;
if (ch && sc&SCF_ALT) goto regular_key;
switch (ch) {
case '\n':
DocUnlock(doc);
FMRightClick;
DocLock(doc);
break;
case CH_CTRLV:
FMCopy(doc);
FMRebuildDoc(&doc,&root,mode);
break;
case 'r':
DocUnlock(doc);
FMRename(doc);
FMRebuildDoc(&doc,&root,mode);
break;
case 'd':
DocUnlock(doc);
FMMkDir(doc);
FMRebuildDoc(&doc,&root,mode);
break;
case CH_CTRLY:
DocUnlock(doc);
FMDelete(doc);
FMRebuildDoc(&doc,&root,mode);
break;
case 'm':
DocUnlock(doc);
FMMount(doc);
FMRebuildDoc(&doc,&root,mode);
break;
case 'M':
DocUnlock(doc);
FMMakeISO(doc);
FMRebuildDoc(&doc,&root,mode);
break;
case 'B':
DocUnlock(doc);
FMBurnISO(doc);
FMRebuildDoc(&doc,&root,mode);
break;
case 'f':
DocUnlock(doc);
FMFmtDrv(doc);
FMRebuildDoc(&doc,&root,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 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 regular_key;
break;
case CH_ESC:
doc_ce=doc->cur_entry;
tempm=doc_ce->user_data;
if (mode==FM_PICK_FILE && doc_ce->type_u8==DOCT_MENU_VAL)
result=StrNew(tempm->full_name,mem_task);
else if (mode==FM_PICK_DIR) {
if (doc_ce->type_u8==DOCT_TREE)
result=StrNew(tempm->full_name,mem_task);
else if (doc_ce->type_u8==DOCT_MENU_VAL && (tempm=tempm->parent))
result=StrNew(tempm->full_name,mem_task);
}
break;
default:
if (sc.u8[0]==SC_INS && sc&SCF_SHIFT && !(sc&SCF_CTRL)) {
FMCopy(doc);
FMRebuildDoc(&doc,&root,mode);
} else if (sc.u8[0]==SC_F5) {
if (doc->cur_entry->type_u8==DOCT_MENU_VAL) {
tempm=doc->cur_entry->user_data;
DocUnlock(doc);
if (sc&SCF_SHIFT)
AdamFile(tempm->full_name);
else
PopUpFile(tempm->full_name);
DocLock(doc);
}
} else {
regular_key:
DocUnlock(doc);
PutKey(ch,sc);
DocLock(doc);
}
}
break;
}
} while (ch!=CH_ESC && ch!=CH_SHIFT_ESC);
fp_final_screen_update=fp_old_final_screen_update;
DocQueRem(doc);
DocQueIns(old_doc,Fs->last_doc);
SettingsPop;
DocDel(doc);
CDirLstDel(root);
Cd(old_cur_dir);
Free(old_cur_dir);
if (mode!=FM_NORMAL && !result)
result=StrNew("",mem_task);
MenuPop;
return result;
}
#help_index ""
+287
View File
@@ -0,0 +1,287 @@
#help_index "Graphics/Windows BMP Files"
//This provides support for Window's BMP files.
class CFileBMP
{
U16 type;
U32 file_size;
U32 reserved;
U32 data_offset;
U32 header_size;
U32 width;
U32 height;
U16 planes;
U16 bit_cnt;
U32 compression;
U32 image_size;
U32 x_pixels_per_meter;
U32 y_pixels_per_meter;
U32 colors_used;
U32 important_colors;
U0 end;
CBGR palette[16];
};
public CFileBMP *BMPFile4To(CDC *dc)
{
//To Windows 4 bit BMP
U8 *src,*ptr;
I64 x,y,w=dc->width>>1,
size=offset(CFileBMP.end)+dc->width*dc->height>>1+16*sizeof(CBGR);
CFileBMP *r=CAlloc(size);
r->type='BM';
r->planes=1;
r->file_size=size;
r->data_offset=offset(CFileBMP.end);
r->header_size=offset(CFileBMP.end)-
offset(CFileBMP.header_size);
r->width=dc->width;
r->height=dc->height;
r->bit_cnt=4;
r->image_size=dc->width*dc->height>>1;
r->data_offset+=16*sizeof(CBGR);
GetVGAPalette4(r->palette);
ptr=r(U8 *)+r->data_offset;
for (y=dc->height-1;y>=0;y--) {
src=y*dc->width_internal+dc->body;
for (x=0;x<w;x++) {
*ptr|=(*src++&15)<<4;
*ptr|=*src++&15;
ptr++;
}
}
return r;
}
public CFileBMP *BMPFileRLE4To(CDC *dc)
{
//To Windows RLE4 bit BMP
U8 *src,*ptr;
I64 x,y,w=dc->width,cnt,pattern;
CFileBMP *r=CAlloc(offset(CFileBMP.end)+2*(dc->width+1)*dc->height+16*sizeof(CBGR));
r->type='BM';
r->planes=1;
r->data_offset=offset(CFileBMP.end);
r->header_size=offset(CFileBMP.end)-
offset(CFileBMP.header_size);
r->width=dc->width;
r->height=dc->height;
r->bit_cnt=4;
r->compression=2; //RLE4
r->data_offset+=16*sizeof(CBGR);
GetVGAPalette4(r->palette);
ptr=r(U8 *)+r->data_offset;
for (y=dc->height-1;y>=0;y--) {
src=y*dc->width_internal+dc->body;
x=0;
while (x<w) {
pattern=(src[0]&15)<<4+src[1]&15;
if (x+1<w && src[0]&15==src[1]&15) {
src+=2;
cnt=2;
x+=2;
while (x<w && cnt<MAX_U8) {
if (*src&15==pattern&15) {
src++;
cnt++;
x++;
} else
break;
}
} else {
src+=2;
if (x+1<w)
cnt=2;
else
cnt=1;
x+=2;
}
*ptr++=cnt;
*ptr++=pattern;
}
*ptr(U16 *)++=0;
}
r->image_size=ptr-(&r->data_offset)(U8 *);
r->file_size=offset(CFileBMP.end)+r->image_size+16*sizeof(CBGR);
return r;
}
public CFileBMP *BMPFile24To(CDC *dc)
{
//To Windows 24 bit BMP
U8 *src;
I64 i,x,y,size=offset(CFileBMP.end)+dc->width*dc->height*sizeof(CRGB);
CBGR *bgr;
CFileBMP *r=CAlloc(size);
r->type='BM';
r->planes=1;
r->file_size=size;
r->data_offset=offset(CFileBMP.end);
r->header_size=offset(CFileBMP.end)-
offset(CFileBMP.header_size);
r->width=dc->width;
r->height=dc->height;
r->bit_cnt=32;
r->image_size=dc->width*dc->height<<2;
bgr=r(U8 *)+r->data_offset;
for (y=dc->height-1;y>=0;y--) {
src=y*dc->width_internal+dc->body;
for (x=0;x<dc->width;x++) {
i=*src++;
if (i&BLUE) bgr->b=0x7F;
if (i&GREEN) bgr->g=0x7F;
if (i&RED) bgr->r=0x7F;
if (i&8) {
if (bgr->b) bgr->b=0xFF;
if (bgr->g) bgr->g=0xFF;
if (bgr->r) bgr->r=0xFF;
}
bgr(U8 *)+=4;
}
}
return r;
}
public I64 BMPFileWrite(U8 *filename,CDC *dc,I64 bits=4)
{ //Window's BMP Files
I64 size;
CFileBMP *r;
if (bits==4) {
if (IsDotZ(filename)) //.Z compression is better than RLE
r=BMPFile4To(dc);
else {
r=BMPFileRLE4To(dc);
if (r->file_size>offset(CFileBMP.end)+dc->width*dc->height>>1+16*sizeof(CBGR)) {
Free(r);
r=BMPFile4To(dc);
}
}
} else if (bits==24)
r=BMPFile24To(dc);
else {
"Format Not Supported.\n";
return 0;
}
size=r->file_size;
FileWrite(filename,r,r->file_size);
Free(r);
return size;
}
U8 *BMPFilePaletteNew(CFileBMP *r)
{
I64 i,j,best,score,best_score;
CBGR palette[16];
U8 *result=CAlloc(16*sizeof(U8));
GetVGAPalette4(palette);
for (i=0;i<16;i++) {
best=i;
best_score=MAX_I64;
for (j=0;j<16;j++) {
score=SqrI64(r->palette[i].r-palette[j].r)+
SqrI64(r->palette[i].g-palette[j].g)+
SqrI64(r->palette[i].b-palette[j].b);
if (score<best_score) {
best=j;
best_score=score;
}
}
result[i]=best;
}
return result;
}
U8 ms_paint_palette[16]={0,4,2,6,1,5,3,8,7,12,10,14,9,13,11,15};
public CDC *BMPFileRead(U8 *filename,Bool use_ms_paint_palette=FALSE)
{ //Window's BMP Files
I64 i,j,cnt;
U8 *palette_map,*ptr;
Bool rle4;
CFileBMP *r;
CDC *result=NULL;
if (ptr=FileRead(filename)) {
r=ptr;
if (0<r->width<MAX_I32 && 0<r->height<MAX_I32) {
result=DCNew(DCT_COLOR8,r->width,r->height);
ptr+=r->data_offset;
if (r->bit_cnt==4) {
if (r->compression==2)
rle4=TRUE;
else
rle4=FALSE;
if (use_ms_paint_palette)
palette_map=ms_paint_palette;
else
palette_map=BMPFilePaletteNew(r);
for (i=r->height-1;i>=0;i--)
if (rle4) { //We don't support full RLE4, just our own subset
j=0;
while (cnt=*ptr++) {
if (cnt==1) {
result->color=palette_map[*ptr++&15];
GrPlot(result,j++,i);
} else {
if (cnt==2 && *ptr>>4!=*ptr&15) {
result->color=palette_map[*ptr&15];
GrPlot(result,j+1,i);
result->color=palette_map[*ptr>>4];
GrPlot(result,j,i);
ptr++;
j+=2;
} else {
result->color=palette_map[*ptr++&15];
while (cnt--)
GrPlot(result,j++,i);
}
}
}
ptr++;
} else
for (j=0;j<(r->width+7)&-8;) {
result->color=palette_map[*ptr&15];
GrPlot(result,j+1,i);
result->color=palette_map[*ptr>>4];
GrPlot(result,j,i);
ptr++;
j+=2;
}
if (!use_ms_paint_palette)
Free(palette_map);
} else {
"Format Not Supported.\n";
DCDel(result);
result=NULL;
}
} else
"Invalid BMP File\n";
Free(r);
}
return result;
}
#help_index "Graphics/CSprite;Graphics/Windows BMP Files;Doc/Output"
public U0 DocPutBMPFile(CDoc *doc=NULL,U8 *fname,Bool use_ms_paint_palette=FALSE)
{
CDC *dc=BMPFileRead(fname,use_ms_paint_palette);
CSprite *elems=DC2Sprite(dc);
DocPutSprite(doc,elems);
Free(elems);
DCDel(dc);
}
#help_index "Graphics/Windows BMP Files;Graphics/Screen"
public I64 BMPFileCaptureScreen(U8 *filename,I64 bits=4)
{
CDC *dc=DCCaptureScreen;
I64 size=BMPFileWrite(filename,dc,bits);
DCDel(dc);
return size;
}
#help_index ""
+603
View File
@@ -0,0 +1,603 @@
#define GEBM_END 0
#define GEBM_CONT 1
#define GEBM_COLOR 2
#define GEBM_DITHER_COLOR 3
#define GEBM_WIDTH 4
#define GEBM_SNAP 5
#define GEBM_PT 6
#define GEBM_LINE 7
#define GEBM_ARROW 8
#define GEBM_RECT 9
#define GEBM_CIRCLE 10
#define GEBM_TEXT 11
#define GEBM_TEXT_BOX 12
#define GEBM_TEXT_DIAMOND 13
#define GEBM_FLOOD_FILL 14
#define GEBM_FLOOD_FILL_NOT 15
#define GEBM_POLYLINE 16
#define GEBM_POLYPT 17
#define GEBM_CUT 18
#define GEBM_DELETE 19
#define GEBM_PASTE 20
#define GEBM_PASTE_TRANSPARENT 21
#define GEBM_FIND_AND_REPLACE 22
#define GEBM_TRIM_TO_EXTENTS 23
#define GEBM_UNDO 24
I64 PopUpSpriteBitMap(CColorROPU32 color,I64 width,I64 snap,F64 ip_scaler)
{
I64 i;
U8 *st1,*st2,buf[136];
CDoc *doc=DocNew;
Color2Text(buf,color);
if (color&ROPF_DITHER) {
st1="";
st2=buf;
} else {
st1=buf;
st2="";
}
DocPrintF(doc,"$$FG,PURPLE$$$$TX+CX,\"BitMap Menu\"$$$$FG$$\n"
"$$FG,RED$$Settings$$FG$$\n"
"$$MU-UL,\"Color %s\",GEBM_COLOR$$\n"
"$$MU-UL,\"Dither Color %s\",GEBM_DITHER_COLOR$$\n"
"$$MU-UL,\"Width %d\",GEBM_WIDTH$$\n"
"$$MU-UL,\"Snap %d %5.3f\",GEBM_SNAP$$\n"
"$$MU-UL,\"Find & Replace Color\",GEBM_FIND_AND_REPLACE$$\n"
"$$MU-UL,\"Trim to Extents\",GEBM_TRIM_TO_EXTENTS$$\n"
"\n$$FG,RED$$Objects$$FG$$\n"
"$$MU-UL,\"Point\",GEBM_PT$$\n"
"$$MU-UL,\"Line\",GEBM_LINE$$\n"
"$$MU-UL,\"Arrow\",GEBM_ARROW$$\n"
"$$MU-UL,\"Rect\",GEBM_RECT$$\n"
"$$MU-UL,\"Circle\",GEBM_CIRCLE$$\n"
"$$MU-UL,\"Text\",GEBM_TEXT$$\n"
"$$MU-UL,\"Text Box\",GEBM_TEXT_BOX$$\n"
"$$MU-UL,\"Text Diamond\",GEBM_TEXT_DIAMOND$$\n"
"$$MU-UL,\"Flood Fill\",GEBM_FLOOD_FILL$$\n"
"$$MU-UL,\"Flood Fill Not Color\",GEBM_FLOOD_FILL_NOT$$\n"
"$$MU-UL,\"PolyLine\",GEBM_POLYLINE$$\n"
"$$MU-UL,\"PolyPoint\",GEBM_POLYPT$$\n"
"\n$$FG,RED$$Clipboard$$FG$$\n"
"$$MU-UL,\"Cut\",GEBM_CUT$$\n"
"$$MU-UL,\"Delete\",GEBM_DELETE$$\n"
"$$MU-UL,\"Paste\",GEBM_PASTE$$\n"
"$$MU-UL,\"Paste Transparent\",GEBM_PASTE_TRANSPARENT$$\n"
"\n$$MU-UL,\"Undo\",GEBM_UNDO$$\n"
"\n$$FM,PURPLE$$$$MU-UL,\"+] Vect Object Menu\",GEBM_CONT$$$$FM,LTBLUE$$\n"
"$$MU-UL,\"End\",GEBM_END$$\n"
"$$MU-UL,\"Cancel\",DOCM_CANCEL$$\n",st1,st2,width,snap,ip_scaler);
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
U0 GrBMEdPrepPersistentDC(CDC *dc,I64 xx1,I64 yy1,CDC *img)
{
DCFill(dc);
GrBlot(dc,xx1,yy1,img);
}
U0 GrBMEFindReplaceColor(CDC *img,I64 pattern,I64 replace)
{
U8 *dst=img->body;
I64 d0=img->height*img->width_internal;
while (d0--) {
if (*dst==pattern)
*dst=replace;
dst++;
}
}
U0 GrBMETrimToExtents(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!=COLOR_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!=COLOR_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!=COLOR_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!=COLOR_TRANSPARENT) goto tr_done;
}
x2--;
}
tr_done:
*_img=DCExtract(img,x1,y1,x2,y2);
*_xx1+=x1; *_yy1+=y1;
*_xx2+=x2-(img->width-1); *_yy2+=y2-(img->height-1); //not inclusive
DCDel(img);
}
I64 SpriteBitMap(CDC *dc,I64 *_xx1,I64 *_yy1,I64 *_xx2,I64 *_yy2,CDC **_img,CColorROPU32 bkcolor,I64 *_import_snap=NULL,F64 *_import_ip_scaler=NULL)
{
I64 i,j,mode=GEBM_LINE,color=BLACK,width=1,msg_code,p1,p2,x1,y1,x11,y11,x22,y22,new_snap=1,
result,xx1=*_xx1,yy1=*_yy1,xx2=*_xx2,yy2=*_yy2;
Bool down=FALSE;
F64 new_ip_scaler=1.0;
U8 *st=NULL;
CDC *img=*_img,
*clipboard=NULL,*undo=NULL,*dc2;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
if (_import_snap) new_snap=*_import_snap;
if (_import_ip_scaler) new_ip_scaler=*_import_ip_scaler;
SetSnap(&Fs->snap,new_snap,new_ip_scaler);
goto bm_menu;
while (TRUE) {
if (sys_cur_scan_code&SCF_CTRL)//grab scroll update?
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=ROPF_DITHER+WHITE<<16+ROP_EQU+BLACK;
dc->pen_width=1;
GrLineRect4(dc,xx1-1,yy1-1,xx2,yy2);//This is done little bit too often.
while (msg_code=ScanMsg(&p1,&p2,1<<MSG_IP_L_DOWN|1<<MSG_IP_L_UP|1<<MSG_IP_R_DOWN|
1<<MSG_IP_MOVE|1<<MSG_KEY_DOWN)) {
switch (msg_code) {
case MSG_KEY_DOWN:
if (p1==CH_SHIFT_ESC) {
result=GE_CANCEL;
goto bm_key_up_done;
} else if (p1==CH_ESC) {
result=GE_OKAY_CONT;
goto bm_key_up_done;
}
break;
case MSG_IP_R_DOWN:
bm_menu:
DCFill(dc);
switch (i=PopUpSpriteBitMap(color,width,new_snap,new_ip_scaler)) {
case DOCM_CANCEL:
result=GE_CANCEL;
goto bm_done;
case GEBM_END:
result=GE_OKAY_DONE;
goto bm_done;
case GEBM_CONT:
result=GE_OKAY_CONT;
goto bm_done;
case GEBM_COLOR:
i=PopUpColor(,,FALSE);
if (i>=0) color=i;
goto bm_menu;
case GEBM_FIND_AND_REPLACE:
i=PopUpColor("Find Color\n",,FALSE);
if (i>=0) {
j=PopUpColor("Replace Color\n",,FALSE);
if (j>=0) {
GrBMEFindReplaceColor(img,i,j);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
}
}
goto bm_menu;
case GEBM_TRIM_TO_EXTENTS:
GrBMETrimToExtents(&img,&xx1,&yy1,&xx2,&yy2,bkcolor);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
goto bm_menu;
case GEBM_DITHER_COLOR:
i=PopUpDitherColor;
if (i>=0) color=i;
goto bm_menu;
case GEBM_WIDTH:
i=PopUpRangeI64(1,16,1,"Pen Width\n");
if (i>=0) width=i;
goto bm_menu;
case GEBM_SNAP:
PopUpSnap(&Fs->snap);
new_snap=Fs->snap.x;
new_ip_scaler=Fs->snap.dx;
goto bm_menu;
case GEBM_UNDO:
if (undo) {
Beep;
img->color=ROP_EQU;
GrBlot(img,0,0,undo);
DCDel(undo);
undo=NULL;
}
goto bm_menu;
case GEBM_PT:
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_RECT:
case GEBM_CIRCLE:
case GEBM_FLOOD_FILL:
case GEBM_FLOOD_FILL_NOT:
case GEBM_POLYPT:
case GEBM_POLYLINE:
case GEBM_CUT:
case GEBM_DELETE:
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
mode=i;
break;
case GEBM_TEXT:
case GEBM_TEXT_BOX:
case GEBM_TEXT_DIAMOND:
Free(st);
st=PopUpMGetS("Enter text and press <ESC>.\n");
if (st && *st)
mode=i;
else
goto bm_menu;
break;
}
DCDel(undo);
undo=DCExtract(img,0,0,img->width-1,img->height-1);
undo->bkcolor=bkcolor;
WinMgrSync(2,TRUE); //Let popup close
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
down=FALSE;
break;
case MSG_IP_L_DOWN:
switch (mode) {
case GEBM_PT:
img->color=color;
img->pen_width=width;
GrPlot3(img,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_RECT:
case GEBM_CIRCLE:
case GEBM_CUT:
case GEBM_DELETE:
if (down)
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
x1=p1; y1=p2;
down=TRUE;
dc->color=color;
dc->pen_width=width;
switch (mode) {
case GEBM_LINE:
GrLine3(dc,x1,y1,0,p1,p2,0);
break;
case GEBM_ARROW:
GrArrow3(dc,x1,y1,0,p1,p2,0);
break;
case GEBM_RECT:
GrRect(dc,x1,y1,1,1);
break;
case GEBM_CIRCLE:
GrCircle3(dc,x1,y1,0,1);
break;
case GEBM_CUT:
case GEBM_DELETE:
dc->color=ROPF_DITHER+WHITE<<16+ROP_EQU+BLACK;
dc->pen_width=1;
GrLineRect4(dc,x1,y1,x1,y1);
break;
}
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,p1,p2,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(dc,p1,p2,dc2);
DCDel(dc2);
}
}
break;
case GEBM_TEXT:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrPutS(dc,p1,p2,st);
break;
case GEBM_TEXT_BOX:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextBox3(dc,p1,p2,0,st);
break;
case GEBM_TEXT_DIAMOND:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextDiamond3(dc,p1,p2,0,st);
break;
case GEBM_FLOOD_FILL:
img->color=color;
GrFloodFill(img,p1-xx1,p2-yy1);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_FLOOD_FILL_NOT:
img->color=color;
GrFloodFill(img,p1-xx1,p2-yy1,TRUE);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_POLYLINE:
if (!down) {
x1=p1; y1=p2;
down=TRUE;
dc->color=color;
dc->pen_width=width;
GrLine3(dc,x1,y1,0,p1,p2,0);
}
break;
case GEBM_POLYPT:
x1=p1; y1=p2;
down=TRUE;
img->color=color;
img->pen_width=width;
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
}
break;
case MSG_IP_MOVE:
switch (mode) {
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_POLYLINE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
dc->pen_width=width;
if (mode==GEBM_ARROW)
GrArrow3(dc,x1,y1,0,p1,p2,0);
else
GrLine3(dc,x1,y1,0,p1,p2,0);
}
break;
case GEBM_RECT:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
dc->color=color;
GrRect(dc,x11,y11,x22-x11+1,y22-y11+1);
}
break;
case GEBM_CUT:
case GEBM_DELETE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
dc->color=ROPF_DITHER+WHITE<<16+ROP_EQU+BLACK;
dc->pen_width=1;
GrLineRect4(dc,x11,y11,x22,y22);
}
break;
case GEBM_CIRCLE:
if (down) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
dc->pen_width=width;
GrCircle3(dc,x1,y1,0,Sqrt(SqrI64(p1-x1)+SqrI64(p2-y1)));
}
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(dc,p1,p2,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(dc,p1,p2,dc2);
DCDel(dc2);
}
}
break;
case GEBM_TEXT:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrPutS(dc,p1,p2,st);
break;
case GEBM_TEXT_BOX:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextBox3(dc,p1,p2,0,st);
break;
case GEBM_TEXT_DIAMOND:
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
dc->color=color;
GrTextDiamond3(dc,p1,p2,0,st);
break;
case GEBM_POLYPT:
if (down) {
img->color=color;
img->pen_width=width;
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
x1=p1; y1=p2;
}
break;
}
break;
case MSG_IP_L_UP:
switch (mode) {
case GEBM_LINE:
case GEBM_ARROW:
case GEBM_POLYPT:
case GEBM_POLYLINE:
img->color=color;
img->pen_width=width;
if (mode==GEBM_ARROW)
GrArrow3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
else
GrLine3(img,x1-xx1,y1-yy1,0,p1-xx1,p2-yy1,0);
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_POLYLINE) {
x1=p1; y1=p2;
} else
down=FALSE;
break;
case GEBM_RECT:
img->color=color;
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
down=FALSE;
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_CUT:
case GEBM_DELETE:
if (x1<p1) {
x11=x1;
x22=p1;
} else {
x11=p1;
x22=x1;
}
if (y1<p2) {
y11=y1;
y22=p2;
} else {
y11=p2;
y22=y1;
}
DCDel(clipboard);
clipboard=DCExtract(img,x11-xx1,y11-yy1,x22-xx1,y22-yy1);
clipboard->bkcolor=bkcolor;
if (mode==GEBM_DELETE) {
img->color=bkcolor;
GrRect(img,x11-xx1,y11-yy1,x22-x11+1,y22-y11+1);
}
goto bm_menu;
case GEBM_CIRCLE:
img->color=color;
img->pen_width=width;
GrCircle3(img,x1-xx1,y1-yy1,0,Sqrt(SqrI64(p1-x1)+SqrI64(p2-y1)));
down=FALSE;
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
break;
case GEBM_PASTE:
case GEBM_PASTE_TRANSPARENT:
if (clipboard) {
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
if (mode==GEBM_PASTE) {
clipboard->flags|=DCF_NO_TRANSPARENTS;
GrBlot(img,p1-xx1,p2-yy1,clipboard);
clipboard->flags&=~DCF_NO_TRANSPARENTS;
} else {
dc2=DCCopy(clipboard);
DCColorChg(dc2,bkcolor);
GrBlot(img,p1-xx1,p2-yy1,dc2);
DCDel(dc2);
}
GrBMEdPrepPersistentDC(dc,xx1,yy1,img);
}
break;
case GEBM_TEXT:
img->color=color;
GrPutS(img,p1-xx1,p2-yy1,st);
goto bm_menu;
case GEBM_TEXT_BOX:
img->color=color;
GrTextBox3(img,p1-xx1,p2-yy1,0,st);
goto bm_menu;
case GEBM_TEXT_DIAMOND:
img->color=color;
GrTextDiamond3(img,p1-xx1,p2-yy1,0,st);
goto bm_menu;
}
break;
}
}
WinMgrSync;
}
bm_key_up_done:
GetMsg(,,1<<MSG_KEY_UP);
bm_done:
DCDel(clipboard);
DCDel(undo);
Free(st);
DCFill(dc);
SettingsPop;
if (_import_snap) *_import_snap=new_snap;
if (_import_ip_scaler) *_import_ip_scaler=new_ip_scaler;
*_img=img;
*_xx1=xx1,*_yy1=yy1,*_xx2=xx2,*_yy2=yy2;
return result;
}
File diff suppressed because it is too large. Load diff
File diff suppressed because it is too large. Load diff
+235
View File
@@ -0,0 +1,235 @@
#help_index "Graphics/CSprite"
#help_file "::/TempleOS/Doc/Sprite"
I64 gr_sprite_base_size[GRST_NUM_TYPES]=
{
offset(CSprite.x1)-offset(CSprite.start), //GRST_END
1,
1+offset(CSprite.color8)-offset(CSprite.start), //GRST_COLOR8
1,
offset(CSprite.x2)-offset(CSprite.start), //GRST_PT
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_LINE
offset(CSprite.y1)-offset(CSprite.start), //GRST_POLYLINE
offset(CSprite.y1)-offset(CSprite.start), //GRST_POLYPT
offset(CSprite.y1)-offset(CSprite.start), //GRST_WIDTH
offset(CSprite.x2)-offset(CSprite.start), //GRST_SHIFT
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE2
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE3
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE2_CLOSED
offset(CSprite.y1)-offset(CSprite.start), //GRST_BSPLINE3_CLOSED
1,
1,
1,
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_RECT
offset(CSprite.y2)-offset(CSprite.start), //GRST_CIRCLE
offset(CSprite.x2)-offset(CSprite.start), //GRST_FLOOD_FILL_NOT
offset(CSprite.x2)-offset(CSprite.start), //GRST_FLOOD_FILL
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_BITMAP8
1,
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT
offset(CSprite.sides)-offset(CSprite.start), //GRST_ELLIPSE
sizeof(CSprite)-offset(CSprite.start), //GRST_REG_POLY
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_PLANAR_SYMMETRY
2+offset(CSprite.dither_color8)-offset(CSprite.start), //GRST_DITHER_COLOR8
offset(CSprite.sides)-offset(CSprite.start), //GRST_ROTATED_RECT
offset(CSprite.x2)-offset(CSprite.start), //GRST_MESH
offset(CSprite.shiftable_triangle_cnt)+sizeof(I32)-offset(CSprite.start), //GRST_SHIFTABLE_MESH
offset(CSprite.x1)-offset(CSprite.start), //GRST_TRANSFORM_ON
offset(CSprite.x1)-offset(CSprite.start), //GRST_TRANSFORM_OFF
offset(CSprite.linespeed)-offset(CSprite.start), //GRST_ARROW
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT_BOX
offset(CSprite.st)-offset(CSprite.start), //GRST_TEXT_DIAMOND
};
I64 gr_sprite_qued_base_size[GRST_NUM_TYPES]=
{
offset(CSprite.x1),//GRST_END
1,
1+offset(CSprite.color8), //GRST_COLOR8
1,
offset(CSprite.x2), //GRST_PT
offset(CSprite.linespeed), //GRST_LINE
offset(CSprite.y1), //GRST_POLYLINE
offset(CSprite.y1), //GRST_POLYPT
offset(CSprite.y1), //GRST_WIDTH
offset(CSprite.x2), //GRST_SHIFT
offset(CSprite.y1), //GRST_BSPLINE2
offset(CSprite.y1), //GRST_BSPLINE3
offset(CSprite.y1), //GRST_BSPLINE2_CLOSED
offset(CSprite.y1), //GRST_BSPLINE3_CLOSED
1,
1,
1,
offset(CSprite.linespeed), //GRST_RECT
offset(CSprite.y2), //GRST_CIRCLE
offset(CSprite.x2), //GRST_FLOOD_FILL_NOT
offset(CSprite.x2), //GRST_FLOOD_FILL
offset(CSprite.linespeed), //GRST_BITMAP8
1,
offset(CSprite.st), //GRST_TEXT
offset(CSprite.sides), //GRST_ELLIPSE
sizeof(CSprite), //GRST_REG_POLY
offset(CSprite.linespeed), //GRST_PLANAR_SYMMETRY
2+offset(CSprite.dither_color8), //GRST_DITHER_COLOR8
offset(CSprite.sides), //GRST_ROTATED_RECT
offset(CSprite.x2), //GRST_MESH
offset(CSprite.shiftable_triangle_cnt)+sizeof(I32), //GRST_SHIFTABLE_MESH
offset(CSprite.x1), //GRST_TRANSFORM_ON
offset(CSprite.x1), //GRST_TRANSFORM_OFF
offset(CSprite.linespeed), //GRST_ARROW
offset(CSprite.st), //GRST_TEXT_BOX
offset(CSprite.st), //GRST_TEXT_DIAMOND
};
I64 SpriteElemSize(CSprite *tempg)
{
I64 i=gr_sprite_base_size[tempg->type];
switch (tempg->type) {
case GRST_POLYLINE:
i+=tempg->num<<1*sizeof(I32);
break;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
i+=StrLen(tempg->st)+1;
break;
case GRST_BITMAP8:
i+=((tempg->width+7)&~7)*tempg->height;
break;
case GRST_POLYPT:
i+=sizeof(I32)<<1+(tempg->num*3+7)>>3;
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
i+=tempg->num*sizeof(CD3I32);
break;
case GRST_MESH:
i+=tempg->vertex_cnt*sizeof(CD3I32)+tempg->triangle_cnt*sizeof(CMeshTri);
break;
case GRST_SHIFTABLE_MESH:
i+=tempg->shiftable_vertex_cnt*sizeof(CD3I32)+tempg->shiftable_triangle_cnt*sizeof(CMeshTri);
break;
}
return i;
}
public I64 SpriteSize(U8 *elems)
{
CSprite *tempg=elems-offset(CSprite.start),*tempg1=tempg;
while (tempg->type)
tempg(U8 *)+=SpriteElemSize(tempg);
return tempg(U8 *)-tempg1(U8 *)+gr_sprite_base_size[GRST_END];
}
I64 SpriteTypeMask(U8 *elems)
{
I64 result=0;
CSprite *tempg=elems-offset(CSprite.start);
while (tempg->type) {
if (tempg->type>=GRST_NUM_TYPES)
return 1<<GRST_NUM_TYPES;
Bts(&result,tempg->type);
tempg(U8 *)+=SpriteElemSize(tempg);
}
return result;
}
public U8 *DC2Sprite(CDC *tempb)
{
CSprite *tempg;
CDC *tempb1;
Bool temp_bitmap;
if (tempb->type!=DCT_COLOR8) {
tempb1=DCNew(DCT_COLOR8,tempb->width,tempb->height,Fs);
tempb1->color=WHITE;
GrBlot(tempb1,0,0,tempb);
temp_bitmap=TRUE;
} else {
tempb1=tempb;
temp_bitmap=FALSE;
}
tempg=CAlloc(gr_sprite_base_size[GRST_BITMAP8]+
tempb1->width_internal*tempb1->height+
gr_sprite_base_size[GRST_END])
(U8 *)-offset(CSprite.start);
tempg->type=GRST_BITMAP8;
tempg->width=tempb1->width;
tempg->height=tempb1->height;
tempg->x2=0;
tempg->y2=0;
MemCpy(tempg(U8 *)+offset(CSprite.linespeed),tempb1->body,
tempb1->width_internal*tempb1->height);
if (temp_bitmap)
DCDel(tempb1);
return tempg(U8 *)+offset(CSprite.start);
}
public U8 *Sprite2Text(CSprite *tempg)
{ //Study $LK-A,"::/TempleOS/Demo/Graphics/SpriteText.CPP"$.
U8 buf[256],buf2[256],buf3[136];
I32 *ptr;
SPrintF(buf,"%Z",tempg->type,"ST_CSPRITE_TYPES");
*buf2=0;
switch (tempg->type) {
case GRST_COLOR8:
SPrintF(buf2," %s",Color2Text(buf3,tempg->color8));
break;
case GRST_PT:
case GRST_FLOOD_FILL:
case GRST_FLOOD_FILL_NOT:
case GRST_SHIFT:
SPrintF(buf2," %d,%d",tempg->x1,tempg->y1);
break;
case GRST_LINE:
case GRST_ARROW:
case GRST_PLANAR_SYMMETRY:
case GRST_RECT:
case GRST_ROTATED_RECT:
SPrintF(buf2," (%d,%d)-(%d,%d)",
tempg->x1,tempg->y1,tempg->x2,tempg->y2);
break;
case GRST_CIRCLE:
SPrintF(buf2," %d,%d:%dR",
tempg->x1,tempg->y1,tempg->x2);
break;
case GRST_WIDTH:
SPrintF(buf2," %d",tempg->width);
break;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
SPrintF(buf2," %d,%d:%-16tQ",tempg->x1,tempg->y1,tempg->st);
break;
case GRST_DITHER_COLOR8:
SPrintF(buf2," %s",Color2Text(buf3,ROPF_DITHER|tempg->dither_color8.u8[0]|tempg->dither_color8.u8[1]<<COLORROP_BITS));
break;
case GRST_POLYLINE:
case GRST_POLYPT:
ptr=&tempg->y1;
SPrintF(buf2," %d %d,%d",tempg->num,ptr[0],ptr[1]);
break;
case GRST_ELLIPSE:
case GRST_REG_POLY:
case GRST_BITMAP8:
SPrintF(buf2," %dW,%dH:%d,%d",
tempg->width,tempg->height,tempg->x2,tempg->y2);
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
SPrintF(buf2," %d",tempg->num);
break;
case GRST_MESH:
SPrintF(buf2," %dV,%dT",tempg->vertex_cnt,tempg->triangle_cnt);
break;
case GRST_SHIFTABLE_MESH:
SPrintF(buf2," %dV,%dT",tempg->shiftable_vertex_cnt,tempg->shiftable_triangle_cnt);
break;
}
StrCat(buf,buf2);
return StrNew(buf);
}
File diff suppressed because it is too large. Load diff
+129
View File
@@ -0,0 +1,129 @@
#help_index "Graphics"
U0 GrInit()
{
DefineLstLoad("ST_CSPRITE_TYPES","End\0 \0Color 8Bit\0 \0Point\0"
"Line\0PolyLine\0PolyPoint\0Width\0Shift\0"
"BSpline2\0BSpline3\0BSpline2 Closed\0BSpline3 Closed\0"
" \0 \0 \0Rect\0Circle\0Flood Fill Not Color\0Flood Fill\0BitMap 8Bit\0"
" \0Text\0Ellipse\0Reg Polygon\0Planar Symmetry\0"
"Dither Color 8Bit\0Rotated Rect\0Mesh\0Shiftable Mesh\0"
"Transform On\0Transform Off\0Arrow\0Text Box\0Text Diamond\0");
}
GrInit;
#help_index "Graphics/CSprite"
#define GRST_END 0
//Unused
#define GRST_COLOR8 2
//Unused
#define GRST_PT 4
#define GRST_LINE 5
#define GRST_POLYLINE 6
#define GRST_POLYPT 7
#define GRST_WIDTH 8
#define GRST_SHIFT 9
#define GRST_BSPLINE2 10
#define GRST_BSPLINE3 11
#define GRST_BSPLINE2_CLOSED 12
#define GRST_BSPLINE3_CLOSED 13
//Unused
//Unused
//Unused
#define GRST_RECT 17
#define GRST_CIRCLE 18
#define GRST_FLOOD_FILL_NOT 19
#define GRST_FLOOD_FILL 20
#define GRST_BITMAP8 21
//Unused
#define GRST_TEXT 23
#define GRST_ELLIPSE 24
#define GRST_REG_POLY 25
#define GRST_PLANAR_SYMMETRY 26
#define GRST_DITHER_COLOR8 27
#define GRST_ROTATED_RECT 28
#define GRST_MESH 29
#define GRST_SHIFTABLE_MESH 30
#define GRST_TRANSFORM_ON 31
#define GRST_TRANSFORM_OFF 32
#define GRST_ARROW 33
#define GRST_TEXT_BOX 34
#define GRST_TEXT_DIAMOND 35
#define GRST_NUM_TYPES 36
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
};
public class CSprite
{
//See $LK,"Graphics/CSprite","HI:Graphics/CSprite"$
//See $LK,"::/TempleOS/Adam/Gr/GrSpritePlot.CPP","FL:::/TempleOS/Adam/Gr/GrSpritePlot.CPP,1"$ for how CSprite are stored.
CSprite *next,*last;
U0 start;
U8 type;
union {
U8 color8;
U16 dither_color8;
I32 x1;
I32 num;
I32 width;
I32 vertex_cnt; //Mesh
}
union {
I32 y1;
I32 height;
I32 triangle_cnt; //Mesh
}
union {
I32 z1;
I32 x2;
U8 st[4];
}
union {
I32 y2;
I32 shiftable_vertex_cnt //Shiftable Mesh
}
union {
F64 linespeed;
F64 rot_angle;
I32 shiftable_triangle_cnt //Shiftable Mesh
}
I32 sides;
};
#help_index "Graphics"
extern CDC *DCNew(I64 type,I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE);
extern CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL);
extern U0 DCDel(CDC *dc);
extern U0 EdExistingGraphic(CDoc *doc,I64 x,I64 y,I64 *import_snap=NULL,F64 *import_ip_scaler=NULL);
extern CSprite *SpriteDoc2Que(CDoc *doc,CSprite *root,I64 *cur_num);
extern Bool GrBlot3(CDC *dc,I64 x1,I64 y1,I64 z1,CDC *img);
extern U8 *GrBitMap4ToBitMap8(U8 *dst,U8 *src,I64 src_size,I64 bkcolor);
#include "GrCfg"
#include "GrAsm"
#include "MathGr"
#include "GrScreen"
#include "GrDC"
#include "GrBitMap"
#include "GrPrimatives"
#include "GrComposites"
#include "GrChar"
#define GE_CANCEL (-1)
#define GE_OKAY_DONE 0
#define GE_OKAY_CONT 1
#include "CSpriteNew"
#include "GrSpritePlot"
#include "CSpriteMesh"
#include "CSpriteBitMap"
#include "CSpriteVect"
#include "CSpriteEd"
#include "GrVectMap"
#help_index ""
+765
View File
@@ -0,0 +1,765 @@
#help_index "Graphics"
I64 *gr_1_to_8_bits,*gr_1_to_8_colors;
#help_index "Graphics/Char;Char/Graphics"
U32 *gr_text_base;
U16 *gr_win_z_buf;
asm {
USE64
// ************************************
_PLOT_SCREEN_U8::
ENTER 0
MOV RBX,U64 SF_ARG2[RBP]
MOV RAX,U64 SF_ARG3[RBP]
OR RBX,RBX
JS @@05
OR RAX,RAX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
CMP RAX,TEXT_ROWS
JGE @@05
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,U64 [&gr_text_base]
MOV RAX,U64 SF_ARG1[RBP]
MOV U32 [RBX],EAX
MOV RAX,1
LEAVE
RET1 24
@@05: XOR RAX,RAX
LEAVE
RET1 24
// ************************************
_PLOT_WIN_U8::
ENTER 0
MOV RCX,U64 SF_ARG1[RBP]
MOV RBX,U64 CTask.win_scroll_x[RCX]
SAR RBX,3
ADD RBX,U64 SF_ARG3[RBP]
MOV RAX,U64 CTask.win_scroll_y[RCX]
SAR RAX,3
ADD RAX,U64 SF_ARG4[RBP]
OR RBX,RBX
JS @@05
ADD RBX,U64 CTask.win_left[RCX]
CMP RBX,U64 CTask.win_right[RCX]
JG @@05
OR RBX,RBX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
OR RAX,RAX
JS @@05
ADD RAX,U64 CTask.win_top[RCX]
CMP RAX,U64 CTask.win_bottom[RCX]
JG @@05
OR RAX,RAX
JS @@05
CMP RAX,TEXT_ROWS
JGE @@05
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,U64 [&gr_text_base]
MOV RAX,U64 SF_ARG2[RBP]
MOV U32 [RBX],EAX
MOV RAX,1
LEAVE
RET1 32
@@05: XOR RAX,RAX
LEAVE
RET1 32
// ************************************
/*
Bool PlotWinStr2(CTask *task,U8 *s,I64 len,
I64 attr,I64 x,I64 y)
*/
_PLOT_WIN_STR2::
ENTER 0
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG2[RBP]
MOV RDI,U64 CTask.win_scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG5[RBP]
MOV RCX,U64 SF_ARG3[RBP]
OR 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: OR 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.win_scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG6[RBP]
OR RAX,RAX
JS @@30
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@30
OR RAX,RAX
JS @@30
CMP RAX,TEXT_ROWS
JGE @@30
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,R9
MOV RAX,U64 SF_ARG4[RBP]
@@25: LODSB
STOSD
DEC RCX
JNZ @@25
POP RDI
POP RSI
MOV RAX,TRUE
LEAVE
RET1 48
@@30: POP RDI
POP RSI
XOR RAX,RAX
LEAVE
RET1 48
// ************************************
/*
Bool PlotAttrStr2(CTask *task,U32 *hl,I64 len,I64 x,I64 y)
*/
_PLOT_ATTR_STR2::
ENTER 0
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RSI,U64 SF_ARG2[RBP]
MOV RDI,U64 CTask.win_scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG4[RBP]
MOV RCX,U64 SF_ARG3[RBP]
OR 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: OR 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.win_scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG5[RBP]
OR RAX,RAX
JS @@30
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@30
OR RAX,RAX
JS @@30
CMP RAX,TEXT_ROWS
JGE @@30
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,R9
@@25: MOVSD
DEC RCX
JNZ @@25
POP RDI
POP RSI
MOV RAX,TRUE
LEAVE
RET1 40
@@30: POP RDI
POP RSI
XOR RAX,RAX
LEAVE
RET1 40
// ************************************
/*
Bool PlotAttr(CTask *task,I64 len,
I64 attr,I64 x,I64 y)
*/
_PLOT_ATTR::
ENTER 0
MOV R9,U64 [&gr_text_base]
PUSH RSI
PUSH RDI
MOV RBX,U64 SF_ARG1[RBP]
MOV RDI,U64 CTask.win_scroll_x[RBX]
SAR RDI,3
ADD RDI,U64 SF_ARG4[RBP]
MOV RCX,U64 SF_ARG2[RBP]
OR 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: OR 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.win_scroll_y[RBX]
SAR RAX,3
ADD RAX,U64 SF_ARG5[RBP]
OR RAX,RAX
JS @@35
ADD RAX,U64 CTask.win_top[RBX]
CMP RAX,U64 CTask.win_bottom[RBX]
JG @@35
OR RAX,RAX
JS @@35
CMP RAX,TEXT_ROWS
JGE @@35
IMUL2 RAX,TEXT_COLS
ADD RDI,RAX
SHL RDI,2
ADD RDI,R9
MOV RBX,U64 SF_ARG3[RBP]
MOV RSI,RDI
@@25: LODSD
OR AL,AL
JNZ @@30
MOV RAX,RBX
STOSD
DEC RCX
JNZ @@25
@@30: POP RDI
POP RSI
MOV RAX,TRUE
LEAVE
RET1 40
@@35: POP RDI
POP RSI
XOR RAX,RAX
LEAVE
RET1 40
// ************************************
_PLOT_BORDER_U8::
ENTER 0
MOV R9,U64 [&gr_text_base]
MOV RCX,U64 SF_ARG1[RBP]
MOV RBX,U64 CTask.win_scroll_x[RCX]
SAR RBX,3
ADD RBX,U64 SF_ARG3[RBP]
MOV RAX,U64 CTask.win_scroll_y[RCX]
SAR RAX,3
ADD RAX,U64 SF_ARG4[RBP]
MOV RDX,-1
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
OR RBX,RBX
JS @@05
CMP RBX,TEXT_COLS
JGE @@05
MOV RDX,-1
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
OR RAX,RAX
JS @@05
CMP RAX,TEXT_ROWS
JGE @@05
IMUL2 RAX,TEXT_COLS
ADD RBX,RAX
SHL RBX,2
ADD RBX,R9
MOV RAX,U64 SF_ARG2[RBP]
MOV U32 [RBX],EAX
MOV RAX,TRUE
LEAVE
RET1 32
@@05: XOR RAX,RAX
LEAVE
RET1 32
// ************************************
_GR_UPDATE_LINE32::
ENTER 0
PUSH RSI
PUSH RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV RSI,U64 [RAX] //rsi=src2
MOV RBX,U64 [&reverse_bits_table]
MOV RCX,U64 SF_ARG3[RBP] //rcx=d5
MOV RAX,U64 SF_ARG4[RBP]
MOV RDI,U64 [RAX] //rdi=vga image
MOV RAX,U64 SF_ARG1[RBP]
MOV R8,U64 [RAX] //rbp=vga dst
@@05: LODSD
CMP U32 [RDI],EAX
JE @@10
MOV U32 [RDI],EAX
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
MOV U32 [R8],EAX
@@10: ADD RDI,4
ADD R8,4
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
LEAVE
RET1 32
// ************************************
_GR_UPDATE_LINE32_FLUSH_CACHE::
ENTER 0
PUSH RSI
PUSH RDI
MOV RAX,U64 SF_ARG2[RBP]
MOV RSI,U64 [RAX] //rsi=src2
MOV RBX,U64 [&reverse_bits_table]
MOV RCX,U64 SF_ARG3[RBP] //rcx=d5
MOV RAX,U64 SF_ARG4[RBP]
MOV RDI,U64 [RAX] //rdi=vga image
MOV RAX,U64 SF_ARG1[RBP]
MOV R8,U64 [RAX] //rbp=vga dst
@@05: LODSD
MOV U32 [RDI],EAX
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
XLATB
ROR EAX,8
MOV U32 [R8],EAX
ADD RDI,4
ADD R8,4
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
LEAVE
RET1 32
// ************************************
_DC_BLOT_COLOR4::
ENTER 0
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 RSI
POP RDI
LEAVE
RET1 32
// ************************************
_IS_PIXEL_COVERED0::
ENTER 0
#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: LEAVE
RET1 24
// ************************************
_GR_ROP_EQU_U8_NO_CLIPPING::
//Puts foreground char shape onto gr_dc.
//ch.u8[1] is color as a whole byte
//ch DOCEt_UNDERLINE attr flag is used.
ENTER 0
MOVZX RAX,U8 SF_ARG1[RBP]
MOV RDX,U64 [&gr_font]
MOV RAX,U64 [RDX+RAX*8] //RAX is 8x8 char font data, 64-bits
BT U64 SF_ARG1[RBP],DOCEt_UNDERLINE
JNC @@05
MOV RBX,0xFF00000000000000
OR RAX,RBX
@@05: OR 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_1_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_1_to_8_bits] //RSI is gr_1_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: LEAVE
RET1 24
}
#help_index "Graphics/Char;Char/Graphics"
public _extern _PLOT_SCREEN_U8 Bool PlotScreenU8(I64 w,I64 x,I64 y);
public _extern _PLOT_WIN_U8 Bool PlotWinU8(CTask *task,I64 w,I64 x,I64 y);
public _extern _PLOT_WIN_STR2 Bool PlotWinStr2(
CTask *task,U8 *s,I64 len,I64 attr,I64 x,I64 y);
public _extern _PLOT_ATTR_STR2 Bool PlotAttrStr2(
CTask *task,U32 *hl,I64 len,I64 x,I64 y);
public _extern _PLOT_ATTR Bool PlotWinAttr(
CTask *task,I64 len,I64 attr,I64 x,I64 y);
public _extern _PLOT_BORDER_U8 Bool PlotBorderU8(CTask *task,I64 w,I64 x,I64 y);
_extern _GR_ROP_EQU_U8_NO_CLIPPING U0 GrRopEquU8NoClipping(I64 ch,U8 *dst,I64 width_internal);
#help_index "Graphics"
//No clipping
public _extern _IS_PIXEL_COVERED0 Bool IsPixelCovered0(CTask *task,I64 x,I64 y);
_extern _GR_UPDATE_LINE32 U0 GrUpdateLine32(
U32 **_dst3,U32 **_src2,I64 w,U8 **_vga);
_extern _GR_UPDATE_LINE32_FLUSH_CACHE U0 GrUpdateLine32FlushCache(
U32 **_dst3,U32 **_src2,I64 w,U8 **_vga);
_extern _DC_BLOT_COLOR4 U0 DCBlotColor4(
U8 *dst,I64 *img,I64 *img_cache,I64 cnt);
#help_index ""
File diff suppressed because it is too large. Load diff
+10
View File
@@ -0,0 +1,10 @@
//See $LK,"SYS_BIOS_GR_MODE","FF:D:/TempleOS/Kernel/KStart.CPP,SYS_BIOS_GR_MODE:2"$
//See $LK,"SysGrInit","MN:SysGrInit"$()
//This allows constants to be used
//instead of vars.
DefinePrintF("BIOS_GR_MODE","%d",bios_gr_mode);
DefinePrintF("GR_WIDTH","%d",gr_width);
DefinePrintF("GR_HEIGHT","%d",gr_height);
DefinePrintF("TEXT_ROWS","%d",text_rows);
DefinePrintF("TEXT_COLS","%d",text_cols);
+106
View File
@@ -0,0 +1,106 @@
#help_index "Graphics/Char;Char/Graphics"
public U0 PlotScreenStr(U8 *s,I64 attr,I64 x,I64 y)
{
U8 ch;
attr<<=8;
while (ch=*s++) {
PlotScreenU8(ch+attr,x,y);
x++;
}
}
public U0 PlotWinStr(CTask *task,U8 *s,I64 attr,I64 x,I64 y)
{
U8 ch;
attr<<=8;
while (ch=*s++) {
PlotWinU8(task,ch+attr,x,y);
x++;
}
}
public U0 PlotBorderStr(CTask *task,U8 *s,I64 attr,I64 x,I64 y)
{
U8 ch;
attr<<=8;
while (ch=*s++) {
PlotBorderU8(task,ch+attr,x,y);
x++;
}
}
public U0 DrawBorder(CTask *task,Bool solid,I64 l,I64 r,I64 t,I64 b,I64 attr,Bool clip_to_win)
{
I64 i;
attr<<=8;
if (clip_to_win) {
if (solid) {
PlotWinU8(task,'É'+attr,l-1,t-1);
PlotWinU8(task,'»'+attr,r+1,t-1);
PlotWinU8(task,'È'+attr,l-1,b+1);
PlotWinU8(task,'¼'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotWinU8(task,'Í'+attr,i,t-1);
PlotWinU8(task,'Í'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotWinU8(task,'º'+attr,l-1,i);
PlotWinU8(task,'º'+attr,r+1,i);
}
} else {
PlotWinU8(task,'Ú'+attr,l-1,t-1);
PlotWinU8(task,'¿'+attr,r+1,t-1);
PlotWinU8(task,'À'+attr,l-1,b+1);
PlotWinU8(task,'Ù'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotWinU8(task,'Ä'+attr,i,t-1);
PlotWinU8(task,'Ä'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotWinU8(task,'³'+attr,l-1,i);
PlotWinU8(task,'³'+attr,r+1,i);
}
}
} else {
if (solid) {
PlotScreenU8('É'+attr,l-1,t-1);
PlotScreenU8('»'+attr,r+1,t-1);
PlotScreenU8('È'+attr,l-1,b+1);
PlotScreenU8('¼'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotScreenU8('Í'+attr,i,t-1);
PlotScreenU8('Í'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotScreenU8('º'+attr,l-1,i);
PlotScreenU8('º'+attr,r+1,i);
}
} else {
PlotScreenU8('Ú'+attr,l-1,t-1);
PlotScreenU8('¿'+attr,r+1,t-1);
PlotScreenU8('À'+attr,l-1,b+1);
PlotScreenU8('Ù'+attr,r+1,b+1);
for (i=l;i<=r;i++) {
PlotScreenU8('Ä'+attr,i,t-1);
PlotScreenU8('Ä'+attr,i,b+1);
}
for (i=t;i<=b;i++) {
PlotScreenU8('³'+attr,l-1,i);
PlotScreenU8('³'+attr,r+1,i);
}
}
}
}
U0 DrawTaskBorder(CTask *task)
{
PushFD;
Cli;
DrawBorder(task,task==sys_focus_task,
task->win_left,task->win_right,
task->win_top,task->win_bottom,
task->border_attr,FALSE);
PopFD;
}
#help_index "Graphics"
+180
View File
@@ -0,0 +1,180 @@
#help_index "Graphics"
public U0 GrLineRect4(CDC *dc,I64 x1,I64 y1,I64 x2,I64 y2,I64 step=1,I64 start=0)
{
//Can be used with ROPF_DITHER+WHITE<<16+ROP_EQU+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 U0 GrArrow3(CDC *dc,I64 x1,I64 y1,I64 z1,I64 x2,I64 y2,I64 z2,F64 w=2.75,I64 step=1,I64 start=0)
{ //transformation with pen width
I64 _x1,_y1,_z1,_x2,_y2,_z2,dx,dy;
F64 d;
Bool 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;
GrReflect(dc,&_x1,&_y1,&_z1);
_x2=x2; _y2=y2; _z2=z2;
GrReflect(dc,&_x2,&_y2,&_z2);
dc->flags&=~DCF_SYMMETRY;
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;
Line(dc,_x2-dx*d+dy*d+0.5,_y2-dy*d-dx*d+0.5,_z2,_x2,_y2,_z2,&GrPlot3,step);
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;
}
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;
Line(dc,x2-dx*d+dy*d+0.5,y2-dy*d-dx*d+0.5,z2,x2,y2,z2,&GrPlot3,step);
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;
}
#help_index "Graphics/Char;Char/Graphics"
public Bool GrTextBox3(CDC *dc,I64 x1,I64 y1,I64 z1,U8 *s,I64 border=2)
{ //transformation
//DCF_SYMMETRY is silly.
Bool result;
U8 ch,*ptr=s;
I64 w=0,w_max=0,h=FONT_HEIGHT;
if (!s) return FALSE;
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;
result=GrPutS(dc,x1,y1,s);
GrLine(dc,x1-border ,y1-border ,x1+w_max+border,y1-border);
GrLine(dc,x1-border ,y1+h+border,x1+w_max+border,y1+h+border);
GrLine(dc,x1-border ,y1-border ,x1-border,y1+h+border);
GrLine(dc,x1+w_max+border,y1-border ,x1+w_max+border,y1+h+border);
return result;
}
#define MAX_DIAMOND_SLOPE 2.75
public Bool GrTextDiamond3(CDC *dc,I64 x1,I64 y1,I64 z1,U8 *_s,I64 border=2)
{ //transformation
//DCF_SYMMETRY is silly.
Bool result=FALSE,first=TRUE;
U8 ch,*ptr,*ptr_end,*st,*s;
I64 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==CH_CARRIAGE_RETURN||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) {
result=GrPutS(dc,x1-w,y,st);
first=FALSE;
} else
GrPutS(dc,x1-w,y,st);
if (w) {
w+=border;
do {
dx_old=dx; dy_old=dy;
m=ToF64(dx)/dy;
if (m<1/MAX_DIAMOND_SLOPE) {
dy=MaxI64(dy,Ceil(MAX_DIAMOND_SLOPE*dx));
m=1/MAX_DIAMOND_SLOPE;
} else if (m>MAX_DIAMOND_SLOPE) {
dy=MaxI64(dy,Ceil(dx/MAX_DIAMOND_SLOPE));
m=MAX_DIAMOND_SLOPE;
}
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);
GrLine(dc,x1,y1-dy,x1+dx,y1);
GrLine(dc,x1+dx,y1,x1,y1+dy);
GrLine(dc,x1,y1+dy,x1-dx,y1);
GrLine(dc,x1-dx,y1,x1,y1-dy);
return result;
}
#help_index "Graphics;Input Pointer/Displayed Image"
//Called by $LK,"DrawInputPtr","MN:DrawInputPtr"$() which is
//called by $LK,"WinFinalUpdate","MN:WinFinalUpdate"$().
public U0 DrawStdInputPtr(CDC *dc,I64 x,I64 y)
{
dc->pen_width=1;
dc->flags&=~(DCF_TRANSFORMATION|DCF_SYMMETRY);
GrArrow3(dc,x+8,y+8,0,x,y,0);
}
public U0 (*fp_draw_input_ptr)(CDC *dc,I64 x,I64 y)=&DrawStdInputPtr;
public U0 (*fp_draw_grab_input_ptr)(CDC *dc,I64 x,I64 y,Bool closed)=NULL;
public U8 *gr_empty_sprite=NULL; //Gets assigned $LK,"gr_empty_sprite","FI:::/TempleOS/Adam/WallPaper.CPP"$
public U0 DrawWaitInputPtr(CDC *dc,I64 x,I64 y)
{
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"
+304
View File
@@ -0,0 +1,304 @@
#help_index "Graphics/DCs"
public U0 DCRst(CDC *dc)
{
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=&GrTransform;
dc->lighting =&GrLighting;
GrIdentEqu(dc->r);
dc->r_norm=gr_scale;
dc->flags&=~(DCF_SYMMETRY|DCF_TRANSFORMATION|DCF_JUST_MIRROR);
}
public CDC *DCAlias(CDC *dc=NULL,CTask *task=NULL)
{
CDC *result;
if (!dc) dc=gr_dc2;
if (!task) task=Fs;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
result=MAlloc(sizeof(CDC),task);
MemCpy(result,dc,sizeof(CDC));
result->win_task=task;
result->mem_task=task;
result->r=MAlloc(16*sizeof(I64),task);
DCRst(result);
result->flags|=DCF_ALIAS;
result->alias=dc;
return result;
}
public CDC *DCNew(I64 type,I64 width,I64 height,CTask *task=NULL,Bool null_bitmap=FALSE)
{ //This internally only allows widths which are divisible by 8
//Don't forget these $MA+A-X+PU,"sizeof(CDC)","Grep(\"sizeof(CDC)\",\"/TempleOS/\"FILENAME_MASK_TXT);View;"$.
CDC *result;
if (!task) task=Fs;
result=CAlloc(sizeof(CDC),task);
result->win_task=task;
result->mem_task=task;
result->type=type;
result->width=width;
result->width_internal=(width+7)&~7;
result->height=height;
switch (type) {
case DCT_COLOR4:
result->plane_size=(result->width_internal*result->height)>>3;
if (!null_bitmap)
result->body=CAlloc(result->plane_size<<2,task);
break;
case DCT_COLOR8:
result->plane_size=result->width_internal*result->height;
if (!null_bitmap)
result->body=CAlloc(result->plane_size,task);
break;
default:
throw(EXCEPT_GRAPHICS,1);
}
if (null_bitmap)
result->flags|=DCF_DONT_DRAW;
result->r=MAlloc(16*sizeof(I64),task);
DCRst(result);
result->dc_signature=DCS_SIGNATURE_VAL;
return result;
}
public U0 DCDel(CDC *dc)
{
if (!dc) return;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
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)
{
if (dc)
return MSize2(dc)+MSize2(dc->body)+MSize2(dc->depth_buf);
else
return 0;
}
public U0 DCDepthBufRst(CDC *dc)
{
if (dc->depth_buf)
MemSetU32(dc->depth_buf,MAX_I32,dc->width_internal*dc->height);
}
public U0 DCAllocDepthBuf(CDC *dc)
{
Free(dc->depth_buf);
dc->depth_buf=MAlloc(dc->width_internal*dc->height*sizeof(I32),dc->mem_task);
DCDepthBufRst(dc);
}
public CDC *DCCopy(CDC *dc,CTask *task=NULL)
{
CDC *result;
if (!dc) return NULL;
if (dc->dc_signature!=DCS_SIGNATURE_VAL)
Dbg;
result=MAllocIdentical(dc,task);
GrSetRotMat(result,MAllocIdentical(dc->r,task));
result->mem_task=task;
result->body=MAllocIdentical(dc->body,task);
return result;
}
public U0 DCMono(CDC *dc,
I64 quest=COLOR_TRANSPARENT,I64 true_color=0,I64 false_color=COLOR_MONO)
{
I64 i;
U8 *dst;
if (dc->type==DCT_COLOR8) {
dst=dc->body;
i=dc->width_internal*dc->height;
while (i--)
if (*dst==quest)
*dst++=true_color;
else
*dst++=false_color;
}
}
public U0 DCColorChg(CDC *dc,I64 src_color,I64 dst_color=COLOR_TRANSPARENT)
{
I64 i;
U8 *dst;
if (dc->type==DCT_COLOR8) {
dst=dc->body;
i=dc->width_internal*dc->height;
while (i--)
if (*dst==src_color)
*dst++=dst_color;
else
dst++;
}
}
public U8 *DCSave(CDC *dc,I64 *_size=NULL,Bool compressed=TRUE)
{ //stores to mem
U8 *result,*ptr,*body;
Bool old_preempt;
CArcCompress *ac;
I64 i,j,old_flags=dc->flags;
if (dc->type==DCT_COLOR8)
i=dc->plane_size;
else
throw(EXCEPT_GRAPHICS,2);
if (compressed) {
ac=CompressBuf(dc->body,i);
j=ac->compressed_size;
body=ac;
} else {
ac=NULL;
j=i;
body=dc->body;
}
ptr=result=MAlloc(offset(CDC.end_saved_area)-
offset(CDC.start_saved_area)+j);
old_preempt=Preempt(OFF); //in case it is a screen bitmap
if (compressed) dc->flags|=DCF_COMPRESSED;
dc->flags&=DCF_COMPRESSED;
MemCpy(result,&dc->start_saved_area,
offset(CDC.end_saved_area)-
offset(CDC.start_saved_area));
dc->flags=old_flags;
Preempt(old_preempt);
ptr+=offset(CDC.end_saved_area)-
offset(CDC.start_saved_area);
MemCpy(ptr,body,j);
ptr+=j;
Free(ac);
if (_size) *_size=ptr-result;
return result;
}
public CDC *DCLoad(U8 *src,I64 *_size=NULL,CTask *task=NULL)
{ //loads from mem
CDC *result;
I64 i;
U8 *ptr=src;
CArcCompress *ac;
if (!task) task=Fs;
result=CAlloc(sizeof(CDC),task);
result->win_task=task;
result->mem_task=task;
MemCpy(&result->start_saved_area,src,
offset(CDC.end_saved_area)-
offset(CDC.start_saved_area));
ptr+=offset(CDC.end_saved_area)-
offset(CDC.start_saved_area);
if (result->type==DCT_COLOR8)
i=result->plane_size;
else
throw(EXCEPT_GRAPHICS,3);
if (result->flags&DCF_COMPRESSED) {
result->flags&=~DCF_COMPRESSED;
ac=ptr;
result->body=ExpandBuf(ac,task);
ptr+=ac->compressed_size;
} else {
result->body=MAlloc(i,task);
MemCpy(result->body,ptr,i);
}
result->pen_width=1;
result->r=GrIdent(task);
result->r_norm.u32[1]=1;
result->dc_signature=DCS_SIGNATURE_VAL;
if (_size) *_size=ptr-src;
return result;
}
public I64 GRAWrite(U8 *filename,CDC *dc)
{ // TempleOS GRA File
I64 size;
U8 *st=DftExt(filename,"GRA.Z"),
*src=DCSave(dc,&size);
FileWrite(st,src,size);
Free(st);
Free(src);
return size;
}
public CDC *GRARead(U8 *filename,CTask *task=NULL)
{ // TempleOS GRA File
CDC *dc=NULL;
U8 *st=DftExt(filename,"GRA.Z"),
*src=FileRead(st);
if (src)
dc=DCLoad(src,NULL,task);
Free(src);
Free(st);
return dc;
}
#help_index "Graphics/CSprite;Graphics/DCs;Doc/Output"
public U0 DocPutGRAFile(CDoc *doc=NULL,U8 *fname)
{
CDC *dc=GRARead(fname);
CSprite *elems=DC2Sprite(dc);
DocPutSprite(doc,elems);
Free(elems);
DCDel(dc);
}
#help_index "Graphics/DCs;Graphics/Screen"
public CDC *DCCaptureScreen(CTask *task=NULL)
{
CDC *dc;
U8 *dst;
WinMgrSync(2,TRUE);
dc=DCCopy(gr_screen_image,task);
if (dc->type==DCT_COLOR4) {
dc->type=DCT_COLOR8;
dc->plane_size*=8;
dst=MAlloc(dc->plane_size,task);
GrBitMap4ToBitMap8(dst,dc->body,dc->plane_size/2,COLOR_INVALID);
Free(dc->body);
dc->body=dst;
}
return dc;
}
public I64 GRACaptureScreen(U8 *filename)
{ // TempleOS GRA File
I64 size;
CDC *dc=DCCaptureScreen;
size=GRAWrite(filename,dc);
DCDel(dc);
return size;
}
#help_index "Graphics;Graphics/DCs"
public U0 DCExtentsInit(CDC *dc)
{//See $LK-A,"::/TempleOS/Demo/Graphics/Extents.CPP"$
//You should clear the record flag yourself
dc->flags|=DCF_RECORD_EXTENTS;
dc->min_x=MAX_I64;
dc->max_x=MIN_I64;
dc->min_y=MAX_I64;
dc->max_y=MIN_I64;
}
File diff suppressed because it is too large. Load diff
+785
View File
@@ -0,0 +1,785 @@
#help_index "Graphics/DCs;Graphics/Screen"
public CDC *gr_screen_image; //This is read only
#help_index "Graphics/DCs"
public CDC *gr_dc=NULL, //This is updated every refresh
*gr_dc_cache,
*gr_dc1=NULL,
*gr_dc2=NULL;
CDC *gr_zoomed_dc;
U16 *gr_win_uncovered_bitmap=NULL,gr_highest_uncovered;
U16 *gr_vga_text_cache;
public U0 DCFill(CDC *dc=NULL,CColorROPU32 val=COLOR_TRANSPARENT)
{
if (!dc) dc=gr_dc2;
nobound_switch (dc->type) {
case DCT_COLOR4:
MemSet(dc->body,val,(dc->width_internal*dc->height)>>1);
break;
case DCT_COLOR8:
MemSet(dc->body,val,dc->width_internal*dc->height);
break;
}
}
public U0 DCClear(CDC *dc=NULL)
{
if (!dc) dc=gr_dc2;
DCFill(dc,0);
}
#help_index "Graphics/Screen"
public U0 (*fp_final_screen_update)(CDC *dc)=NULL;
public U0 (*fp_wall_paper)(CTask *task)=NULL;
#help_index "Graphics/Screen;Windows"
U0 WinZBufFill(CTask *task)
{ //Not public
I64 y,t,dc,l,r,w;
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER)) {
t= task->win_top-1>0
? task->win_top-1 : 0,
dc= task->win_bottom+1<TEXT_ROWS
? task->win_bottom+1 : TEXT_ROWS-1,
l= task->win_left-1>0
? task->win_left-1 : 0,
r= task->win_right+1<TEXT_COLS
? task->win_right+1 : TEXT_COLS-1;
} else {
t= task->win_top>0
? task->win_top : 0,
dc= task->win_bottom<TEXT_ROWS
? task->win_bottom : TEXT_ROWS-1,
l= task->win_left>0
? task->win_left : 0,
r= task->win_right<TEXT_COLS
? task->win_right : TEXT_COLS-1;
}
t=LimitI64(t,0,TEXT_ROWS-1);
dc=LimitI64(dc,t,TEXT_ROWS-1);
l=LimitI64(l,0,TEXT_COLS-1);
r=LimitI64(r,l,TEXT_COLS-1);
if (w=r-l+1)
for (y=t;y<=dc;y++)
MemSetU16(gr_win_z_buf(U8 *)+(y*TEXT_COLS+l)*sizeof(U16),
task->win_z_num,w);
}
public U0 WinZBufUpdate()
{ //You might have to call this if you are doing graphics outside
//the window mgr callback routines. Call it if, for example,
//a pop-up window closes and you need to refresh before graphics.
I64 i,z=1;
U16 *ptr;
CTask *task,*task1;
Bool old_preempt=Preempt(OFF);
if (gr_win_z_buf) {
LBtr(&sys_semas[SYS_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++);
}
Preempt(old_preempt);
}
#help_index "Graphics/Char;Char"
public U0 WinTextFill(I64 d,CTask *task=NULL)
{
if (!task) task=Fs;
if (!TaskValidate(task)) return;
I64 y,w,
t= task->win_top>0
? task->win_top : 0,
dc= task->win_bottom<TEXT_ROWS
? task->win_bottom : TEXT_ROWS-1,
l= task->win_left>0
? task->win_left : 0,
r= task->win_right<TEXT_COLS
? task->win_right : TEXT_COLS-1;
if (w=r-l+1)
for (y=t;y<=dc;y++)
MemSetU32(gr_text_base(U8 *)+(y*TEXT_COLS+l)*sizeof(U32),
d,w);
}
public U0 WinTextClear(CTask *task=NULL)
{
if (!task) task=Fs;
if (!TaskValidate(task)) return;
WinTextFill(task->text_attr<<8,task);
}
public U0 SetWinBkColor(I64 c,CTask *task=NULL)
{
if (!task) task=Fs;
if (!TaskValidate(task)) return;
task->text_attr=task->text_attr&0x0F | c<<4;
WinTextFill(c<<12,task);
}
#help_index "Graphics/Color"
public I32 gr_rainbow_10[10]=
{
BLACK,BROWN,RED,LTRED,YELLOW,
GREEN,BLUE,PURPLE,LTGRAY,WHITE
};
DefineLstLoad("ST_RAINBOW_10",
"BLACK\0BROWN\0RED\0LTRED\0YELLOW\0"
"GREEN\0BLUE\0PURPLE\0LTGRAY\0WHITE\0");
U0 SetVGAPalette4Indices()
{//4-bit (16 color)
/*There is a level of indirection we wish to identity map.
This sets the 16-colors to use
the first 16 DAC rgb entries, so
we never need to worry about indexes,
just DAC palette settings.
*/
I64 i;
if (text_mode) return;
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
InU8(VGA_INPUT_STAT); //Rsts attr index/data
for (i=0;i<16;i++) {
OutU8(VGA_ATTR_INDEX,i);
OutU8(VGA_ATTR_DATA_WRITE,i);
}
OutU8(VGA_ATTR_INDEX,0x20);
OutU8(VGA_ATTR_DATA_WRITE,0); //Dummy write
InU8(VGA_INPUT_STAT); //Rsts attr index/data
LBtr(&sys_semas[SYS_SEMA_VGA],0);
PopFD;
}
public U0 SetVGAPaletteColor(I64 color_num,CBGR bgr)
{ //6-bits per r,dc and g
if (text_mode) return;
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
OutU8(VGA_PALETTE_MASK,0xFF);
OutU8(VGA_REG_WRITE,color_num);
OutU8(VGA_PALETTE_DATA,bgr.r>>2);
OutU8(VGA_PALETTE_DATA,bgr.g>>2);
OutU8(VGA_PALETTE_DATA,bgr.b>>2);
LBtr(&sys_semas[SYS_SEMA_VGA],0);
PopFD;
}
public CBGR GetVGAPaletteColor(I64 color_num)
{ //6-bits per r,dc and g
CBGR result=0;
if (text_mode) return 0;
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_VGA],0))
Yield;
OutU8(VGA_PALETTE_MASK,0xFF);
OutU8(VGA_REG_READ,color_num);
result.r=InU8(VGA_PALETTE_DATA)<<2;
result.g=InU8(VGA_PALETTE_DATA)<<2;
result.b=InU8(VGA_PALETTE_DATA)<<2;
LBtr(&sys_semas[SYS_SEMA_VGA],0);
PopFD;
return result;
}
public CBGR vga_palette4_std[16]={
0x000000,0x0000AA,0x00AA00,0x00AAAA,
0xAA0000,0xAA00AA,0xAA5500,0xAAAAAA,
0x555555,0x5555FF,0x55FF55,0x55FFFF,
0xFF5555,0xFF55FF,0xFFFF55,0xFFFFFF};
public CBGR vga_palette4_gray[16]={
0x000000,0x111111,0x222222,0x333333,
0x444444,0x555555,0x666666,0x777777,
0x888888,0x999999,0xAAAAAA,0xBBBBBB,
0xCCCCCC,0xDDDDDD,0xEEEEEE,0xFFFFFF};
public U0 GetVGAPalette4(CBGR *bgr)
{//4-bit (16 color)
I64 i;
for (i=0;i<16;i++)
bgr[i]=GetVGAPaletteColor(i);
}
public U0 SetVGAPalette4(CBGR *bgr)
{//4-bit (16 color)
I64 i;
for (i=0;i<16;i++)
SetVGAPaletteColor(i,bgr[i]);
}
public U0 SetStdPalette()
{
SetVGAPalette4(vga_palette4_std);
}
#help_index "Graphics/Screen"
#define GR_NUM_PEN_BRUSHES 64
CDC *gr_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_collision_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_even_pen_brushes[GR_NUM_PEN_BRUSHES],
*gr_odd_pen_brushes[GR_NUM_PEN_BRUSHES];
#define GR_MAX_SCREEN_ZOOM 8
U8 *gr_screen_zoom_tables[GR_MAX_SCREEN_ZOOM+1];
I64 gr_screen_zoom=1,grsx=0,grsy=0;
//When zoomed, this keeps the mouse centered.
public Bool gr_continuous_scroll=FALSE;
#define GR_REFRESH_LOG_CNT 16
F64 gr_refresh_time_stamps[GR_REFRESH_LOG_CNT];
I64 gr_refresh_ts_ptr=0;
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_1_to_8_bits(U8 *)[k++]=0xFF;
else
gr_1_to_8_bits(U8 *)[k++]=0x00;
k=0;
for (i=0;i<256;i++)
for (j=0;j<8;j++)
gr_1_to_8_colors(U8 *)[k++]=i;
for (i=0;i<GR_NUM_PEN_BRUSHES;i++) {
k=i+1;
dc=DCNew(DCT_COLOR8,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(DCT_COLOR8,i,i);
gr_collision_pen_brushes[i]=dc;
dc->color=COLOR_INVALID;
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(DCT_COLOR8,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(DCT_COLOR8,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 (text_mode) {
MemSet(VGA_TEXT_MEM_BASE,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
MemSet(gr_vga_text_cache,0,TEXT_ROWS*TEXT_COLS*sizeof(U16));
} else {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,0x0F);
//Virtual Box crashes on the following for some reason.
// MemSet(VGA_GRAPHIC_MEM_BASE,0,GR_HEIGHT*GR_WIDTH>>3);
MemSet(gr_screen_image->body,0,GR_WIDTH*GR_HEIGHT>>1);
}
for (i=1;i<=GR_MAX_SCREEN_ZOOM;i++) {
dst=gr_screen_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];
}
}
for (i=0;i<GR_REFRESH_LOG_CNT;i++)
gr_refresh_time_stamps[i]=tT;
}
U0 GrInit()
{
SetStdPalette;
fp_set_std_palette=&SetStdPalette;
SetVGAPalette4Indices;
gr_1_to_8_bits =MAlloc(256*sizeof(I64));
gr_1_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_z_buf=MAlloc(TEXT_ROWS*TEXT_COLS*sizeof(U16));
gr_win_uncovered_bitmap=CAlloc(65536/8);
gr_highest_uncovered=0;
gr_dc=DCNew(DCT_COLOR8,GR_WIDTH,GR_HEIGHT);
gr_dc->flags|=DCF_SCREEN_BITMAP;
gr_dc_cache=DCNew(DCT_COLOR8,GR_WIDTH,GR_HEIGHT);
gr_dc2=DCNew(DCT_COLOR8,GR_WIDTH,GR_HEIGHT);
gr_dc2->flags|=DCF_SCREEN_BITMAP;
DCFill;
gr_dc1=DCNew(DCT_COLOR4,GR_WIDTH,GR_HEIGHT);
gr_dc1->flags|=DCF_SCREEN_BITMAP;
gr_screen_image=DCNew(DCT_COLOR4,GR_WIDTH,GR_HEIGHT);
gr_zoomed_dc =DCNew(DCT_COLOR4,GR_WIDTH,GR_HEIGHT);
gr_zoomed_dc->flags|=DCF_SCREEN_BITMAP;
GrSetUpTables;
WinZBufUpdate;
}
U0 GrUpdateWins()
{ //Only called by WinMgr
I64 i;
CTask *task,*task1;
CD3I64 saved_scroll;
CDC *dc;
Bool old_preempt=Preempt(OFF);
try {
refresh_ode_time=0;
if (Bt(&sys_semas[SYS_SEMA_UPDATE_WIN_Z_BUF],0))
WinZBufUpdate;
task1=task=sys_winmgr_task;
do {
if (!TaskValidate(task))
break;
sys_task_being_screen_updated=task;
Preempt(old_preempt);
ODEsUpdate(task);
Preempt(OFF);
if (!TaskValidate(task))
break;
if (Bt(&task->display_flags,DISPLAYf_SHOW) &&
Bt(gr_win_uncovered_bitmap,task->win_z_num)) {
try {
if (!Bt(&task->display_flags,DISPLAYf_NO_BORDER))
DrawTaskBorder(task);
WinTextClear(task);
Preempt(old_preempt);
if (task==sys_winmgr_task) {
if (fp_wall_paper)
(*fp_wall_paper)(task);
} else {
if (!(task->win_inhibit&WIF_DOC))
DocUpdateTaskDocs(task);
}
if (TaskValidate(task)) {
if (task->draw_it) {
dc=DCAlias(gr_dc,task);
(*task->draw_it)(task,dc);
DCDel(dc);
}
if (TaskValidate(task)) {
Preempt(OFF);
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: DrawIt\n";
PutExcept;
Sleep(3000);
VGAFlush;
Fs->catch_except=TRUE;
}
}
}
if (!TaskValidate(task))
break;
task=task->next_task;
} while (task!=task1);
for (i=1;i<mp_cnt;i++) {
task1=task=cpu_structs[i].seth_task;
do {
if (!TaskValidate(task))
break;
try {
sys_task_being_screen_updated=task;
Preempt(old_preempt);
ODEsUpdate(task);
Preempt(OFF);
} catch {
LBts(&task->win_inhibit,WIf_ODE);
"Exception in WinMgr: ODE\n";
PutExcept;
Sleep(3000);
VGAFlush;
Fs->catch_except=TRUE;
}
if (!TaskValidate(task))
break;
task=task->next_task;
} while (task!=task1);
}
} catch {
PutExcept;
Dbg("Exception in WinMgr");
}
last_refresh_ode_time=refresh_ode_time;
ode_allocated_factor=LowPass1(0.1,ode_allocated_factor,
Limit(Gs->idle_factor-0.1,0.2,0.8),1/win_actual_refresh);
sys_task_being_screen_updated=NULL;
gr_refresh_time_stamps[gr_refresh_ts_ptr++&(GR_REFRESH_LOG_CNT-1)]=tT;
win_actual_refresh=(GR_REFRESH_LOG_CNT-1)/
(gr_refresh_time_stamps[(gr_refresh_ts_ptr-1)&(GR_REFRESH_LOG_CNT-1)]-
gr_refresh_time_stamps[gr_refresh_ts_ptr&(GR_REFRESH_LOG_CNT-1)]);
Preempt(old_preempt);
}
U0 GrFixZoomScale()
{
gr_screen_zoom=LimitI64(gr_screen_zoom,1,GR_MAX_SCREEN_ZOOM);
if (gr_screen_zoom==1) {
grsx=0;
grsy=0;
} else {
grsx=LimitI64(grsx,0,GR_WIDTH-GR_WIDTH/gr_screen_zoom)&~7;
grsy=LimitI64(grsy,0,GR_HEIGHT-GR_HEIGHT/gr_screen_zoom);
}
}
public U0 GrScaleZoom(F64 scale)
{
Bool old_preempt=Preempt(OFF);
F64 s=gr_screen_zoom;
gr_screen_zoom=gr_screen_zoom*scale;
GrFixZoomScale;
s/=gr_screen_zoom;
ipx_scale*=s;
ipy_scale*=s;
ipz_scale*=s;
ipx_offset=ipx-(ipx-ipx_offset)*s;
ipy_offset=ipy-(ipy-ipy_offset)*s;
ipz_offset=ipz-(ipz-ipz_offset)*s;
grsx=ipx-gr_zoomed_dc->width >>1/gr_screen_zoom;
grsy=ipy-gr_zoomed_dc->height>>1/gr_screen_zoom;
GrFixZoomScale;
Preempt(old_preempt);
}
public U0 GrZoomIn()
{
GrScaleZoom(2.0);
}
public U0 GrZoomOut()
{
GrScaleZoom(0.5);
}
U0 CtrlAltZ(I64 sc)
{
if (sc&SCF_SHIFT)
GrZoomOut;
else
GrZoomIn;
}
SetCtrlAltLetCB('Z',&CtrlAltZ,"Sys/Zoom In or Out");
U0 GrZoomInScreen()
{
GrFixZoomScale;
I64 plane,row,col,k,l,
d2=gr_zoomed_dc->width>>3/gr_screen_zoom,
d4=gr_zoomed_dc->width_internal>>3,
d5=d4-d2*gr_screen_zoom,
d3=gr_zoomed_dc->height/gr_screen_zoom,
d6=(gr_zoomed_dc->height-d3)*gr_dc1->width_internal>>3,
d7=gr_zoomed_dc->height%gr_screen_zoom*d4;
U8 *src,*src2,*dst,*src3,*map=gr_screen_zoom_tables[gr_screen_zoom];
src=gr_dc1->body+grsx>>3+grsy*gr_dc1->width_internal>>3;
dst=gr_zoomed_dc->body;
for (plane=1;plane<0x10;plane<<=1) {
row=d3;
while (row--) {
k=gr_screen_zoom;
while (k--) {
src2=src;
col=d2;
while (col--) {
src3=&map[*src2++];
l=gr_screen_zoom;
while (l--) {
*dst++=*src3;
src3+=256;
}
}
l=d5;
while (l--)
*dst++=0;
}
src+=d4;
}
l=d7;
while (l--)
*dst++=0;
src+=d6;
}
}
U0 GrUpdateBackgroundOfText()
{
I64 reg RSI *dst=gr_dc->body,reg R13 c,row,col,,cur_ch,
reg R12 w1=gr_dc->width_internal,reg R10 w2=-7*w1+8,w3=7*w1,
reg *my_1_to_8_colors=gr_1_to_8_colors;
U32 reg *src=gr_text_base;
$HL,1$ Bool blink_flag=Blink;
nounusedwarn w2;
for (row=TEXT_ROWS;row--;) {
for (col=TEXT_COLS;col--;) {
cur_ch=*src++;
if (cur_ch & (DOCET_SELECTED | DOCET_INVERT | DOCET_BLINK)) {
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+ cur_ch.u8[1]>>4;
}
c=my_1_to_8_colors[cur_ch.u8[1]>>4];
asm {
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
ADD RSI,R10
}
}
dst(U8 *)+=w3;
}
}
//$AN,"ExtScreenCodes","ExtScreenCodes"$
// Bits 0-7 ASCII (Screen Code)
// Bits 8-11 Foreground color
// Bits 12-15 Background color
// Bits 16-20 Signed X pos shift val
// Bits 21-25 Signed Y pos shift val
// Bit 28 Blink
// Bit 29 Inverted (Swap foreground and background)
// Bit 30 Selected (XOR colors with FF)
// Bit 31 Underline
U0 GrUpdateForegroundOfText()
{
U32 *src=gr_text_base;
I64 i,j,cur_ch,reg *dst=gr_dc->body,
reg w1=gr_dc->width_internal,w2=7*w1,
row,col;
U8 *dst_start=gr_dc->body,*dst_end=dst_start+w1*gr_dc->height-7*w1-8;
Bool blink_flag=Blink;
for (row=TEXT_ROWS;row--;) {
for (col=TEXT_COLS;col--;) {
cur_ch=*src++;
if (cur_ch & (DOCET_UNDERLINE | DOCET_SELECTED | DOCET_INVERT | DOCET_BLINK)) {
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
}
if (i=cur_ch.u16[1]&0x3FF) {
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&(DOCET_UNDERLINE+0xFFF),dst(U8 *)+i,w1);
} else
GrRopEquU8NoClipping(cur_ch&(DOCET_UNDERLINE+0xFFF),dst,w1);
dst(U8 *)+=8;
}
dst(U8 *)+=w2;
}
}
U0 DCBlotColor8(CDC *dc,CDC *img)
{
U8 reg *src=img->body,*b0=dc->body;
I64 reg j,reg k,reg d0=img->width_internal*img->height;
for (k=0;k<d0;k++) {
j=*src++;
if (j!=COLOR_TRANSPARENT)
*b0++=j;
else
b0++;
}
}
U0 GrUpdateTextModeText()
{
U32 *src=gr_text_base;
I64 cur_ch,i,d0=TEXT_COLS*TEXT_ROWS;
U16 *dst=VGA_TEXT_MEM_BASE,*dst2=gr_vga_text_cache;
Bool blink_flag=Blink;
if (LBtr(&sys_semas[SYS_SEMA_FLUSH_VGA_IMAGE],0)) {
i=d0;
while (i--) {
cur_ch=*src++;
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_BLINK)
if (blink_flag)
cur_ch.u8[1]= cur_ch.u8[1]<<4+ cur_ch.u8[1]>>4;
cur_ch&=0x7FFF;
*dst++=*dst2++=cur_ch;
}
} else {
i=d0;
while (i--) {
cur_ch=*src++;
if (cur_ch & DOCET_SELECTED)
cur_ch.u8[1]=cur_ch.u8[1]^0xFF;
if (cur_ch & DOCET_INVERT)
cur_ch.u8[1]=cur_ch.u8[1]<<4+cur_ch.u8[1]>>4;
if (cur_ch & DOCET_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()
{
I64 row,plane,d2=gr_zoomed_dc->width_internal>>5;
U32 *src,*dst,*dst2;
//Update Graphic Card
if (gr_screen_zoom==1)
src=gr_dc1->body;
else {
GrZoomInScreen;
src=gr_zoomed_dc->body;
}
dst2=gr_screen_image->body;
if (LBtr(&sys_semas[SYS_SEMA_FLUSH_VGA_IMAGE],0)) {
for (plane=1;plane<0x10;plane<<=1) {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,plane);
dst=VGA_GRAPHIC_MEM_BASE;
row=gr_zoomed_dc->height;
while (row--)
GrUpdateLine32FlushCache(&dst,&src,d2,&dst2);
}
} else {
for (plane=1;plane<0x10;plane<<=1) {
OutU8(VGA_SC_INDEX,VGA_MAP_MASK);
OutU8(VGA_SC_DATA,plane);
dst=VGA_GRAPHIC_MEM_BASE;
row=gr_zoomed_dc->height;
while (row--)
GrUpdateLine32(&dst,&src,d2,&dst2);
}
}
}
U0 GrUpdateScreen()
{
CDC *dc;
Bool old_preempt=IsPreempt;
if (!IsSysDeterministic)
Preempt(ON);
if (text_mode)
GrUpdateWins;
else {
GrUpdateBackgroundOfText;
GrUpdateForegroundOfText;
GrUpdateWins;
DCBlotColor8(gr_dc,gr_dc2);
}
dc=DCAlias(gr_dc,Fs);
dc->flags|=DCF_ON_TOP;
if (fp_final_screen_update)
(*fp_final_screen_update)(dc);
DCDel(dc);
if (text_mode)
GrUpdateTextModeText;
else {
DCBlotColor4(gr_dc1->body,gr_dc->body,gr_dc_cache->body,
gr_dc->height*gr_dc->width_internal>>3);
GrUpdateVGAGraphics;
}
Preempt(old_preempt);
}
#help_index "Graphics"
+526
View File
@@ -0,0 +1,526 @@
#help_index "Graphics/CSprite"
/*
$LK,"CSprite","MN:CSprite"$s are stored as a sequence of var
length operations with a 1-byte type leading
each operation. The types available are lsted
here, $LK,"GRST_PT","MN:GRST_PT"$. They are stored, one after another,
in a chunk of memory terminated by a type $LK,"GRST_END","MN:GRST_END"$.
$LK,"SpritePlot3","MN:SpritePlot3"$() and $LK,"SpriteVect","MN:SpriteVect"$() shows how the
unions are used. It's kind-of a mess using a union.
$LK,"SpriteSize","MN:SpriteSize"$() will return the size of a single
operation, while $LK,"SpriteSize","MN:SpriteSize"$() with an 's' will
return the size of an entire lst. Look at
$LK,"gr_sprite_base_size","MN:gr_sprite_base_size"$.
To get familiar, type <CTRL-R> on sprite in
a document and select "Display as Text". It
will show the raw data for each CSprite. This
is how they are stored in files, as well.
See $MA+A-X+PU,"::/TempleOS/Apps/GrModels","Cd(\"::/TempleOS/Apps/GrModels\");Dir;View;\n"$ for an example of
making CSprite by hand. Those are type
$LK,"GRST_MESH","MN:GRST_MESH"$, one of the most complicated.
*/
public U0 SpritePlot3(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,Bool just_one=FALSE)
{
CSprite *tempg=elems-offset(CSprite.start);
I64 i,j,k,x1,y1,z1,x2,y2,
cur_sprite_elem_num=0,*old_r,*r2,
old_flags=dc->flags,
old_pen_width=dc->pen_width;
I32 *ptr;
CColorROPU32 old_color=dc->color;
CDC *img;
CD3I32 *p;
CGrSym old_sym;
MemCpy(&old_sym,&dc->sym,sizeof(CGrSym));
while (tempg->type) {
dc->cur_sprite_elem_num=cur_sprite_elem_num++;
switch (tempg->type) {
case GRST_COLOR8:
dc->color=dc->color&~(COLORROP_COLORS_MASK|ROPF_DITHER)|tempg->color8;
break;
case GRST_DITHER_COLOR8:
dc->color=dc->color&~COLORROP_COLORS_MASK|
tempg->dither_color8.u8[0]|
tempg->dither_color8.u8[1]<<COLORROP_BITS|ROPF_DITHER;
break;
case GRST_WIDTH:
dc->pen_width=tempg->width;
GrScalePenWidth(dc);
break;
case GRST_TRANSFORM_ON:
if (!(dc->flags&DCF_TRANSFORMATION)) {
x-=dc->x;
y-=dc->y;
z-=dc->z;
}
dc->flags|=DCF_TRANSFORMATION;
break;
case GRST_TRANSFORM_OFF:
if (dc->flags&DCF_TRANSFORMATION) {
x+=dc->x;
y+=dc->y;
z+=dc->z;
}
dc->flags&=~DCF_TRANSFORMATION;
break;
case GRST_PT:
GrPlot3(dc,tempg->x1+x,tempg->y1+y,z);
break;
case GRST_TEXT:
GrPutS3(dc,tempg->x1+x,tempg->y1+y,z,tempg->st);
break;
case GRST_TEXT_BOX:
GrTextBox3(dc,tempg->x1+x,tempg->y1+y,z,tempg->st);
break;
case GRST_TEXT_DIAMOND:
GrTextDiamond3(dc,tempg->x1+x,tempg->y1+y,z,tempg->st);
break;
case GRST_FLOOD_FILL:
GrFloodFill3(dc,tempg->x1+x,tempg->y1+y,z,FALSE);
break;
case GRST_FLOOD_FILL_NOT:
i=dc->color;
dc->color=dc->color.c0;
GrFloodFill3(dc,tempg->x1+x,tempg->y1+y,z,TRUE);
dc->color=i;
break;
case GRST_SHIFT:
x+=tempg->x1;
y+=tempg->y1;
break;
case GRST_LINE:
GrLine3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z);
break;
case GRST_ARROW:
GrArrow3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z);
break;
case GRST_PLANAR_SYMMETRY:
if (GrSetSymmetry3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2+x,tempg->y2+y,z,tempg->x2+x,tempg->y2+y,z+1))
dc->flags|=DCF_SYMMETRY;
else
dc->flags&=~DCF_SYMMETRY;
break;
case GRST_BITMAP8:
img=CAlloc(sizeof(CDC));
img->type=DCT_COLOR8;
img->width=tempg->width;
img->width_internal=(tempg->width+7)&~7;
img->height=tempg->height;
img->plane_size=img->width_internal*img->height;
img->body=tempg(U8 *)+offset(CSprite.linespeed);
img->dc_signature=DCS_SIGNATURE_VAL;
GrBlot3(dc,tempg->x2+x,tempg->y2+y,z,img);
Free(img);
break;
case GRST_RECT:
GrRect3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2-tempg->x1,tempg->y2-tempg->y1);
break;
case GRST_ROTATED_RECT:
x1=tempg->x1+x;
y1=tempg->y1+y;
z1=z;
GrRot(dc->r,&x1,&y1,&z1);
old_r=dc->r;
dc->flags|=DCF_TRANSFORMATION;
r2=GrRotZ(-tempg->rot_angle);
GrSetTranslation(r2,x1,y1,z1);
GrSetRotMat(dc,GrMulMat(old_r,r2));
GrRect3(dc,0,0,0,tempg->x2-tempg->x1,tempg->y2-tempg->y1);
Free(dc->r);
Free(r2);
GrSetRotMat(dc,old_r);
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
break;
case GRST_CIRCLE:
GrCircle3(dc,tempg->x1+x,tempg->y1+y,z,tempg->x2);
break;
case GRST_ELLIPSE:
GrEllipse3(dc,tempg->x2+x,tempg->y2+y,z,tempg->width,tempg->height,tempg->rot_angle);
break;
case GRST_REG_POLY:
GrRegPoly3(dc,tempg->x2+x,tempg->y2+y,z,tempg->width,tempg->height,tempg->sides,tempg->rot_angle);
break;
case GRST_POLYLINE:
ptr=&tempg->y1;
x1=ptr[0];
y1=ptr[1];
for (i=1;i<tempg->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 GRST_POLYPT:
ptr=&tempg->y1;
x1=ptr[0];
y1=ptr[1];
ptr+=2;
k=tempg->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;
case GRST_BSPLINE2:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr2BSpline3(dc,&tempg->y1,tempg->num,FALSE);
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_BSPLINE3:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr3BSpline3(dc,&tempg->y1,tempg->num,FALSE);
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_BSPLINE2_CLOSED:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr2BSpline3(dc,&tempg->y1,tempg->num,TRUE);
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_BSPLINE3_CLOSED:
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr3BSpline3(dc,&tempg->y1,tempg->num,TRUE);
p=&tempg->y1;
for (i=0;i<tempg->num;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_MESH:
p=&tempg->x2;
for (i=0;i<tempg->vertex_cnt;i++,p++) {
p->x+=x;
p->y+=y;
p->z+=z;
}
Gr3Mesh(dc,tempg->vertex_cnt,&tempg->x2,tempg->triangle_cnt,(&tempg->x2)(U8 *)+sizeof(CD3I32)*tempg->vertex_cnt);
p=&tempg->x2;
for (i=0;i<tempg->vertex_cnt;i++,p++) {
p->x-=x;
p->y-=y;
p->z-=z;
}
break;
case GRST_SHIFTABLE_MESH:
if (dc->flags&DCF_TRANSFORMATION) {
dc->x+=tempg->x1;
dc->y+=tempg->y1;
dc->z+=tempg->z1;
x1=x;
y1=y;
z1=z;
} else {
x1=tempg->x1+x;
y1=tempg->y1+y;
z1=tempg->z1+z;
}
p=(&tempg->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg->shiftable_vertex_cnt;i++,p++) {
p->x+=x1;
p->y+=y1;
p->z+=z1;
}
p=(&tempg->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
Gr3Mesh(dc,tempg->shiftable_vertex_cnt,p,tempg->shiftable_triangle_cnt,p(U8 *)+sizeof(CD3I32)*tempg->shiftable_vertex_cnt);
p=(&tempg->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg->shiftable_vertex_cnt;i++,p++) {
p->x-=x1;
p->y-=y1;
p->z-=z1;
}
if (dc->flags&DCF_TRANSFORMATION) {
dc->x-=tempg->x1;
dc->y-=tempg->y1;
dc->z-=tempg->z1;
}
break;
}
if (just_one) break;
tempg(U8 *)+=SpriteElemSize(tempg);
}
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 SpritePlot3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems)
{
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;
SpritePlot3(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 SpritePlotRotMat3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,I64 *m)
{
I64 *old_r=dc->r,old_m[16],
old_flags=dc->flags&DCF_TRANSFORMATION;
MemCpy(old_m,m,16*sizeof(I64));
dc->flags|=DCF_TRANSFORMATION;
GrAddTranslation(m,x,y,z);
dc->r=GrMulMat(old_r,m);
SpritePlot3(dc,0,0,0,elems);
Free(dc->r);
dc->r=old_r;
MemCpy(m,old_m,16*sizeof(I64));
dc->flags=dc->flags&~DCF_TRANSFORMATION|old_flags;
}
public U0 SpritePlotRotX3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,F64 è=0)
{
I64 *r=GrRotX(è);
SpritePlotRotMat3b(dc,x,y,z,elems,r);
Free(r);
}
public U0 SpritePlotRotY3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,F64 ê=0)
{
I64 *r=GrRotY(ê);
SpritePlotRotMat3b(dc,x,y,z,elems,r);
Free(r);
}
public U0 SpritePlotRotZ3b(CDC *dc,I64 x,I64 y,I64 z,U8 *elems,F64 é=0)
{
I64 *r=GrRotZ(é);
SpritePlotRotMat3b(dc,x,y,z,elems,r);
Free(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(DCT_COLOR8,MAX_I32,MAX_I32,Fs,TRUE);
DCExtentsInit(dc);
SpritePlot3(dc,MAX_I32/2,MAX_I32/2,MAX_I32/2,elems);
if (dc->min_x<=dc->max_x) {
dc->min_x-=MAX_I32/2;
dc->max_x-=MAX_I32/2;
}
if (dc->min_y<=dc->max_y) {
dc->min_y-=MAX_I32/2;
dc->max_y-=MAX_I32/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,I64 type=DCT_COLOR8)
{
CDC *result;
I64 min_x,max_x,min_y,max_y;
SpriteExtents(elems,&min_x,&max_x,&min_y,&max_y);
result=DCNew(type,max_x-min_x+1,max_y-min_y+1);
SpritePlot3(result,-min_x,-min_y,0,elems);
return result;
}
public U8 *SpriteInterpolate(U8 *elems0,U8 *elems1,F64 t)
{
//The two CSprite should be identical
//except for points shifted around.
//t ranges from 0.0 to 1.0
//
//See $LK-A,"::/TempleOS/Demo/Graphics/Golf.CPP"$ for an example.
I64 i=SpriteSize(elems0),
t1=gr_scale*t,t0=gr_scale-t1;
I32 *ptr0,*ptr1,*ptrr;
CD3I32 *p0,*p1,*pr;
U8 *result=MAlloc(i);
CSprite *tempg0=elems0-offset(CSprite.start),
*tempg1=elems1-offset(CSprite.start),
*tempgr=result-offset(CSprite.start);
MemCpy(result,elems0,i);
while (tempg0->type) {
if (tempg0->type!=tempg1->type)
throw(EXCEPT_GRAPHICS,4);
switch (tempg0->type) {
case GRST_ROTATED_RECT:
tempgr->rot_angle=(tempg0->rot_angle*t0+tempg1->rot_angle*t1)/gr_scale;
case GRST_RECT:
case GRST_LINE:
case GRST_ARROW:
case GRST_PLANAR_SYMMETRY:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
case GRST_TEXT:
case GRST_TEXT_BOX:
case GRST_TEXT_DIAMOND:
case GRST_PT:
case GRST_FLOOD_FILL:
case GRST_FLOOD_FILL_NOT:
case GRST_SHIFT:
tempgr->x1=(tempg0->x1*t0+tempg1->x1*t1)>>32;
tempgr->y1=(tempg0->y1*t0+tempg1->y1*t1)>>32;
break;
case GRST_CIRCLE:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->x1=(tempg0->x1*t0+tempg1->x1*t1)>>32;
tempgr->y1=(tempg0->y1*t0+tempg1->y1*t1)>>32;
break;
case GRST_ELLIPSE:
case GRST_REG_POLY:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
tempgr->width=(tempg0->width*t0+tempg1->width*t1)>>32;
tempgr->height=(tempg0->height*t0+tempg1->height*t1)>>32;
break;
case GRST_BITMAP8:
tempgr->x2=(tempg0->x2*t0+tempg1->x2*t1)>>32;
tempgr->y2=(tempg0->y2*t0+tempg1->y2*t1)>>32;
break;
case GRST_POLYLINE:
ptr0=&tempg0->y1;
ptr1=&tempg1->y1;
ptrr=&tempgr->y1;
for (i=0;i<tempg0->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 GRST_POLYPT:
ptr0=&tempg0->y1;
ptr1=&tempg1->y1;
ptrr=&tempgr->y1;
ptrr[0]=(ptr0[0]*t0+ptr1[0]*t1)>>32;
ptrr[1]=(ptr0[1]*t0+ptr1[1]*t1)>>32;
break;
case GRST_BSPLINE2:
case GRST_BSPLINE3:
case GRST_BSPLINE2_CLOSED:
case GRST_BSPLINE3_CLOSED:
p0=&tempg0->y1;
p1=&tempg1->y1;
pr=&tempgr->y1;
for (i=0;i<tempg0->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 GRST_MESH:
p0=&tempg0->x2;
p1=&tempg1->x2;
pr=&tempgr->x2;
for (i=0;i<tempg0->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 GRST_SHIFTABLE_MESH:
p0=(&tempg0->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
p1=(&tempg1->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
pr=(&tempgr->shiftable_triangle_cnt)(U8 *)+sizeof(I32);
for (i=0;i<tempg0->shiftable_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;
}
i=SpriteElemSize(tempg0);
tempg0(U8 *)+=i;
tempg1(U8 *)+=i;
tempgr(U8 *)+=i;
}
return result;
}
#help_index "Graphics/CSprite;Doc/Output"
public CDocEntry *DocPutSprite(CDoc *doc=NULL,U8 *elems,U8 *txt=NULL)
{
I64 size;
U8 *st;
Bool unlock;
CDocEntry *doc_e;
CDocBin *tempb;
if (!doc && !(doc=DocCur)) return NULL;
unlock=DocLock(doc);
size=SpriteSize(elems);
tempb=CAlloc(sizeof(CDocBin),doc->mem_task);
tempb->type=DOCBT_CSPRITE;
tempb->size=size;
tempb->data=MAlloc(size,doc->mem_task);
MemCpy(tempb->data,elems,size);
tempb->num=doc->cur_bin_num;
tempb->use_cnt=1;
QueIns(tempb,doc->bin_root.last);
if (txt)
st=MSPrintF(txt,doc->cur_bin_num++);
else
st=MSPrintF("$$SP,\"\",%d$$",doc->cur_bin_num++);
doc_e=DocPutS(doc,st);
Free(st);
doc_e->bin_data=tempb;
if (doc_e && Bt(doc_tag_types,doc_e->type_u8) && doc_e->tag && *doc_e->tag)
tempb->tag=StrNew(doc_e->tag,doc->mem_task);
if (unlock)
DocUnlock(doc);
return doc_e;
}
public CDocEntry *PutSprite(U8 *elems,U8 *txt=NULL)
{
//If you set txt,
//then include dollarsigns ("$$SP ...$$")
//and leave a %d for the number.
CDoc *doc;
if (doc=DocCur)
return DocPutSprite(doc,elems,txt);
return NULL;
}
+486
View File
@@ -0,0 +1,486 @@
#help_index "Graphics/CGrVectMap"
/*
This processes a monocrome map, finds edges and generates vect graphic
representations of the map broken into small rectangles. The rectangles
are encoded a bit-oriented structure.
PolyLineStruct {
1 Bit : set is valid polyline, clear is end of polyline lst
(R_BITS) : X-coordinate of polyline start
(R_BITS) : Y-coordinate of polyline start
(poly_line_cnt_bits): Number of polyline direction entries
N*3 : N-long seq of 1 pixel directional movements
}
FloodFillStruct {
1 Bit : set is valid flood fill entry, clear is end of floodfill lst
(1+R_BITS): X-coordinate*2 of flood fill (half pixels)
(1+R_BITS): Y-coordinate*2 of flood fill (half pixels)
}
Rect {
1 Bit : set is valid rectangle entry, clear is end of rectangle lst
PolyLineStructLst
FloodFillStructLst
}
*/
#define R_BITS 6
#define R_BORDER 1
#define R_WIDTH (1<<R_BITS-2*R_BORDER)
#define R_HEIGHT (1<<R_BITS-2*R_BORDER)
U0 VectMapBlotRect(CDC *dc,CGrVectMap *vm,I64 bit,F64 scale)
{
I64 k,cnt,i0,j0,i,j,rect_dft,not_rect_dft;
U8 *body=vm->body;
F64 d=scale/2;
dc->pen_width=scale+0.5;
dc->color=rect_dft=Bt(body,bit++);
not_rect_dft=1-rect_dft;
dc->bkcolor=vm->bkcolor;
GrRect(dc,0,0,dc->width,dc->height);
dc->color=not_rect_dft;
while (Bt(body,bit++)) {
j=BFieldExtU32(body,bit,R_BITS);
bit+=R_BITS;
i=BFieldExtU32(body,bit,R_BITS);
bit+=R_BITS;
cnt=BFieldExtU32(body,bit,vm->poly_line_cnt_bits);
bit+=vm->poly_line_cnt_bits;
if (!cnt)
GrPlot3(dc,(j-R_BORDER)*scale+d,(i-R_BORDER)*scale+d,0);
else {
i0=i;j0=j;
while (cnt--) {
k=BFieldExtU32(body,bit,3);
bit+=3;
i+=gr_y_offsets[k];
j+=gr_x_offsets[k];
GrLine3(dc,(j0-R_BORDER)*scale+d,(i0-R_BORDER)*scale+d,0,
(j-R_BORDER)*scale+d,(i-R_BORDER)*scale+d,0);
i0=i; j0=j;
}
}
}
while (Bt(body,bit++)) {
j=BFieldExtU32(body,bit,R_BITS+1);
bit+=R_BITS+1;
i=BFieldExtU32(body,bit,R_BITS+1);
bit+=R_BITS+1;
if (GrPeek(dc,(j/2.0-R_BORDER)*scale+d,(i/2.0-R_BORDER)*scale+d)==rect_dft)
GrFloodFill(dc,(j/2.0-R_BORDER)*scale+d,(i/2.0-R_BORDER)*scale+d);
}
}
class CMPVMBlot
{
CDC *dc,*rect_dc;
CGrVectMap *vm;
I64 bit;
I64 xx,yy;
F64 scale;
I64 busy;
};
U0 VectMapBlotRectMP(CMPVMBlot *mp)
{
VectMapBlotRect(mp->rect_dc,mp->vm,mp->bit,mp->scale);
GrBlot(mp->dc,mp->xx,mp->yy,mp->rect_dc);
mp->busy=FALSE;
}
public U0 VectMapBlotMP(CDC *dc,I64 x,I64 y,CGrVectMap *vm,F64 scale=1.0,I64 _mp_cnt=0)
{
I64 i,i_lo,i_hi,j,j_lo,j_hi,k,cpu,pass,
w=(vm->width +R_WIDTH-1)/R_WIDTH,
h=(vm->height+R_HEIGHT-1)/R_HEIGHT;
F64 xx,yy,r_scale=scale*(R_WIDTH+1.0/scale)/R_WIDTH;
CMPVMBlot *mp;
if (!dc || !vm) return;
if (Gs->num)
_mp_cnt=1; //Only core #0 can be master
else if (!_mp_cnt)
_mp_cnt=mp_cnt;
else if (_mp_cnt>mp_cnt)
_mp_cnt=mp_cnt;
cpu=_mp_cnt-1;
mp=MAlloc(_mp_cnt*sizeof(CMPVMBlot));
for (i=0;i<_mp_cnt;i++) {
mp[i].rect_dc=DCNew(DCT_COLOR8,R_WIDTH*r_scale,R_HEIGHT*r_scale,Fs);
mp[i].dc=DCAlias(dc,dc->win_task);
mp[i].dc->color=dc->color;
mp[i].vm=vm;
mp[i].scale=r_scale;
mp[i].busy=FALSE;
}
if (y<0)
i_lo=-y/(R_HEIGHT*scale);
else
i_lo=0;
if (R_HEIGHT*scale*h+y>dc->height)
i_hi=MinI64((dc->height-y)/(R_HEIGHT*scale)+1,h);
else
i_hi=h;
if (x<0)
j_lo=-x/(R_WIDTH*scale);
else
j_lo=0;
if (R_WIDTH*scale*w+x>dc->width)
j_hi=MinI64((dc->width-x)/(R_WIDTH*scale)+1,w);
else
j_hi=w;
xx=x+j_lo*R_WIDTH*scale;
for (j=j_lo;j<j_hi;j++) {
yy=y+i_lo*R_WIDTH*scale;
k=i_lo*w+j;
for (i=i_lo;i<i_hi;i++) {
if (_mp_cnt>1) {
pass=0;
//Does up to two passes
while (TRUE)
if (!pass && !cpu) {
pass++;
cpu=_mp_cnt-1;
} else if (mp[cpu].busy) //by the way, core #0 is never busy
cpu--;
else
break;
}
mp[cpu].xx=xx;
mp[cpu].yy=yy;
mp[cpu].bit=vm->rect_start_bits[k];
if (!cpu)
VectMapBlotRectMP(mp);
else {
mp[cpu].busy=TRUE;
MPJob(&VectMapBlotRectMP,&mp[cpu],cpu);
}
k+=w;
yy+=R_HEIGHT*scale;
}
xx+=R_WIDTH*scale;
}
for (i=_mp_cnt-1;i>=0;i--) {
while(mp[i].busy)
Yield;
DCDel(mp[i].rect_dc);
DCDel(mp[i].dc);
}
Free(mp);
}
Bool IsSolidSquare(CDC *dc,I64 x,I64 y,I64 edge,CColorROPU32 color)
{
I64 i,j;
edge>>=1;
for (i=-edge;i<edge;i++)
for (j=-edge;j<edge;j++)
if (GrPeek(dc,x+j,y+i)!=color)
return FALSE;
return TRUE;
}
I64 VectizeRect(CDC *dc,I64 _x,I64 _y,CGrVectMap *vm,I64 _bit,
I64 poly_line_cnt_bits,I64 *_max_poly_line_cnt_bits)
{ //Returns number of bits to represent rect
CDC *b_desired =DCExtract(dc,_x-R_BORDER,_y-R_BORDER,_x+R_WIDTH+R_BORDER*2-1,_y+R_BORDER*2+R_HEIGHT-1),
*b_edge=DCNew(DCT_COLOR8,R_WIDTH+R_BORDER*2,R_HEIGHT+R_BORDER*2,Fs),
*b_actual,
*b_link_check=DCNew(DCT_COLOR8,R_WIDTH+R_BORDER*2,R_HEIGHT+R_BORDER*2,Fs);
I64 step,step_bits,x,y,xx,yy,xx1,yy1,xx2,yy2,cnt=0,k,kk,rect_dft,not_rect_dft,
cnt_bit,link_bit1,link_bit2,link_bit_limit,bit=_bit,max_poly_line_cnt_bits;
U8 *body=vm->body;
Bool found;
if (_max_poly_line_cnt_bits)
max_poly_line_cnt_bits=*_max_poly_line_cnt_bits;
else
max_poly_line_cnt_bits=3;
//Count ON pixels
for (y=0;y<R_HEIGHT;y++)
for (x=0;x<R_WIDTH;x++)
if (GrPeek(b_desired,R_BORDER+x,R_BORDER+y)==1)
cnt++;
if (cnt>=R_WIDTH*R_HEIGHT/2)
rect_dft=1;
else
rect_dft=0;
not_rect_dft=1-rect_dft;
BEqu(body,bit++,rect_dft);
if (!cnt || cnt==R_WIDTH*R_HEIGHT) {
//Rect is all ON or OFF
Btr(body,bit++); //End of poly-line lst
Btr(body,bit++); //End of flood-fill lst
} else {
for (y=0;y<R_HEIGHT+R_BORDER*2;y++)
for (x=0;x<R_WIDTH+R_BORDER*2;x++) {
b_edge->color=0;
if (GrPeek(b_desired,x,y)==not_rect_dft)
for (k=0;k<8;k++)
if (GrPeek(b_desired,x+gr_x_offsets[k],y+gr_y_offsets[k])==rect_dft)
b_edge->color=1;
GrPlot(b_edge,x,y);
}
b_edge->color=0;
link_bit1=bit;
for (y=0;y<R_HEIGHT+R_BORDER*2;y++)
for (x=0;x<R_WIDTH+R_BORDER*2;x++)
if (GrPeek(b_edge,x,y)==1) {
Bts(body,bit++); //Show not end of poly-line lst
GrPlot(b_edge,x,y);
BFieldOrU32(body,bit,x); //Poly-line starting X coordinate in rect
bit+=R_BITS;
BFieldOrU32(body,bit,y); //Poly-line starting Y coordinate in rect
bit+=R_BITS;
yy=y; xx=x;
cnt_bit=bit;
bit+=poly_line_cnt_bits; //Reserve space for count of direction offsets in poly-line
cnt=0;
do {
found=FALSE;
for (k=0;k<8;k++) {
yy2=yy+gr_y_offsets[k];
xx2=xx+gr_x_offsets[k];
if (0<=xx2<R_WIDTH+R_BORDER*2 &&
0<=yy2<R_HEIGHT+R_BORDER*2 &&
GrPeek(b_edge,xx2,yy2)==1) {
cnt++;
BFieldOrU32(body,bit,k); //3-bit (or 2) incoding of direction movement
bit+=3;
GrPlot(b_edge,xx2,yy2);
yy=yy2; xx=xx2;
found=TRUE;
break;
}
}
} while (found);
BFieldOrU32(body,cnt_bit,cnt);
if (cnt && Bsr(cnt)+1>max_poly_line_cnt_bits)
max_poly_line_cnt_bits=Bsr(cnt)+1;
}
//Connect adjacent groups with link to prevent flood-fill leaks.
link_bit_limit=bit;
while (link_bit1<link_bit_limit) {
link_bit1++;
x=BFieldExtU32(body,link_bit1,R_BITS);
link_bit1+=R_BITS;
y=BFieldExtU32(body,link_bit1,R_BITS);
link_bit1+=R_BITS;
link_bit2=link_bit1;
yy=y;xx=x;
cnt=BFieldExtU32(body,link_bit2,poly_line_cnt_bits);
link_bit2+=poly_line_cnt_bits;
while (TRUE) {
for (k=0;k<8;k++) {
yy2=yy+gr_y_offsets[k];
xx2=xx+gr_x_offsets[k];
if (0<=xx2<R_WIDTH+R_BORDER*2 &&
0<=yy2<R_HEIGHT+R_BORDER*2 &&
GrPeek(b_link_check,xx2,yy2)==1) {
Bts(body,bit++);
BFieldOrU32(body,bit,xx);
bit+=R_BITS;
BFieldOrU32(body,bit,yy);
bit+=R_BITS;
BFieldOrU32(body,bit,1);
bit+=poly_line_cnt_bits;
BFieldOrU32(body,bit,k);
bit+=3;
}
}
if (!cnt--)
break;
kk=BFieldExtU32(body,link_bit2,3);
link_bit2+=3;
yy+=gr_y_offsets[kk];
xx+=gr_x_offsets[kk];
}
link_bit2=link_bit1;
yy=y;xx=x;
b_link_check->color=1;
GrPlot(b_link_check,xx,yy);
cnt=BFieldExtU32(body,link_bit2,poly_line_cnt_bits);
link_bit2+=poly_line_cnt_bits;
while (cnt--) {
kk=BFieldExtU32(body,link_bit2,3);
link_bit2+=3;
yy+=gr_y_offsets[kk];
xx+=gr_x_offsets[kk];
GrPlot(b_link_check,xx,yy);
}
link_bit1=link_bit2;
}
Btr(body,bit++); //End of poly-line lst
b_desired->color=rect_dft;
GrLineRect4(b_desired,0,0,R_WIDTH+2*R_BORDER-1,R_HEIGHT+2*R_BORDER-1);
Btr(body,bit); //Temp end of flood-fill lst
for (step_bits=2;step_bits>=1;step_bits-=1) {
step=1<<step_bits;
b_actual=DCNew(DCT_COLOR8,R_WIDTH/step,R_HEIGHT/step,Fs);
VectMapBlotRect(b_actual,vm,_bit,1.0/step);
b_actual->color=not_rect_dft;
GrLineRect4(b_actual,0,0,R_WIDTH+2*R_BORDER-1,R_HEIGHT+2*R_BORDER-1);
//Flood fill
for (y=R_BORDER;y<R_HEIGHT+R_BORDER;y+=step)
for (x=R_BORDER;x<R_WIDTH+R_BORDER;x+=step)
if (IsSolidSquare(b_desired,x,y,step,not_rect_dft) && GrPeek(b_actual,x>>step_bits,y>>step_bits)==rect_dft) {
Bts(body,bit++); //Show not end of flood-fill lst
yy=y; xx=x;
for (k=0;k<4;k++) {
yy2=yy;
while (yy2<R_HEIGHT+R_BORDER-1 &&
IsSolidSquare(b_desired,xx,yy2,step,not_rect_dft) && GrPeek(b_actual,xx>>step_bits,yy2>>step_bits)==rect_dft)
yy2++;
while (yy>R_BORDER &&
IsSolidSquare(b_desired,xx,yy,step,not_rect_dft) && GrPeek(b_actual,xx>>step_bits,yy>>step_bits)==rect_dft)
yy--;
yy1=yy+yy2;
yy=yy1/2;
xx2=xx;
while (xx2<R_WIDTH+R_BORDER-1 &&
IsSolidSquare(b_desired,xx2,yy,step,not_rect_dft) && GrPeek(b_actual,xx2>>step_bits,yy>>step_bits)==rect_dft)
xx2++;
while (xx>R_BORDER &&
IsSolidSquare(b_desired,xx,yy,step,not_rect_dft) && GrPeek(b_actual,xx>>step_bits,yy>>step_bits)==rect_dft)
xx--;
xx1=xx+xx2;
xx=xx1/2;
}
GrFloodFill(b_actual,xx>>step_bits,yy>>step_bits);
BFieldOrU32(body,bit,xx1); //Flood fill X-coordinate in rect
bit+=R_BITS+1;
BFieldOrU32(body,bit,yy1); //Flood fill Y-coordinate in rect
bit+=R_BITS+1;
}
DCDel(b_actual);
Btr(body,bit); //Temp end of flood-fill lst
}
bit++; //End of flood-fill lst
}
DCDel(b_desired);
DCDel(b_edge);
DCDel(b_link_check);
if (_max_poly_line_cnt_bits) *_max_poly_line_cnt_bits=max_poly_line_cnt_bits;
return bit-_bit;
}
#define TEMP_BODY_SIZE 0x10000
public CGrVectMap *DC2VectMap(CDC *dc,CTask *mem_task=NULL,I64 *_size=NULL)
{ //Currently does not convert outer 1 pixel border
I64 i,j,k,cnt,size,
w=(dc->width-R_BORDER*2+R_WIDTH-1)/R_WIDTH,
h=(dc->height-R_BORDER*2+R_HEIGHT-1)/R_HEIGHT,
rect_cnt=w*h,poly_line_cnt_bits=12,max_poly_line_cnt_bits=3;
U32 *rect_start_bits;
U8 *body;
CGrVectMap *result,tempv;
body=MAlloc(TEMP_BODY_SIZE);
//Pass 1: Get max_poly_line_cnt_bits
for (i=0;i<h;i++)
for (j=0;j<w;j++) {
MemSet(&tempv,0,sizeof(CGrVectMap));
MemSet(body,0,TEMP_BODY_SIZE);
tempv.width =dc->width-R_BORDER*2;
tempv.height=dc->height-R_BORDER*2;
tempv.body=body;
tempv.rect_cnt=rect_cnt;
tempv.r_bits=R_BITS;
tempv.poly_line_cnt_bits=poly_line_cnt_bits;
VectizeRect(dc,R_BORDER+j*R_WIDTH,R_BORDER+i*R_HEIGHT,&tempv,0,poly_line_cnt_bits,&max_poly_line_cnt_bits);
}
//Pass 2: Get cnt
poly_line_cnt_bits=max_poly_line_cnt_bits;
cnt=0;
for (i=0;i<h;i++)
for (j=0;j<w;j++) {
MemSet(&tempv,0,sizeof(CGrVectMap));
MemSet(body,0,TEMP_BODY_SIZE);
tempv.width =dc->width-R_BORDER*2;
tempv.height=dc->height-R_BORDER*2;
tempv.body=body;
tempv.rect_cnt=rect_cnt;
tempv.r_bits=R_BITS;
tempv.poly_line_cnt_bits=poly_line_cnt_bits;
cnt+=VectizeRect(dc,R_BORDER+j*R_WIDTH,R_BORDER+i*R_HEIGHT,&tempv,0,poly_line_cnt_bits,NULL);
}
Free(body);
//Pass 3
size=(cnt+7)/8;
result=CAlloc(sizeof(CGrVectMap),mem_task);
result->body=CAlloc(size,mem_task);
rect_start_bits=MAlloc((rect_cnt+1)*sizeof(U32),mem_task);
result->width =dc->width-R_BORDER*2;
result->height=dc->height-R_BORDER*2;
result->rect_cnt=rect_cnt;
result->r_bits=R_BITS;
result->poly_line_cnt_bits=poly_line_cnt_bits;
result->rect_start_bits=rect_start_bits;
k=0;
cnt=0;
for (i=0;i<h;i++)
for (j=0;j<w;j++) {
rect_start_bits[k++]=cnt;
cnt+=VectizeRect(dc,R_BORDER+j*R_WIDTH,R_BORDER+i*R_HEIGHT,result,cnt,poly_line_cnt_bits,NULL);
}
rect_start_bits[k]=cnt;
if (_size) *_size=size;
return result;
}
public U0 VectMapDel(CGrVectMap *vm)
{
Free(vm->rect_start_bits);
Free(vm->body);
Free(vm);
}
U32 *VectMapRectStartBits(CGrVectMap *vm,CTask *mem_task=NULL)
{
I64 k=0,bit=0;
U8 *body=vm->body;
U32 *result=MAlloc((vm->rect_cnt+1)*sizeof(U32),mem_task);
for (k=0;k<vm->rect_cnt;k++) {
result[k]=bit++;
while (Bt(body,bit++)) {
bit+=2*R_BITS;
bit+=vm->poly_line_cnt_bits+3*BFieldExtU32(body,bit,vm->poly_line_cnt_bits);
}
while (Bt(body,bit++))
bit+=2*(R_BITS+1);
}
result[k]=bit;
return result;
}
File diff suppressed because it is too large. Load diff
+261
View File
@@ -0,0 +1,261 @@
#help_index "Utils;Cmd Line (Typically)"
#define GRF_REPLACE 0
#define GRF_SKIP 1
#define GRF_ALL 2
#define GRF_ED 3
#define GRF_ABORT_FILE 4
#define GRF_SKIP_FILE 5
I64 PopUpReplaceSkipAllCancelEd(U8 *msg)
{
I64 i;
CDoc *doc=DocNew;
DocPutS(doc,msg);
DocPutS(doc,"$$CM+LX,2,4$$$$BT,\"REPLACE\",GRF_REPLACE$$"
"$$CM+LX,22,0$$$$BT,\"SKIP\",GRF_SKIP$$"
"$$CM+LX,2,4$$$$BT,\"ALL\",GRF_ALL$$"
"$$CM+LX,22,0$$$$BT,\"ABORT ALL\",DOCM_CANCEL$$"
"$$CM+LX,2,4$$$$BT,\"EDIT\",GRF_ED$$"
"$$CM+LX,22,0$$$$BT,\"ABORT FILE\",GRF_ABORT_FILE$$"
"$$CM+LX,2,4$$$$BT,\"SKIP FILE\",GRF_SKIP_FILE$$\n");
i=PopUpMenu(doc);
DocDel(doc);
return i;
}
I64 GrepFile(U8 *pattern,U8 *name,I64 *_fuf_flags,U8 *replace_text)
{
Bool first_on_line,write_this_file=FALSE,cont=!Bt(_fuf_flags,FUf_CANCEL);
U8 *src,*dst,*dst2,*name_buf=NULL;
I64 i,j,plen,rlen,dlen,cnt=0,old_flags,ss_flags;
CDoc *cur_l,*doc=DocRead(name,DOCF_PLAIN_TEXT_WITH_TABS|DOCF_NO_CURSOR);
CDocEntry *doc_e;
ss_flags=Bt(_fuf_flags,FUf_IGNORE) ? SRF_IGNORE_CASE :0;
if (Bt(_fuf_flags,FUf_WHOLE_LABELS))
ss_flags|=SRG_WHOLE_LABELS;
if (Bt(_fuf_flags,FUf_WHOLE_LABELS_FRONT))
ss_flags|=SRF_WHOLE_LABELS_FRONT;
if (Bt(_fuf_flags,FUf_WHOLE_LABELS_BACK))
ss_flags|=SRF_WHOLE_LABELS_BACK;
plen=StrLen(pattern);
if (replace_text)
rlen=StrLen(replace_text);
doc_e=doc->root.next;
while (doc_e!=doc && cont) {
if (doc_e->type_u8==DOCT_TEXT) {
src=doc_e->tag;
first_on_line=TRUE;
while (src && cont) {
if (src=SearchStr(src,pattern,ss_flags)) {
cnt++;
if (first_on_line || Bt(_fuf_flags,FUf_REPLACE)) {
first_on_line=FALSE;
PutFileLink(name,doc_e->y+1,TRUE);
name_buf=MSPrintF("%s,%d",name,doc_e->y+1);
if (cur_l=DocCur) {
old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
cur_l->flags|=DOCF_PLAIN_TEXT;
}
" %s\n",doc_e->tag;
if (cur_l)
cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
}
if (Bt(_fuf_flags,FUf_REPLACE)) {
if (Bt(_fuf_flags,FUf_ALL))
i=GRF_ALL;
else {
i=PopUpReplaceSkipAllCancelEd("");
if (i<0) {
LBts(_fuf_flags,FUf_CANCEL);
cont=FALSE;
write_this_file=FALSE;
} else if (i==GRF_ALL)
LBts(_fuf_flags,FUf_ALL);
else if (i==GRF_ABORT_FILE) {
cont=FALSE;
write_this_file=FALSE;
} else if (i==GRF_SKIP_FILE)
cont=FALSE;
}
if (i==GRF_REPLACE || i==GRF_ALL) {
dlen=StrLen(doc_e->tag);
dst=MAlloc(dlen+1+rlen-plen);
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++=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;
if (cur_l=DocCur) {
old_flags=cur_l->flags&DOCF_PLAIN_TEXT;
cur_l->flags|=DOCF_PLAIN_TEXT;
}
"%12s,%04d*%s\n",name,doc_e->y+1,dst2;
if (cur_l)
cur_l->flags= cur_l->flags&~DOCF_PLAIN_TEXT |old_flags;
write_this_file=TRUE;
} else {
src++;
if (i==GRF_ED) {
Free(name_buf);
name_buf=StrNew(doc->filename.name);
doc->flags&=~DOCF_NO_CURSOR;
doc->cur_entry=doc_e;
doc->cur_data_col=doc_e->min_col;
DocWrite(doc);
DocDel(doc);
"Wrote:%s\n",name_buf;
Ed(name_buf);
doc=DocRead(name_buf, DOCF_PLAIN_TEXT_WITH_TABS);
doc_e=doc->cur_entry;
if (doc_e->last!=doc) doc_e=doc_e->last;
src=NULL;
write_this_file=FALSE;
}
}
} else
src++;
Free(name_buf);
name_buf=NULL;
}
}
}
doc_e=doc_e->next;
}
if (write_this_file) {
DocWrite(doc);
"Wrote:%s\n",doc->filename.name;
}
DocDel(doc);
return cnt;
}
I64 GrepLst(U8 *pattern,CDirEntry *tempm1,I64 *_fuf_flags,U8 *replace_text)
{
I64 cnt=0;
CDirEntry *tempm2;
while (tempm1 && !Bt(_fuf_flags,FUf_CANCEL)) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub) {
"%S %s\n","ST_SCANNING_DIR",tempm1->full_name;
cnt+=GrepLst(pattern,tempm1->sub,_fuf_flags,replace_text);
}
} else
cnt+=GrepFile(pattern,tempm1->full_name,_fuf_flags,replace_text);
CDirEntryDel(tempm1);
tempm1=tempm2;
}
return cnt;
}
public I64 Grep(U8 *pattern,U8 *files_find_mask=FILENAME_MASK_TXT,U8 *fu_flags=NULL,U8 *replace_text=NULL)
/*
This does not do regular expressions--my bad.
Anyway, it's good for searching and replacing.
Let's say it stands for global replace ;-)
"+r"=recurse
"+i"=ignore case
"+l"=whole labels only.
This will check for a nonlabel character before
and after. If you have a var, "doc_e" and don't
want to match words like "will" and "wallow", you
set this flag and it will see that the characters
before or after "doc_e" are label characters.
*/
{
I64 cnt=0,fuf_flags=0;
CDirEntry *tempm;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+i"); //Set dft flags
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (fuf_flags&~(FUG_FILES_FIND|FUF_IGNORE|FUF_WHOLE_LABELS|FUF_WHOLE_LABELS_FRONT|FUF_WHOLE_LABELS_BACK))
throw(EXCEPT_FUF,1);
LBEqu(&fuf_flags,FUf_REPLACE,replace_text);
tempm=FilesFind(files_find_mask,fuf_flags&FUG_FILES_FIND);
fuf_flags&=FUF_REPLACE|FUF_IGNORE|FUF_WHOLE_LABELS|FUF_WHOLE_LABELS_FRONT|FUF_WHOLE_LABELS_BACK;
cnt+=GrepLst(pattern,tempm,&fuf_flags,replace_text);
return cnt;
}
public I64 FileOcc(U8 *pattern,U8 *files_find_mask=FILENAME_MASK_TXT,U8 *fu_flags="+r+i+l")
{/*
"+r"=recurse
"+i"=ignore case
"+l"=whole labels only.
*/
I64 cnt=0;
Bool old_silent=Silent(TRUE);
cnt=Grep(pattern,files_find_mask,fu_flags);
Silent(old_silent);
return cnt;
}
class CGrep
{
U8 find_text[136] fmtstr "$$DA-P,135,\"FIND :%s\"$$\n";
U8 replace_text[136] fmtstr "$$DA-P,135,\"REPLACE :%s\"$$\n";
Bool replace fmtstr "$$CB,\"REPLACE\"$$\n";
Bool match_case fmtstr "$$CB,\"MATCH CASE\"$$\n";
Bool whole_labels fmtstr "$$CB,\"WHOLE LABELS\"$$\n";
U8 filemask[136] fmtstr "$$DA-P,135,\"FILE MASK :%s\"$$\n";
Bool recurse fmtstr "$$CB,\"RECURSE\"$$\n";
};
I64 GrepWiz()
{
CDoc *doc;
U8 buf[32],*dir,*st;
CGrep *g=CAlloc(sizeof(CGrep));
I64 result=0;
g->recurse=TRUE;
StrCpy(g->filemask,FILENAME_MASK_TXT);
if (doc=DocCur) {
StrCpy(g->find_text,doc->find_replace->find_text);
StrCpy(g->replace_text,doc->find_replace->replace_text);
g->replace=doc->find_replace->replace;
g->match_case=doc->find_replace->match_case;
g->whole_labels=doc->find_replace->whole_labels;
}
if (DocFormDo(g,"CGrep",0,"$$FG,PURPLE$$$$TX+CX,\"Grep\"$$\n$$FG$$")) {
if (doc) {
StrCpy(doc->find_replace->find_text,g->find_text);
StrCpy(doc->find_replace->replace_text,g->replace_text);
doc->find_replace->replace=g->replace;
doc->find_replace->match_case=g->match_case;
doc->find_replace->whole_labels=g->whole_labels;
}
dir=PopUpPickDir;
if (*dir) {
*buf=0;
if (g->match_case)
StrCat(buf,"-i");
if (!g->recurse)
StrCat(buf,"-r");
if (g->whole_labels)
StrCat(buf,"+l");
if (g->replace)
st=MSPrintF("\"$$$$WW+H,1$$$$\";Cd(\"%s\");Grep(\"%Q\",\"%Q\",\"%Q\",\"%Q\");UserTaskCont;",dir,g->find_text,g->filemask,buf,g->replace_text);
else
st=MSPrintF("\"$$$$WW+H,1$$$$\";Cd(\"%s\");Grep(\"%Q\",\"%Q\",\"%Q\");UserTaskCont;",dir,g->find_text,g->filemask,buf);
result=PopUp(st);
}
Free(dir);
}
Free(g);
return result;
}
#help_index ""
+546
View File
@@ -0,0 +1,546 @@
#help_index "Hash"
public I64 HashVal(CHash *temph)
{
nobound_switch (HashTypeNum(temph)) {
case HTt_EXPORT_SYS_SYM:
return temph(CHashExport *)->val;
case HTt_IMPORT_SYS_SYM:
return temph(CHashImport *)->module_base;
case HTt_DEFINE_STR:
case HTt_CLASS:
case HTt_INTERNAL_TYPE:
case HTt_WORD:
case HTt_DICT_WORD:
case HTt_OPCODE:
case HTt_HELP_FILE:
return temph;
case HTt_GLBL_VAR:
if (temph(CHashGlblVar *)->flags&GVAF_EXTERN)
return &temph(CHashGlblVar *)->data_addr;
else
return temph(CHashGlblVar *)->data_addr;
case HTt_FUN:
if (Bt(temph(CHashFun *)->flags,Cf_EXTERN))
return temph;
else
return temph(CHashFun *)->executable_addr;
case HTt_REG:
return temph(CHashReg *)->reg_num|temph(CHashReg *)->reg_type<<8;
case HTt_KEYWORD:
case HTt_ASM_KEYWORD:
case HTt_MODULE:
case HTt_FILE:
case HTt_NAMED_FRAME_PTR:
return temph(CHashGeneric *)->user_data0;
case -1: //nobound_switch
case HTt_NUM_TYPES: //nobound_switch
default:
return 0;
}
}
#help_index "Info;Hash/Reports;"
class CHashRep
{
CHashGeneric *h;
U8 *index;
};
I64 HashEntriesCompare(CHashRep *h1,CHashRep *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(CHashRep *h1,CHashRep *h2)
{
CHashFun *tempf1=h1->h,*tempf2=h2->h;
I64 i1=HashVal(tempf1),i2=HashVal(tempf2);
if (i1==i2) {
i1=HashTypeNum(tempf1);
i2=HashTypeNum(tempf2);
if (i1==i2)
return StrCmp(tempf1->str,tempf2->str);
}
return i1-i2;
}
I64 HelpIndexCnt(U8 *ptr,U8 *index)
{
U8 cnt=0,ch;
I64 index_len=StrLen(index);
while (*ptr) {
if (!StrNCmp(ptr,index,index_len))
cnt++;
while (ch=*ptr++)
if (ch==';')
break;
if (!ch)
ptr--;
}
return cnt;
}
U8 *HelpIndexStr(U8 **ptr_,U8 *index)
{
U8 *ptr=*ptr_,*ptr2,ch,*result;
I64 index_len=StrLen(index);
while (*ptr) {
ptr2=ptr;
while (ch=*ptr++)
if (ch==';')
break;
if (!ch)
ptr--;
*ptr_=ptr;
if (!StrNCmp(ptr2,index,index_len)) {
if (ch==';')
ptr--;
*ptr=0;
result=StrNew(ptr2);
*ptr=ch;
return result;
}
}
return NULL;
}
I64 HashEntriesCompare3(CHashRep *h1,CHashRep *h2)
{
I64 i,i1=0,i2=0;
i=StrCmp(h1->index,h2->index);
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);
}
}
//Possible choices for first arg, "h" include
// "adam_task->hash_table"
// "Fs->hash_table"
public U0 HashRep(CHashTable *h=NULL,
I64 mask=HTG_ALL,U8 *outname=NULL,U8 *flags=NULL,U8 mapfile_drv=0,U8 *index=NULL,
CDoc *_doc=NULL)
{
CHashTable *tempht;
CHashSrcSym *temph;
CHashGeneric *ptr;
CHashRep *lst;
I64 cnt,i,j,k,size,f=0,
dbg_bin_num,indent_bin_num;
U8 buf[512],*buf4,*last_index=StrNew(""),*cur_index;
CDoc *doc,*doc1;
Bool recurse,publics,map,old_preempt=Preempt(OFF);
CDocBin *tempb;
CDbgInfo *dbg;
CIndentInfo *indent;
GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),"+r+p");
GetFFlags(&f,Define("ST_FILE_UTIL_FLAGS"),flags);
if (f&~(FUF_RECURSE|FUF_PUBLIC|FUF_MAP))
throw(EXCEPT_FUF,2);
recurse=Bt(&f,FUf_RECURSE);
publics=Bt(&f,FUf_PUBLIC);
map =Bt(&f,FUf_MAP);
if (!h) h=Fs->hash_table;
if (_doc)
doc=_doc;
else if (outname) {
doc=DocNew;
doc->flags|=DOCF_NO_CURSOR;
StrCpy(doc->filename.name,outname);
} else
doc=NULL;
cnt=0;
tempht=h;
while (tempht) {
temph=tempht->next_added;
while (temph!=tempht) {
if (!(temph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
temph->type & mask &&
(temph->type & HTF_PUBLIC || !publics))
if (!index)
cnt++;
else
if (temph->type&HTG_SRC_SYM &&
(cur_index=temph->index))
cnt+=HelpIndexCnt(cur_index,index);
temph=temph->next_added;
}
if (recurse)
tempht=tempht->next;
else
break;
}
if (!cnt) goto end_hash;
lst=CAlloc(cnt*sizeof(CHashRep));
j=0;
tempht=h;
while (tempht) {
temph=tempht->next_added;
while (temph!=tempht) {
if (!(temph->type & (HTF_IMPORT | HTF_PRIVATE)) &&
temph->type & mask &&
(temph->type & HTF_PUBLIC || !publics))
if (!index)
lst[j++].h=temph;
else
if (temph->type&HTG_SRC_SYM &&
(cur_index=temph->index))
if (k=HelpIndexCnt(cur_index,index)) {
while (k--) {
lst[j].index=HelpIndexStr(&cur_index,index);
lst[j++].h=temph;
}
}
temph=temph->next_added;
}
if (recurse)
tempht=tempht->next;
else
break;
}
Preempt(old_preempt);
if (map)
QSort(lst,cnt,sizeof(CHashRep),&HashEntriesCompare2);
else if (index)
QSort(lst,cnt,sizeof(CHashRep),&HashEntriesCompare3);
else
QSort(lst,cnt,sizeof(CHashRep),&HashEntriesCompare);
for (i=0;i<cnt;i++) {
ptr=lst[i].h;
dbg=NULL;
if (index)
if (cur_index=lst[i].index) {
if (StrCmp(cur_index,last_index)) {
Free(last_index);
last_index=StrNew(cur_index);
if (doc)
DocPrintF(doc,"$$FG,GREEN$$%s$$FG$$\n",cur_index);
else
"$$FG,GREEN$$%s$$FG$$\n",cur_index;
}
}
if (index && ptr->type & HTT_HELP_FILE) {
if (doc) {
doc1=DocRead(ptr->str);
DocInsDoc(doc,doc1);
DocDel(doc1);
} else
Type(ptr->str);
} else {
if (ptr->type&HTG_SRC_SYM && ptr(CHashSrcSym *)->src_link) {
buf4=StrNew(ptr(CHashSrcSym *)->src_link);
if (mapfile_drv && StrLen(buf4)>4 && buf[1]==':' && buf4[4]==':')
buf4[3]=mapfile_drv;
dbg=indent=NULL;
if (outname && doc && ptr->type & HTT_FUN) {
if (dbg=ptr(CHashFun *)->debug) {
size=offset(CDbgInfo.body)+
sizeof(U8 *)*
(dbg->max_line-dbg->min_line+2);
if (size>MSize(dbg)) {
"Corrupt Map Entry\n";
dbg=NULL;
} else {
if (dbg->min_line<=dbg->max_line) {
tempb=CAlloc(sizeof(CDocBin));
tempb->type=DOCBT_DEBUG_LINES;
tempb->size=size;
tempb->data=MAlloc(size);
MemCpy(tempb->data,dbg,size);
dbg_bin_num=tempb->num=doc->cur_bin_num++;
tempb->use_cnt=1;
QueIns(tempb,doc->bin_root.last);
} else
dbg=NULL;
}
}
if (indent=ptr(CHashFun *)->indent) {
size=offset(CIndentInfo.body)+
sizeof(U8)*
(indent->max_line-indent->min_line+2);
if (size>MSize(indent)) {
"Corrupt Indent Entry\n";
indent=NULL;
} else {
if (indent->min_line<=indent->max_line) {
tempb=CAlloc(sizeof(CDocBin));
tempb->type=DOCBT_INDENTS;
tempb->size=size;
tempb->data=MAlloc(size);
MemCpy(tempb->data,indent,size);
indent_bin_num=tempb->num=doc->cur_bin_num++;
tempb->use_cnt=1;
QueIns(tempb,doc->bin_root.last);
} else
indent=NULL;
}
}
}
if (dbg || indent) {
if (dbg) {
SPrintF(buf,"$$LK+BI,\"%-26s\",\"%s\",%d$$",
ptr->str,buf4,dbg_bin_num);
DocPutS(doc,buf);
}
if (indent) {
if (dbg)
SPrintF(buf,"$$LK+BI,\"\",\"%s\",%d$$",
ptr->str,indent_bin_num);
else
SPrintF(buf,"$$LK+BI,\"%-26s\",\"%s\",%d$$",
ptr->str,buf4,indent_bin_num);
DocPutS(doc,buf);
}
} else {
SPrintF(buf,"$$LK,\"%-26s\",\"%s\"$$",
ptr->str,buf4);
if (doc)
DocPutS(doc,buf);
else
"" buf;
}
Free(buf4);
} else {
SPrintF(buf,"%-26ts",ptr->str);
if (doc)
DocPutS(doc,buf);
else
"" buf;
}
if (!index) {
if (ptr->type & HTT_DEFINE_STR) {
j=ptr(CHashDefineStr *)->cnt;
if (j==-1)
SPrintF(buf,"%-10tQ ",ptr(CHashDefineStr *)->data);
else
SPrintF(buf,"%-10tQ %02X",ptr(CHashDefineStr *)->data,j);
} else if (ptr->type & HTT_GLBL_VAR) {
if (outname)
SPrintF(buf,"%010X ",ptr(CHashGlblVar *)->data_addr_ip);
else
SPrintF(buf,"%010X ",ptr(CHashGlblVar *)->data_addr);
} else
SPrintF(buf,"%010X ",HashVal(ptr));
j=HashEntrySize(ptr);
if (j==-1)
SPrintF(buf+StrLen(buf)," %04X ",ptr->use_cnt);
else
SPrintF(buf+StrLen(buf)," %04X %010X ",ptr->use_cnt,j);
} else
*buf=0;
k=ptr->type;
if (publics)
k&=~HTF_PUBLIC;
for (j=0;j<32;j++)
if (Bt(&k,j))
SPrintF(buf+StrLen(buf),"%Z ",j,"ST_HTT_TYPES");
StrCat(buf,"\n");
if (doc)
DocPutS(doc,buf);
else
"" buf;
}
Free(lst[i].index);
}
Free(lst);
end_hash:
Preempt(old_preempt);
if (doc) {
DocBinsValidate(doc);
if (!_doc) {
DocWrite(doc);
DocDel(doc);
} else {
if (doc->root.next==doc)
DocPutS(doc,"No Match");
else
DocRecalc(doc);
}
}
Free(last_index);
}
public U0 HFunsRep(U8 *flags="",U8 *index=NULL)
{
HashRep(Fs->hash_table,HTT_FUN,NULL,flags,0,index);
}
public U0 HMapRep(U8 *flags="-p+m",U8 *index=NULL)
{
HashRep(Fs->hash_table,HTT_FUN,NULL,flags,0,index);
}
public U0 HVarsRep(U8 *flags="",U8 *index=NULL)
{
HashRep(Fs->hash_table,HTT_GLBL_VAR,NULL,flags,0,index);
}
public U0 HClassesRep(U8 *flags="-p",U8 *index=NULL)
{
HashRep(Fs->hash_table,HTT_CLASS,NULL,flags,0,index);
}
public U0 HDefinesRep(U8 *flags="-p",U8 *index=NULL)
{
HashRep(Fs->hash_table,HTT_DEFINE_STR,NULL,flags,0,index);
}
public U0 HSymsRep(U8 *flags="-p",U8 *index=NULL)
{
HashRep(Fs->hash_table,HTT_EXPORT_SYS_SYM,NULL,flags,0,index);
}
public U0 HAllRep(U8 *flags="-p",U8 *index=NULL)
{
HashRep(Fs->hash_table,HTG_ALL,NULL,flags,0,index);
}
#define HDR_MAX 16
public I64 HashDepthRep(CHashTable *tempht=NULL)
{
I64 i,j,longest=0,cnt=0,a[HDR_MAX];
CHash *temph;
if (!tempht) tempht=Fs->hash_table;
MemSet(a,0,sizeof(a));
for (i=0;i<=tempht->mask;i++) {
temph=tempht->body[i];
if (temph) {
j=1;
while (temph->next) {
temph=temph->next;
j++;
}
if (j<HDR_MAX)
a[j]++;
cnt+=j;
if (j>longest)
longest=j;
}
}
"Histogram\n";
for (i=0;i<HDR_MAX;i++)
if (a[i])
"%02d:%d\n",i,a[i];
"Size:%d Count:%d Longest:%d\n",
tempht->mask+1,cnt,longest;
return longest;
}
#help_index "Help System;Training"
#help_file "::/TempleOS/Doc/HelpSystem"
public U0 DocHelpIndex(CDoc *doc,U8 *index)
{
HashRep(Fs->hash_table,HTG_ALL,NULL,NULL,0,index,doc);
}
public U0 PopUpHelpIndex(U8 *index,CTask *parent=NULL)
{
U8 *buf;
buf=MSPrintF("DocHelpIndex(DocCur,\"%s\");View;",index);
PopUp(buf,parent);
Free(buf);
}
#help_index "Hash"
public U0 MapFileLoad(U8 *filename)
{
U8 *st,*ptr,*name=DftExt(filename,"MAP.Z"),
*absname=FileNameAbs(name);
CDoc *doc=DocRead(name);
CDocEntry *doc_e;
CHashSrcSym *temph;
I64 i,j,base=0;
CDbgInfo *dbg;
CIndentInfo *indent;
FileExtRem(absname);
if (absname[1]==':' && StrLen(absname)>2 &&
(temph=HashSingleTableFind(absname+2,Fs->hash_table,HTT_MODULE)))
base=temph(CHashGeneric *)->user_data0+sizeof(CBinFile);
if (!doc) return;
doc_e=doc->root.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 (temph=HashSingleTableFind(st,Fs->hash_table,HTG_SRC_SYM)) {
if (*doc_e->tag) {
Free(temph->src_link);
temph->src_link=doc_e->aux_str;
ptr=temph->src_link;
if (ptr[0] && ptr[1] && ptr[2]==':' && ptr[3]==':')
ptr[3]=dft_drv;
doc_e->aux_str=NULL;
}
if (temph->type&(HTT_FUN|HTT_EXPORT_SYS_SYM)) {
dbg =temph->debug;
indent=temph->indent;
if (!dbg && doc_e->bin_data && doc_e->bin_data->type==DOCBT_DEBUG_LINES) {
if (dbg=doc_e->bin_data->data) {
if (doc_e->bin_data->size>MSize(dbg))
"Corrupt Map Entry\n";
else {
doc_e->bin_data->data=NULL;
temph->debug=dbg;
for (i=dbg->min_line;i<=dbg->max_line+1;i++) {
j=i-dbg->min_line;
if (dbg->body[j])
dbg->body[j]=dbg->body[j]+base;
}
}
}
}
if (!indent && doc_e->bin_data && doc_e->bin_data->type==DOCBT_INDENTS) {
if (indent=doc_e->bin_data->data) {
if (doc_e->bin_data->size>MSize(indent))
"Corrupt Indent Entry\n";
else {
doc_e->bin_data->data=NULL;
temph->indent=indent;
}
}
}
}
}
Free(st);
}
doc_e=doc_e->next;
}
DocDel(doc);
Free(name);
Free(absname);
}
#help_index ""
+159
View File
@@ -0,0 +1,159 @@
#help_index "Debugging/Heap"
class CHeapLog
{
CHeapLog *next,*last;
U8 *addr;
U8 *caller1;
U8 *caller2;
U8 *caller3;
U8 *caller4;
};
class CHeapLogHash
{
CHeapLog *next,*last;
};
#define HEAPLOG_HASH_SIZE 0x1000
CTask *heaplog_task=NULL;
CHeapCtrl *heaplog_hc;
CHeapLogHash *heaplog_root=NULL;
U0 HeapLogTask(I64)
{
while (TRUE)
Yield;
}
U0 HeapLogMAlloc(U8 *addr)
{
CHeapLog *temph;
I64 i;
if (MHeapCtrl(addr)==heaplog_hc) {
temph=MAlloc(sizeof(CHeapLog),heaplog_task);
temph->addr=addr;
temph->caller1=Caller(2);
temph->caller2=Caller(3);
temph->caller3=Caller(4);
temph->caller4=Caller(5);
i=addr>>3 &(HEAPLOG_HASH_SIZE-1);
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0))
Pause;
QueIns(temph,heaplog_root[i].last);
LBtr(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0);
PopFD;
}
}
U0 HeapLogFree(U8 *addr)
{
I64 i;
CHeapLog *temph;
if (!addr) return;
if (MHeapCtrl(addr)==heaplog_hc) {
i=addr>>3 &(HEAPLOG_HASH_SIZE-1);
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0))
Pause;
temph=heaplog_root[i].next;
while (temph!=&heaplog_root[i]) {
if (addr==temph->addr) {
QueRem(temph);
LBtr(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0);
PopFD;
Free(temph);
return;
}
temph=temph->next;
}
LBtr(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0);
PopFD;
}
}
public U0 HeapLogRep()
{
I64 i,total=0;
CHeapLog *temph;
if (!LBtr(&sys_semas[SYS_SEMA_HEAPLOG_ACTIVE],0)) {
"HeapLog Not Active\n";
return;
}
"$$WW,0$$";
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0))
Pause;
for (i=0;i<HEAPLOG_HASH_SIZE;i++) {
temph=heaplog_root[i].next;
while (temph!=&heaplog_root[i]) {
"$$FG,PURPLE$$%08X$$FG$$ %08X ",MSize(temph->addr),temph->addr;
if (!PutSrcLink(temph->caller1,64))
"%P",temph->caller1;
'' CH_SPACE;
if (!PutSrcLink(temph->caller2,64))
"%P",temph->caller2;
'' CH_SPACE;
if (!PutSrcLink(temph->caller3,64))
"%P",temph->caller3;
'' CH_SPACE;
if (!PutSrcLink(temph->caller4,64))
"%P",temph->caller4;
NewLine;
total+=MSize(temph->addr);
temph=temph->next;
}
}
LBtr(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0);
PopFD;
"\n$$FG,LTRED$$Total:%08X$$FG$$\n",total;
LBts(&sys_semas[SYS_SEMA_HEAPLOG_ACTIVE],0);
}
public U0 HeapLog(Bool val=TRUE,CTask *task=NULL)
{
I64 i;
if (val) {
if (Bt(&sys_semas[SYS_SEMA_HEAPLOG_ACTIVE],0))
"HeapLog Already Active\n";
else {
if (!task) task=Fs;
if (TaskValidate(task))
heaplog_hc=task->data_heap;
else
heaplog_hc=task;
PushFD;
Cli;
while (LBts(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0))
Pause;
heaplog_task=Spawn(&HeapLogTask);
ext[EXT_HEAPLOG_MALLOC]=&HeapLogMAlloc;
ext[EXT_HEAPLOG_FREE]=&HeapLogFree;
heaplog_root=MAlloc(sizeof(CHeapLogHash)*HEAPLOG_HASH_SIZE,heaplog_task);
for (i=0;i<HEAPLOG_HASH_SIZE;i++)
QueInit(&heaplog_root[i]);
LBtr(&sys_semas[SYS_SEMA_HEAPLOG_LOCK],0);
PopFD;
LBts(&sys_semas[SYS_SEMA_HEAPLOG_ACTIVE],0);
}
} else {
if (!LBtr(&sys_semas[SYS_SEMA_HEAPLOG_ACTIVE],0))
"HeapLog Not Active\n";
else {
Kill(heaplog_task);
heaplog_root=heaplog_task=NULL;
ext[EXT_HEAPLOG_MALLOC]=NULL;
ext[EXT_HEAPLOG_FREE]=NULL;
}
}
}
#help_index ""
+113
View File
@@ -0,0 +1,113 @@
#help_index "Utils;Cmd Line (Typically)"
I64 LineCntRepFiles(CDirEntry *tempm)
{
CDoc *doc;
I64 result=0,i;
while (tempm) {
i=0;
if (tempm->attr&_ATTR_DIR)
i=LineCntRepFiles(tempm->sub);
else {
if (FilesFindMatch(FILENAME_MASK_SRC,tempm->name)) {
doc=DocRead(tempm->full_name);
if (doc->root.next!=doc)
i=doc->root.last->y+2;
DocDel(doc);
}
}
tempm->user_data=i;
result+=i;
tempm=tempm->next;
}
return result;
}
U0 PutLineCntFiles(CDoc *doc,CDirEntry *tempm)
{
while (tempm) {
if (tempm->attr&_ATTR_DIR) {
DocPrintF(doc,"%8,d $$TR+C,\"%s\"$$\n$$ID,2$$",tempm->user_data,tempm->name);
PutLineCntFiles(doc,tempm->sub);
DocPutS(doc,"$$ID,-2$$");
} else {
if (FilesFindMatch(FILENAME_MASK_SRC,tempm->name)) {
DocPrintF(doc,"%8,d ",tempm->user_data);
DocPrintF(doc,"$$LK,\"%s\",\"FI:%s\"$$\n",
tempm->name,tempm->full_name);
}
}
tempm=tempm->next;
}
}
public I64 LineCntRep(U8 *files_find_mask="/TempleOS/*",U8 *fu_flags=NULL)
{
I64 fuf_flags=0,result=0;
CDoc *doc=DocNew;
CDirEntry *tempm1=NULL;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (tempm1=FilesFind(files_find_mask,fuf_flags)) {
result=LineCntRepFiles(tempm1);
DocPrintF(doc,"%8,d $$TR+C,\"%s\"$$\n$$ID,2$$",result,files_find_mask);
PutLineCntFiles(doc,tempm1);
DocPutS(doc,"$$ID,-2$$");
CDirLstDel(tempm1);
}
DocInsDoc(DocCur,doc);
DocDel(doc);
return result;
}
I64 TreeSizeRepFiles(CDirEntry *tempm)
{
I64 result=0,i;
while (tempm) {
if (tempm->attr&_ATTR_DIR)
i=TreeSizeRepFiles(tempm->sub);
else
i=tempm->size;
tempm->user_data=i;
result+=i;
tempm=tempm->next;
}
return result;
}
U0 PutTreeSizeFiles(CDoc *doc,CDirEntry *tempm)
{
while (tempm) {
if (tempm->attr&_ATTR_DIR) {
DocPrintF(doc,"%10,d $$TR+C,\"%s\"$$\n$$ID,2$$",tempm->user_data,tempm->name);
PutTreeSizeFiles(doc,tempm->sub);
DocPutS(doc,"$$ID,-2$$");
} else {
DocPrintF(doc,"%10,d ",tempm->user_data);
DocPrintF(doc,"$$LK,\"%s\",\"FI:%s\"$$\n",
tempm->name,tempm->full_name);
}
tempm=tempm->next;
}
}
public I64 TreeSizeRep(U8 *files_find_mask="/TempleOS/*",U8 *fu_flags=NULL)
{
I64 fuf_flags=0,result=0;
CDoc *doc=DocNew;
CDirEntry *tempm1=NULL;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (tempm1=FilesFind(files_find_mask,fuf_flags)) {
result=TreeSizeRepFiles(tempm1);
DocPrintF(doc,"%10,d $$TR+C,\"%s\"$$\n$$ID,2$$",result,files_find_mask);
PutTreeSizeFiles(doc,tempm1);
DocPutS(doc,"$$ID,-2$$");
CDirLstDel(tempm1);
}
DocInsDoc(DocCur,doc);
DocDel(doc);
return result;
}
#help_index ""
+75
View File
@@ -0,0 +1,75 @@
#help_index "Debugging;Utils;Cmd Line (Typically)"
I64 LinkChkDoc(CDoc *doc,I64 *_fuf_flags)
{
U8 *st;
Bool found,unlock=DocLock(doc);
CDoc *old_doc=DocCur;
CDocEntry *doc_e=doc->root.next;
I64 result=0;
while (doc_e!=doc) {
if (ScanKey) {
LBts(_fuf_flags,FUf_CANCEL);
break;
}
if (st=DocEntryLink(doc,doc_e)) {
DocLock(old_doc);
DocQueRem(old_doc);
DocQueIns(doc,Fs->last_doc);
found=DocLinkChk(st);
DocQueRem(doc);
DocQueIns(old_doc,Fs->last_doc);
DocUnlock(old_doc);
if (!found) {
PutFileLink(doc->filename.name,doc_e->y);
"$$FG,RED$$ %04d:%s\n$$FG$$",doc_e->y,st;
result++;
}
Free(st);
} else if (doc_e->type_u8==DOCT_ERROR) {
PutFileLink(doc->filename.name,doc_e->y);
"$$FG,RED$$ Doc Error\n$$FG$$";
result++;
}
doc_e=doc_e->next;
}
if (unlock) DocUnlock(doc);
return result;
}
I64 LinkChkFile(U8 *filename,I64 *_fuf_flags)
{
CDoc *doc=DocRead(filename,DOCF_NO_CURSOR);
I64 result=LinkChkDoc(doc,_fuf_flags);
DocDel(doc);
return result;
}
I64 LinkChkLst(CDirEntry *tempm1,I64 *_fuf_flags)
{
CDirEntry *tempm2;
I64 result=0;
while (tempm1 && !Bt(_fuf_flags,FUf_CANCEL)) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub) {
"%S %s\n","ST_SCANNING_DIR",tempm1->full_name;
result+=LinkChkLst(tempm1->sub,_fuf_flags);
}
} else
result+=LinkChkFile(tempm1->full_name,_fuf_flags);
CDirEntryDel(tempm1);
tempm1=tempm2;
}
return result;
}
public I64 LinkChk(U8 *files_find_mask=FILENAME_MASK_TXT,U8 *fu_flags=NULL)
//Checks for broken file links.
{
I64 fuf_flags=0;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+T");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
return LinkChkLst(FilesFind(files_find_mask,fuf_flags),&fuf_flags);
}
#help_index ""
+168
View File
@@ -0,0 +1,168 @@
#help_index "Task/Login"
//This is temporary until defined in $LK-A,"HOME/Adam3fSys.CPP"$.
U0 UserStartUp()
{ //Run each time a user a spawned
UseTermDoc;
DocCurAttr(WHITE<<4+BLUE);
Type("::/TempleOS/Doc/Start.TXT");
LBts(&Fs->display_flags,DISPLAYf_SHOW);
WinZBufUpdate;
if (!IsSysDeterministic)
Preempt(ON);
}
//This is temporary until defined in $LK-A,"HOME/Adam3fSys.CPP"$.
U0 ServantStartUp()
{ //Run each time a servant task is spawned.
UseTermDoc;
LBts(&Fs->display_flags,DISPLAYf_SHOW);
WinZBufUpdate;
if (!IsSysDeterministic)
Preempt(ON);
}
U8 *PopUpSysAcctGet()
{
U8 *result,*st;
CDoc *doc=DocNew;
CDirEntry *tempm1=FilesFind("/TempleOS/Accts/*",FUF_RECURSE|FUF_JUST_DIRS|FUF_FLATTEN_TREE),
*tempm=tempm1;
DocPutS(doc,"$$CM+CX-LE,8$$");
DocPutSprite(doc,$IB+BP,"<1>",1,"::/TempleOS/Demo/Graphics/Logo.CPP,1"$,"$$SP+SIF,\"\",%d$$");
DocPutS(doc,"$$CM+LX,0,14$$Select Account.\nCursor down and press <SPACE BAR>.\n");
while (tempm) {
if (*tempm->name!='.') {
st=tempm->full_name;
if (!StrNCmp(st+2,"/TempleOS/Accts/",10))
st+=12;
DocPrintF(doc,"$$CM+LX,2,3$$$$BT,\"%s\",%d$$",st,tempm);
}
tempm=tempm->next;
}
DocPutS(doc,"\n\n\n\nLog-in as USER if you are new and get familiar\n"
"before you try to install.\n");
do tempm=PopUpMenu(doc,DOF_WIN_MAX);
while (tempm<0);
DocDel(doc);
result=AStrNew(tempm->full_name);
CDirLstDel(tempm1);
return result;
}
U0 SysLogin()
{
U8 *st;
if (!FileFind(sys_acct)||!StrCmp(sys_acct+2,"/TempleOS/Accts")) {
st=sys_acct;
sys_acct=PopUpSysAcctGet;
Free(st);
}
}
#define ACCT_REGISTRY_FILENAME "HOME/Registry.CPP.Z"
CDoc *sys_registry_doc=NULL;
I64 sys_msg_flags[1]={0};
F64 registry_version;
Bool AcctCacheRegistry()
{
Bool old_silent;
if (!sys_registry_doc) {
old_silent=Silent(ON);
sys_registry_doc=DocRead(ACCT_REGISTRY_FILENAME);
Silent(old_silent);
return FALSE;
} else
return TRUE;
}
public Bool AcctRegSetDftEntry(U8 *path,U8 *val,Bool is_adam_entry=FALSE)
{
Bool result,unlock_doc;
AcctCacheRegistry;
unlock_doc=DocLock(sys_registry_doc);
if (!DocTreeFind(sys_registry_doc,path)) {
DocTreeMake(sys_registry_doc,path);
DocPutS(sys_registry_doc,val);
if (is_adam_entry) {
if (Fs==adam_task)
ExePutS(val);
else
Adam("%s",val);
}
if (IsDrvWritable(dft_drv))
DocWrite(sys_registry_doc);
result=FALSE;
} else
result=TRUE;
if (unlock_doc)
DocUnlock(sys_registry_doc);
return result;
}
public I64 AcctRegExecuteBranch(U8 *path)
{
AcctCacheRegistry;
return DocTreeBranchExe(sys_registry_doc,path);
}
public Bool AcctRegWriteBranch(U8 *path,U8 *fmt,...)
{
Bool result,unlock_doc;
CDocEntry *tree_branch,*start_indent,*end_indent;
U8 *buf=SPrintFJoin(NULL,fmt,argc,argv);
AcctCacheRegistry;
unlock_doc=DocLock(sys_registry_doc);
if (result=DocTreeFind(sys_registry_doc,path,&tree_branch,&start_indent,&end_indent))
DocCut(sys_registry_doc,tree_branch,end_indent);
DocTreeMake(sys_registry_doc,path);
DocPutS(sys_registry_doc,buf);
if (IsDrvWritable(dft_drv))
DocWrite(sys_registry_doc);
if (unlock_doc)
DocUnlock(sys_registry_doc);
Free(buf);
return result;
}
U0 AcctOneTimePopUp(I64 flag_num,U8 *msg)
{ //You're not supposed to make system pop-up flags, only me.
CDoc *doc=DocNew;
CDocEntry *doc_e;
if (!Bt(sys_msg_flags,flag_num)) {
if (msg) DocPutS(doc,msg);
doc_e=DocPutS(doc,"\n$$CB+LE,\"Do not show this msg again.\",1$$");
DocPutS(doc,"$$CM+CX,0,4$$$$BT,\"OKAY\",1$$\n");
if (PopUpMenu(doc)==1 && doc_e->flags1&DOCEF1_CHECKED_COLLAPSED) {
LBts(sys_msg_flags,flag_num);
AcctRegWriteBranch("Adam/TempleOS/SysMsgFlags",
"sys_msg_flags[0]=0x%X;\n",
sys_msg_flags[0]);
}
DocDel(doc);
}
}
U0 RegistryInit()
{
U8 buf[136];
Bool existed=FileFind(ACCT_REGISTRY_FILENAME),version_present;
AcctRegSetDftEntry("Adam/TempleOS/SysMsgFlags","sys_msg_flags[0]=0;\n",TRUE);
SPrintF(buf,"registry_version=%4.3f;\n",os_version);
version_present=AcctRegSetDftEntry("Adam/TempleOS/SysRegVer",buf,TRUE);
AcctRegExecuteBranch("Adam");
//Convert old registries
if (existed && !version_present)
registry_version=5.10;
if (registry_version!=os_version) {
if (registry_version<5.101)
AcctRegWriteBranch("TempleOS","");
AcctRegWriteBranch("Adam/TempleOS/SysRegVer",buf);
AcctRegExecuteBranch("Adam");
}
}
#help_index ""
+138
View File
@@ -0,0 +1,138 @@
#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 result=é%(2*ã);
if (result>=base+2*ã)
result-=2*ã;
else if (result<base)
result+=2*ã;
return result;
}
public I64 DistI64(I64 x1,I64 y1,I64 x2,I64 y2)
{
I64 dx=x1-x2,dy=y1-y2;
return dx*dx+dy*dy;
}
public F64 ASin(F64 s)
{
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)
{
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)
{
return 0.5*(Exp(x)-Exp(-x));
}
public F64 Cosh(F64 x)
{
return 0.5*(Exp(x)+Exp(-x));
}
#help_index "Math/Complex"
public Complex *CAdd(Complex *n1,Complex *n2,Complex *sum)
{
sum->x=n1->x+n2->x;
sum->y=n1->y+n2->y;
return sum;
}
public Complex *CSub(Complex *n1,Complex *n2,Complex *diff)
{
diff->x=n1->x-n2->x;
diff->y=n1->y-n2->y;
return diff;
}
public Complex *CMul(Complex *n1,Complex *n2,Complex *prod)
{
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 *n1,Complex *n2,Complex *quot)
{
F64 m1,a1,m2,a2;
R2P(&m1,&a1,n1->x,n1->y);
R2P(&m2,&a2,n2->x,n2->y);
m1/=m2;
a1-=a2;
quot->x=m1*Cos(a1);
quot->y=m1*Sin(a1);
return quot;
}
public Complex *CScale(Complex *dst,F64 s)
{
dst->x*=s;
dst->y*=s;
return dst;
}
public Complex *CCopy(Complex *dst,Complex *src)
{
dst->x=src->x;
dst->y=src->y;
return dst;
}
public Complex *CEqu(Complex *dst,F64 x,F64 y)
{
dst->x=x;
dst->y=y;
return dst;
}
public Complex *CPoly(Complex *dst,Complex *x,Complex *zeros,I64 n)
{
I64 i;
Complex n1,n2;
if (n>0) {
CSub(x,&zeros[0],dst);
for (i=1;i<n;i++) {
CCopy(&n1,dst);
CSub(x,&zeros[i],&n2);
CMul(&n1,&n2,dst);
}
} else
CEqu(dst,1.0,0.0);
return dst;
}
#help_index ""
+635
View File
@@ -0,0 +1,635 @@
#help_index "Math/CMathODE;CMathODE"
#help_file "::/TempleOS/Doc/ODE"
//See $LK-A,"::/TempleOS/Doc/Acknowledgements.TXT"$ (5).
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->temp0=ptr;
ptr(I64)+=s;
ode->temp1=ptr;
ptr(I64)+=s;
ode->temp2=ptr;
ptr(I64)+=s;
ode->temp3=ptr;
ptr(I64)+=s;
ode->temp4=ptr;
ptr(I64)+=s;
ode->temp5=ptr;
ptr(I64)+=s;
ode->temp6=ptr;
ptr(I64)+=s;
ode->temp7=ptr;
}
public CMathODE *ODENew(I64 n,F64 max_tolerance=1e-6,I64 flags=0)
{
//See $LK,"flags","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);
ode->ode_signature=ODE_SIGNATURE_VAL;
return ode;
}
public U0 ODEDel(CMathODE *ode)
{
if (!ode) return;
ode->ode_signature=0;
Free(ode->state);
Free(ode->array_base);
Free(ode);
}
public I64 ODESize(CMathODE *ode)
{
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 *tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
tempm->state=ptr1++;
tempm->DstateDt=ptr2++;
tempm=tempm->next;
}
}
U0 ODEState2Internal(CMathODE *ode)
{
CMass *tempm;
F64 *old_array_base;
I64 mass_cnt;
if (ode->flags&ODEF_HAS_MASSES) {
mass_cnt=0;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
mass_cnt++;
tempm=tempm->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);
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
MemCpy(tempm->state,&tempm->saved_state,sizeof(COrder2D3));
tempm=tempm->next;
}
}
MemCpy(ode->state_internal,ode->state,ode->n*sizeof(F64));
}
U0 ODEInternal2State(CMathODE *ode)
{
CMass *tempm;
MemCpy(ode->state,ode->state_internal,ode->n*sizeof(F64));
if (ode->flags&ODEF_HAS_MASSES) {
ODESetMassesPtrs(ode,ode->state_internal,ode->state_internal);
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
MemCpy(&tempm->saved_state,tempm->state,sizeof(COrder2D3));
tempm=tempm->next;
}
}
}
public U0 ODERenum(CMathODE *ode)
{
I64 i;
CSpring *temps;
CMass *tempm;
i=0;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
tempm->num=i++;
tempm=tempm->next;
}
i=0;
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
temps->num=i++;
temps->end1_num=temps->end1->num;
temps->end2_num=temps->end2->num;
temps=temps->next;
}
}
public CMass *MassFind(CMathODE *ode,F64 x,F64 y,F64 z=0)
{
CMass *tempm,*best_mass=NULL;
F64 d,best_d=MAX_F64;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
d=Sqr(tempm->x-x)+Sqr(tempm->y-y)+Sqr(tempm->z-z);
if (d<best_d) {
best_d=d;
best_mass=tempm;
}
tempm=tempm->next;
}
return best_mass;
}
public CSpring *SpringFind(CMathODE *ode,F64 x,F64 y,F64 z=0)
{
CSpring *temps,*best_spring=NULL;
F64 d,best_d=MAX_F64;
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
d=Sqr((temps->end1->x+temps->end2->x)/2-x)+
Sqr((temps->end1->y+temps->end2->y)/2-y)+
Sqr((temps->end1->z+temps->end2->z)/2-z);
if (d<best_d) {
best_d=d;
best_spring=temps;
}
temps=temps->next;
}
return best_spring;
}
public U0 MassOrSpringFind(CMathODE *ode,CMass **result_mass,CSpring **result_spring,
F64 x,F64 y,F64 z=0)
{
CMass *tempm,*best_mass=NULL;
CSpring *temps,*best_spring=NULL;
F64 d,best_d=MAX_F64;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
d=Sqr(tempm->x-x)+Sqr(tempm->y-y)+Sqr(tempm->z-z);
if (d<best_d) {
best_d=d;
best_mass=tempm;
}
tempm=tempm->next;
}
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
d=Sqr((temps->end1->x+temps->end2->x)/2-x)+
Sqr((temps->end1->y+temps->end2->y)/2-y)+
Sqr((temps->end1->z+temps->end2->z)/2-z);
if (d<best_d) {
best_d=d;
best_spring=temps;
best_mass=NULL;
}
temps=temps->next;
}
if (result_mass) *result_mass =best_mass;
if (result_spring) *result_spring=best_spring;
}
public CMass *MassFindNum(CMathODE *ode,I64 num)
{
CMass *tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (tempm->num==num)
return tempm;
tempm=tempm->next;
}
return NULL;
}
public U0 ODERstInactive(CMathODE *ode)
{
CMass *tempm;
CSpring *temps;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
tempm->flags&=~MSF_INACTIVE;
tempm=tempm->next;
}
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
temps->flags&=~SSF_INACTIVE;
temps=temps->next;
}
}
U0 ODECalcSprings(CMathODE *ode)
{
CSpring *temps=ode->next_spring;
CMass *e1,*e2;
F64 d;
CD3 p;
while (temps!=&ode->next_spring) {
if (temps->flags&SSF_INACTIVE) {
temps->displacement=0;
temps->f=0;
} else {
e1=temps->end1;
e2=temps->end2;
d=D3Norm(D3Sub(&e2->state->x,&e1->state->x,&p));
temps->displacement=d-temps->rest_len;
temps->f=temps->displacement*temps->constant;
if (temps->f>0 && temps->flags&SSF_NO_TENSION)
temps->f=0;
else if (temps->f<0 && temps->flags&SSF_NO_COMPRESSION)
temps->f=0;
if (d>0) {
D3MulEqu(&p,temps->f/d);
D3AddEqu(&e1->DstateDt->DxDt,&p);
D3SubEqu(&e2->DstateDt->DxDt,&p);
}
}
temps=temps->next;
}
}
U0 ODECalcDrag(CMathODE *ode)
{
CMass *tempm;
F64 d,dd;
CD3 p;
if (ode->drag_v || ode->drag_v2 || ode->drag_v3) {
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (!(tempm->flags & MSF_INACTIVE) &&
tempm->drag_profile_factor &&
(dd=D3SqrNorm(&tempm->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(&tempm->DstateDt->DxDt,
D3Mul(d*tempm->drag_profile_factor,&tempm->state->DxDt,&p));
}
tempm=tempm->next;
}
}
}
U0 ODEApplyAccelerationLimit(CMathODE *ode)
{
CMass *tempm;
F64 d;
if (ode->acceleration_limit) {
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (!(tempm->flags & MSF_INACTIVE) &&
(d=D3Norm(&tempm->DstateDt->DxDt))>ode->acceleration_limit)
D3MulEqu(&tempm->DstateDt->DxDt,ode->acceleration_limit/d);
tempm=tempm->next;
}
}
}
U0 ODECallDerivative(CMathODE *ode,F64 t,F64 *state,F64 *DstateDt)
{
CMass *tempm;
if (ode->flags&ODEF_HAS_MASSES) {
ODESetMassesPtrs(ode,state,DstateDt);
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (!(tempm->flags&MSF_INACTIVE)) {
D3Zero(&tempm->DstateDt->DxDt);
D3Copy(&tempm->DstateDt->x,&tempm->state->DxDt);
}
tempm=tempm->next;
}
ODECalcSprings(ode);
ODECalcDrag(ode);
(*ode->derivative)(ode,t,state,DstateDt);
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (!(tempm->flags&MSF_INACTIVE)) {
if (tempm->flags&MSF_FIXED) {
D3Zero(&tempm->DstateDt->DxDt);
D3Zero(&tempm->DstateDt->x);
} else if (tempm->mass)
D3DivEqu(&tempm->DstateDt->DxDt,tempm->mass);
}
tempm=tempm->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->temp0;
dyt =ode->temp1;
yt =ode->temp2;
DstateDt=ode->temp3;
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,*tempstate,*stateerr,*outstate;
ak2=ode->temp0;
ak3=ode->temp1;
ak4=ode->temp2;
ak5=ode->temp3;
ak6=ode->temp4;
tempstate=ode->temp5;
outstate=ode->temp6;
stateerr=ode->temp7;
for (i=0;i<n;i++)
tempstate[i]=state[i]+ODEb21*h*DstateDt[i];
ODECallDerivative(ode,ode->t+ODEa2*h,tempstate,ak2);
for (i=0;i<n;i++)
tempstate[i]=state[i]+h*(ODEb31*DstateDt[i]+ODEb32*ak2[i]);
ODECallDerivative(ode,ode->t+ODEa3*h,tempstate,ak3);
for (i=0;i<n;i++)
tempstate[i]=state[i]+h*(ODEb41*DstateDt[i]+ODEb42*ak2[i]+ODEb43*ak3[i]);
ODECallDerivative(ode,ode->t+ODEa4*h,tempstate,ak4);
for (i=0;i<n;i++)
tempstate[i]=state[i]+h*(ODEb51*DstateDt[i]+ODEb52*ak2[i]+ODEb53*ak3[i]+ODEb54*ak4[i]);
ODECallDerivative(ode,ode->t+ODEa5*h,tempstate,ak5);
for (i=0;i<n;i++)
tempstate[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,tempstate,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,temp,*tempstate=ode->temp6,*stateerr=ode->temp7;
while (TRUE) {
ode->h=Limit(ode->h,ode->h_min,ode->h_max);
ODECashKarp(ode);
errmax=0.0;
for (i=0;i<ode->n_internal;i++) {
temp=Abs(stateerr[i]/ode->state_scale[i]);
if (temp>errmax)
errmax=temp;
}
errmax/=ode->tolerance_internal;
if (errmax<=1.0 || ode->h==ode->h_min) break;
temp=ode->h*SAFETY*errmax`PSHRNK;
if (temp<0.1*ode->h)
ode->h*=0.1;
else
ode->h=temp;
}
ode->t+=ode->h;
if (errmax>ERRCON)
ode->h*=SAFETY*errmax`PGROW;
else
ode->h*=5.0;
ode->h=Limit(ode->h,ode->h_min,ode->h_max);
MemCpy(ode->state_internal,tempstate,sizeof(F64)*ode->n_internal);
}
F64 ode_allocated_factor=0.75;
U0 ODEsUpdate(CTask *task)
{
/*
This routine is called by the $LK,"window mgr","FF:::/TempleOS/Adam/Gr/GrScreen.CPP,ODEsUpdate"$ on a continuous
basis to allow real-time simulation. It is intended
to provide results 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;
Bool old_suspend;
if (task->next_ode==&task->next_ode)
task->last_ode_time=0;
else {
//See $LK,"GrUpdateWins","MN:GrUpdateWins"$()
if (!Bt(&task->win_inhibit,WIf_ODE)) {
//TODO: Being preempted here woulds be bad
if (task!=Fs)
old_suspend=Suspend(task);
//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=tT;
d=1.0/win_actual_refresh;
timeout_time=start_time+
(task->last_ode_time/d+0.1)/(last_refresh_ode_time/d+0.1)*
ode_allocated_factor*d;
ode=task->next_ode;
while (ode!=&task->next_ode) {
if (ode->ode_signature==ODE_SIGNATURE_VAL) {
t_initial=ode->t;
d=tT;
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 (tT>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 allocated time.
d=(tT-start_time)/(timeout_time-start_time)-0.75;
ode=task->next_ode;
while (ode!=&task->next_ode) {
if (ode->ode_signature==ODE_SIGNATURE_VAL &&
!(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=Limit(ode->tolerance_internal,ode->min_tolerance,ode->max_tolerance);
}
ode=ode->next;
}
refresh_ode_time+=task->last_ode_time=tT-start_time;
//See $LK,"GrUpdateWins","MN:GrUpdateWins"$()
if (task!=Fs)
Suspend(task,old_suspend);
}
}
}
#help_index ""
+240
View File
@@ -0,0 +1,240 @@
#help_index "Info;Utils;Memory/Info;Cmd Line (Typically)"
I64 TSSSize(CTSS *tss)
{
return MSize2(tss)+
MSize2(tss->st0)+
MSize2(tss->st1)+
MSize2(tss->st2);
}
I64 PenBrushesSize()
{
I64 result=0,i;
for (i=0;i<GR_NUM_PEN_BRUSHES;i++)
result+=
DCSize(gr_pen_brushes[i])+
DCSize(gr_collision_pen_brushes[i])+
DCSize(gr_even_pen_brushes[i])+
DCSize(gr_odd_pen_brushes[i] );
return result;
}
I64 ScreenZoomTablesSize()
{
I64 result=0,i;
for (i=1;i<=GR_MAX_SCREEN_ZOOM;i++)
result+=MSize2(gr_screen_zoom_tables[i]);
return result;
}
I64 TaskStkSize(CTask *task)
{
CTaskStk *temps=task->stk;
I64 result=0;
while (temps) {
result+=MSize2(temps);
temps=temps->next_stk;
}
return result;
}
I64 TaskQueSize(CTask *task)
{
CTaskCmd *tempc,*tempc1;
I64 result=0;
PushFD;
Cli;
while (LBts(&task->locked_flags,TASKLf_TASK_LOCK))
Pause;
tempc1=&task->next_servant_cmd;
tempc=tempc1->next;
while (tempc!=tempc1) {
result+=MSize2(tempc);
if (tempc->cmd_code==TASKCT_EXECUTE_STR ||
tempc->cmd_code==TASKCT_EXECUTE_FILE ||
tempc->cmd_code==TASKCT_TEXT_INPUT)
result+=MSize2(tempc->data);
tempc=tempc->next;
}
LBtr(&task->locked_flags,TASKLf_TASK_LOCK);
PopFD;
return result;
}
I64 BlkDevsSize()
{
I64 i,result=MSize2(sys_blkdevs);
CBlkDev *bdev;
for (i=0;i<NUM_BLKDEVS;i++) {
bdev=&sys_blkdevs[i];
if (bdev->bd_signature==BD_SIGNATURE_VAL) {
if (bdev->type==BDT_RAM)
"RAMDsk %C\t:%010X Unused:%010X\n",
bdev->first_drv_let,MSize2(bdev->RAM_dsk),
UnusedDrvSpace(bdev->first_drv_let);
result+=MSize2(bdev->dev_id_record);
}
}
return result;
}
I64 PrtsSize()
{
I64 i,result=MSize2(sys_prts);
for (i=0;i<NUM_PRTS;i++)
result+=MSize2(sys_prts[i].buffered_map_dirty_bits)+
MSize2(sys_prts[i].fis);
return result;
}
Bool MemRepTask(CTask *task,Bool override_validate=FALSE)
{
I64 i,j,k,m,n;
U8 *st;
CDoc *doc;
CLex *lx;
CMathODE *o;
CCPU *c;
CTask *task1;
if (!override_validate && !TaskValidate(task))
return FALSE;
if (task==Fs)
task->rsp=GetStkPtr;
st=MStrUtil(task->task_title,SUF_REM_CTRL_CHARS|SUF_SAFE_DOLLAR);
"$$FG,GREEN$$Task:%010X$$FG,CYAN$$ %-30ts$$FG$$\n$$ID,2$$",task,st;
Free(st);
"$$FG,PURPLE$$Alloced:%010X Used:%010X $$FG,RED$$Unused:%010X$$FG$$\n",
TaskAllocatedMem(task,override_validate),
TaskUsedMem(task,override_validate),
TaskUnusedAllocatedMem(task,override_validate);
"HashTable:%010X\n",HashTableSize2(task->hash_table);
i=UnusedStk(task);
if (0<=i<=task->stk->stk_size)
"Stk Size :%010X Unused:%010X\n",TaskStkSize(task),i;
else
"Stk Size :%010X $$FG,RED$$$$BK,1$$Overflow$$BK,0$$$$FG$$\n",TaskStkSize(task);
doc=task->last_doc;
while (doc!=(&task->next_doc)(U8 *)-offset(CDoc.next_doc) &&
doc->doc_in_que_signature==DOC_IN_QUE_SIGNATURE_VAL) {
"Doc :%010X\n",DocSize(doc);
doc=doc->last_doc;
}
lx=task->next_lex;
while (lx!=&task->next_lex) {
"Lex :%010X\n",LexSize(lx);
lx=lx->next;
}
o=task->next_ode;
while (o!=&task->next_ode) {
"CMathODE :%010X\n",ODESize(o);
o=o->next;
}
if (task==sys_winmgr_task) {
"gr_dc2\t\t:%010X\n",DCSize(gr_dc2);
"gr_dc\t\t:%010X\n",DCSize(gr_dc);
"gr_dc_cache\t\t:%010X\n",DCSize(gr_dc_cache);
"gr_screen_image\t:%010X\n",DCSize(gr_screen_image);
"gr_zoomed_dc\t:%010X\n",DCSize(gr_zoomed_dc);
"gr_pen_brushes\t:%010X\n",PenBrushesSize;
"gr_1_to_8_bits\t:%010X\n",MSize2(gr_1_to_8_bits);
"gr_1_to_8_colors\t:%010X\n",MSize2(gr_1_to_8_colors);
"gr_text_base\t:%010X\n",MSize2(gr_text_base);
"gr_vga_text_cache\t:%010X\n",MSize2(gr_vga_text_cache);
"gr_win_z_buf\t:%010X\n",MSize2(gr_win_z_buf)+MSize2(gr_win_uncovered_bitmap);
"gr_screen_zoom_tbles:%010X\n",ScreenZoomTablesSize;
} else if (task==adam_task) {
j=0;k=0;m=0;n=0;
for (i=0;i<mp_cnt;i++) {
c=&cpu_structs[i];
k+=TSSSize(c->tss);
task1=c->seth_task;
do {
if (task1!=adam_task) {//adam task located in Kernel mem
j+=MSize2(task1);
m+=MSize2(task1->code_heap);
if (task1->data_heap!=task1->code_heap)
m+=MSize2(task1->code_heap);
}
n+=TaskQueSize(task1);
task1=task1->next_task;
} while (task1!=c->seth_task);
task1=c->idle_task;
j+=MSize2(task1);
m+=MSize2(task1->code_heap);
if (task1->data_heap!=task1->code_heap)
m+=MSize2(task1->code_heap);
}
"TaskStructs\t:%010X\n",j;
"TSSes\t:%010X\n",k;
"HeapCtrls\t:%010X\n",m;
"TaskQues\t:%010X\n",n;
"BlkDevs\t:%010X\n",BlkDevsSize;
"Prts\t:%010X\n",PrtsSize;
"Audio\t:%010X\n",CallExtStr("AudioSize");
if (sys_dsk_cache_base)
"DskCache\t:%010X\n",
MSize2(sys_dsk_cache_base)+MSize2(sys_dsk_cache_hash_table)+MSize2(sys_dsk_cache_ctrl);
"WordStat\t:%010X\n",CallExtStr("WordStatSize");
"Clipboard\t:%010X\n",DocSize(sys_clipboard_doc);
}
"$$ID,-2$$";
return TRUE;
}
public U0 MemRep()
{
I64 i;
CTask *task;
CCPU *c;
U32 *u32_ptr;
Bool old_preempt=Preempt(OFF);
CBinFile *bfh=sys_boot_base-sizeof(CBinFile);
bfh(I64)+=bfh->file_size-1;
"$$FG,BLACK$$Low Memory\t:0000100000$$FG$$\n$$ID,2$$";
u32_ptr=SYS_BOOT_BASE;
"Kernel\t:%010X-%010X\n",*u32_ptr-sizeof(CBinFile),bfh;
"VGA\t\t:00000A0000-00000BFFFF\n";
"$$ID,-2$$$$FG,BLACK$$High Memory\t:0000100000-%010X$$FG$$\n",
sys_heap_limit;
"$$ID,2$$Page Tables\t:%010X-%010X\n",PAGE_TABLE_BASE,sys_heap_base-1;
"$$ID,-2$$";
if (sys_data_bp) {
"$$FG,BLACK$$Code Heap:%010X Used:%010X $$FG,RED$$Unused:%010X$$FG$$\n",
sys_code_bp->size*PAGE_SIZE,sys_code_bp->allocated_u8s,UnusedBPMem(sys_code_bp);
"$$FG,BLACK$$Data Heap:%010X Used:%010X $$FG,RED$$Unused:%010X$$FG$$\n",
sys_data_bp->size*PAGE_SIZE,sys_data_bp->allocated_u8s,UnusedBPMem(sys_data_bp);
} else
"$$FG,BLACK$$Code/Data Heap:%010X Used:%010X $$FG,RED$$Unused:%010X$$FG$$\n",
sys_code_bp->size*PAGE_SIZE,sys_code_bp->allocated_u8s,UnusedBPMem(sys_code_bp);
for (i=0;i<mp_cnt;i++) {
c=&cpu_structs[i];
"$$FG,GREEN$$CPU%d$$FG$$\n$$ID,2$$",i;
task=c->seth_task;
do {
if (!MemRepTask(task))
break;
task=task->next_task;
} while (task!=c->seth_task);
MemRepTask(c->idle_task,TRUE);
"$$ID,-2$$";
}
"$$FG,GREEN$$Independent Heaps$$FG$$\n$$ID,2$$";
"$$FG,BLACK$$sys_uncached_heap:%010X Used:%010X $$FG,RED$$Unused:%010X$$FG$$\n",
sys_uncached_heap->bp->size*PAGE_SIZE,sys_uncached_heap->used_u8s,UnusedBPMem(sys_uncached_heap->bp);
"$$ID,-2$$\n";
Preempt(old_preempt);
}
#help_index ""
+241
View File
@@ -0,0 +1,241 @@
#help_index "Menus"
#help_file "::/TempleOS/Doc/Menus"
CMenuEntry *sys_cur_submenu_entry=NULL;
public CMenuEntry *MenuSubEntryFind(CMenuEntry *first,U8 *entry_name)
{
while (first) {
if (!StrCmp(first->name,entry_name))
return first;
first=first->next;
}
return NULL;
}
public CMenuEntry *MenuEntryFind(CMenu *m,U8 *full_name)
{
U8 *st,*st2;
CMenuEntry *tempse;
if (!m || m->mu_signature!=MENU_SIGNATURE_VAL || !full_name)
return NULL;
st=StrNew(full_name);
st2=StrNew(full_name);
tempse=(&m->sub)(U8 *)-offset(CMenuEntry.sub);
while (*st && tempse) {
StrFirstRem(st,"/",st2);
tempse=MenuSubEntryFind(tempse->sub,st2);
}
return tempse;
}
CMenuEntry *MenuNewSub(CLex *lx,CTask *task)
{
CMenuEntry *tempme=NULL,*tempse;
if (lx->token==TK_IDENT) {
tempme=CAlloc(sizeof(CMenuEntry),task);
if (StrLen(lx->ident)>31)
lx->ident[31]=0;
StrCpy(tempme->name,lx->ident);
Lex(lx); //skip ident
if (lx->token=='(') {
tempme->msg_code=MSG_KEY_DOWN_UP;
Lex(lx); //Skip (
if (lx->token!=',' && lx->token!=')')
tempme->msg_code=Expression(lx);
if (lx->token==',')
Lex(lx);
if (lx->token!=',' && lx->token!=')')
tempme->p1=Expression(lx);
if (lx->token==',')
Lex(lx);
if (lx->token!=',' && lx->token!=')')
tempme->p2=Expression(lx);
if (lx->token!=')')
LexExcept(lx,"ST_MISSING_RIGHT_PAREN");
if (Lex(lx)!=';')
LexExcept(lx,"ST_MISSING_SEMICOLON");
Lex(lx); //Skip ;
} else if (lx->token=='{') {
Lex(lx); //Skip {
tempme->dir=TRUE;
tempse=&tempme->sub;
while (tempse && lx->token!='}')
tempse=tempse->next=MenuNewSub(lx,task);
if (lx->token!='}')
LexExcept(lx,"ST_MISSING_RIGHT_BRACE");
else
Lex(lx); //Skip }
} else
LexExcept(lx,"ST_EXPECTING_LEFT_BRACE");
}
return tempme;
}
public CMenu *MenuNew(U8 *st,I64 flags=0,CTask *task=NULL)
{
CMenu *m;
CMenuEntry *tempse;
CLex *lx=LexNew(st,LF_DONT_FREE_BUF);
if (!task) task=Fs;
Lex(lx);
m=CAlloc(sizeof(CMenu),task);
m->task=task;
m->flags=flags;
m->attr =LTBLUE<<4 +YELLOW;
m->checked_attr=LTGREEN<<4+BROWN;
tempse=&m->sub;
while (tempse)
tempse=tempse->next=MenuNewSub(lx,task);
LexDel(lx);
m->mu_signature=MENU_SIGNATURE_VAL;
return m;
}
public CMenu *MenuFile(U8 *filename,I64 flags=0,CTask *task=NULL)
{
CMenu *m;
U8 *st=MSPrintF("#include \"%s\"",filename);
m=MenuNew(st,flags,task);
Free(st);
return m;
}
U0 MenuDelSub(CMenuEntry *tempme)
{
CMenuEntry *tempse,*tempse1;
if (tempme) {
tempse=tempme->sub;
while (tempse) {
tempse1=tempse->next;
MenuDelSub(tempse);
tempse=tempse1;
}
Free(tempme);
}
}
public U0 MenuDel(CMenu *m)
{
CMenuEntry *tempme,*tempme1;
if (!m || m->mu_signature!=MENU_SIGNATURE_VAL)
return;
m->mu_signature=0;
tempme=m->sub;
while (tempme) {
tempme1=tempme->next;
MenuDelSub(tempme);
tempme=tempme1;
}
Free(m);
}
I64 MenuEntryWidth(CMenuEntry *tempme)
{
I64 result=StrLen(tempme->name);
CMenuEntry *tempse=tempme->sub;
while (tempse) {
result=MaxI64(result,StrLen(tempse->name));
tempse=tempse->next;
}
return result+1;
}
public CMenu *MenuPush(U8 *st)
{
CMenu *m=MenuNew(st);
m->next=Fs->cur_menu;
Fs->cur_menu=m;
return m;
}
public CMenu *MenuFilePush(U8 *filename)
{
CMenu *m=MenuFile(filename);
m->next=Fs->cur_menu;
Fs->cur_menu=m;
return m;
}
public U0 MenuPop()
{
CMenu *m=Fs->cur_menu;
if (!m) return;
Fs->cur_menu=m->next;
MenuDel(m);
}
U0 DrawMenu(CDC *dc)
{
CMenu *m;
CMenuEntry *tempme,*tempse,*cur_submenu=NULL;
U8 *st=NULL;
CTask *task=sys_focus_task;
I64 i,w,x0,y0,x1=ipx,y1=ipy;
if (!TaskValidate(task) || !(m=task->cur_menu) ||
m->mu_signature!=MENU_SIGNATURE_VAL) {
sys_cur_submenu_entry=NULL;
return;
}
dc->color=m->attr>>4;
GrRect(dc,0,0,GR_WIDTH,FONT_HEIGHT);
x0=0;
tempme=m->sub;
while (tempme) {
w=MenuEntryWidth(tempme)*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;
GrPutS(dc,x0,0,tempme->name);
y0=FONT_HEIGHT;
tempse=tempme->sub;
while (tempse) {
if (tempse->checked)
i=m->checked_attr;
else
i=m->attr;
if (y0<=y1<y0+FONT_HEIGHT) {
if (tempse->msg_code==MSG_KEY_DOWN||tempse->msg_code==MSG_KEY_DOWN_UP) {
if (!tempse->p2)
tempse->p2=A2ScanCode(tempse->p1);
st=ScanCode2KeyName(tempse->p2);
}
sys_cur_submenu_entry=cur_submenu=tempse;
dc->color=i&15;
GrRect(dc,x0,y0,w,FONT_HEIGHT);
dc->color=i>>4;
GrPutS(dc,x0,y0,tempse->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;
GrPutS(dc,x0+w,y0,st);
Free(st);
}
} else {
dc->color=i>>4;
GrRect(dc,x0,y0,w,FONT_HEIGHT);
dc->color=i&15;
GrPutS(dc,x0,y0,tempse->name);
}
y0+=FONT_HEIGHT;
tempse=tempse->next;
}
} else {
dc->color=m->attr&15;
GrPutS(dc,x0,0,tempme->name);
}
x0+=w;
tempme=tempme->next;
}
sys_cur_submenu_entry=cur_submenu;
}
#help_index ""
+91
View File
@@ -0,0 +1,91 @@
#help_index "Utils;Cmd Line (Typically)"
CDirEntry MCMatchFind(CDirEntry *pattern,CDirEntry *lst)
{
while (lst) {
if (!StrCmp(pattern->name,lst->name))
return lst;
lst=lst->next;
}
return NULL;
}
U0 MergeChkLst(CDirEntry *m1,CDirEntry *m2,I64 *_fuf_flags,I64 *_df_flags)
{
I64 i;
CDirEntry *tempm2;
while (m1 && !(*_df_flags & DF_ABORT_ALL_FILES)) {
tempm2=MCMatchFind(m1,m2);
if (!tempm2)
"$$FG,BROWN$$Does Not Exist:%s$$FG$$\n",m1->full_name;
else {
if (m1->attr & _ATTR_DIR)
MergeChkLst(m1->sub,tempm2->sub,_fuf_flags,_df_flags);
else {
i=m1->datetime-tempm2->datetime;
if (AbsI64(i)>CDATE_FREQ*2) { //Filedates can shift due to conversion
"" m1->full_name;
NewLine;
if (Bt(_fuf_flags,FUf_DIFF)) {
if (FilesFindMatch(FILENAME_MASK_TXT,m1->full_name))
Diff(tempm2->full_name,m1->full_name,_df_flags);
}
}
}
}
m1=m1->next;
}
}
public U0 MergeChk(
U8 *dst_files_find_mask="/TempleOS/*",
U8 *src_files_find_mask="/TempleOS/*",
U8 *fu_flags=NULL)
//"+d"=Do $LK,"Diff","MN:Diff"$() on files
{
I64 df_flags=0,fuf_flags=0;
CDirEntry *tempm1=NULL,*tempm2=NULL;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (fuf_flags&~(FUG_FILES_FIND|FUF_DIFF))
throw(EXCEPT_FUF,3);
PrintFWarn("This is based strictly on file dates.\n");
tempm1=FilesFind(src_files_find_mask,fuf_flags&FUG_FILES_FIND);
tempm2=FilesFind(dst_files_find_mask,fuf_flags&FUG_FILES_FIND);
fuf_flags&=FUF_DIFF;
MergeChkLst(tempm1,tempm2,&fuf_flags,&df_flags);
CDirLstDel(tempm1);
CDirLstDel(tempm2);
}
#help_index "Utils;Cmd Line (Typically)"
U0 LstNewFilesLst(CDirEntry *tempm,CDate spdt)
{
while (tempm) {
if (tempm->datetime>spdt) {
"" tempm->full_name;
NewLine;
}
LstNewFilesLst(tempm->sub,spdt);
tempm=tempm->next;
}
}
public U0 LstNewFiles(U8 *files_find_mask="/TempleOS/*",CDate spdt=0,
U8 *fu_flags=NULL)
//"+T"=is just text files
{
I64 fuf_flags=0;
CDirEntry *tempm1=NULL;
if (!spdt)
spdt=sys_compile_time;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),"+r+T");
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
if (tempm1=FilesFind(files_find_mask,fuf_flags)) {
LstNewFilesLst(tempm1,spdt);
CDirLstDel(tempm1);
}
}
#help_index ""
+200
View File
@@ -0,0 +1,200 @@
#help_index "Debugging/Profiler;Utils/Profiler;Profiler"
#help_file "::/TempleOS/Doc/Profiler"
#define PF_ARRAY_CNT 0x100000
I64 pf_time_start,pf_time_end;
I64 pf_low=0,pf_high=SYS_KERNEL_END,pf_size=PF_ARRAY_CNT;
I64 *pf_array=NULL;
I64 pf_cpu=0;
U0 (*fp_chained_timer_routine)(CTask *task)=cpu_structs[pf_cpu].timer_irq_chain;
I64 pf_ptr,pf_depth;
#define PFM_OFF 0
#define PFM_BIN 1
#define PFM_ALL 2
I64 prof_mode=PFM_OFF;
F64 pf_t0;
U0 ProfTimerInt(CTask *task)
{
I64 i,j=task->rip,k;
nobound_switch (prof_mode) {
case PFM_OFF:
break;
case PFM_BIN:
i=(j-pf_low) * pf_size/(pf_high-pf_low);
if (0<=i<pf_size)
pf_array[i]++;
break;
case PFM_ALL:
for (k=0;k<=pf_depth;k++) {
if (task==Gs->idle_task)
j=SYS_IDLE_PT;
else
j=TaskCaller(task,k,TRUE);
if (pf_ptr<PF_ARRAY_CNT) {
pf_array[pf_ptr++]=j;
if (pf_ptr==PF_ARRAY_CNT)
pf_time_end=sys_jiffies;
}
}
break;
}
(*fp_chained_timer_routine)(task);
}
cpu_structs[pf_cpu].timer_irq_chain=&ProfTimerInt;
public U0 ProfBin(U8 *start,I64 cnt=PF_ARRAY_CNT*3)
//Start profiler in bin mode. Profilers
//report where time is spent by checking
//the instruction ptr during the
//timer interrupt. Do a $LK,"ProfRep","MN:ProfRep"$(), (profiler report)
//after you have collected data.
{
if (cnt<PF_ARRAY_CNT)
pf_size=cnt;
else
pf_size=PF_ARRAY_CNT;
pf_low=start;
pf_high=start+cnt;
if (!pf_array)
pf_array=AMAlloc(sizeof(I64)*PF_ARRAY_CNT);
MemSet(pf_array,0,PF_ARRAY_CNT*sizeof(I64));
pf_time_end=0;
pf_time_start=sys_jiffies;
prof_mode=PFM_BIN;
pf_t0=tT;
}
public U0 ProfCPUSet(I64 num)
{
if (num>=mp_cnt)
ST_ERR_ST "Invalid CPU\n";
else if (cpu_structs[pf_cpu].timer_irq_chain!=&ProfTimerInt)
ST_ERR_ST "Unchaining not implemented!\n";
else {
cpu_structs[pf_cpu].timer_irq_chain=fp_chained_timer_routine;
pf_cpu=num;
fp_chained_timer_routine=cpu_structs[pf_cpu].timer_irq_chain;
cpu_structs[pf_cpu].timer_irq_chain=&ProfTimerInt;
}
}
public U0 ProfAll(I64 depth=0)
//Start profiler in record-all mode. Profilers
//report where time is spent by checking
//the instruction ptr during the
//timer interrupt. Do a $LK,"ProfRep","MN:ProfRep"$(), (profiler report)
//after you have collected data.
{
pf_depth=depth;
pf_ptr=0;
if (!pf_array)
pf_array=AMAlloc(sizeof(I64)*PF_ARRAY_CNT);
pf_time_end=0;
pf_time_start=sys_jiffies;
prof_mode=PFM_ALL;
pf_t0=tT;
}
I64 PFACompare(U8 *i1,U8 *i2)
{
if (i1<i2)
return -1;
else if (i1>i2)
return 1;
else
return 0;
}
public U0 ProfRep(I64 filter_cnt=1)
{
F64 pf_tf=tT;
I64 i,ip,last_ip=pf_low,hits,
total_time,routine_total=0,old_mode=prof_mode;
U8 buf[128],buf2[128],buf3[128],last_buf[128];
prof_mode=PFM_OFF;
if (pf_time_end)
total_time=pf_time_end-pf_time_start;
else
total_time=sys_jiffies-pf_time_start;
if (!total_time) total_time=1;
switch (old_mode) {
case PFM_BIN:
*last_buf=0;
for (i=0;i<pf_size;i++) {
ip=pf_low+i*(pf_high-pf_low)/pf_size;
SPrintF(buf,"%P",ip);
StrCpy(buf3,buf);
StrFirstRem(buf3,"+",buf2);
if (StrCmp(buf2,last_buf)) {
if (*last_buf && routine_total>=filter_cnt) {
"$$FG,GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time,
routine_total*10000/total_time%100,routine_total;
"%s\n$$FG$$",last_buf;
}
StrCpy(last_buf,buf2);
routine_total=0;
}
hits=pf_array[i];
routine_total+=hits;
if (hits>=filter_cnt) {
"%3d.%02d%% %08X:",hits*100/total_time,
hits*10000/total_time%100,hits;
if (!PutSrcLink(ip,ip-last_ip))
"%s\n",buf;
else
NewLine;
last_ip=ip;
}
}
if (*last_buf && routine_total>=filter_cnt) {
"$$FG,GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time,
routine_total*10000/total_time%100,routine_total;
"%s\n$$FG$$",last_buf;
}
break;
case PFM_ALL:
QSortI64(pf_array,pf_ptr,&PFACompare);
*last_buf=0;
for (i=0;i<pf_ptr;i++) {
ip=pf_array[i];
hits=0;
while (pf_array[i]==ip) {
hits++;
i++;
if (i>=pf_ptr) break;
}
SPrintF(buf,"%P",ip);
StrCpy(buf3,buf);
StrFirstRem(buf3,"+",buf2);
if (StrCmp(buf2,last_buf)) {
if (*last_buf && routine_total>=filter_cnt) {
"$$FG,GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time,
routine_total*10000/total_time%100,routine_total;
"%s\n$$FG$$",last_buf;
}
StrCpy(last_buf,buf2);
routine_total=0;
}
routine_total+=hits;
if (hits>=filter_cnt) {
"%3d.%02d%% %08X:",hits*100/total_time,
hits*10000/total_time%100,hits;
if (!PutSrcLink(ip,ip-last_ip))
"%s\n",buf;
else
NewLine;
last_ip=ip;
}
}
if (*last_buf && routine_total>=filter_cnt) {
"$$FG,GREEN$$%3d.%02d%% %08X:",routine_total*100/total_time,
routine_total*10000/total_time%100,routine_total;
"%s\n$$FG$$",last_buf;
}
break;
}
"Total Time:%12.6fs\n",pf_tf-pf_t0;
}
#help_index ""
+69
View File
@@ -0,0 +1,69 @@
#help_index "Utils;Cmd Line (Typically)"
//$LK,"StrUtil","MN:StrUtil"$() operations on files
public U0 SUFile(U8 *name,I64 su_flags,F64 indent_scale_factor)
{//String utility on a single file
//See $LK,"SU Flags","MN:SUF_SINGLE_SPACE"$
U8 *dst;
Bool chged=FALSE;
I64 reduced=0;
CDoc *doc=DocRead(name,DOCF_PLAIN_TEXT_WITH_TABS | DOCF_NO_CURSOR);
CDocEntry *doc_e=doc->root.next;
while (doc_e!=doc) {
if (doc_e->type_u8==DOCT_TEXT) {
dst=MStrUtil(doc_e->tag,su_flags,indent_scale_factor);
if (StrCmp(dst,doc_e->tag)) {
reduced+=StrLen(doc_e->tag)-StrLen(dst);
chged=TRUE;
Free(doc_e->tag);
doc_e->tag=dst;
} else
Free(dst);
}
doc_e=doc_e->next;
}
if (chged) {
"Reduced %s by %d chars\n",name,reduced;
StrCpy(doc->filename.name,name);
DocWrite(doc);
}
DocDel(doc);
}
U0 SULst(CDirEntry *tempm1,I64 su_flags,F64 indent_scale_factor)
{
CDirEntry *tempm2;
while (tempm1) {
tempm2=tempm1->next;
if (tempm1->attr & _ATTR_DIR) {
if (tempm1->sub) {
"%S%s\n","ST_SCANNING_DIR",tempm1->full_name;
SULst(tempm1->sub,su_flags,indent_scale_factor);
}
} else
SUFile(tempm1->full_name,su_flags,indent_scale_factor);
CDirEntryDel(tempm1);
tempm1=tempm2;
}
}
public U0 SU(U8 *files_find_mask,I64 su_flags,U8 *fu_flags=NULL,F64 indent_scale_factor=0)
{//Apply string utilities to files
//You can convert spaces to tabs, for example
//or removing trailing spaces on lines.
//See $LK,"SU Flags","MN:SUF_SINGLE_SPACE"$
I64 fuf_flags=0;
GetFFlags(&fuf_flags,Define("ST_FILE_UTIL_FLAGS"),fu_flags);
SULst(FilesFind(files_find_mask,fuf_flags),su_flags,indent_scale_factor);
}
public U0 S2T(U8 *files_find_mask,U8 *fu_flags=NULL)
{
//Spaces to tabs.
//Use "Hard Space" (SHIFT-SPACE) for spaces
//in string constants in your code.
SU(files_find_mask,SUF_S2T|SUF_REM_TRAILING,fu_flags);
}
#help_index ""
+651
View File
@@ -0,0 +1,651 @@
#help_index "Snd/HDAudio"
#define HD_1_CHAN 0
#define HD_2_CHAN 1
#define HD_3_CHAN 2
#define HD_4_CHAN 3
#define HD_8_BIT 0
#define HD_16_BIT 1
#define HD_20_BIT 2
#define HD_24_BIT 3
#define HD_32_BIT 4
#define HD_48kHz 0
#define HD_DFT_OUT_FMT (HD_2_CHAN+HD_24_BIT<<4+HD_48kHz<<8)
#define HD_DFT_IN_FMT (HD_2_CHAN+HD_16_BIT<<4+HD_48kHz<<8)
#define HD_POS_BUF_MULTIPLES 0x1000
#define HD_CORB_ENTRIES 256
#define HD_RIRB_ENTRIES 256
#define HD_BDL_ENTRIES 256
#define HD_GCTL 0x08
#define HD_STATESTS 0x0E
#define HD_GSTS 0x10
#define HD_CORBLBASE 0x40
#define HD_CORBUBASE 0x44
#define HD_CORBWP 0x48
#define HD_CORBRP 0x4A
#define HD_CORBCTL 0x4C
#define HD_CORBST 0x4D
#define HD_RIRBLBASE 0x50
#define HD_RIRBUBASE 0x54
#define HD_RIRBWP 0x58
#define HD_RIRBCTL 0x5C
#define HD_RIRBSTS 0x5D
#define STRCTL 0x00
#define STRSTS 0x03
#define STRLPIB 0x04
#define STRCBL 0x08
#define STRLVI 0x0C
#define STRFIFOW 0x0E
#define STRFIFOS 0x10
#define STRFMT 0x12
#define STRBDPL 0x18
#define STRBDPU 0x1C
#define ISTR0 0x080
#define ISTR1 0x0A0
#define ISTR2 0x0C0
#define ISTR3 0x0E0
#define OSTR0 0x100
#define OSTR1 0x120
#define OSTR2 0x140
#define OSTR3 0x160
#define VERB_GET_PARAM 0xF0000
#define VERB_CONNECT_SELECT_GET 0xF0100
#define VERB_CONNECT_SELECT_SET 0x70100
#define VERB_GET_CONNECT_LST 0xF0200
#define VERB_PROCESS_STATE_GET 0xF0300
#define VERB_PROCESS_STATE_SET 0x70300
#define VERB_COEFF_INDEX_GET 0xD0000
#define VERB_COEFF_INDEX_SET 0x50000
#define VERB_PROCESS_COEFF_GET 0xC0000
#define VERB_PROCESS_COEFF_SET 0x40000
#define VERB_AMPLIFIER_GAIN_GET 0xB0000
#define VERB_AMPLIFIER_GAIN_SET 0x30000
#define VERB_STREAM_FMT_GET 0xA0000
#define VERB_STREAM_FMT_SET 0x20000
#define VERB_DIGIT_CONVERT1_GET 0xF0D00
#define VERB_DIGIT_CONVERT1_SET 0x70D00
#define VERB_DIGIT_CONVERT2_GET 0xF0D00
#define VERB_DIGIT_CONVERT2_SET 0x70E00
#define VERB_POWER_STATE_GET 0xF0500
#define VERB_POWER_STATE_SET 0x70500
#define VERB_CHAN_STREAM_ID_GET 0xF0600
#define VERB_CHAN_STREAM_ID_SET 0x70600
#define VERB_SDI_SELECT_GET 0xF0400
#define VERB_SDI_SELECT_SET 0x70400
#define VERB_PIN_WIDGET_CTL_GET 0xF0700
#define VERB_PIN_WIDGET_CTL_SET 0x70700
#define VERB_UNSOL_ENABLE_GET 0xF0800
#define VERB_UNSOL_ENABLE_SET 0x70800
#define VERB_PIN_SENSE_GET 0xF0900
#define VERB_PIN_SENSE_SET 0x70900
#define VERB_EAPDBTL_ENABLE_GET 0xF0C00
#define VERB_EAPDBTL_ENABLE_SET 0x70C00
#define VERB_BEEP_CTL_GET 0xF0A00
#define VERB_BEEP_CTL_SET 0x70A00
#define VERB_GPI_CTRL0_GET 0xF1000
#define VERB_GPI_CTRL0_SET 0x71000
#define VERB_GPI_CTRL1_GET 0xF1100
#define VERB_GPI_CTRL1_SET 0x71100
#define VERB_GPI_CTRL2_GET 0xF1200
#define VERB_GPI_CTRL2_SET 0x71200
#define VERB_GPI_CTRL3_GET 0xF1300
#define VERB_GPI_CTRL3_SET 0x71300
#define VERB_GPI_CTRL4_GET 0xF1400
#define VERB_GPI_CTRL4_SET 0x71400
#define VERB_GPI_CTRL5_GET 0xF1500
#define VERB_GPI_CTRL5_SET 0x71500
#define VERB_GPI_CTRL6_GET 0xF1600
#define VERB_GPI_CTRL6_SET 0x71600
#define VERB_GPI_CTRL7_GET 0xF1700
#define VERB_GPI_CTRL7_SET 0x71700
#define VERB_GPI_CTRL8_GET 0xF1800
#define VERB_GPI_CTRL8_SET 0x71800
#define VERB_GPI_CTRL9_GET 0xF1900
#define VERB_GPI_CTRL9_SET 0x71900
#define VERB_GPI_CTRLA_GET 0xF1A00
#define VERB_GPI_CTRLA_SET 0x71A00
#define VERB_VOL_CTL_GET 0xF0F00
#define VERB_VOL_CTL_SET 0x70F00
#define VERB_SUB_SYS_ID0_GET 0xF2000
#define VERB_SUB_SYS_ID0_SET 0x72000
#define VERB_SUB_SYS_ID1_GET 0xF2000
#define VERB_SUB_SYS_ID1_SET 0x72100
#define VERB_SUB_SYS_ID2_GET 0xF2000
#define VERB_SUB_SYS_ID2_SET 0x72200
#define VERB_SUB_SYS_ID3_GET 0xF2000
#define VERB_SUB_SYS_ID3_SET 0x72300
#define VERB_CFG_DFT0_GET 0xF1C00
#define VERB_CFG_DFT0_SET 0x71C00
#define VERB_CFG_DFT1_GET 0xF1C00
#define VERB_CFG_DFT1_SET 0x71D00
#define VERB_CFG_DFT2_GET 0xF1C00
#define VERB_CFG_DFT2_SET 0x71E00
#define VERB_CFG_DFT3_GET 0xF1C00
#define VERB_CFG_DFT3_SET 0x71F00
#define VERB_STRIPE_CTL_GET 0xF2400
#define VERB_STRIPE_CTL_SET 0x72400
#define VERB_RST 0x7FF00
//Parameters
#define P_VENDOR_ID 0x00
#define P_REVISION_ID 0x02
#define P_SUBNODE_CNT 0x04
#define P_FUN_GRP_TYPE 0x05
#define P_AUDIO_FUN_CAP 0x08
#define P_AUDIO_WIDGET_CAP 0x09
#define P_SAMPLE_SIZE_RATE_CAP 0x0A
#define P_STREAM_FMTS 0x0B
#define P_PIN_CAP 0x0C
#define P_INPUT_AMP_CAP 0x0D
#define P_OUTPUT_AMP_CAP 0x12
#define P_CONNECT_LST_LEN 0x0E
#define P_POWER_STATES 0x0F
#define P_PROCESSING_CAP 0x10
#define P_GPIO_CNT 0x11
#define P_VOL_KNOB_CAP 0x13
//Function Group Types
//00 reserved
#define FGT_AUDIO 1
#define FGT_VENDOR_MODEM 2
//03-7F reserved
//80-FF vendor function group
//Audio Widget Types
#define AWT_OUTPUT 0x0
#define AWT_INPUT 0x1
#define AWT_MIXER 0x2
#define AWT_SELECTOR 0x3
#define AWT_PIN_COMPLEX 0x4
#define AWT_POWER_WIDGET 0x5
#define AWT_VOL_KNOB_WIDGET 0x6
#define AWT_BEEP_GEN_WIDGET 0x7
#define AWT_VENDOR 0xF
#define AWT_NODE 0x10
DefineLstLoad("ST_AUDIO_WIDGET_TYPES",
"Output\0Input\0Mixer\0Selector\0Pin Complex\0"
"Power Widget\0Vol Knob\0Beep Gen\0 \0 \0 \0 \0 \0 \0 \0Vendor\0Node\0");
class CHDBufDesc
{
I32 *buf;
U32 len;
U32 ctrl;
};
#define HD_TONES 8
class CHDAudioCtrl
{
U8 *bar;
I64 cad;
U32 *corb;
I64 *rirb;
CHDBufDesc *ostr0_bdl,*istr0_bdl;
SND_OUT_CONTAINER *ostr0_buf[2],*o_temp_buf;
SND_IN_CONTAINER *istr0_buf[2];
CTask *task;
I64 waveform;
F64 freq,amp;
CSndWaveCtrl *tone_swcs[HD_TONES];
U8 rirb_rp,corb_wp;
Bool audio_task_started,in_running,out_running;
} *_hda=NULL;
I64 AudioSize()
{//$LK,"MemRep","MN:MemRep"$ uses this for Adam Heap
I64 result=MSize2(snd_reverb_buf);
if (_hda) {
result+=MSize2(_hda)+MSize2(_hda->o_temp_buf);
/* uncached heap
result+=MSize2(_hda->corb)+MSize(_hda->rirb)+
MSize2(_hda->ostr0_bdl)+MSize2(_hda->istr0_bdl);
for (i=0;i<2;i++)
result+=MSize2(_hda->ostr0_buf[i]);
for (i=0;i<2;i++)
result+=MSize2(_hda->istr0_buf[i]);
*/
}
return result;
}
U0 HDSyncCORB()
{
U16 *wp,*rp;
wp =_hda->bar+HD_CORBWP;
*wp=_hda->corb_wp;
rp =_hda->bar+HD_CORBRP;
while (*rp&255!=_hda->corb_wp)
Yield;
}
U0 HDWriteCORB(I64 cad,I64 nid,U32 val)
{
val|=cad<<28+nid<<20;
_hda->corb[++_hda->corb_wp]=val;
}
I64 HDSyncRIRB()
{
U16 *_w;
I64 wp,result=0;
_w=_hda->bar+HD_RIRBWP;
wp=*_w;
while (_hda->rirb_rp!=wp)
result=_hda->rirb[++_hda->rirb_rp];
return result;
}
I64 HDReadRIRB()
{
U16 *_w;
I64 wp,result=0;
_w=_hda->bar+HD_RIRBWP;
do {
Yield;
wp=*_w;
} while (wp==_hda->rirb_rp);
result=_hda->rirb[++_hda->rirb_rp];
return result;
}
I64 HDWriteCORBSync(I64 cad,I64 nid,U32 val)
{
HDSyncCORB;
HDSyncRIRB;
HDWriteCORB(cad,nid,val);
HDSyncCORB;
return HDReadRIRB;
}
Bool HDTestCORBSync(I64 cad,I64 nid,U32 val)
{ //Checks for a response
U16 *_w;
U8 wp;
HDSyncCORB;
HDSyncRIRB;
HDWriteCORB(cad,nid,val);
HDSyncCORB;
Sleep(1);
_w=_hda->bar+HD_RIRBWP;
wp=*_w;
if (wp==_hda->rirb_rp)
return FALSE;
HDReadRIRB;
return TRUE;
}
U0 HDTraverse(I64 cad,I64 nid)
{
I64 i,len,aud_cap,type;
HDWriteCORBSync(cad,nid,VERB_POWER_STATE_SET+0x00); //0 is on
HDWriteCORBSync(cad,nid,VERB_EAPDBTL_ENABLE_SET+0x02);
HDWriteCORBSync(cad,nid,VERB_PROCESS_STATE_SET+0x02);
HDWriteCORBSync(cad,nid,VERB_CONNECT_SELECT_SET+0x00);
aud_cap=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_SUBNODE_CNT);
if (aud_cap.u16[0]) {
for (i=aud_cap.u16[1];i<aud_cap.u16[1]+aud_cap.u16[0];i++)
HDTraverse(cad,i);
} else {
aud_cap=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_AUDIO_WIDGET_CAP);
type=aud_cap>>20&15;
if (Bt(&aud_cap,8))
len=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_CONNECT_LST_LEN)&127;
else
len=0;
HDWriteCORBSync(cad,nid,VERB_AMPLIFIER_GAIN_SET+0xF07F); //set I/O amp #0
for (i=1;i<len;i++)
HDWriteCORBSync(cad,nid,VERB_AMPLIFIER_GAIN_SET+0x7080+i<<8); //Set IN amps to mute
switch (type) {
case AWT_OUTPUT:
if (FALSE) //if disabled
HDWriteCORBSync(cad,nid,VERB_CHAN_STREAM_ID_SET+0x00);
else
HDWriteCORBSync(cad,nid,VERB_CHAN_STREAM_ID_SET+0x10);
HDWriteCORBSync(cad,nid,VERB_STREAM_FMT_SET+HD_DFT_OUT_FMT);
HDWriteCORBSync(cad,nid,VERB_PROCESS_STATE_SET+0x01);
break;
case AWT_INPUT:
if (TRUE) //if disabled
HDWriteCORBSync(cad,nid,VERB_CHAN_STREAM_ID_SET+0x00);
else
HDWriteCORBSync(cad,nid,VERB_CHAN_STREAM_ID_SET+0x20);
HDWriteCORBSync(cad,nid,VERB_STREAM_FMT_SET+HD_DFT_IN_FMT);
HDWriteCORBSync(cad,nid,VERB_PROCESS_STATE_SET+0x01);
break;
case AWT_PIN_COMPLEX:
HDWriteCORBSync(cad,nid,VERB_PIN_WIDGET_CTL_SET+0xE2);
break;
}
}
}
U0 HDRun(Bool in,Bool out)
{
U32 *_d;
if (_hda->bar) {
if (out) {
_d=_hda->bar+OSTR0+STRCTL;
*_d=0x100002;
_hda->out_running=TRUE;
}
if (in) {
_d=_hda->bar+ISTR0+STRCTL;
*_d=0x200002;
_hda->in_running=TRUE;
}
}
}
U0 HDStop(Bool in,Bool out)
{
U32 *_d;
if (_hda->bar) {
if (out) {
_d=_hda->bar+OSTR0+STRCTL;
*_d=0;
_hda->out_running=FALSE;
}
if (in) {
_d=_hda->bar+ISTR0+STRCTL;
*_d=0;
_hda->in_running=FALSE;
}
}
}
U0 HDSnd(F64 freq,I64 waveform=WF_SQUARE,F64 amp=1.0)
{
_hda->waveform=waveform;
_hda->amp=amp;
_hda->freq=freq;
}
U0 HDFillBuf(SND_OUT_CONTAINER *buf,I64)
{
I64 i,size=SND_BUF_LEN*sizeof(SND_OUT_CONTAINER);
if (!_hda->o_temp_buf)
_hda->o_temp_buf=AMAlloc(size);
MemSet(_hda->o_temp_buf,0,size);
for (i=0;i<HD_TONES;i++)
SndWaveAddBuf(_hda->tone_swcs[i],_hda->o_temp_buf,SND_BUF_LEN/SND_OCHANNELS,_hda->freq,_hda->waveform,snd_vol*_hda->amp);
MemCpy(buf,_hda->o_temp_buf,size);
}
U0 HDAudioTaskEndCB()
{
I64 i;
HDStop(FALSE,TRUE);
fp_snd=NULL;
for (i=0;i<HD_TONES;i++) {
SndWaveCtrlDel(_hda->tone_swcs[i]);
_hda->tone_swcs[i]=NULL;
}
Exit;
}
public U0 HDTonesInit()
{
I64 i;
if (_hda) {
for (i=0;i<HD_TONES;i++) {
_hda->tone_swcs[i]->freq_multiplier=1.0;
_hda->tone_swcs[i]->amp_multiplier=0;
}
_hda->tone_swcs[0]->amp_multiplier=1.0;
}
}
U0 HDAudioTask(I64)
{
//I didn't feel like messing around with PCI interrupts
//so this task polls every millisecond to know when to
//switch buffers.
I64 i,next_obuf_trigger=SND_BUF_LEN*sizeof(SND_OUT_CONTAINER)/2,
obuf_rollover=0,
next_ibuf_trigger=SND_BUF_LEN*sizeof(SND_IN_CONTAINER),
ibuf_rollover=0;
U32 *pos_in_obuf=_hda->bar+OSTR0+STRLPIB,
*pos_in_ibuf=_hda->bar+ISTR0+STRLPIB;
Fs->task_end_cb=&HDAudioTaskEndCB;
for (i=0;i<HD_TONES;i++)
_hda->tone_swcs[i]=SndWaveCtrlNew;
HDTonesInit;
_hda->freq=0;
Snd(0);
fp_snd=&HDSnd;
fp_snd_fill_buf=&HDFillBuf;
fp_snd_copy_buf=NULL;
if (!IsSysDeterministic)
Preempt(ON);
snd_obuf_num=1;
snd_ibuf_num=1;
HDRun(FALSE,TRUE);
_hda->audio_task_started=TRUE; //This flag is probably not necessary
while (TRUE) {
if (next_obuf_trigger-obuf_rollover<=*pos_in_obuf<next_obuf_trigger-obuf_rollover+(HD_POS_BUF_MULTIPLES-1)*SND_BUF_LEN*sizeof(SND_OUT_CONTAINER)) {
next_obuf_trigger+=SND_BUF_LEN*sizeof(SND_OUT_CONTAINER);
if (next_obuf_trigger-obuf_rollover>=HD_POS_BUF_MULTIPLES*SND_BUF_LEN*sizeof(SND_OUT_CONTAINER))
obuf_rollover+=HD_POS_BUF_MULTIPLES*SND_BUF_LEN*sizeof(SND_OUT_CONTAINER);
if (fp_snd_fill_buf) {
LBts(&snd_flags,Sf_FILLING_OUT);
(*fp_snd_fill_buf)(_hda->ostr0_buf[snd_obuf_num&1],snd_obuf_num);
if (IsMute)
MemSet(_hda->ostr0_buf[snd_obuf_num&1],0,SND_BUF_LEN*sizeof(SND_OUT_CONTAINER));
else if (snd_reverb_intensity &&
0<snd_reverb_delay<10.0)
SndReverb(_hda->ostr0_buf[snd_obuf_num&1],snd_obuf_num);
LBtr(&snd_flags,Sf_FILLING_OUT);
}
snd_obuf_num++;
}
if (next_ibuf_trigger-ibuf_rollover<=*pos_in_ibuf<next_ibuf_trigger-ibuf_rollover+(HD_POS_BUF_MULTIPLES-1)*SND_BUF_LEN*sizeof(SND_IN_CONTAINER)) {
next_ibuf_trigger+=SND_BUF_LEN*sizeof(SND_IN_CONTAINER);
if (next_ibuf_trigger-ibuf_rollover>=HD_POS_BUF_MULTIPLES*SND_BUF_LEN*sizeof(SND_IN_CONTAINER))
ibuf_rollover+=HD_POS_BUF_MULTIPLES*SND_BUF_LEN*sizeof(SND_IN_CONTAINER);
if (fp_snd_copy_buf)
(*fp_snd_copy_buf)(_hda->istr0_buf[snd_obuf_num&1],snd_ibuf_num);
snd_ibuf_num++;
}
Sleep(1);
}
}
U0 HDRst()
{
U32 d,*_d;
HDStop(TRUE,TRUE);
_d=_hda->bar+HD_GCTL;
*_d=0; //rst
do {
Sleep(1);
d=*_d;
} while (d & 1);
*_d=1;
do {
Sleep(1);
d=*_d;
} while (!(d & 1));
Sleep(1);
}
public U0 HDAudioEnd(Bool rst=TRUE)
{
snd_dev=SD_PC_SPEAKER;
if (_hda && _hda->bar) {
Kill(_hda->task);
_hda->task=NULL;
if (rst)
HDRst;
Free(_hda->corb);
Free(_hda->rirb);
Free(_hda->o_temp_buf);
Free(_hda->ostr0_buf[0]);
Free(_hda->ostr0_buf[1]);
Free(_hda->istr0_buf[0]);
Free(_hda->istr0_buf[1]);
Free(_hda->ostr0_bdl);
Free(_hda->istr0_bdl);
Mem32DevFree(_hda->bar);
Free(_hda);
_hda=NULL;
}
}
public Bool HDAudioInit(I64 hd_bus,I64 hd_dev,I64 hd_fun)
{
I64 i;
U32 *_d;
U16 w,*_w;
U8 *_b;
if (_hda)
HDAudioEnd;
if (PCIReadU16(hd_bus,hd_dev,hd_fun,0)==0x8086 &&
(_hda=ACAlloc(sizeof(CHDAudioCtrl))) &&
(_hda->bar=Mem32DevAlloc(0x4000,0x4000)) ) {
PCIWriteU32(hd_bus,hd_dev,hd_fun,0x14,_hda->bar(I64).u32[1]);
PCIWriteU32(hd_bus,hd_dev,hd_fun,0x10,_hda->bar(I64).u32[0]);
PCIWriteU16(hd_bus,hd_dev,hd_fun,0x04,
PCIReadU16(hd_bus,hd_dev,hd_fun,0x04)|0x406);
HDRst;
_hda->corb=CAllocAligned(HD_CORB_ENTRIES*sizeof(U32),128,sys_uncached_heap);
_d=_hda->bar+HD_CORBLBASE;
*_d=_hda->corb(I64).u32[0];
_d=_hda->bar+HD_CORBUBASE;
*_d=_hda->corb(I64).u32[1];
_hda->rirb=CAllocAligned(HD_RIRB_ENTRIES*sizeof(I64),128,sys_uncached_heap);
_d=_hda->bar+HD_RIRBLBASE;
*_d=_hda->rirb(I64).u32[0];
_d=_hda->bar+HD_RIRBUBASE;
*_d=_hda->rirb(I64).u32[1];
_w=_hda->bar+HD_CORBRP;
*_w=0x8000; //Rst read ptr
do {
Yield;
w=*_w;
} while (!(w&0x8000));
*_w=0x0000; //Rst read ptr
do {
Yield;
w=*_w;
} while (w&0x8000);
_w=_hda->bar+HD_RIRBWP;
*_w=0x8000; //Rst write ptr
_b=_hda->bar+HD_CORBCTL;
*_b=0x02; //Run
_b=_hda->bar+HD_RIRBCTL;
*_b=0x02; //Run
_w=_hda->bar+HD_CORBWP;
_hda->corb_wp=*_w;
_w=_hda->bar+HD_RIRBWP;
_hda->rirb_rp=*_w;
_hda->ostr0_bdl =CAllocAligned(HD_BDL_ENTRIES*sizeof(CHDBufDesc),128,sys_uncached_heap);
_d=_hda->bar+OSTR0+STRBDPL;
*_d=_hda->ostr0_bdl(I64).u32[0];
_d=_hda->bar+OSTR0+STRBDPU;
*_d=_hda->ostr0_bdl(I64).u32[1];
for (i=0;i<2;i++) {
_hda->ostr0_bdl[i].buf=_hda->ostr0_buf[i]=CAllocAligned(SND_BUF_LEN*sizeof(SND_OUT_CONTAINER),128,sys_uncached_heap);
_hda->ostr0_bdl[i].len=SND_BUF_LEN*sizeof(SND_OUT_CONTAINER);
_hda->ostr0_bdl[i].ctrl=1;
}
_hda->istr0_bdl =CAllocAligned(HD_BDL_ENTRIES*sizeof(CHDBufDesc),128,sys_uncached_heap);
_d=_hda->bar+ISTR0+STRBDPL;
*_d=_hda->istr0_bdl(I64).u32[0];
_d=_hda->bar+ISTR0+STRBDPU;
*_d=_hda->istr0_bdl(I64).u32[1];
for (i=0;i<2;i++) {
_hda->istr0_bdl[i].buf=_hda->istr0_buf[i]=CAllocAligned(SND_BUF_LEN*sizeof(SND_IN_CONTAINER),128,sys_uncached_heap);
_hda->istr0_bdl[i].len=SND_BUF_LEN*sizeof(SND_IN_CONTAINER);
_hda->istr0_bdl[i].ctrl=1;
}
_w=_hda->bar+HD_STATESTS;
w=*_w;
while (w) {
_hda->cad=Bsf(w);
if (HDTestCORBSync(_hda->cad,0,VERB_GET_PARAM+P_SUBNODE_CNT)) {
HDTraverse(_hda->cad,0);
_d=_hda->bar+OSTR0+STRLPIB;
*_d=0;
_d=_hda->bar+OSTR0+STRCBL;
*_d=HD_POS_BUF_MULTIPLES*SND_BUF_LEN*sizeof(SND_OUT_CONTAINER);
_w=_hda->bar+OSTR0+STRLVI;
*_w=1; //last valid index
_w=_hda->bar+OSTR0+STRFMT;
*_w=HD_DFT_OUT_FMT;
_d=_hda->bar+ISTR0+STRLPIB;
*_d=0;
_d=_hda->bar+ISTR0+STRCBL;
*_d=HD_POS_BUF_MULTIPLES*SND_BUF_LEN*sizeof(SND_IN_CONTAINER);
_w=_hda->bar+ISTR0+STRLVI;
*_w=1; //last valid index
_w=_hda->bar+ISTR0+STRFMT;
*_w=HD_DFT_IN_FMT;
LBts(&sys_semas[SYS_SEMA_SND],0); //turn off until cfg completed
LBtr(&snd_flags,Sf_FILLING_OUT);
_hda->audio_task_started=FALSE;
if (mp_cnt>1)
_hda->task=MPSpawn(&HDAudioTask,NULL,"HD Audio");
else
_hda->task=Spawn(&HDAudioTask,NULL,"HD Audio");
while (!_hda->audio_task_started)
Yield;
snd_dev=SD_HD_AUDIO;
return TRUE;
}
Btr(&w,_hda->cad);
}
HDAudioEnd(FALSE);
} else {
Free(_hda);
_hda=NULL;
}
return FALSE;
}
Bool HDAudioScan()
{
I64 i=-1,j;
while (TRUE) {
j=PCIClassFind(0x040300,++i);
if (j<0)
return FALSE;
//!!! Remove the following line. !!!
if (j.u8[1]!=0x1B) break;
//!!! We got problems with $LK,"0xF0000000","FF:::/TempleOS/Kernel/Memory.CPP,0xF000000"$ !!!
if (HDAudioInit(j.u8[2],j.u8[1],j.u8[0]))
return TRUE;
}
}
HDAudioScan;
//$BK,1$Run $LK-A,"::/TempleOS/Adam/Snd/HDCfg.CPP"$.$BK,0$
#help_index ""
+638
View File
@@ -0,0 +1,638 @@
#define MAX_CONNECTS 16
class MyMass:CMass
{
F64 radius;
U8 nid,type,num_connects,cur_connect;
U32 audio_widget_capabilities;
U8 connect_lst[MAX_CONNECTS];
U8 gain_lst[MAX_CONNECTS];
U32 pin_capabilities,pin_sense,
pcm_size_rates,
in_amp_cap,out_amp_cap;
U8 pin_widget_ctl;
Bool disabled;
};
class MySpring:CSpring
{
I64 color;
};
CMathODE *ode=NULL;
#define BORDER 10
U0 DrawIt(CTask *task,CDC *dc)
{
Bool old_suspend,old_preempt;
I16 *buf;
I64 i,cxx,cyy,
cy=task->win_pixel_height>>1;
F64 dx,dy,d;
MyMass *tempm;
MySpring *temps;
old_preempt=Preempt(OFF);
old_suspend=Suspend(task);
temps=ode->next_spring;
while (temps!=&ode->next_spring) {
dc->color=temps->color;
GrLine(dc,temps->end1->x,temps->end1->y,
temps->end2->x,temps->end2->y);
cxx=(temps->end1->x+temps->end2->x)/2;
cyy=(temps->end1->y+temps->end2->y)/2;
dx=temps->end1->x-temps->end2->x;
dy=temps->end1->y-temps->end2->y;
d=Sqrt(dx*dx+dy*dy);
dx/=d;
dy/=d;
GrLine(dc,cxx,cyy,cxx+3.0*dy-3.0*dx,cyy-3.0*dx-3.0*dy);
GrLine(dc,cxx,cyy,cxx-3.0*dy-3.0*dx,cyy+3.0*dx-3.0*dy);
temps=temps->next;
}
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (tempm->disabled)
dc->color=BLUE;
else
dc->color=LTBLUE;
GrCircle(dc,tempm->x,tempm->y,tempm->radius);
GrPrintF(dc,tempm->x,tempm->y-FONT_HEIGHT/2,"%02X %3tZ",
tempm->nid,tempm->type,
"ST_AUDIO_WIDGET_TYPES");
tempm=tempm->next;
}
Suspend(task,old_suspend);
Preempt(old_preempt);
dc->color=BLUE;
buf=_hda->istr0_buf[0];
for (i=0;i<SND_BUF_LEN;i++)
GrPlot(dc,i*task->win_pixel_width/SND_BUF_LEN,
cy-buf[i]*cy/MAX_I16);
}
U0 MyDerivative(CMathODE *ode,F64,COrder2D3 *,COrder2D3 *)
{
//The forces due to springs and drag are
//automatically handled by the
//ode code. We can add new forces
//here.
CTask *task=ode->win_task;
I64 h=task->win_pixel_width,v=task->win_pixel_height;
F64 d,dd;
CD3 p;
MyMass *tempm1,*tempm2;
tempm1=ode->next_mass;
while (tempm1!=&ode->next_mass) {
tempm2=tempm1->next;
while (tempm2!=&ode->next_mass) {
D3Sub(&tempm2->state->x,&tempm1->state->x,&p);
dd=D3SqrNorm(&p);
if (dd<=Sqr(tempm1->radius+tempm2->radius)) {
d=Sqrt(dd)+0.0001;
dd=10.0*Sqr(Sqr(Sqr(tempm1->radius+tempm2->radius)-dd));
D3MulEqu(&p,dd/d);
D3AddEqu(&tempm2->DstateDt->DxDt,&p);
D3SubEqu(&tempm1->DstateDt->DxDt,&p);
} else {
D3MulEqu(&p,100000.0/dd);
D3AddEqu(&tempm2->DstateDt->DxDt,&p);
D3SubEqu(&tempm1->DstateDt->DxDt,&p);
}
tempm2=tempm2->next;
}
if (tempm1->state->x<BORDER)
tempm1->DstateDt->DxDt+=1000*Sqr(tempm1->state->x-BORDER);
if (tempm1->state->y<BORDER)
tempm1->DstateDt->DyDt+=1000*Sqr(tempm1->state->y-BORDER);
if (tempm1->state->x>h-BORDER-FONT_WIDTH*6)
tempm1->DstateDt->DxDt-=1000*Sqr(tempm1->state->x-(h-BORDER-FONT_WIDTH*6));
if (tempm1->state->y>v-BORDER)
tempm1->DstateDt->DyDt-=1000*Sqr(tempm1->state->y-(v-BORDER));
tempm1=tempm1->next;
}
}
MyMass *PlaceMass(I64 nid)
{
MyMass *tempm=CAlloc(sizeof(MyMass));
tempm->mass=1.0;
tempm->drag_profile_factor=100.0;
tempm->radius=5;
tempm->nid=nid;
tempm->gain_lst[0]=0x7F;
MemSet(tempm->gain_lst+1,0x80,(MAX_CONNECTS-1)*sizeof(U8));
QueIns(tempm,ode->last_mass);
return tempm;
}
MyMass *FindMassByNID(I64 nid)
{
MyMass *tempm;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
if (tempm->nid==nid)
return tempm;
tempm=tempm->next;
}
return NULL;
}
MyMass *FindMassByXY(I64 x,I64 y)
{
I64 dd,best_dd=MAX_I64;
MyMass *tempm,*result=NULL;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
dd=SqrI64(tempm->x-x)+SqrI64(tempm->y-y);
if (dd<best_dd) {
result=tempm;
best_dd=dd;
}
tempm=tempm->next;
}
return result;
}
I64 FindConnectIndex(MyMass *tempm,I64 nid)
{
I64 i;
for (i=0;i<tempm->num_connects;i++)
if (tempm->connect_lst[i]==nid)
return i;
return -1;
}
MySpring *PlaceSpring(MyMass *tempm1,MyMass *tempm2)
{
MySpring *temps=CAlloc(sizeof(MySpring));
temps->end1=tempm1;
temps->end2=tempm2;
temps->constant=10;
temps->rest_len=0;
temps->color=LTGRAY;
QueIns(temps,ode->last_spring);
return temps;
}
U0 RedoSprings()
{
I64 i,k;
MyMass *tempm,*tempm1;
MySpring *temps;
QueDel(&ode->next_spring,TRUE);
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
for (i=0;i<tempm->num_connects;i++) {
if ((k=tempm->connect_lst[i]) &&
(tempm1=FindMassByNID(k)) ) {
temps=PlaceSpring(tempm,tempm1);
switch (tempm->type) {
case AWT_MIXER:
if (!(tempm->gain_lst[i]&0x80)) { //If not mute
temps->color=GREEN;
temps->constant=100;
}
break;
case AWT_INPUT:
case AWT_SELECTOR:
case AWT_PIN_COMPLEX:
case AWT_VENDOR:
if (i==tempm->cur_connect) {
temps->color=RED;
temps->constant=100;
}
break;
}
}
}
tempm=tempm->next;
}
}
U0 Init()
{
ode=ODENew(0,1e-4,ODEF_HAS_MASSES);
ode->derivative=&MyDerivative;
ode->drag_v2=0.002;
ode->drag_v3=0.00001;
ode->acceleration_limit=5e3;
QueIns(ode,Fs->last_ode);
}
U0 CleanUp()
{
QueRem(ode);
QueDel(&ode->next_mass,TRUE);
QueDel(&ode->next_spring,TRUE);
ODEDel(ode);
}
U0 HDCfgConnectLst(MyMass *tempm,I64 cad,I64 nid)
{
I64 i,j,connection_lst_len;
j=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_CONNECT_LST_LEN);
connection_lst_len=j&127;
if (j&128) { //Long form?
for (i=0;i<connection_lst_len;i+=2) {
j=HDWriteCORBSync(cad,nid,VERB_GET_CONNECT_LST+i);
tempm->connect_lst[tempm->num_connects++]=j.u16[0];
if (i+1<connection_lst_len)
tempm->connect_lst[tempm->num_connects++]=j.u16[1];
}
} else {
for (i=0;i<connection_lst_len;i+=4) {
j=HDWriteCORBSync(cad,nid,VERB_GET_CONNECT_LST+i);
tempm->connect_lst[tempm->num_connects++]=j.u8[0];
if (i+1<connection_lst_len)
tempm->connect_lst[tempm->num_connects++]=j.u8[1];
if (i+2<connection_lst_len)
tempm->connect_lst[tempm->num_connects++]=j.u8[2];
if (i+3<connection_lst_len)
tempm->connect_lst[tempm->num_connects++]=j.u8[3];
}
}
}
U0 HDCfgTraverse(I64 cad,I64 nid)
{
I64 i,j;
MyMass *tempm=PlaceMass(nid);
j=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_SUBNODE_CNT);
if (j.u16[0]) {
tempm->type=AWT_NODE;
for (i=j.u16[1];i<j.u16[1]+j.u16[0];i++)
HDCfgTraverse(cad,i);
} else {
tempm->audio_widget_capabilities=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_AUDIO_WIDGET_CAP);
tempm->pcm_size_rates=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_SAMPLE_SIZE_RATE_CAP);
tempm->in_amp_cap=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_INPUT_AMP_CAP);
tempm->out_amp_cap=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_OUTPUT_AMP_CAP);
tempm->type=tempm->audio_widget_capabilities>>20&15;
switch (tempm->type) {
case AWT_PIN_COMPLEX:
tempm->pin_widget_ctl=HDWriteCORBSync(cad,nid,VERB_PIN_WIDGET_CTL_GET);
tempm->pin_capabilities=HDWriteCORBSync(cad,nid,VERB_GET_PARAM+P_PIN_CAP);
if (Bt(&tempm->pin_capabilities,0) ||
Bt(&tempm->pin_capabilities,2))
tempm->pin_sense=HDWriteCORBSync(cad,nid,VERB_PIN_SENSE_GET);
HDWriteCORBSync(cad,nid,VERB_CONNECT_SELECT_SET+0x00);
break;
case AWT_INPUT:
tempm->disabled=TRUE;
case AWT_SELECTOR:
case AWT_VENDOR:
HDWriteCORBSync(cad,nid,VERB_CONNECT_SELECT_SET+0x00);
break;
}
if (Bt(&tempm->audio_widget_capabilities,8))
HDCfgConnectLst(tempm,cad,nid);
}
}
U0 HDCfgRandomizeXY()
{
I64 h=Fs->win_pixel_width,v=Fs->win_pixel_height;
MyMass *tempm;
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
tempm->x=RandU32%(h-2*BORDER-FONT_WIDTH*6)+BORDER;
tempm->y=RandU32%(v-2*BORDER)+BORDER;
tempm=tempm->next;
}
}
U0 HDCfgPopUpInfoTask(MyMass *tempm)
{
I64 i;
"$$FG,RED$$NID:$$FG$$0x%02X $$FG,RED$$Type:$$FG$$%Z\n",
tempm->nid,tempm->type,"ST_AUDIO_WIDGET_TYPES";
i=tempm->audio_widget_capabilities;
"\n$$FG,RED$$Audio Widget Capabilities:$$FG$$\n";
if (Bt(&i,0))
"Stereo, ";
if (Bt(&i,1))
"In Amp, ";
if (Bt(&i,2))
"Out Amp, ";
if (Bt(&i,3))
"Amp Override, ";
if (Bt(&i,4))
"Fmt Override, ";
if (Bt(&i,5))
"Stripe, ";
if (Bt(&i,6))
"Proc Wgt, ";
if (Bt(&i,7))
"Unsolicited, ";
if (Bt(&i,8))
"Cnt Lst, ";
if (Bt(&i,9))
"Digital, ";
if (Bt(&i,10))
"Power Ctrl, ";
if (Bt(&i,11))
"Left/Right Swap, ";
"Delay:%d\n",i.u16[1]&0xF;
i=tempm->in_amp_cap;
"\n$$FG,RED$$Input Amp Capabilities:$$FG$$\n"
"Offset:0x%02X Steps:0x%02X StepSize:%5.2fdB Mutable:%d\n",
i&127,i.u8[1]&127+1,0.25*(i.u16[1]&127),Bt(&i,31);
i=tempm->out_amp_cap;
"\n$$FG,RED$$Output Amp Capabilities:$$FG$$\n"
"Offset:0x%02X Steps:0x%02X StepSize:%5.2fdB Mutable:%d\n",
i&127,i.u8[1]&127+1,0.25*(i.u16[1]&127),Bt(&i,31);
"\n$$FG,RED$$Size Rates Capabilities:$$FG$$\n";
for (i=0;i<21;i++)
if (Bt(&tempm->pcm_size_rates,i))
"%z",i,
" 8.0kHz\0 11.025kHz\0 16.0kHz\0 22.05kHz\0"
" 32.0kHz\0 44.1kHz\0 48.0kHz\0 88.2kHz\0"
" 96.0kHz\0 176.4kHz\0 192.0kHz\0 384kHz\0"
" \0 \0 \0 \0"
" 8Bit\0 16bit\0 20Bit\0 24Bit\0 32Bit\0";
NewLine;
"\n$$FG,RED$$Connection Lst:$$FG$$\n";
for (i=0;i<tempm->num_connects;i++)
"%02X,",tempm->connect_lst[i];
NewLine;
"\n$$FG,RED$$Gain Lst:$$FG$$\n";
for (i=0;i<tempm->num_connects;i++)
"%02X,",tempm->gain_lst[i];
NewLine;
switch (tempm->type) {
case AWT_PIN_COMPLEX:
"\n$$FG,RED$$Pin Capabilities:$$FG$$\n";
i=tempm->pin_capabilities;
if (Bt(&i,0))
"Impedance Sense, ";
if (Bt(&i,1))
"Trigger Required, ";
if (Bt(&i,2))
"Presence Detect, ";
if (Bt(&i,3))
"Headphone Drive, ";
if (Bt(&i,4))
"Output, ";
if (Bt(&i,5))
"Input, ";
if (Bt(&i,6))
"Balanced, ";
if (Bt(&i,16))
"EAPD, ";
"Vref:%02X\n\n",i.u8[1];
if (Bt(&tempm->pin_capabilities,0) ||
Bt(&tempm->pin_capabilities,2))
tempm->pin_sense=HDWriteCORBSync(_hda->cad,tempm->nid,VERB_PIN_SENSE_GET);
if (Bt(&tempm->pin_capabilities,0))
"Impedance Measurement:%08X\n",tempm->pin_sense&0x7FFFFFFF;
if (Bt(&tempm->pin_capabilities,2))
"Presence:%d\n",Bt(&tempm->pin_sense,31);
"\n\nPin widget ctrl bits:\n"
" 7: High phn enable (low impedance output amp)\n"
" 6: Output Enable\n"
" 5: Input Enable\n"
"0-2: Vref 0=HiZ 1=50% 2=Gnd 4=80% 5=100%\n";
tempm->pin_widget_ctl=PmtI64("Widget Ctrl (0x%02X):",tempm->pin_widget_ctl,0,0xFF);
HDWriteCORBSync(_hda->cad,tempm->nid,VERB_PIN_WIDGET_CTL_SET+tempm->pin_widget_ctl);
break;
case AWT_INPUT:
"Disable";
if (tempm->disabled=YorN)
HDWriteCORBSync(_hda->cad,tempm->nid,VERB_CHAN_STREAM_ID_SET+0x00);
else
HDWriteCORBSync(_hda->cad,tempm->nid,VERB_CHAN_STREAM_ID_SET+0x20);
NewLine;
break;
case AWT_OUTPUT:
"Disable";
if (tempm->disabled=YorN)
HDWriteCORBSync(_hda->cad,tempm->nid,VERB_CHAN_STREAM_ID_SET+0x00);
else
HDWriteCORBSync(_hda->cad,tempm->nid,VERB_CHAN_STREAM_ID_SET+0x10);
NewLine;
break;
}
}
U0 HDCfgPopUpInfo(MyMass *tempm)
{
U8 buf[136];
SPrintF(buf,"HDCfgPopUpInfoTask(0x%X);\"\\n\\nPress SHIFT-ESC\\n\\n\\n\\n\";View;",tempm);
Fs->win_inhibit|=WIF_ODE;
Fs->draw_it=NULL;
WinMgrSync;
PopUp(buf,Fs);
Fs->win_inhibit&=~WIF_ODE;
Fs->draw_it=&DrawIt;
}
U0 HDCfgEdLink(MyMass *tempm_out,MyMass *tempm_in)
{
I64 i,j;
if ((i=FindConnectIndex(tempm_in,tempm_out->nid))>=0) {
switch (tempm_in->type) {
case AWT_MIXER:
MemSet(tempm_in->gain_lst,0x80,sizeof(U8)*MAX_CONNECTS);
tempm_in->gain_lst[i]=0x7F;
for (j=0;j<tempm_in->num_connects;j++)
HDWriteCORBSync(_hda->cad,tempm_in->nid,
VERB_AMPLIFIER_GAIN_SET+0x7000+tempm_in->gain_lst[j]+j<<8);
break;
case AWT_INPUT:
case AWT_SELECTOR:
case AWT_PIN_COMPLEX:
case AWT_VENDOR:
tempm_in->cur_connect=i;
HDWriteCORBSync(_hda->cad,tempm_in->nid,VERB_CONNECT_SELECT_SET+i);
break;
}
RedoSprings;
}
}
U0 HDCfgSave()
{
CDoc *doc=DocNew;
I64 i;
MyMass *tempm;
DocPutS(doc,"//This file was generated by $$LK,\"::/TempleOS/Adam/Snd/HDCfg.CPP.Z\",\"FI:::/TempleOS/Adam/Snd/HDCfg.CPP\"$$\n\n"
"U0 MyHDCfg()\n{\n");
tempm=ode->next_mass;
while (tempm!=&ode->next_mass) {
DocPrintF(doc," //0x%02X %Z\n",tempm->nid,tempm->type,"ST_AUDIO_WIDGET_TYPES");
if (tempm->num_connects) {
DocPutS(doc," //Connection Lst:");
for (i=0;i<tempm->num_connects;i++) {
if (i==tempm->cur_connect)
DocPutS(doc,"*");
DocPrintF(doc,"0x%02X ",tempm->connect_lst[i]);
}
DocPutS(doc,"\n");
if (tempm->type==AWT_MIXER) {
DocPutS(doc," //Gain Lst:");
for (i=0;i<tempm->num_connects;i++)
DocPrintF(doc,"0x%02X ",tempm->gain_lst[i]);
DocPutS(doc,"\n");
}
}
switch (tempm->type) {
case AWT_OUTPUT:
if (tempm->disabled)
DocPrintF(doc," HDWriteCORBSync(_hda->cad,0x%02X,VERB_CHAN_STREAM_ID_SET+0x00);\n",
tempm->nid);
else
DocPrintF(doc," HDWriteCORBSync(_hda->cad,0x%02X,VERB_CHAN_STREAM_ID_SET+0x10);\n",
tempm->nid);
break;
case AWT_MIXER:
DocPrintF(doc," HDWriteCORBSync(_hda->cad,0x%02X,VERB_AMPLIFIER_GAIN_SET+0xB07F);\n",
tempm->nid);
for (i=0;i<tempm->num_connects;i++)
DocPrintF(doc," HDWriteCORBSync(_hda->cad,0x%02X,VERB_AMPLIFIER_GAIN_SET+0x%04X);\n",
tempm->nid,0x7000+tempm->gain_lst[i]+i<<8);
break;
case AWT_INPUT:
if (tempm->disabled)
DocPrintF(doc," HDWriteCORBSync(_hda->cad,0x%02X,VERB_CHAN_STREAM_ID_SET+0x00);\n",
tempm->nid);
else
DocPrintF(doc," HDWriteCORBSync(_hda->cad,0x%02X,VERB_CHAN_STREAM_ID_SET+0x20);\n",
tempm->nid);
goto here;
case AWT_PIN_COMPLEX:
DocPrintF(doc," HDWriteCORBSync(_hda->cad,0x%02X,VERB_PIN_WIDGET_CTL_SET+0x%02X);\n",
tempm->nid,tempm->pin_widget_ctl);
case AWT_SELECTOR:
case AWT_VENDOR:
here:
if (tempm->num_connects>1)
DocPrintF(doc," HDWriteCORBSync(_hda->cad,0x%02X,VERB_CONNECT_SELECT_SET+0x%02X);\n",
tempm->nid,tempm->cur_connect);
break;
}
DocPutS(doc,"\n");
tempm=tempm->next;
}
DocPutS(doc," LBtr(&sys_semas[SYS_SEMA_SND],0);\n"
"}\n\nif (snd_dev==SD_HD_AUDIO)\n"
" MyHDCfg;\n");
StrCpy(doc->filename.name,"HOME/HDAudioCfg.CPP.Z");
DocWrite(doc);
DocDel(doc);
}
U0 HDCfg()
{
I64 p1,p2;
MyMass *tempm1=NULL,*tempm2=NULL;
if (snd_dev!=SD_HD_AUDIO) {
"HD Audio not detected\n";
return;
}
HDAudioInit(0,27,0);
MenuPush(
"File {"
" Abort(,CH_SHIFT_ESC);"
" Exit(,CH_ESC);"
"}"
"Edit {"
" Randomize(,'\n');"
" Options(,CH_SPACE);"
"}"
);
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
Preempt(OFF);
DocBottom;
WordStat;
WinMax;
WinBorder;
Fs->win_inhibit=WIF_IP_L|WIF_IP_R|WIF_DBL_CLICK|WIF_DOC;
Init;
HDCfgTraverse(_hda->cad,0);
HDCfgRandomizeXY;
RedoSprings;
DocCursor;
DocClear;
Fs->draw_it=&DrawIt;
PopUpOk(
"This is a tool to cfgure\n"
"HD Audio. It creates $$FG,RED$$HOME/HDAudioCfg.CPP.Z$$FG$$\n"
"which you should $$FG,GREEN$$#include$$FG$$ in your\n"
"$$FG,RED$$HOME/Adam3cSnd.CPP.Z$$FG$$ file.\n\n\n"
"Left click to see info and cfgure a widget.\n"
"Right click drag to connect output to input.\n\n"
"You will need to set input and output amplifier\n"
"gains by hand -- edit $$FG,RED$$HOME/HDAudioCfg.CPP.Z$$FG$$.\n\n"
"The $$FG,BLUE$$BLUE$$FG$$ line in the middle is microphone waveform.\n\n"
);
HDRun(TRUE,TRUE); //run input output
Snd(500,WF_SINE,0.50);
try {
while (TRUE) {
switch (GetMsg(&p1,&p2,1<<MSG_IP_L_UP|1<<MSG_IP_R_DOWN|1<<MSG_IP_R_UP|1<<MSG_KEY_DOWN)) {
case MSG_IP_L_UP:
if (tempm1=FindMassByXY(p1,p2))
HDCfgPopUpInfo(tempm1);
tempm1=NULL;
break;
case MSG_IP_R_DOWN:
tempm1=FindMassByXY(p1,p2);
break;
case MSG_IP_R_UP:
tempm2=FindMassByXY(p1,p2);
if (tempm1 && tempm2)
HDCfgEdLink(tempm1,tempm2);
break;
case MSG_KEY_DOWN:
switch (p1) {
case CH_SPACE:
if (tempm1=FindMassByXY(ipx-Fs->win_pixel_left-Fs->win_scroll_x,ipy-Fs->win_pixel_top-Fs->win_scroll_y))
HDCfgPopUpInfo(tempm1);
tempm1=NULL;
break;
case '\n':
HDCfgRandomizeXY;
break;
case CH_ESC:
HDCfgSave;
case CH_SHIFT_ESC:
goto hd_done;
}
break;
}
}
hd_done: //Don't goto out of try
GetMsg(,,1<<MSG_KEY_UP);
} catch
Fs->catch_except=TRUE;
SettingsPop;
HDStop(TRUE,FALSE); //stop input
CleanUp;
MenuPop;
"$$BK,1$$Note: #include \"HOME/HDAudioCfg\" in your start-up scripts.$$BK,0$$\n";
}
HDCfg;
+253
View File
@@ -0,0 +1,253 @@
#help_index "Snd/Math;Math"
public F64 Saw(F64 t,F64 period)
{ //0.0 - 1.0 think "(Sin+1)/2"
if (period) {
if (t>=0.0)
return t%period/period;
else
return 1.0+t%period/period;
} else
return 0.0;
}
public F64 FullSaw(F64 t,F64 period)
{ //1.0 - -1.0 think "Sin"
if (period) {
if (t>=0.0)
return 2.0*(t%period/period)-1.0;
else
return 2.0*(t%period/period)+1.0;
} else
return 0.0;
}
public F64 Caw(F64 t,F64 period)
{ //1.0 - 0.0 think "(Cos+1)/2"
if (period) {
if (t>=0.0)
return 1.0-t%period/period;
else
return -(t%period)/period;
} else
return 1.0;
}
public F64 FullCaw(F64 t,F64 period)
{ //1.0 - -1.0 think "Cos"
if (period) {
if (t>=0.0)
return -2.0*(t%period/period)+1.0;
else
return -2.0*(t%period/period)-1.0;
} else
return 1.0;
}
public F64 Tri(F64 t,F64 period)
{ //0.0 - 1.0 - 0.0
if (period) {
t=2.0*(Abs(t)%period)/period;
if (t<=1.0)
return t;
else
return 2.0-t;
} else
return 0.0;
}
public F64 FullTri(F64 t,F64 period)
{ //0.0 - 1.0 - 0.0 - -1.0 -0.0
if (period) {
t=4.0*(t%period)/period;
if (t<=-1.0) {
if (t<=-3.0)
return t+4.0;
else
return -2.0-t;
} else {
if (t<=1.0)
return t;
else if (t<=3.0)
return 2.0-t;
else
return t-4.0;
}
} else
return 0.0;
}
#help_index "Snd/Math"
public F64 Note2Freq(I64 note,I64 octave=3)
{
return 440.0*2.0`(octave-3+note/12.0);
}
F64 SinPhaseCont(F64 last_y,F64 last_dydt,
F64 current_amp,F64 phase_offset)
{
F64 phase;
phase=last_y/current_amp;
if (phase>1.0) phase=1.0;
if (phase<-1.0) phase=-1.0;
if (last_dydt<0)
phase=ã-ASin(phase);
else
phase=ASin(phase);
return phase-phase_offset;
}
public CSndWaveCtrl *SndWaveCtrlNew(I64 sample_rate=SND_SAMPLE_RATE,I64 sample_bits=SND_SAMPLE_BITS,
I64 channels=SND_OCHANNELS,CTask *mem_task=NULL)
{
CSndWaveCtrl *swc=CAlloc(sizeof(CSndWaveCtrl),mem_task);
swc->freq_multiplier=1.0;
swc->amp_multiplier=1.0;
swc->sample_rate=sample_rate;
swc->sample_bits=sample_bits;
swc->channels=channels;
swc->last_dydt=1.0;
return swc;
}
public U0 SndWaveCtrlDel(CSndWaveCtrl *swc)
{
Free(swc);
}
public U0 SndWaveAddBuf(CSndWaveCtrl *swc,U8 *buf,I64 num_samples,
F64 _freq,I64 _waveform=WF_SQUARE,F64 _amp=1.0,F64 _left=1.0, F64 _right=1.0)
{
//num_samples is multiplied by channels to get buf_len.
//left,right range from 0.0-1.0
//Supports 16,24 and 32 bits
I64 reg i,reg j,reg k;
F64 a,f,amp,reg phase;
if (!swc) return;
_freq*=swc->freq_multiplier;
_amp*=swc->amp_multiplier;
if (!_freq||!_amp) {
swc->last_y=swc->phase=0;
swc->last_dydt=1.0;
} else {
phase=swc->phase;
i=0;
amp=Min(MAX_I32,MAX_I32*_amp);
f=2*ã/swc->sample_rate*_freq;
switch (_waveform) {
case WF_NOISE:
a=2.0/ã*amp;
break;
case WF_SAWTOOTH:
a=amp/ã;
break;
case WF_SINE:
phase=SinPhaseCont(swc->last_y,swc->last_dydt,amp,0.0);
break;
}
while (phase<0)
phase+=2*ã;
while (phase>=2*ã)
phase-=2*ã;
num_samples*=swc->channels;
while (i<num_samples) {
switch (_waveform) {
case WF_SQUARE:
if (phase>=ã)
j=-amp;
else
j=amp;
break;
case WF_SINE:
j=amp*Sin(phase);
break;
case WF_TRIANGLE:
if (phase>=ã) {
swc->last_y=swc->next_y;
swc->next_y=-amp*Sign(swc->last_y)+.00001;
phase-=ã;
}
j=(swc->last_y*(ã-phase)+swc->next_y*phase)/ã;
break;
case WF_SAWTOOTH:
j=a*(phase-ã);
break;
case WF_NOISE:
if (phase<ã) {
if (phase<f) {
swc->last_y=swc->next_y;
swc->next_y=a*RandI16/MAX_U16;
}
j=swc->last_y*(ã-phase)+swc->next_y*phase;
} else {
if (phase-ã<f) {
swc->last_y=swc->next_y;
swc->next_y=a*RandI16/MAX_U16;
}
j=swc->last_y*(2.0*ã-phase)+swc->next_y*(phase-ã);
}
break;
}
//left channel
k=j*_left;
if (swc->sample_bits==16) {
k>>=16;
buf(I16 *)[i++]+=k;
} else {
if (swc->sample_bits==24)
k&=0xFFFFFF00;
buf(I32 *)[i++]+=k;
}
//right channel
if (swc->channels==2) {
k=j*_right;
if (swc->sample_bits==16) {
k>>=16;
buf(I16 *)[i++]+=k;
} else {
if (swc->sample_bits==24)
k&=0xFFFFFF00;
buf(I32 *)[i++]+=k;
}
}
phase+=f;
while (phase>=2*ã)
phase-=2*ã;
}
if (_waveform==WF_SINE) {
swc->last_y=amp*Sin(phase);
swc->last_dydt=Cos(phase);
}
swc->phase=phase;
}
}
#help_index "Snd/HDAudio"
I64 snd_reverb_buf_cnt;
SND_OUT_CONTAINER *snd_reverb_buf=NULL;
U0 SndReverb(SND_OUT_CONTAINER *buf,I64 buf_num)
{
I64 i,j,mask,span=RoundI64(SND_SAMPLE_RATE*SND_OCHANNELS*snd_reverb_delay,SND_OCHANNELS);
if (!snd_reverb_buf || span>snd_reverb_buf_cnt) {
Free(snd_reverb_buf);
snd_reverb_buf_cnt=1<<(Bsr(span)+1);
snd_reverb_buf=ACAlloc(snd_reverb_buf_cnt*sizeof(SND_OUT_CONTAINER));
}
j=buf_num*SND_BUF_LEN;
mask=snd_reverb_buf_cnt-1;
for (i=0;i<SND_BUF_LEN;i++,j++) {
snd_reverb_buf[j&mask]=
buf[i]=
LimitI64(buf[i]+snd_reverb_intensity*snd_reverb_buf[(j-span)&mask],
MIN_I32,MAX_I32)&0xFFFFFF00;
}
}
I64 AudioSize()
{
return MSize2(snd_reverb_buf);
}
#help_index "Snd"
+260
View File
@@ -0,0 +1,260 @@
#help_index "Snd/Music"
U8 *cur_song=NULL;
CTask *cur_song_task=NULL;
I64 music_octave;
F64 music_note_len;
U8 music_note_map[7]={0,2,3,5,7,8,10};
I64 music_mute=0;
I64 music_waveform,music_meter_top,music_meter_bottom;
public F64 music_tempo,music_stacatto_factor,music_amplitude;
//This is if you wish to sync with a
//note in a Play() string. 0 is the start
public I64 music_play_note_num=0;
#help_index "Snd/Music;Time/Seconds"
F64 music_tM_correction=0,music_last_tMBeat=0,music_last_tM=0;
public F64 tM()
{
return (sys_jiffies+music_tM_correction)/JIFFY_FREQ;
}
public F64 tMBeat()
{ //Time in music beats
F64 result,cur_tM;
PushFD;
Cli;
if (mp_cnt>1)
while (LBts(&sys_semas[SYS_SEMA_TMBEAT],0))
Pause;
cur_tM=tM;
result=music_last_tMBeat;
if (music_tempo)
result+=(cur_tM-music_last_tM)*music_tempo;
music_last_tM=cur_tM;
music_last_tMBeat=result;
LBtr(&sys_semas[SYS_SEMA_TMBEAT],0);
PopFD;
return result;
}
#help_index "Snd/Music"
U8 *MusicSetOctave(U8 *st)
{
U8 ch=*st++;
while ('0'<=ch<='9') {
music_octave=ch-'0';
ch=*st++;
}
return --st;
}
U8 *MusicSetWaveform(U8 *st)
{
U8 ch=*st++;
while (ch=='W') {
ch=*st++;
if ('0'<=ch<'0'+WF_NUM_WAVEFORMS) {
music_waveform=ch-'0';
ch=*st++;
}
}
return --st;
}
U8 *MusicSetMeter(U8 *st)
{
U8 ch=*st++;
while (ch=='M') {
ch=*st++;
if ('0'<=ch<='9') {
music_meter_top=ch-'0';
ch=*st++;
}
if (ch=='/')
ch=*st++;
if ('0'<=ch<='9') {
music_meter_bottom=ch-'0';
ch=*st++;
}
}
return --st;
}
U8 *MusicSetNoteLen(U8 *st)
{
Bool cont=TRUE;
do {
switch (*st++) {
case 'w': music_note_len=4.0; break;
case 'h': music_note_len=2.0; break;
case 'q': music_note_len=1.0; break;
case 'e': music_note_len=0.5; break;
case 's': music_note_len=0.25; break;
case 't': music_note_len=2.0*music_note_len/3.0; break;
case '.': music_note_len=1.5*music_note_len; break;
default:
st--;
cont=FALSE;
}
} while (cont);
return st;
}
public U0 Play(U8 *st,U8 *words=NULL)
/*
Notes are entered with a capital letter.
Octaves are entered with a digit and
stay set until changed.
Durations are entered with
'w' whole note
'h' half note
'q' quarter note
'e' eighth note
't' sets to 2/3rds the current duration
'.' sets to 1.5 times the current duration
durations stay set until changed.
'(' tie, placed before the note to be extended
Accents are made with
'!' *1.5
'!!' *1.5`2
$LK,"music_waveform","MN:music_waveform"$ is set with
"W1" for $LK,"WF_SQUARE","MN:WF_SQUARE"$
"W2" for $LK,"WF_SINE","MN:WF_SINE"$
"W3" for $LK,"WF_TRIANGLE","MN:WF_TRIANGLE"$
"W4" for $LK,"WF_SAWTOOTH","MN:WF_SAWTOOTH"$
"W5" for $LK,"WF_NOISE","MN:WF_NOISE"$
$LK,"music_meter_top","MN:music_meter_top"$,$LK,"music_meter_bottom","MN:music_meter_bottom"$ is set with
"M3/4"
"M4/4"
etc.
Sharp and flat are done with '#' or 'b'.
The var music_stacatto_factor can
be set to a range from 0.0 to 1.0.
The var music_amplitude can
be set to a range from 0.0 to 1.0.
The var music_tempo is quarter-notes
per second. It defaults to
2.5 and gets faster when bigger.
*/
{
U8 *word,*last_st;
I64 note,i=0,timeout_val,timeout_val2;
Bool tie,old_preempt=Preempt(OFF);
F64 f,d,a,on_jiffies,off_jiffies;
music_play_note_num=0;
while (*st) {
timeout_val=sys_jiffies;
a=music_amplitude;
tie=FALSE;
do {
last_st=st;
if (*st=='!') {
a*=1.5;
st++;
} else if (*st=='(') {
tie=TRUE;
st++;
} else {
st=MusicSetWaveform(st);
st=MusicSetMeter(st);
st=MusicSetOctave(st);
st=MusicSetNoteLen(st);
}
} while (st!=last_st);
if (!*st) break;
note=*st++-'A';
if (note<7) {
note=music_note_map[note];
if (*st=='b') {
note--;
st++;
} else if (*st=='#') {
note++;
st++;
}
f=Note2Freq(note,music_octave);
} else
f=0;
if (words) {
if (word=LstEntryPt(i++,words))
if (StrCmp(word," "))
"" word;
}
d=JIFFY_FREQ*music_note_len/music_tempo;
if (tie) {
on_jiffies =d;
off_jiffies =0;
} else {
on_jiffies =d*music_stacatto_factor;
off_jiffies =d*(1.0-music_stacatto_factor);
}
timeout_val+=on_jiffies;
timeout_val2=timeout_val+off_jiffies;
if (!music_mute)
Snd(f,music_waveform,a);
SleepUntil(timeout_val);
music_tM_correction+=on_jiffies-ToI64(on_jiffies);
if (!music_mute)
Snd(0,music_waveform,a);
SleepUntil(timeout_val2);
music_tM_correction+=off_jiffies-ToI64(off_jiffies);
music_play_note_num++;
}
Preempt(old_preempt);
}
U0 MusicSettingsRst()
{
music_play_note_num=0;
music_stacatto_factor=0.9;
music_amplitude=1/1.5`2;
music_tempo=2.5;
music_octave=3;
music_note_len=1.0;
music_waveform=WF_SQUARE;
music_meter_top=4;
music_meter_bottom=4;
snd_reverb_intensity=0.2;
snd_reverb_delay=0.3;
PushFD;
Cli;
if (mp_cnt>1)
while (LBts(&sys_semas[SYS_SEMA_TMBEAT],0))
Pause;
music_last_tM=tM;
music_last_tMBeat=0.0;
LBtr(&sys_semas[SYS_SEMA_TMBEAT],0);
PopFD;
}
MusicSettingsRst;
U0 CurSongTask()
{
if (!IsSysDeterministic)
Preempt(ON);
Fs->task_end_cb=&SndTaskEndCB;
while (TRUE)
Play(cur_song);
}
#help_index "Snd"
+66
View File
@@ -0,0 +1,66 @@
#help_index "Snd"
class CSndWaveCtrl
{
I64 sample_rate,sample_bits,channels;
F64 freq_multiplier,amp_multiplier;
F64 phase,last_y,last_dydt,next_y;
};
I64 snd_obuf_num,snd_ibuf_num;
#define Sf_FILLING_OUT 0
I64 snd_flags;
public U0 SndTaskEndCB()
//This will turn-off snd when a task gets killed.
{
Snd(0);
Exit;
}
class CSndData
{
CSndData *next,*last;
U8 waveform,pad[7];
F64 amp; //0.0-1.0
F64 freq; //Hz
F64 time_stamp;
} snd_record_root;
U0 SndRecord(F64 freq,I64 waveform,F64 amp)
{
CSndData *d;
d=ACAlloc(sizeof(CSndData));
d->freq=freq;
d->time_stamp=tT;
d->waveform=waveform;
d->amp=amp;
QueIns(d,snd_record_root.last);
}
U0 CtrlAltV(I64 sc)
{
if (sc&SCF_SHIFT)
snd_vol/=1.5;
else
snd_vol*=1.5;
}
SetCtrlAltLetCB('V',&CtrlAltV,"Sys/Snd Volume +/-");
U0 SndInit()
{
QueInit(&snd_record_root);
snd_record_root.freq=0;
snd_record_root.time_stamp=tT;
fp_snd_record=&SndRecord;
}
SndInit;
#include "MathAudio"
#include "Music"
#include "SndEffects"
#include "SndFile"
#help_index ""
+68
View File
@@ -0,0 +1,68 @@
#define SE_NOISE 0
#define SE_SWEEP 1
class CSoundEffectFrame
{
I32 type,waveform;
F64 duration,freq1,freq2;
};
U0 SoundEffectEndTaskCB()
{
Free(NamedFramePtr("CSoundEffectFrame"));
music_mute--;
SndTaskEndCB;
}
U0 SoundEffectTask(CSoundEffectFrame *ns)
{
I64 i;
F64 f,t0=tS,t,timeout=t0+ns->duration;
NamedFramePtrAdd("CSoundEffectFrame",ns);
Fs->task_end_cb=&SoundEffectEndTaskCB;
switch (ns->type) {
case SE_NOISE:
i=MaxI64(ns->freq2-ns->freq1,1);
while (tS<timeout)
if (f=RandU16%i+ns->freq1) {
Snd(f,ns->waveform);
Sleep(MaxI64(3000/f,1));
} else
break;
break;
case SE_SWEEP:
while (tS<timeout) {
t=(tS-t0)/ns->duration;
if (f=(1.0-t)*ns->freq1+t*ns->freq2) {
Snd(f,ns->waveform);
Sleep(MaxI64(3000/f,1));
} else
break;
}
break;
}
}
public CTask *Noise(I64 mS,F64 min_freq,F64 max_freq,I64 waveform=WF_NOISE)
{
CSoundEffectFrame *ns=MAlloc(sizeof(CSoundEffectFrame));
ns->type=SE_NOISE;
ns->waveform=waveform;
ns->duration=mS/1000.0;
ns->freq1=min_freq;
ns->freq2=max_freq;
music_mute++;
return Spawn(&SoundEffectTask,ns,"Noise",Fs);
}
public CTask *Sweep(I64 mS,F64 freq1,F64 freq2,I64 waveform=WF_SINE)
{
CSoundEffectFrame *ns=MAlloc(sizeof(CSoundEffectFrame));
ns->type=SE_SWEEP;
ns->waveform=waveform;
ns->duration=mS/1000.0;
ns->freq1=freq1;
ns->freq2=freq2;
music_mute++;
return Spawn(&SoundEffectTask,ns,"Noise",Fs);
}
+315
View File
@@ -0,0 +1,315 @@
#help_index "Snd/Snd Files"
#define SNDFILE_SAMPLE_RATE 8000
//Header for a ".SND" file
class CFileSND
{ //big endian
U32 signature; //0x646e732e
U32 offset; //24
U32 data_size;
U32 coding; //3=16bit uncompressed
U32 sample_rate; //Hz
U32 channels; //1=mono
I16 body[1];
};
//This is a windows media constraint.
#define MAX_SND_FILE_DATA 0x7FF00
public I64 SndFileCreate(U8 *base_filename,F64 normalized_vol=1.0,F64 averaging=0.0,I64 waveform=WF_NULL,
F64 reverb_delay=0,F64 reverb_intensity=0)
//Use "snd_record" flag to start or stop
//recording, then call this routine.
//Averaging should be a num from 0.0 to 0.999.
//Vol should be from 0.0 to 1.0.
//If waveform is $LK,"WF_NULL","MN:WF_NULL"$, the original passed to $LK,"Snd","MN:Snd"$() will be used.
//Set reverb_delay to like 0.3 sec and reverb_intensity to like 0.4.
{
I64 i,k,cnt,cnt2,level,file_num;
F64 avg,dt;
CFileSND *s;
CSndWaveCtrl *swc=SndWaveCtrlNew(SNDFILE_SAMPLE_RATE,16,1);
CSndData *d,*d1;
U8 *name,*name2;
snd_record=FALSE;
dt=snd_record_root.last->time_stamp-snd_record_root.next->time_stamp;
if (!dt) return 0;
cnt=dt*SNDFILE_SAMPLE_RATE;
cnt++; //terminator
name=StrNew(base_filename);
FileExtRem(name);
s=CAlloc(offset(CFileSND.body)+cnt*sizeof(I16));
s->signature=0x646e732e;
s->offset=EndianU32(offset(CFileSND.body));
s->coding=EndianU32(3);
s->sample_rate=EndianU32(SNDFILE_SAMPLE_RATE);
s->channels=EndianU32(1);
d=snd_record_root.next;
k=0;
while (d->next!=&snd_record_root) {
d1=d->next;
dt=d1->time_stamp-d->time_stamp;
cnt2=dt*SNDFILE_SAMPLE_RATE;
SndWaveAddBuf(swc,&s->body[k],cnt2,d->freq,waveform ?waveform:d->waveform,d->amp*normalized_vol);
k+=cnt2;
QueRem(d);
Free(d);
d=d1;
}
//Average
if (averaging) {
avg=0;
for (i=0;i<cnt-1;i++)
s->body[i]=avg=LowPass1(averaging,avg,s->body[i],1.0);
}
//reverb
if (reverb_intensity) {
if (dt=reverb_delay*SNDFILE_SAMPLE_RATE)
for (i=dt;i<cnt;i++)
s->body[i]+=reverb_intensity*s->body[i-dt];
}
//Get rid of D.C. component
for (k=0;k<3;k++) {
level=0;
for (i=0;i<cnt-1;i++)
level+=s->body[i];
level/=cnt-1;
for (i=0;i<cnt-1;i++)
s->body[i]=LimitI64(s->body[i]-level,MIN_I16,MAX_I16);
}
for (i=0;i<cnt-1;i++)
s->body[i]=EndianU16(s->body[i]);
s->body[cnt-1]=0;
d=snd_record_root.next;
while (d!=&snd_record_root) {
d1=d->next;
QueRem(d);
Free(d);
d=d1;
}
name2=MAlloc(StrLen(name)+3+1+3+1);
cnt2=cnt;
file_num=0;
while (cnt2>0) {
i=cnt2;
if (i>MAX_SND_FILE_DATA)
i=MAX_SND_FILE_DATA;
s->data_size=EndianU32(i*sizeof(I16));
MemCpy(s->body,&s->body[file_num*MAX_SND_FILE_DATA],i*sizeof(I16));
SPrintF(name2,"%s%03d.SND",name,file_num++);
FileWrite(name2,s,offset(CFileSND.body)+i*sizeof(I16));
cnt2-=i;
}
Free(s);
Free(name);
Free(name2);
SndWaveCtrlDel(swc);
return cnt;
}
public U0 SndFileWrite(U8 *filename,SND_IN_CONTAINER *buf,I64 cnt)
{
CFileSND *s;
I64 i,j,l=SND_SAMPLE_RATE/SNDFILE_SAMPLE_RATE;
F64 level,a1,a2;
cnt/=l;
s=CAlloc(offset(CFileSND.body)+cnt*sizeof(I16));
s->signature=0x646e732e;
s->offset=EndianU32(offset(CFileSND.body));
s->coding=EndianU32(3);
s->sample_rate=EndianU32(SNDFILE_SAMPLE_RATE);
s->channels=EndianU32(1);
s->data_size=EndianU32(cnt*sizeof(I16));
//Get rid of D.C. component
j=cnt*l;
level=0;
for (i=0;i<j;i++)
level+=buf[i];
level/=j;
for (i=0;i<j;i++)
buf[i]=LimitI64(buf[i]-level,MIN_I16,MAX_I16);
//2nd order low pass filter. Time constant set by nyquest freq.
a1=1.0/SND_SAMPLE_RATE/(2.0/SNDFILE_SAMPLE_RATE+1.0/SND_SAMPLE_RATE);
a2=1.0-a1;
for (i=1;i<j;i++)
buf[i]=a1*buf[i]+a2*buf[i-1];
for (i=1;i<j;i++)
buf[i]=a1*buf[i]+a2*buf[i-1];
j=0;
for (i=0;i<cnt;i++) {
s->body[i]=EndianU16(buf[j]);
j+=l;
}
FileWrite(filename,s,offset(CFileSND.body)+cnt*sizeof(I16));
Free(s);
}
public U0 SndFileView(U8 *name,Bool zoom=FALSE)
{
I64 i,start,end,w=Fs->win_pixel_width,h=Fs->win_pixel_height;
F64 x_scale,y_scale;
CFileSND *s=FileRead(name);
if (s) {
s->data_size=EndianU32(s->data_size)/sizeof(I16);
for (i=0;i<s->data_size;i++)
s->body[i]=EndianU16(s->body[i]);
start=1;
end=s->data_size;
if (zoom) {
for (i=1;i<end;i++)
if (s->body[i]!=s->body[i-1]) {
start=i;
break;
}
if (s->data_size-start>w)
end=start+w;
}
"$$CL$$";
DCFill;
CDC *dc=DCAlias;
dc->color=GREEN;
x_scale=ToF64(w)/(end-start+1);
y_scale=ToF64(h)/MAX_U16;
for (i=start;i<end;i++)
GrLine(dc,x_scale*(i-start),y_scale*(s->body[i]+MAX_I16),
x_scale*(i-start-1),y_scale*(s->body[i-1]+MAX_I16));
Free(s);
PressAKey;
DCFill;
DCDel(dc);
}
}
CFileSND *snd_play_snd_file=NULL;
I64 snd_play_start_buf_num,snd_play_samples_per_sample;
Bool snd_play_done=TRUE,snd_play_single_done;
U0 (*fp_snd_play_task_end_cb)()=NULL;
U0 (*fp_snd_play_old_fill_buf)(SND_OUT_CONTAINER *buf,I64 buf_num)=NULL;
CFileSND *SndFileLoad(U8 *name)
{
I64 i;
CFileSND *s=FileRead(name);
if (s) {
s->data_size=EndianU32(s->data_size)/sizeof(I16);
for (i=0;i<s->data_size;i++)
s->body[i]=EndianU16(s->body[i]);
}
return s;
}
U0 SndFileFillBuf(SND_OUT_CONTAINER *buf,I64 buf_num)
{
I64 i,j,k,m;
if (snd_play_done) return;
buf_num-=snd_play_start_buf_num;
j=buf_num*(SND_BUF_LEN/SND_OCHANNELS*SNDFILE_SAMPLE_RATE/SND_SAMPLE_RATE);
i=j%snd_play_snd_file->data_size;
k=j%snd_play_samples_per_sample;
j=0;
while (j<SND_BUF_LEN) {
m=snd_vol*snd_play_snd_file->body[i++]<<16;
while (j<SND_BUF_LEN) {
buf[j++]=m;
buf[j++]=m;
if (++k==snd_play_samples_per_sample)
break;
}
if (i>=snd_play_snd_file->data_size) {
while (j<SND_BUF_LEN) {
buf[j++]=0;
buf[j++]=0;
}
snd_play_done=TRUE;
break;
}
k=0;
}
}
U0 SndFilePlayTaskEndCB()
{
snd_play_done=TRUE;
fp_snd_fill_buf=fp_snd_play_old_fill_buf;
if (fp_snd_play_task_end_cb)
(*fp_snd_play_task_end_cb)();
else
Exit;
}
//See $LK-A,"::/TempleOS/Apps/MusicOrgan/Help.TXT"$
//See $LK,"SndFileCreate","MN:SndFileCreate"$().
public U0 SndFilePlay(U8 *snz_filename)
{
if (snd_play_done) {
TaskInitExt;
snd_play_snd_file=SndFileLoad(snz_filename);
snd_play_samples_per_sample=SND_SAMPLE_RATE/SNDFILE_SAMPLE_RATE;
fp_snd_play_task_end_cb=Fs->task_end_cb;
Fs->task_end_cb=&SndFilePlayTaskEndCB;
snd_play_start_buf_num=snd_obuf_num;
snd_play_done=FALSE;
fp_snd_play_old_fill_buf=fp_snd_fill_buf;
fp_snd_fill_buf=&SndFileFillBuf;
try {
while (!snd_play_done)
Sleep(1);
} catch {
snd_play_done=TRUE;
fp_snd_fill_buf=fp_snd_play_old_fill_buf;
Fs->task_end_cb=fp_snd_play_task_end_cb;
Free(snd_play_snd_file);
snd_play_snd_file=NULL;
}
fp_snd_fill_buf=fp_snd_play_old_fill_buf;
Fs->task_end_cb=fp_snd_play_task_end_cb;
Free(snd_play_snd_file);
snd_play_snd_file=NULL;
}
snd_play_single_done=TRUE;
}
public U0 SndFilePlaySeq(U8 *snz_filename,I64 num)
{ //This has gaps between files. I might fix it someday. You fix it;-)
I64 i;
Bool old_preempt=Preempt(OFF),old_idle;
U8 *fname=StrNew(snz_filename),*fname2;
FileExtRem(fname);
old_idle=LBts(&Fs->task_flags,TASKf_IDLE);
for (i=0;i<num;i++) {
fname2=MSPrintF("%s%04d.SNZ",fname,i);
while (!snd_play_done)
Yield;
snd_play_single_done=FALSE;
Spawn(&SndFilePlay,fname2,"Play .SNZ",Fs);
while (!snd_play_single_done)
Yield;
Free(fname2);
}
old_idle=LBEqu(&Fs->task_flags,TASKf_IDLE,old_idle);
Free(fname);
Preempt(old_preempt);
}
#help_index ""
+27
View File
@@ -0,0 +1,27 @@
#if snd_dev==SD_HD_AUDIO
#include "::/TempleOS/Demo/Snd/PolyPhonic"
#endif
U0 Start()
{
CTask *task;
Type("::/TempleOS/Doc/Splash.TXT");
SetWinHorz(TEXT_COLS/4-1,3*TEXT_COLS/4);
SetWinVert(TEXT_ROWS/4-3,Fs->win_bottom);
LBts(&Fs->display_flags,DISPLAYf_WIN_ON_TOP);
"$$FG,GREEN$$Tip of day$$FG$$\n";
TipOfDay;
"$$FG,GREEN$$<SHIFT-ESC>$$FG$$ to exit.\n";
#if snd_dev==SD_HD_AUDIO
PopUp("#include \"::/TempleOS/Demo/Snd/SndScope\";",NULL,&task);
TaskWait(task);
WinToTop;
PolyPhonic;
Kill(task);
#else
nounusedwarn task;
View;
#endif
}
Start;
+121
View File
@@ -0,0 +1,121 @@
#help_index "Task/Settings"
public CTaskSettings *SettingsPush(CTask *task=NULL,I64 flags=0)
{ //This is typically used at the start of an application.
//It saves many settings so they can be restored
//at the end of the application with $LK,"SettingsPop","MN:SettingsPop"$().
CTaskSettings *tempse;
CDoc *doc;
if (!task) task=Fs;
if (!TaskValidate(task)) return NULL;
tempse=CAlloc(sizeof(CTaskSettings),task);
tempse->draw_it=task->draw_it;
GetVGAPalette4(tempse->palette4);
tempse->task_end_cb=task->task_end_cb;
if (!(flags&TSF_SAME_SONG)) {
if (tempse->song_task=task->song_task) {
Suspend(task->song_task);
Snd(0);
}
task->song_task=NULL;
}
if (tempse->animate_task=task->animate_task)
Suspend(task->animate_task);
task->animate_task=NULL;
if (doc=DocCur(task)) {
tempse->cursor=!Bt(&doc->flags,DOCf_HIDE_CURSOR);
tempse->scroll=!Bt(&doc->flags,DOCf_NO_SCROLL_BARS);
tempse->doc_cur_attr=doc->start_text_attr;
}
if (doc=DocAux(task))
tempse->doc_aux_attr=doc->start_text_attr;
tempse->left=task->win_left;
tempse->right=task->win_right;
tempse->top=task->win_top;
tempse->bottom=task->win_bottom;
tempse->scroll_x=task->win_scroll_x;
tempse->scroll_y=task->win_scroll_y;
tempse->scroll_z=task->win_scroll_z;
tempse->win_inhibit=task->win_inhibit;
MemCpy(&tempse->snap,&task->snap,sizeof(CSnap));
tempse->win_max_refresh=task->win_max_refresh;
tempse->text_attr=task->text_attr;
tempse->border_attr=task->border_attr;
tempse->border=!Bt(&task->display_flags,DISPLAYf_NO_BORDER);
tempse->preempt=Bt(&task->task_flags,TASKf_PREEMPT);
if (TaskValidate(ws_task))
tempse->wordstat=TRUE;
else
tempse->wordstat=FALSE;
tempse->next=task->next_settings;
task->next_settings=tempse;
return tempse;
}
public U0 SettingsPop(CTask *task=NULL,I64 flags=0)
{
CTaskSettings *tempse;
CDoc *doc;
Bool old_preempt=Preempt(OFF);
if (!task) task=Fs;
if (!TaskValidate(task)) {
Preempt(old_preempt);
return;
}
if (tempse=task->next_settings) {
task->next_settings=tempse->next;
task->draw_it=tempse->draw_it;
SetVGAPalette4(tempse->palette4);
task->task_end_cb=tempse->task_end_cb;
if (task->animate_task)
Kill(task->animate_task);
if (task->animate_task=tempse->animate_task)
Suspend(task->animate_task,FALSE);
if (!(flags&TSF_SAME_SONG)) {
if (task->song_task)
Kill(task->song_task);
if (task->song_task=tempse->song_task)
Suspend(task->song_task,FALSE);
}
if (doc=DocCur(task)) {
LBEqu(&doc->flags,DOCf_HIDE_CURSOR,!tempse->cursor);
LBEqu(&doc->flags,DOCf_NO_SCROLL_BARS,!tempse->scroll);
doc->start_text_attr=tempse->doc_cur_attr;
}
if (doc=DocAux(task))
doc->start_text_attr=tempse->doc_aux_attr;
WinBorder(tempse->border,task);
SetWinHorz(tempse->left,tempse->right,task);
SetWinVert(tempse->top,tempse->bottom,task);
task->win_scroll_x=tempse->scroll_x;
task->win_scroll_y=tempse->scroll_y;
task->win_scroll_z=tempse->scroll_z;
MemCpy(&task->snap,&tempse->snap,sizeof(CSnap));
task->win_inhibit=tempse->win_inhibit;
task->win_max_refresh=tempse->win_max_refresh;
task->text_attr=tempse->text_attr;
task->border_attr=tempse->border_attr;
WordStat(tempse->wordstat);
Snd(0);
Free(tempse);
WinMgrSync(,TRUE);
Preempt(old_preempt);
LBEqu(&task->task_flags,TASKf_PREEMPT,tempse->preempt);
} else
Preempt(old_preempt);
}
#help_index ""
+348
View File
@@ -0,0 +1,348 @@
#help_index "Utils;Cmd Line (Typically);Doc/Html"
//See $LK-A,"::/TempleOS/Doc/Acknowledgements.TXT"$ (12).
U0 HtmlPutS(CDoc *doc,I64 c,I64 *_old_c,U8 *st,I64 *_col,U8 *style_bitmap=NULL)
{
U8 *ch;
if (c!=*_old_c) {
if (*_old_c!=-1)
DocPutS(doc,"</span>");
DocPrintF(doc,"<span class=c%02X>",c);
*_old_c=c;
if (style_bitmap)
LBts(style_bitmap,c);
}
while (ch=*st++) {
switch (ch) {
case '\t':
do {
DocPutKey(doc,CH_SPACE,0);
*_col=*_col+1;
} while (*_col&7);
break;
case '&':
DocPutS(doc,"&amp;");
*_col=*_col+1;
break;
case '<':
DocPutS(doc,"&lt;");
*_col=*_col+1;
break;
case '>':
DocPutS(doc,"&gt;");
*_col=*_col+1;
break;
case '"':
DocPutS(doc,"&quot;");
*_col=*_col+1;
break;
case 'ã':
DocPutS(doc,"pi");
*_col=*_col+1;
break;
case 'é':
DocPutS(doc,"theta");
*_col=*_col+1;
break;
case 'è':
DocPutS(doc,"phi");
*_col=*_col+1;
break;
case 'ê':
DocPutS(doc,"omega");
*_col=*_col+1;
break;
case 'ì':
DocPutS(doc,"inf");
*_col=*_col+1;
break;
case 'æ':
DocPutS(doc,"u");
*_col=*_col+1;
break;
case CH_SHIFT_SPACE:
DocPutS(doc," ");
*_col=*_col+1;
break;
default:
if (CH_SPACE<=ch<0x7F || ch=='\n')
DocPutKey(doc,ch,0);
else
DocPutS(doc,".");
*_col=*_col+1;
}
}
}
U8 *TSLinkCvt2(U8 *filename,I64 line_num)
{ // ::/TempleOS/ --> http://www.templeos.org/Wb/
// Make your own LinkCvt routine
U8 *result=NULL,*st;
if (filename) {
st=ChgExt(filename,"html");
if (st && StrLen(st)>12 && !StrNCmp(st+1,":/TempleOS/",11))
result=MSPrintF("http://www.templeos.org/Wb/%s#l%d",st+12,line_num);
Free(st);
}
return result;
}
U8 *TSLinkCvt1(U8 *link_st)
{
static CDoc *bible=NULL;
static I64 locks=0;
U8 *result=NULL,*filename,*pattern;
I64 i,num;
if (link_st) {
switch (i=EdLinkCvt(link_st,&filename,&pattern,&num)) {
case LK_FILE_LINE:
case LK_PLAIN_LINE:
case LK_FILE:
result=TSLinkCvt2(filename,num);
break;
case -1:
case LK_DEF:
case LK_HELP_INDEX:
break;
case LK_BIBLE_FIND:
while (LBts(&locks,0))
Yield;
if (!bible)
bible=Adam("DocRead(\"%s\");",filename);
if (DocPatternFind(bible,num,pattern))
result=TSLinkCvt2(filename,bible->cur_entry->y+1);
LBtr(&locks,0);
break;
default:
if (DocFileEd(i,filename,pattern,&num,EDF_UNCOLLAPSE|EDF_BAIL))
result=TSLinkCvt2(filename,num);
}
Free(filename);
Free(pattern);
}
return result;
}
public CDoc *Doc2Html(CDoc *doc_in,
U8 *html_header=NULL,
U8 *body_header=NULL,U8 *body_footer=NULL,Bool line_anchors=TRUE,
U8 (*link_cvt)(U8 *link_st)=&TSLinkCvt1)
{
CDocEntry *doc_e,*style,*doc_e2;
CDocSettings *s;
I64 i,y,old_y=MIN_I64,cur_u8_attr,col,old_c=-1;
U32 *hl,*src;
U8 *st,st_2[2],*link_st,*style_bitmap=CAlloc(256/8);
CBGR p[16];
GetVGAPalette4(p);
CDoc *doc_out=DocNew;
Bool unlock_doc_in=DocLock(doc_in),no_backward;
for (i=0xF0;i<=0xFF;i++)
LBts(style_bitmap,i);
DocRecalc(doc_in);
st_2[0]=0; st_2[1]=0;
doc_out->flags|=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
if (!html_header) html_header="";
if (!body_header) body_header="";
if (!body_footer) body_footer="";
DocPrintF(doc_out,
"<!DOCTYPE HTML>\n"
"<html>\n"
"<head>\n"
"<meta http-equiv=\"Content-Type\" content=\"text/html;charset=US-ASCII\">\n"
"%s"
"<meta name=\"generator\" content=\"TempleOS V%4.2f\">\n"
"<style type=\"text/css\">\n",html_header,os_version);
style=doc_out->cur_entry->last;
DocPutS(doc_out,
"</style>\n"
"</head>\n"
"<body>\n"
"<pre style=\"font-family:courier;font-size:10pt\">\n");
DocPutS(doc_out,body_header);
doc_e=doc_in->root.next;
s=DocSettingsLast(doc_e);
col=doc_e->x;
y=doc_e->y;
cur_u8_attr=doc_e->type.u8[1];
while (doc_e!=doc_in) {
if (!(doc_e->flags1&(DOCEF1_SKIP|DOCEF1_HARD_SKIP))) {
if (line_anchors && y!=old_y) {
DocPrintF(doc_out,"<a name=\"l%d\"></a>",y+1);
old_y=y;
}
while (y<doc_e->y) {
HtmlPutS(doc_out,cur_u8_attr,&old_c,"\n",&col,style_bitmap);
y++;
if (line_anchors && y!=old_y) {
DocPrintF(doc_out,"<a name=\"l%d\"></a>",y+1);
old_y=y;
}
col=0;
}
no_backward=TRUE;
doc_e2=doc_e->next;
while (doc_e2!=doc_in && doc_e2->y==doc_e->y) {
if (doc_e2->x<doc_e->x) {
no_backward=FALSE;
break;
}
doc_e2=doc_e2->next;
}
if (no_backward)
while (col<doc_e->x)
HtmlPutS(doc_out,cur_u8_attr,&old_c," ",&col,style_bitmap);
link_st=NULL;
if (doc_e->flags1&DOCEF1_HTML_LINK)
link_st=StrNew(doc_e->html_link);
else if (st=DocEntryLink(doc_in,doc_e)) {
link_st=link_cvt(st);
Free(st);
}
if (link_st) {
if (old_c!=-1) {
DocPutS(doc_out,"</span>");
old_c=-1;
}
DocPrintF(doc_out,"<a href=\"%s\">",link_st);
}
if (doc_e->settings)
s=doc_e->settings;
cur_u8_attr=doc_e->type.u8[1];
switch (doc_e->type_u8) {
case DOCT_TEXT:
if (doc_e->flags1&DOCEF1_HIGHLIGHT) {
src=hl=DocHighlight(doc_in,FALSE,doc_e,&s,doc_e->tag,StrLen(doc_e->tag),cur_u8_attr<<8);
while (*src) {
st_2[0]=*src&0xFF;
HtmlPutS(doc_out,*src>>8,&old_c,st_2,&col,style_bitmap);
src++;
}
Free(hl);
} else
HtmlPutS(doc_out,cur_u8_attr,&old_c,doc_e->tag,&col,style_bitmap);
break;
case DOCT_TAB:
HtmlPutS(doc_out,cur_u8_attr,&old_c,"\t",&col,style_bitmap);
break;
case DOCT_HTML_IMG:
if (old_c!=-1) {
DocPutS(doc_out,"</span>");
old_c=-1;
}
DocPrintF(doc_out,"<img src=\"%s\" width=\"640\" height=\"480\" alt=\"\">\n",doc_e->tag);
break;
case DOCT_HTML_VIDEO:
if (old_c!=-1) {
DocPutS(doc_out,"</span>");
old_c=-1;
}
DocPrintF(doc_out,
"<!--begin exclude-->\n"
"<object classid=\"clsid:22D6F312-B0F6-11D0-94AB-0080C74C7E95\" "
"codebase=\"http://activex.microsoft.com/activex/controls/mplayer/en/nsmp2inf.cab\" "
"width=\"640\" height=\"512\">\n"
"<param name=\"FileName\" value=\"%s\">\n"
"<param name=\"AutoStart\" value=\"false\">\n"
"<param name=\"ShowTracker\" value=\"true\">\n"
"<param name=\"ShowControls\" value=\"true\">\n"
"<param name=\"ShowGotoBar\" value=\"false\">\n"
"<param name=\"ShowDisplay\" value=\"false\">\n"
"<param name=\"ShowStatusBar\" value=\"false\">\n"
"<param name=\"AutoSize\" value=\"false\">\n"
"<embed src=\"%s\" AutoStart=\"false\" ShowTracker=\"true\" ShowControls=\"true\" "
"ShowGotoBar=\"false\" ShowDisplay=\"false\" ShowStatusBar=\"false\" "
"AutoSize=\"false\" pluginspage=\"http://www.microsoft.com/windows/windowsmedia/download/\" "
"width=\"640\" height=\"512\"></embed></object>\n"
"<!--end exclude-->\n",doc_e->tag,doc_e->tag);
break;
case DOCT_HTML_CODE:
if (old_c!=-1) {
DocPutS(doc_out,"</span>");
old_c=-1;
}
DocPutS(doc_out,doc_e->tag);
break;
case DOCT_SPRITE:
HtmlPutS(doc_out,cur_u8_attr,&old_c,doc_e->tag,&col,style_bitmap);
HtmlPutS(doc_out,s->comment_attr&15+old_c&0xF0,&old_c,"/* Graphics Not Rendered in HTML */",&col,style_bitmap);
break;
default:
if (Bt(doc_tag_types,doc_e->type_u8))
HtmlPutS(doc_out,cur_u8_attr,&old_c,doc_e->tag,&col,style_bitmap);
}
if (link_st) {
if (old_c!=-1) {
DocPutS(doc_out,"</span>");
old_c=-1;
}
DocPutS(doc_out,"</a>");
Free(link_st);
}
}
doc_e=doc_e->next;
}
while (y<doc_e->y) {
HtmlPutS(doc_out,cur_u8_attr,&old_c,"\n",&col,style_bitmap);
y++;
col=0;
}
if (old_c!=-1) {
DocPutS(doc_out,"</span>");
old_c=-1;
}
DocPutS(doc_out,body_footer);
DocPutS(doc_out,"</pre></body>\n</html>\n");
doc_out->cur_entry=style->next;
for (i=0;i<256;i++)
if (Bt(style_bitmap,i))
DocPrintF(doc_out,".c%02X{color:#%02x%02x%02x;background-color:#%02x%02x%02x;}\n",i,p[i&15].r,p[i&15].g,p[i&15].b,p[i/16].r,p[i/16].g,p[i/16].b);
doc_out->cur_entry=&doc_out->root;
DocRecalc(doc_out);
if (unlock_doc_in)
DocUnlock(doc_in);
return doc_out;
}
public U0 ToHtml(U8 *_in_name,U8 *_out_name=NULL,U8 *html_header=NULL,
U8 *body_header=NULL,U8 *body_footer=NULL,I64 width=80,
Bool line_anchors=TRUE,U8 (*link_cvt)(U8 *link_st)=&TSLinkCvt1)
//Supply your own link_cvt routine.
{
U8 *in_name,*out_name;
CDoc *doc_in,*doc_out;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
SetWinHorz(0,width-1); //This sets doc width for word wrap
in_name=DftExt(_in_name,"CPP.Z"),
if (_out_name)
out_name=DftExt(_out_name,"html");
else
out_name=ChgExt(_in_name,"html");
doc_in=DocRead(in_name);
doc_out=Doc2Html(doc_in,html_header,body_header,body_footer,line_anchors,link_cvt);
StrCpy(&doc_out->filename.name,out_name);
SettingsPop;
DocWrite(doc_out);
DocDel(doc_in);
DocDel(doc_out);
Free(in_name);
Free(out_name);
}
#help_index ""
+149
View File
@@ -0,0 +1,149 @@
#help_index "Utils;Cmd Line (Typically)"
U0 TXTPutS(CDoc *doc,U8 *st,I64 *_col)
{
U8 *ch;
while (ch=*st++) {
switch (ch) {
case '\t':
do {
DocPutKey(doc,CH_SPACE,0);
*_col=*_col+1;
} while (*_col&7);
break;
case 'ã':
DocPutS(doc,"pi");
*_col=*_col+1;
break;
case 'é':
DocPutS(doc,"theta");
*_col=*_col+1;
break;
case 'è':
DocPutS(doc,"phi");
*_col=*_col+1;
break;
case 'ê':
DocPutS(doc,"omega");
*_col=*_col+1;
break;
case 'ì':
DocPutS(doc,"inf");
*_col=*_col+1;
break;
case 'æ':
DocPutS(doc,"u");
*_col=*_col+1;
break;
case CH_SHIFT_SPACE:
DocPutS(doc," ");
*_col=*_col+1;
break;
default:
if (CH_SPACE<=ch<0x7F || ch=='\n')
DocPutKey(doc,ch,0);
else
DocPutS(doc,".");
*_col=*_col+1;
}
}
}
public CDoc *Doc2TXT(CDoc *doc_in)
{
CDocEntry *doc_e,*doc_e2;
I64 y,col;
CDoc *doc_out=DocNew;
Bool unlock_doc_in=DocLock(doc_in),no_backward;
DocRecalc(doc_in);
doc_out->flags|=DOCF_PLAIN_TEXT|DOCF_NO_CURSOR;
doc_e=doc_in->root.next;
col=doc_e->x;
y=doc_e->y;
while (doc_e!=doc_in) {
if (!(doc_e->flags1&(DOCEF1_SKIP|DOCEF1_HARD_SKIP))) {
while (y<doc_e->y) {
TXTPutS(doc_out,"\n",&col);
y++;
col=0;
}
no_backward=TRUE;
doc_e2=doc_e->next;
while (doc_e2!=doc_in && doc_e2->y==doc_e->y) {
if (doc_e2->x<doc_e->x) {
no_backward=FALSE;
break;
}
doc_e2=doc_e2->next;
}
if (no_backward)
while (col<doc_e->x)
TXTPutS(doc_out," ",&col);
switch (doc_e->type_u8) {
case DOCT_TEXT:
TXTPutS(doc_out,doc_e->tag,&col);
break;
case DOCT_TAB:
TXTPutS(doc_out,"\t",&col);
break;
case DOCT_HTML_IMG:
break;
case DOCT_HTML_VIDEO:
break;
case DOCT_HTML_CODE:
break;
case DOCT_SPRITE:
break;
default:
if (Bt(doc_tag_types,doc_e->type_u8))
TXTPutS(doc_out,doc_e->tag,&col);
}
}
doc_e=doc_e->next;
}
while (y<doc_e->y) {
TXTPutS(doc_out,"\n",&col);
y++;
col=0;
}
doc_out->cur_entry=&doc_out->root;
DocRecalc(doc_out);
if (unlock_doc_in)
DocUnlock(doc_in);
return doc_out;
}
public U0 ToTXT(U8 *_in_name,U8 *_out_name=NULL,I64 width=70)
{
U8 *in_name,*out_name;
CDoc *doc_in,*doc_out;
SettingsPush; //See $LK,"SettingsPush","MN:SettingsPush"$
SetWinHorz(0,width-1); //This sets doc width for word wrap
in_name=DftExt(_in_name,"TXT.Z"),
if (_out_name)
out_name=DftExt(_out_name,"TXT");
else
out_name=ChgExt(_in_name,"TXT");
doc_in=DocRead(in_name);
doc_out=Doc2TXT(doc_in);
StrCpy(&doc_out->filename.name,out_name);
SettingsPop;
DocWrite(doc_out);
DocDel(doc_in);
DocDel(doc_out);
Free(in_name);
Free(out_name);
}
#help_index ""
+242
View File
@@ -0,0 +1,242 @@
#help_index "Training"
public U0 PressKeyHelp(CTask *task=NULL)
{
I64 p1=0,p2=0;
Bool old_preempt=Preempt(OFF);
CTask *old_hash=Fs->hash_table;
if (!task) task=Fs;
//This feat is a burden in code.
//It would be nice to lst key
//cmds for all applications,
//but it makes the code too ugly.
//
task=Fs;
Fs->hash_table=task->hash_table;
"Press keys to show handler code.\n"
"<SHIFT-ESC> to exit.\n"
"Do not press <CTRL-ALT-keys>.\n";
while (p1!=CH_ESC && p1!=CH_SHIFT_ESC) {
GetMsg(&p1,&p2,1<<MSG_KEY_DOWN);
*key_desc=0;
key_handler=NULL;
if (task==Fs)
PutKey(p1,p2|SCF_KEY_DESC);
else if (TaskValidate(task)) {
PostMsg(task,MSG_KEY_DOWN,p1,p2|SCF_KEY_DESC);
while (!key_handler)
Yield;
}
if (*key_desc)
E(key_handler,512);
}
Fs->hash_table=old_hash;
Preempt(old_preempt);
}
U0 KeyMapCtrlAltFamily()
{
I64 i,p2;
U8 *st,*st2;
p2=SC_DELETE+SCF_CTRL+SCF_ALT;
st2=ScanCode2KeyName(p2);
st=SrcEdLink(&Reboot,256);
"%20s $$LK,\"%s\",\"%s\"$$\n",st2,"Sys/Reboot",st;
Free(st);
Free(st2);
p2=SC_ESC+SCF_CTRL+SCF_ALT;
st2=ScanCode2KeyName(p2);
st=SrcEdLink(&SpawnUser,256);
"%20s $$LK,\"%s\",\"%s\"$$\n",st2,"Sys/Spawn New User Task",st;
Free(st);
Free(st2);
p2=SC_TAB+SCF_CTRL+SCF_ALT;
st2=ScanCode2KeyName(p2);
st=SrcEdLink(&WinToTop,256);
"%20s $$LK,\"%s\",\"%s\"$$\n",st2,"Sys/Switch Focus to Next Task",st;
Free(st);
Free(st2);
for (i=0;i<26;i++) {
if (fp_ctrl_alt_let_cbs[i] &&
ctrl_alt_let_descs[i]) {
p2=A2ScanCode(i+'a')+SCF_CTRL+SCF_ALT;
st2=ScanCode2KeyName(p2);
st=SrcEdLink(fp_ctrl_alt_let_cbs[i],256);
"%20s $$LK,\"%s\",\"%s\"$$\n",st2,ctrl_alt_let_descs[i],st;
Free(st);
Free(st2);
}
}
}
I64 KMCompare(U8 *e1,U8 *e2)
{
I64 i;
U8 *ee1,*ee2,ch1,ch2;
Bool e1_shift=FALSE,e2_shift=FALSE;
if (e1) {
if (e2) {
while (*e1==CH_SPACE)
e1++;
while (*e2==CH_SPACE)
e2++;
while (*e1 && *e1==*e2) {
e1++;
e2++;
}
if (!StrNCmp(e1,"SHIFT",5)) {
e1+=6;
e1_shift=TRUE;
} else if (!StrNCmp(e1," ",5))
e1+=6;
if (!StrNCmp(e2,"SHIFT",5)) {
e2+=6;
e2_shift=TRUE;
} else if (!StrNCmp(e2," ",5))
e2+=6;
ee1=e1;
while (*ee1 && *ee1!='$$')
ee1++;
ch1=*ee1;
*ee1=0;
ee2=e2;
while (*ee2 && *ee2!='$$')
ee2++;
ch2=*ee2;
*ee2=0;
i=StrCmp(e1,e2);
*ee1=ch1;
*ee2=ch2;
if (i)
return i;
else
return e1_shift-e2_shift;
} else
return 1;
} else {
if (e2)
return -1;
else
return 0;
}
}
U0 KeyMapFamily2(U8 **entries,U8 *family,CTask *task,I64 scf)
{
I64 i,p2,p1;
U8 *st,*st2;
CTask *old_hash=Fs->hash_table;
Fs->hash_table=task->hash_table;
for (i=0;i<256;i++) {
p2=scf|i|SCF_KEY_DESC;
p1=ScanCode2A(p2);
*key_desc=0;
key_handler=NULL;
if (task==Fs)
PutKey(p1,p2);
else if (TaskValidate(task)) {
PostMsg(task,MSG_KEY_DOWN,p1,p2);
while (!key_handler)
Yield;
}
if (*key_desc && StrNCmp(key_desc,"Char/",5)) {
st=ScanCode2KeyName(p2&~(SCF_CTRL|SCF_ALT|SCF_SHIFT));
st2=MSPrintF("%s %s",family,st);
Free(st);
st=SrcEdLink(key_handler,256);
entries[i]=MSPrintF("%20s $$LK,\"%s\",\"%s\"$$\n",
st2,key_desc,st);
Free(st);
Free(st2);
}
}
Fs->hash_table=old_hash;
}
U0 KeyMapFamily(U8 *family,CTask *task,I64 scf)
{
I64 i;
U8 **entries=CAlloc(2*256*sizeof(U8 *)),st1[32],st2[32];
SPrintF(st1,"%s ",family);
SPrintF(st2,"%s SHIFT",family);
KeyMapFamily2(entries ,st1,task,scf);
KeyMapFamily2(entries+256,st2,task,scf+SCF_SHIFT);
QSortI64(entries,2*256,&KMCompare);
for (i=0;i<2*256;i++)
if (entries[i]) {
"" entries[i];
Free(entries[i]);
}
Free(entries);
}
public U0 KeyMap(CTask *task=NULL)
{
if (!task) task=Fs;
//This feat is a burden in code.
//It would be nice to lst key
//cmds for all applications,
//but it makes the code too ugly.
//
task=Fs;
DocMax;
KeyMapFamily("",task,0);
KeyMapFamily("CTRL",task,SCF_CTRL);
KeyMapFamily("ALT",task,SCF_ALT);
KeyMapCtrlAltFamily;
"\n$$MA+A-X+PU,\"Click for help on key pressed\",\"PressKeyHelp(0x%X);\"$$\n",task;
}
public U0 TipOfDay(U8 *tip_file="::/TempleOS/Doc/Tips.TXT")
{
I64 i=RandU16;
CDoc *doc=DocRead(tip_file),*doc2=DocNew;
CDocEntry *doc_e=doc->root.next;
"$$WW,1$$\n";
while (TRUE) {
if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*')
if (!i--) break;
doc_e=doc_e->next;
}
if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*') {
while (doc_e!=doc) {
if (doc_e->type_u8!=DOCT_ERROR)
DocIns(doc2,DocEntryCopy(doc2,doc_e));
doc_e=doc_e->next;
if (doc_e->type_u8==DOCT_TEXT && *doc_e->tag=='*')
break;
}
}
DocInsDoc(DocCur,doc2);
DocDel(doc2);
DocDel(doc);
}
/****
//This feat is a burden in code.
//It would be nice to lst key
//cmds for all applications,
//but it makes the code too ugly.
//
U0 CtrlAltK(I64)
{
U8 buf[136];
SPrintF(buf,"KeyMap(0x%X);View;",
sys_focus_task);
PopUp(buf);
}
SetCtrlAltLetCB('K',&CtrlAltK,"Sys/Show KeyMap");
****/
+443
View File
@@ -0,0 +1,443 @@
#help_index "Memory"
U0 StkOverflow(CTask *task)
{
Dbg("Stk Overflow",task);
}
U0 MemSysCorrupt()
{
Dbg("Corrupt Sys Memory");
}
U0 MemTaskCorrupt()
{
Dbg("Corrupt Task Memory");
}
public I64 UnusedBPMem(CBlkPool *bp)
{
I64 result=0,i;
CMemBlk *tempm;
if (!bp) return 0;
PushFD;
Cli;
while (LBts(&bp->locked_flags,BPlf_LOCKED))
Pause;
tempm=bp->mem_free_lst;
while (tempm) {
if (tempm->mb_signature!=MBS_UNUSED_SIGNATURE_VAL)
MemSysCorrupt;
result+=tempm->pages;
tempm=tempm->next;
}
for (i=0;i<FREE_PAGE_HASH_SIZE;i++) {
tempm=bp->free_page_hash[i];
while (tempm) {
if (tempm->mb_signature!=MBS_UNUSED_SIGNATURE_VAL)
MemSysCorrupt;
result+=tempm->pages;
tempm=tempm->next;
}
}
for (i=0;i<64-PAGE_BITS;i++) {
tempm=bp->free_page_hash2[i];
while (tempm) {
if (tempm->mb_signature!=MBS_UNUSED_SIGNATURE_VAL)
MemSysCorrupt;
result+=tempm->pages;
tempm=tempm->next;
}
}
LBtr(&bp->locked_flags,BPlf_LOCKED);
PopFD;
return result*PAGE_SIZE;
}
public I64 UnusedSysMem()
{
return UnusedBPMem(sys_code_bp);
}
public I64 TaskAllocatedMem(CTask *task=NULL,Bool override_validate=FALSE)
{
CMemBlk *m,*m1;
I64 result=0;
if (!task) task=Fs;
if (!override_validate && !TaskValidate(task)) return 0;
PushFD;
Cli;
while (LBts(&task->code_heap->locked_flags,HClf_LOCKED))
Pause;
if (task->code_heap!=task->data_heap)
while (LBts(&task->data_heap->locked_flags,HClf_LOCKED))
Pause;
m=task->code_heap->next_mem_blk;
m1=&task->code_heap->next_mem_blk;
while (m!=m1) {
if (m->mb_signature!=MBS_USED_SIGNATURE_VAL)
MemTaskCorrupt;
result+=m->pages*PAGE_SIZE;
m=m->next;
}
if (task->code_heap!=task->data_heap) {
m=task->data_heap->next_mem_blk;
m1=&task->data_heap->next_mem_blk;
while (m!=m1) {
if (m->mb_signature!=MBS_USED_SIGNATURE_VAL)
MemTaskCorrupt;
result+=m->pages*PAGE_SIZE;
m=m->next;
}
}
if (task->code_heap!=task->data_heap)
LBtr(&task->data_heap->locked_flags,HClf_LOCKED);
LBtr(&task->code_heap->locked_flags,HClf_LOCKED);
PopFD;
return result;
}
I64 MemBlkLstSize(CHeapCtrl *hc)
{
CMemBlk *m;
I64 result=0;
m=hc->next_mem_blk;
while (m!=&hc->next_mem_blk) {
result+=sizeof(CMemBlk);
m=m->next;
}
return result;
}
public I64 TaskUnusedAllocatedMem(CTask *task=NULL,Bool override_validate=FALSE)
{
I64 result=0,i;
CMemUnusedAllocated *uum;
if (!task) task=Fs;
if (!override_validate && !TaskValidate(task)) return 0;
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;
result+=MemBlkLstSize(task->code_heap);
for (i=0;i<HEAP_HASH_SIZE>>3;i++) {
uum=task->code_heap->heap_hash[i];
while (uum) {
result+=uum->size;
uum=uum->next;
}
}
uum=task->code_heap->malloc_free_lst;
while (uum) {
result+=uum->size;
uum=uum->next;
}
if (task->data_heap!=task->code_heap) {
result+=MemBlkLstSize(task->data_heap);
for (i=0;i<HEAP_HASH_SIZE>>3;i++) {
uum=task->data_heap->heap_hash[i];
while (uum) {
result+=uum->size;
uum=uum->next;
}
}
uum=task->data_heap->malloc_free_lst;
while (uum) {
result+=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;
return result;
}
public I64 TaskUsedMem(CTask *task=NULL,Bool override_validate=FALSE)
{
I64 result=0;
if (!task) task=Fs;
if (!override_validate && !TaskValidate(task)) return 0;
result=task->code_heap->used_u8s;
if (task->data_heap!=task->code_heap)
result+=task->data_heap->used_u8s;
return result;
}
#help_index "Memory/Heap Ctrl"
public I64 UnusedHCMem(CHeapCtrl *hc)
{
I64 result,i;
CMemUnusedAllocated *u;
if (!hc) return 0;
result=UnusedBPMem(hc->bp);
PushFD;
Cli;
while (LBts(&hc->locked_flags,HClf_LOCKED))
Pause;
for (i=0;i<HEAP_HASH_SIZE>>3;i++) {
u=hc->heap_hash[i];
while (u) {
result+=u->size;
u=u->next;
}
}
u=hc->malloc_free_lst;
while (u) {
result+=u->size;
u=u->next;
}
LBtr(&hc->locked_flags,HClf_LOCKED);
PopFD;
return result;
}
#help_index "Info;Memory/Info;Debugging/Heap"
public Bool HeapRep(CTask *task)
{
I64 i,cnt;
CMemUnusedAllocated *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<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;
}
NewLine;
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;
NewLine;
}
#help_index "Memory;Debugging/Heap"
public Bool IsInHeap(U8 *a,CTask *task=NULL,Bool lock=TRUE)
{
CMemBlk *m;
if (!task) task=Fs;
if (!TaskValidate(task)) return FALSE;
PushFD;
Cli;
if (lock) {
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;
}
m=task->code_heap->next_mem_blk;
while (m!=&task->code_heap->next_mem_blk) {
if (a>=m && a<m(U8 *)+m->pages*PAGE_SIZE) {
if (lock)
LBtr(&task->code_heap->locked_flags,HClf_LOCKED);
PopFD;
return TRUE;
}
m=m->next;
}
if (task->data_heap!=task->code_heap) {
m=task->data_heap->next_mem_blk;
while (m!=&task->code_heap->next_mem_blk) {
if (a>=m && a<m(U8 *)+m->pages*PAGE_SIZE) {
if (lock)
LBtr(&task->data_heap->locked_flags,HClf_LOCKED);
PopFD;
return TRUE;
}
m=m->next;
}
}
if (lock) {
LBtr(&task->code_heap->locked_flags,HClf_LOCKED);
if (task->data_heap!=task->code_heap)
LBtr(&task->data_heap->locked_flags,HClf_LOCKED);
}
PopFD;
return FALSE;
}
public Bool HeapWalk(CTask *task=NULL)
{
I64 i;
CMemUnusedAllocated *uum;
Bool result=TRUE;
if (!task) task=Fs;
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<HEAP_HASH_SIZE>>3;i++) {
uum=task->code_heap->heap_hash[i];
while (uum) {
if (!IsInHeap(uum,task,FALSE))
result=FALSE;
uum=uum->next;
}
if (task->data_heap!=task->code_heap) {
uum=task->data_heap->heap_hash[i];
while (uum) {
if (!IsInHeap(uum,task,FALSE))
result=FALSE;
uum=uum->next;
}
}
}
uum=task->code_heap->malloc_free_lst;
while (uum) {
if (!IsInHeap(uum,task,FALSE))
result=FALSE;
uum=uum->next;
}
if (task->data_heap!=task->code_heap) {
uum=task->data_heap->malloc_free_lst;
while (uum) {
if (!IsInHeap(uum,task,FALSE))
result=FALSE;
uum=uum->next;
}
}
#if _CFG_HEAP_DBG
CMemUsedAllocated *um,*um1;
um1=(&task->code_heap->next_um)(U8 *)-offset(CMemUsedAllocated.next);
um=um1->next;
while (um!=um1) {
if (!IsInHeap(um,task,FALSE))
result=FALSE;
um=um->next;
}
if (task->data_heap!=task->code_heap) {
um1=(&task->data_heap->next_um)(U8 *)-offset(CMemUsedAllocated.next);
um=um1->next;
while (um!=um1) {
if (!IsInHeap(um,task,FALSE))
result=FALSE;
um=um->next;
}
}
#endif
if (task->data_heap!=task->code_heap)
LBtr(&task->data_heap->locked_flags,HClf_LOCKED);
LBtr(&task->code_heap->locked_flags,HClf_LOCKED);
PopFD;
return result;
}
#help_index "Info;Task"
U0 TaskRepTask(CTask *task,I64 indent)
{
CTask *task1;
U8 *st,*desc=MSPrintF("%q",task->task_title);
st=MSPrintF("$$MA+A,\"%08X\",\"Kill(0x%X);\n\",$$",task,task,task);
Spaces(indent);
"%s $$TX+SCX,\"%Q...\",16$$ Mem:%08X\n",
st,desc,TaskAllocatedMem(task);
Spaces(indent+2);
"Flags:%04X:%04X %02X\n",
task->task_flags,task->display_flags,ExceptDepth(task);
"Time:%9.2fm\n",task->total_time/60.0/time_stamp_freq_initial;
Free(st);
Free(desc);
task1=task->next_child_task;
while (task1!=(&task->next_child_task)(U8 *)-offset(CTask.next_sibling_task)) {
TaskRepTask(task1,indent+2);
task1=task1->next_sibling_task;
}
}
public U0 TaskRep()
{
U8 i;
CCPU *c;
PushFD;
Cli;
for (i=0;i<mp_cnt;i++) {
c=&cpu_structs[i];
"$$FG,RED$$CPU:%d$$FG$$\n",i;
TaskRepTask(c->seth_task,2);
}
PopFD;
}
#help_index ""
Binary file not shown.
File diff suppressed because it is too large. Load diff
Binary file not shown.
+306
View File
@@ -0,0 +1,306 @@
#help_index "WordStat/Dictionary"
public U0 WSDWordsLoad()
{
I64 size;
CHashGeneric *temph;
U8 *in_ptr,*in_start,*st2;
U16 *d;
ws_dict_num_words=0;
if (in_ptr=FileRead(WSD_WORD_FILENAME,&size)) {
in_start=in_ptr;
Free(ws_dict_word_lst);
ws_dict_word_lst=AMAlloc(size);
MemCpy(ws_dict_word_lst,in_start,size);
ws_dict_word_lst_size=size;
while (in_ptr<in_start+size) {
if (*in_ptr==WSD_WORD_CHAR)
in_ptr++;
if (*in_ptr) {
st2=MStrUtil(in_ptr,SUF_TO_UPPER);
temph=ACAlloc(sizeof(CHashGeneric)+StrLen(st2)+1);
StrCpy(temph+1,st2);
Free(st2);
in_ptr+=StrLen(in_ptr)+1;
temph->str=temph+1;
temph->use_cnt=1;
temph->type=HTT_DICT_WORD;
d=in_ptr;
temph->user_data0=*d;
in_ptr+=2;
HashAdd(temph,ws_hash_table);
ws_dict_num_words++;
} else
in_ptr+=3;
}
Free(in_start);
}
}
public U8 *WSDGetDef(U8 *st,I64 def_num=1)
{
CFile *f;
CHashGeneric *temph;
U8 *result=NULL,*buf,*in_ptr,
*st2=MStrUtil(st,SUF_TO_UPPER);
temph=HashFind(st2,ws_hash_table,HTT_DICT_WORD);
Free(st2);
if (temph) {
if (f=FOpen(WSD_DEF_FILENAME,"r")) {
buf=MAlloc(WSD_BLK_SIZE*2+1);
buf[WSD_BLK_SIZE*2]=0; //terminate
FRBlks(f,buf,temph->user_data0*WSD_BLK_SIZE/BLK_SIZE,WSD_BLK_SIZE*2/BLK_SIZE);
FClose(f);
in_ptr=buf;
while (in_ptr<buf+WSD_BLK_SIZE*2) {
while (*in_ptr!=WSD_WORD_CHAR && in_ptr<buf+WSD_BLK_SIZE*2)
in_ptr++;
if (*in_ptr++==WSD_WORD_CHAR) {
if (!StrICmp(st,in_ptr)) {
while (def_num && *in_ptr!=WSD_WORD_CHAR
&& in_ptr<buf+WSD_BLK_SIZE*2) {
if (*in_ptr==WSD_DEF_CHAR) {
if (!--def_num)
break;
else
in_ptr++;
} else
in_ptr++;
}
if (*in_ptr++==WSD_DEF_CHAR) {
result=StrNew(in_ptr);
break;
}
}
}
}
Free(buf);
}
}
return result;
}
public U8 *WSDGetWord(U8 *st)
{
CFile *f;
CHashGeneric *temph;
U8 *result=NULL,*buf,*in_ptr,*in_ptr2,
*st2=MStrUtil(st,SUF_TO_UPPER);
temph=HashFind(st2,ws_hash_table,HTT_DICT_WORD);
Free(st2);
if (temph) {
if (f=FOpen(WSD_DEF_FILENAME,"r")) {
buf=MAlloc(WSD_BLK_SIZE*2+1);
buf[WSD_BLK_SIZE*2]=0; //terminate
FRBlks(f,buf,temph->user_data0*WSD_BLK_SIZE/BLK_SIZE,WSD_BLK_SIZE*2/BLK_SIZE);
FClose(f);
in_ptr=buf;
while (in_ptr<buf+WSD_BLK_SIZE*2) {
while (*in_ptr!=WSD_WORD_CHAR && in_ptr<buf+WSD_BLK_SIZE*2)
in_ptr++;
if (*in_ptr++==WSD_WORD_CHAR) {
if (!StrICmp(st,in_ptr)) {
in_ptr2=in_ptr;
in_ptr--;
while (*in_ptr2!=WSD_WORD_CHAR
&& in_ptr2<buf+WSD_BLK_SIZE*2) {
in_ptr2++;
}
result=MAlloc(in_ptr2+1-in_ptr);
MemCpy(result,in_ptr,in_ptr2-in_ptr);
result[in_ptr2-in_ptr]=WSD_END_CHAR;
break;
}
}
}
Free(buf);
}
}
return result;
}
/*
Fmt of word lst entry:
U8 WSD_WORD_CHAR
U8 word[] with terminating zero
I16 block;
*/
public U8 *WSDPtAtWord(U8 *st)
{
I64 i;
U8 *start=ws_dict_word_lst,*r=start,
*end=ws_dict_word_lst+ws_dict_word_lst_size;
if (!st || !*st)
return ws_dict_word_lst;
if (ws_dict_word_lst_size) {
while (start+3<end) {
r=(start+end)>>1;
while (TRUE) {
while (*r!=WSD_WORD_CHAR && r>ws_dict_word_lst)
r--;
if ((r[2]==WSD_WORD_CHAR||r[1]==WSD_WORD_CHAR)&&r-3>ws_dict_word_lst)
r--;
else
break;
}
if (*r==WSD_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!=WSD_WORD_CHAR && r>ws_dict_word_lst)
r--;
if ((r[2]==WSD_WORD_CHAR||r[1]==WSD_WORD_CHAR)&&r-3>ws_dict_word_lst)
r--;
else
break;
}
if (*r==WSD_WORD_CHAR && StrICmp(st,r+1)>0)
r+=StrLen(r)+3;
}
if (*r==WSD_WORD_CHAR)
return r;
else
return ws_dict_word_lst;
}
U0 WSDDictWordsAdd(CDoc *doc,U8 *st=NULL)
{
I64 i;
U8 *ptr;
if (!st)
st=ws_cur_word;
if (st) {
if (ptr=WSDPtAtWord(st)) {
for (i=0;i<WSD_MAX_FILLINS;i++) {
if (*ptr++!=WSD_WORD_CHAR)
break;
if (i)
DocPutS(doc,"\n");
wsd_fillins[i]=ptr-1;
DocPrintF(doc," '%d' %s",i,ptr);
ptr+=StrLen(ptr)+3;
}
wsd_num_fillins=i;
}
}
}
U0 WSDFillin(I64 n)
{
U8 *s;
I64 len;
if (0<=n<wsd_num_fillins) {
s=wsd_fillins[n]+1;
len=StrLen(s);
if (len>ws_prtial_len)
Auto(s+ws_prtial_len);
}
}
public U0 WSDDisplayDefs(CDoc *doc,U8 *st,I64 num=-1)
{
U8 *st2,*st3,ch;
I64 i=0;
if (!st) return;
if (*st==WSD_WORD_CHAR)
st++;
DocPrintF(doc,"$$WW,1$$$$FG,RED$$%s:$$FG$$\n\n",st);
if (num<0) {
if (st3=WSDGetWord(st)) {
st2=st3;
while (ch=*st2++) {
switch (ch) {
case WSD_WORD_CHAR:
break;
case WSD_DEF_CHAR:
DocPrintF(doc,"$$FG,GREEN$$(%d)$$FG$$ %s\n",
++i,st2);
break;
case WSD_PRONUNCIATION_CHAR:
DocPrintF(doc,"$$FG,LTGREEN$$%s$$FG$$\n",st2);
break;
case WSD_POS_CHAR:
DocPrintF(doc,"$$FG,BLACK$$%s$$FG$$\n",st2);
break;
case WSD_EXTRA_CHAR:
DocPrintF(doc,"$$FG,LTBLUE$$%s$$FG$$\n",st2);
break;
}
st2+=StrLen(st2)+1;
}
Free(st3);
}
} else {
while (st2=WSDGetDef(st,++i)) {
if (i==num)
DocPrintF(doc,"$$FG,GREEN$$(%d)$$FG$$ %s\n",
i,st2);
Free(st2);
}
}
}
U0 WSDPopUpDef(U8 *st,I64 num=-1,CTask *parent=NULL)
{
U8 *buf;
buf=MSPrintF("WSDDisplayDefs(DocCur,\"%s\",%d);View;",st,num);
PopUp(buf,parent);
Free(buf);
}
U0 WSDDef(I64 n,CTask *parent=NULL)
{
if (0<=n<wsd_num_fillins)
WSDPopUpDef(wsd_fillins[n],-1,parent);
}
U0 WSFindMisspelled(CDoc *doc)
{
Bool unlock=DocLock(doc);
CDocEntry *doc_e=doc->cur_entry;
I64 col=doc->cur_data_col,col2,ch;
do {
if (doc_e!=doc && Bt(doc_tag_types,doc_e->type_u8)) {
while (col<doc_e->max_col) {
while (col<doc_e->max_col && !Bt(word_bitmap,doc_e->tag[col]))
col++;
if (col<doc_e->max_col) {
col2=col;
while (col2<doc_e->max_col && Bt(word_bitmap,doc_e->tag[col2]))
col2++;
ch=doc_e->tag[col2];
doc_e->tag[col2]=0;
if (StrICmp(&doc_e->tag[col],WSDPtAtWord(&doc_e->tag[col])+1)) {
doc_e->tag[col2]=ch;
doc->cur_entry=doc_e;
doc->cur_data_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 ""
+219
View File
@@ -0,0 +1,219 @@
/*
This file is a stand-alone program
which will regenerate processed dictionary
files from a raw Project Gutenberg
dictionary file.
Supply the raw dictionary filename in
the call at the bottom of this file
and #include this file.
I ran $LK-A,"::/TempleOS/Misc/Dollar.CPP"$ on it, first.
See $LK-A,"::/TempleOS/Doc/Acknowledgements.TXT"$ (20).
*/
I64 WSDNextCmd(U8 **_ptr)
{
U8 ch,*ptr=*_ptr,*ptr2;
I64 result=-1;
do {
do {
if (!(ch=*ptr++)) goto ncmd_done;
} while (ch!='<');
ptr2=ptr;
do {
if (!(ch=*ptr2++)) goto ncmd_done;
} while (ch!='>');
*--ptr2=0;
result=LstEntryMatch(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 (result<0);
ncmd_done:
*_ptr=ptr;
return result;
}
U8 *WSDNextEntry(U8 **_ptr)
{
U8 *result,*ignore,ch,*ptr=*_ptr,buf[WSD_BLK_SIZE],*out_ptr=buf;
I64 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>\0p>\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;
result=StrNew(buf);
*_ptr=ptr-1;
return result;
}
I64 WSDCompareWords(U8 *e1,U8 *e2)
{
return StrICmp(e1,e2);
}
U8 *WSDSortWords(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,&WSDCompareWords);
"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 WSDGen(U8 *raw_dict_filename)
{
I64 cmd,size,word_cnt=0,largest_entry=0;
U8 *st,*in_ptr=FileRead(raw_dict_filename,&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=WSDNextCmd(&in_ptr);
if (cmd==WSD_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=WSDNextEntry(&in_ptr)) {
if (*st) {
if (StrICmp(st,last_word)) {
word_cnt++;
*word_ptr++=WSD_WORD_CHAR;
last_word=word_ptr;
StrCpy(word_ptr,st);
word_ptr+=StrLen(st)+1;
d=word_ptr;
*d=(out_ptr-out_start)/WSD_BLK_SIZE;
word_ptr+=2;
*out_ptr++=WSD_WORD_CHAR;
StrCpy(out_ptr,st);
out_ptr+=StrLen(st)+1;
}
Free(st);
do {
do {
cmd=WSDNextCmd(&in_ptr);
if (cmd==WSD_H1)
goto next_word;
} while (cmd>=0 && !(cmd==WSD_DEF||cmd==WSD_PRONUNCIATION||cmd==WSD_POS||cmd==WSD_EXTRA));
if (cmd==WSD_DEF) {
if(st=WSDNextEntry(&in_ptr)) {
if (*st) {
*out_ptr++=WSD_DEF_CHAR;
StrCpy(out_ptr,st);
out_ptr+=StrLen(st)+1;
}
Free(st);
}
} else if (cmd==WSD_PRONUNCIATION) {
if(st=WSDNextEntry(&in_ptr)) {
if (*st) {
*out_ptr++=WSD_PRONUNCIATION_CHAR;
StrCpy(out_ptr,st);
out_ptr+=StrLen(st)+1;
}
Free(st);
}
} else if (cmd==WSD_POS) {
if(st=WSDNextEntry(&in_ptr)) {
if (*st) {
*out_ptr++=WSD_POS_CHAR;
StrCpy(out_ptr,st);
out_ptr+=StrLen(st)+1;
}
Free(st);
}
} else if (cmd==WSD_EXTRA) {
if(st=WSDNextEntry(&in_ptr)) {
if (*st) {
*out_ptr++=WSD_EXTRA_CHAR;
StrCpy(out_ptr,st);
out_ptr+=StrLen(st)+1;
}
Free(st);
}
}
} while (cmd==WSD_DEF||cmd==WSD_PRONUNCIATION||cmd==WSD_POS||cmd==WSD_EXTRA);
} else
Free(st);
}
}
} while (cmd>=0);
*out_ptr++=WSD_END_CHAR;
*word_ptr++=WSD_END_CHAR;
Free(in_start);
"Blk Size :%d\n",WSD_BLK_SIZE;
"Blk Cnt :%04X\n",(out_ptr-out_start+WSD_BLK_SIZE-1)/WSD_BLK_SIZE;
"Largest Entry :%d\n",largest_entry;
"Word Count :%d\n",word_cnt;
FileWrite(WSD_DEF_FILENAME,out_start,out_ptr-out_start);
"Def File Size :%d\n",out_ptr-out_start;
sorted_word_start=WSDSortWords(word_start,word_ptr-word_start,word_cnt);
FileWrite(WSD_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);
}
WSDGen("DICTIONARY.TXT");
+721
View File
@@ -0,0 +1,721 @@
#help_index "WordStat"
/**** Debug code
U0 WSPutMatrix(CWSMatrix *m)
{
I64 i,j;
CWSMatrixSide *ms;
CWS *tempw;
"n:%d\n",m->n;
for (i=0;i<ws_num_matrix_words;i++) {
ms=&m->side[i];
"col:%d rhits:%d chits:%d\n",i,ms->row_hits,ms->col_hits;
tempw=ms->next;
while (tempw!=ms) {
"substructs:%d entries:%d\n",tempw->substructs,tempw->entries;
for (j=0;j<tempw->substructs;j++) {
"(%04X %04X) ",
tempw->subs[j].hits,
tempw->subs[j].repeats;
}
NewLine;
tempw=tempw->next;
}
}
View;
}
****/
CHashWS *WSHashAdd(U8 *w)
{
CHashWS *tempw=HashFind(w,ws_hash_table,HTT_WORD);
if (tempw) {
tempw->hits++;
return tempw;
}
tempw=ACAlloc(sizeof(CHashWS));
tempw->str=AStrNew(w);
tempw->type=HTT_WORD;
tempw->use_cnt=1;
tempw->hits=1;
tempw->num=-1;
HashAdd(tempw,ws_hash_table);
ws_num_words++;
return tempw;
}
U0 WSSidesInit(CWSMatrix *m)
{
I64 i;
CWS *tempa;
m->n=0;
for (i=0;i<WS_MAX_MATRIX_WORDS;i++) {
m->side[i].next=m->side[i].last=&m->side[i].next;
m->side[i].const_minus_one=-1;
m->side[i].row_hits=0;
m->side[i].col_hits=0;
tempa=AMAlloc(sizeof(CWS));
ws_structs_size+=MSize2(tempa);
tempa->subs[0].hits=0;
tempa->subs[0].repeats=ws_num_matrix_words;
tempa->entries=ws_num_matrix_words;
tempa->substructs=1;
QueIns(tempa,m->side[i].last);
}
}
CWS *WSStructFind(CWSMatrix *m,I64 col,I64 row,
I64 *_row_base,I64 *_substruct)
{
CWS *tempa;
I64 row_base,i,j;
if (row>=ws_num_matrix_words ||
col>=ws_num_matrix_words)
return NULL;
if (row<ws_num_matrix_words>>1) {
tempa=m->side[col].next;
row_base=0;
j=row;
while (row>=(i=tempa->entries)) {
row-=i;
tempa=tempa->next;
}
row_base+=j-row;
for (*_substruct=0;row>=tempa->subs[*_substruct].repeats;*_substruct=*_substruct+1) {
row-=tempa->subs[*_substruct].repeats;
row_base+=tempa->subs[*_substruct].repeats;
}
} else {
row=ws_num_matrix_words-row;
tempa=m->side[col].last;
row_base=ws_num_matrix_words;
j=row;
while (row>(i=tempa->entries)) {
row-=i;
tempa=tempa->last;
}
row_base+=j-row;
for (*_substruct=tempa->substructs-1;row>tempa->subs[*_substruct].repeats;
*_substruct=*_substruct-1) {
row-=tempa->subs[*_substruct].repeats;
row_base-=tempa->subs[*_substruct].repeats;
}
row_base-=tempa->subs[*_substruct].repeats;
}
*_row_base=row_base;
return tempa;
}
public I64 WSGetHits(CWSMatrix *m,I64 col,I64 row)
{
I64 row_base,substruct;
CWS *tempa;
if (row>=ws_num_matrix_words ||
col>=ws_num_matrix_words)
return 0;
tempa=WSStructFind(m,col,row,
&row_base,&substruct);
return tempa->subs[substruct].hits;
}
CWSSub *WSNext(CWSSub *s,CWS **_parent)
{
I64 i=(s(U8 *)-(&(*_parent)->subs)(U8 *))/sizeof(CWSSub)+1;
if (i>=(*_parent)->substructs) {
i=0;
*_parent=(*_parent)->next;
if ((*_parent)->substructs==-1)
return NULL;
}
return &(*_parent)->subs[i];
}
CWSSub *WSLast(CWSSub *s,CWS **_parent)
{
I64 i=(s(U8 *)-(&(*_parent)->subs)(U8 *))/sizeof(CWSSub)-1;
if (i<0) {
*_parent=(*_parent)->last;
if ((*_parent)->substructs==-1)
return NULL;
i=(*_parent)->substructs-1;
}
return &(*_parent)->subs[i];
}
U0 WSRem(CWSSub *s,CWS *parent)
{
I64 i=(s(U8 *)-(&parent->subs)(U8 *))/sizeof(CWSSub);
if (i<0 || i>=WS_SUBSTRUCTS_PER_STRUCT || parent->substructs<1)
return;
if (parent->substructs==1) {
QueRem(parent);
ws_structs_size-=MSize2(parent);
Free(parent);
} else {
parent->entries-=s->repeats;
parent->substructs--;
MemCpy(&parent->subs[i],&parent->subs[i+1],
(parent->substructs-i)*sizeof(CWSSub));
}
}
CWSSub *WSIns(CWSSub *s,CWS **_parent,CWSSub *last)
{
CWS *tempa,*parent=*_parent;
I64 j,k,i=(last(U8 *)-(&parent->subs)(U8 *))/sizeof(CWSSub)+1;
if (i>=WS_SUBSTRUCTS_PER_STRUCT) {
i=0;
parent=parent->next;
*_parent=parent;
if (parent->substructs==-1) {
tempa=AMAlloc(sizeof(CWS));
ws_structs_size+=MSize2(tempa);
QueIns(tempa,parent->last);
parent=tempa;
*_parent=parent;
tempa->entries=0;
tempa->substructs=0;
}
}
if (parent->substructs==WS_SUBSTRUCTS_PER_STRUCT) {
tempa=parent->next;
if (tempa->substructs==-1 || tempa->substructs==WS_SUBSTRUCTS_PER_STRUCT) {
tempa=AMAlloc(sizeof(CWS));
ws_structs_size+=MSize2(tempa);
tempa->entries=0;
tempa->substructs=0;
QueIns(tempa,parent);
k=0;
for (j=i;j<parent->substructs;j++) {
MemCpy(&tempa->subs[k],&parent->subs[j],sizeof(CWSSub));
tempa->entries+=tempa->subs[k++].repeats;
tempa->substructs++;
}
parent->entries-=tempa->entries;
parent->substructs-=tempa->substructs;
} else {
for (j=tempa->substructs-1;j>=0;j--)
MemCpy(&tempa->subs[j+1],&tempa->subs[j],sizeof(CWSSub));
MemCpy(&tempa->subs[0],
&parent->subs[WS_SUBSTRUCTS_PER_STRUCT-1],
sizeof(CWSSub));
parent->entries-=tempa->subs[0].repeats;
parent->substructs--;
tempa->entries+=tempa->subs[0].repeats;
tempa->substructs++;
for (j=WS_SUBSTRUCTS_PER_STRUCT-2;j>=i;j--)
MemCpy(&parent->subs[j+1],
&parent->subs[j],sizeof(CWSSub));
}
} else {
for (j=parent->substructs-1;j>=i;j--)
MemCpy(&parent->subs[j+1],
&parent->subs[j],sizeof(CWSSub));
}
parent->entries+=s->repeats;
parent->substructs++;
MemCpy(&parent->subs[i],s,sizeof(CWSSub));
return &parent->subs[i];
}
CWSSub *WSCondense(CWSSub *s,CWS **_parent)
{
CWSSub *temps,*temps_l,*temps_n;
CWS *tempa_l,*tempa_n;
if ((*_parent)->substructs==-1)
return NULL;
temps=s;
tempa_l=*_parent;
temps_l=WSLast(temps,&tempa_l);
if (temps_l && temps_l->hits==temps->hits) {
temps_l->repeats+=temps->repeats;
tempa_l->entries+=temps->repeats;
WSRem(temps,*_parent);
*_parent=tempa_l;
temps=temps_l;
}
tempa_n=*_parent;
temps_n=WSNext(temps,&tempa_n);
if (temps_n && temps_n->hits==temps->hits) {
temps->repeats=temps->repeats+temps_n->repeats;
(*_parent)->entries=(*_parent)->entries+temps_n->repeats;
WSRem(temps_n,tempa_n);
}
return temps;
}
I64 WSHitsInc(CWSMatrix *m,I64 col,I64 row)
{
I64 row_base,substruct,repeats;
CWSSub sn,*temps,*temps1,*temps_l;
CWS *tempa,*tempa1,*tempa_l;
if (row>=ws_num_matrix_words ||
col>=ws_num_matrix_words)
return 0;
tempa=WSStructFind(m,col,row,&row_base,&substruct);
temps=&tempa->subs[substruct];
repeats=temps->repeats;
if (repeats==1) {
temps->hits++;
temps=WSCondense(temps,&tempa);
} else {
if (row==row_base) {
temps->repeats--;
tempa->entries--;
sn.hits=1;
sn.repeats=1;
tempa_l=tempa;
if (!(temps_l=WSLast(&tempa->subs[substruct],&tempa_l))) {
tempa_l=tempa->last; //header
temps_l=&tempa_l->subs[WS_SUBSTRUCTS_PER_STRUCT-1];
}
temps=WSIns(&sn,&tempa_l,temps_l);
temps=WSCondense(temps,&tempa_l);
} else if (row==repeats-1+row_base) {
temps->repeats--;
tempa->entries--;
sn.hits=1;
sn.repeats=1;
temps=WSIns(&sn,&tempa,temps);
temps=WSCondense(temps,&tempa);
} else {
tempa->entries-=repeats;
sn.hits=temps->hits+1;
sn.repeats=1;
tempa1=tempa;
temps1=temps;
temps=WSIns(&sn,&tempa1,temps1);
temps1->repeats=row-row_base;
tempa->entries+=temps1->repeats;
sn.repeats=row_base+repeats-(row+1);
sn.hits=temps1->hits;
WSIns(&sn,&tempa1,temps);
}
}
m->n++;
m->side[col].col_hits++;
m->side[row].row_hits++;
return temps->hits;
}
U0 WSSingleFileAdd(U8 *buf,I64 pass)
{
U8 ch,*ptr=buf,*ptr2,*ptr3;
CHashWS *cur_ptr,*last_ptr=NULL;
while (TRUE) {
while (TRUE) {
if (ch=*ptr++) {
if (Bt(alpha_numeric_bitmap,ch))
break;
} else
return;
}
ptr3=ptr;
ptr2=ptr;
ptr--;
while (TRUE) {
if (ch=*ptr2++) {
if (ch!=CH_CURSOR) {
if (!Bt(alpha_numeric_bitmap,ch))
break;
else
*ptr3++=ch;
}
} else {
ptr2--;
break;
}
}
*ptr3=0;
if (pass==1)
WSHashAdd(ptr);
else {
cur_ptr=HashFind(ptr,ws_hash_table,HTT_WORD);
if (cur_ptr->num<0)
cur_ptr=NULL;
else
if (last_ptr)
WSHitsInc(ws_matrix,last_ptr->num,cur_ptr->num);
last_ptr=cur_ptr;
}
ptr=ptr2;
}
}
I64 WSCompare(CHashWS *e1,CHashWS *e2)
{
I64 r;
if (!(r=e2->hits - e1->hits))
r=StrCmp(e1->str,e2->str);
return r;
}
I64 WSSkipCrap(U8 *src,I64 len)
{
I64 j;
j=len-1;
while (j>=0) {
if (Bt(alpha_numeric_bitmap,src[j]))
break;
else
j--;
}
return j+1;
}
I64 WSPriorWordInStr(U8 *src,U8 *dst,I64 len,I64 buf_size)
{
I64 i,j=0,k;
Bool cont=TRUE;
i=len-1;
while (i>=0 && cont) {
if (!Bt(alpha_numeric_bitmap,src[i]))
cont=FALSE;
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;
}
Bool WSPartialMatch(U8 *partial,U8 *complete)
{
I64 i,l=StrLen(partial);
for (i=0;i<l;i++)
if (partial[i]!=complete[i])
return FALSE;
return TRUE;
}
U0 WSFillIn(I64 n)
{
U8 *s;
I64 len;
if (0<=--n<ws_num_fillins) {
s=ws_sorted_words[ws_fillin_matches[n]]->str;
len=StrLen(s);
if (len>ws_prtial_len)
Auto(s+ws_prtial_len);
}
}
U0 WSMan(I64 n,CTask *parent_task=NULL)
{
U8 *buf;
CHashWS *tempw;
CHashSrcSym *temph;
Bool old_preempt=Preempt(OFF);
if (0<=--n<ws_num_fillins) {
if (tempw=ws_sorted_words[ws_fillin_matches[n]]) {
if (temph=HashFind(tempw->str,Fs->hash_table,HTG_SRC_SYM)) {
if (temph->src_link) {
buf=MSPrintF("Ed(\"%s\");",temph->src_link);
Preempt(old_preempt);
PopUp(buf,parent_task);
Free(buf);
} else if (temph->type&HTT_DEFINE_STR && temph(CHashDefineStr *)->caller)
E(temph(CHashDefineStr *)->caller,DFT_ADDR_LINK_BIN_SIZE);
}
}
}
Preempt(old_preempt);
}
U0 WSFillInAdd(I64 i,I64 j,I64 old_num_fillins)
{
Bool cont;
I64 k;
if (ws_num_fillins<WS_MAX_FILLINS || i>ws_fillin_scores[ws_num_fillins-1] ||
i==ws_fillin_scores[ws_num_fillins-1] && ws_sorted_words[j]->hits>ws_fillin_hits[ws_num_fillins-1]) {
cont=TRUE;
for (k=ws_num_fillins-1;k>=old_num_fillins && cont;k--)
if (i<=ws_fillin_scores[k] || i==ws_fillin_scores[k] && ws_sorted_words[j]->hits<=ws_fillin_hits[k]) {
cont=FALSE;
k++; //offset k--
} else {
ws_fillin_scores[k+1]=ws_fillin_scores[k];
ws_fillin_matches[k+1]=ws_fillin_matches[k];
ws_fillin_hits[k+1]=ws_fillin_hits[k];
}
if (ws_num_fillins<WS_MAX_FILLINS)
ws_num_fillins++;
ws_fillin_scores[k+1]=i;
ws_fillin_hits[k+1]=ws_sorted_words[j]->hits;
ws_fillin_matches[k+1]=j;
}
}
U0 WSPutChoices(CDoc *focus_l,CDocEntry *doc_e,CTask *focus_task)
{
I64 i,j,k,data_col;
U8 ch=0,*buf,*buf1,*src=NULL,*st;
CHashWS *w2;
F64 timeout_time=tS+0.5;
CHashSrcSym *temph;
CDoc *doc=DocCur;
src=DocGetLine(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=WSPriorWordInStr(src,buf,data_col,256);
ws_prtial_len=StrLen(buf);
data_col=WSSkipCrap(src,data_col);
data_col=WSPriorWordInStr(src,buf1,data_col,256);
if (ws_cur_word && !StrCmp(ws_cur_word,buf))
goto pc_done;
st=ws_cur_word;
ws_cur_word=AStrNew(buf);
Free(st);
if (!IsSysDeterministic)
Preempt(ON);
if (StrLen(buf1)&&ws_hash_table)
w2=HashFind(buf1,ws_hash_table,HTT_WORD);
else
w2=NULL;
ws_num_fillins=0;
if (w2 && w2->num<ws_num_matrix_words)
for (j=0;j<ws_num_matrix_words && tS<timeout_time;j++)
if (WSPartialMatch(ws_cur_word,ws_sorted_words[j]->str)) {
i=WSGetHits(ws_matrix,w2->num,ws_sorted_words[j]->num);
WSFillInAdd(i,j,0);
}
k=ws_num_fillins;
for (j=0;j<ws_num_words && tS<timeout_time;j++)
if (WSPartialMatch(ws_cur_word,ws_sorted_words[j]->str))
WSFillInAdd(0,j,k);
Preempt(OFF);
pc_done:
DocRst(doc,TRUE);
doc->flags|=DOCF_MIN_SIZE;
DocCursor;
DocCurAttr(LTBLUE<<4+WHITE);
DocAuxAttr(LTBLUE<<4+BLACK);
DocPrintF(doc,"Word:%s\n",ws_cur_word);
for (i=0;i<ws_num_fillins;i++) {
st=ws_sorted_words[ws_fillin_matches[i]]->str;
ch=CH_SPACE;
if (TaskValidate(focus_task)) {
if (temph=HashFind(st,focus_task->hash_table,HTG_SRC_SYM))
if (temph->src_link ||
temph->type&HTT_DEFINE_STR && temph(CHashDefineStr *)->caller)
ch='*';
}
DocPrintF(doc,"%cF%02d %s\n",ch,i+1,st);
}
WSDDictWordsAdd(doc);
DocRecalc(doc);
if (!LBts(&Fs->display_flags,DISPLAYf_SHOW))
WinZBufUpdate;
Free(src);
Free(buf);
Free(buf1);
}
U0 WSTask(I64)
{
CTask *focus_task,*original_focus_task;
CDoc *doc;
CDocEntry *doc_e;
TaskInitExt;
UseTermDoc;
SetWinHorz(50,Fs->win_right);
LBts(&Fs->display_flags,DISPLAYf_WIN_ON_TOP);
do {
Sleep(333);
if (Bt(&ws_flags,WSf_ENABLE)) {
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 (TaskValidate(focus_task) && (doc=DocCur(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_signature==DOC_SIGNATURE_VAL && doc==DocCur(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;
if (Bt(&ws_flags,WSf_ENABLE))
WSPutChoices(doc,doc_e,focus_task);
else
DocUnlock(doc);
} else
DocUnlock(doc);
}
}
} while (!ScanKey);
ws_task=NULL;
}
U0 WSMainFileLstTraverse(U8 *files_find_mask,I64 pass)
{
I64 i,cnt;
CDirEntry **flst=NULL;
U8 *buf;
try {
flst=FilesOrder(FilesFind(files_find_mask,
FUF_RECURSE|FUF_JUST_TXT_FILES|FUF_JUST_FILES|FUF_FLATTEN_TREE),&cnt);
for (i=0;i<cnt;i++) {
"%s\n",flst[i]->full_name;
buf=TextFileRead(flst[i]->full_name);
WSSingleFileAdd(buf,pass);
Free(buf);
CDirEntryDel(flst[i]);
}
} catch
Fs->catch_except=TRUE;
Free(flst);
}
U0 WSMatrixDel(CWSMatrix *m)
{
I64 i;
CWS *tempw,*tempw1,*tempw2;
if (!m) return;
for (i=0;i<WS_MAX_MATRIX_WORDS;i++) {
tempw1=&m->side[i];
tempw=tempw1->next;
while (tempw!=tempw1) {
tempw2=tempw->next;
Free(tempw);
tempw=tempw2;
}
}
Free(m);
}
public Bool WordStat(Bool val=OFF)
{
Bool old_wordstat=FALSE,
old_preempt=Preempt(OFF);
if (val) {
if (TaskValidate(ws_task))
old_wordstat=TRUE;
else {
ws_task=Spawn(&WSTask,NULL,"WordStat");
TaskWait(ws_task);
}
if (!LBts(&ws_flags,WSf_ENABLE))
WinToTop(ws_task);
} else {
LBtr(&ws_flags,WSf_ENABLE);
if (TaskValidate(ws_task)) {
old_wordstat=TRUE;
Kill(ws_task);
while (TaskValidate(ws_task))
Yield;
ws_task=NULL;
}
}
Preempt(old_preempt);
return old_wordstat;
}
U0 WSProgressTask(Bool *_start_flag)
{
I64 start=sys_dsk_writes;
TaskInitExt; //needed for disk access
progress1=0;
progress1_max=(FileSizeExpanded(WSD_DEF_FILENAME_Z)+BLK_SIZE-1)>>BLK_SIZE_BITS;
StrCpy(progress1_desc,"Uncompressing Dictionary");
start=sys_dsk_writes;
*_start_flag=TRUE;
while (progress1<progress1_max) {
progress1=sys_dsk_writes-start;
Sleep(10);
}
*progress1_desc=progress1=progress1_max=0;
}
public U0 WSInit(U8 *mask=NULL)
{
I64 i,j=0;
Bool start_flag;
CHashWS *tempw;
CBlkDev *bdev=Drv2BlkDev;
while (LBts(&ws_flags,WSf_INIT_IN_PROGRESS))
Yield;
WordStat;
if (IsDrvWritable && FileFind(WSD_DEF_FILENAME_Z) && !FileFind(WSD_DEF_FILENAME)) {
if (bdev->type!=BDT_RAM) {
start_flag=FALSE;
Spawn(&WSProgressTask,&start_flag);
while (!start_flag)
Yield;
}
Move(WSD_DEF_FILENAME_Z,WSD_DEF_FILENAME);
}
HashTableDel(ws_hash_table);
ws_hash_table=HashTableNew(0x4000,adam_task);
ws_num_words=0;
ws_num_matrix_words=0;
ws_structs_size=0;
Free(ws_cur_word);
ws_cur_word=NULL;
"\n\nPass #1\n";
if (mask) WSMainFileLstTraverse(mask,1);
Free(ws_sorted_words);
ws_sorted_words=AMAlloc(sizeof(U8 *)*ws_num_words);
tempw=ws_hash_table->next_added;
while (tempw!=ws_hash_table) {
ws_sorted_words[j++]=tempw;
tempw=tempw->next_added;
}
QSortI64(ws_sorted_words,ws_num_words,&WSCompare);
for (i=0;i<ws_num_words;i++)
ws_sorted_words[i]->num=i;
if (ws_num_words<=WS_MAX_MATRIX_WORDS)
ws_num_matrix_words=ws_num_words;
else
ws_num_matrix_words=WS_MAX_MATRIX_WORDS;
WSMatrixDel(ws_matrix);
ws_matrix=AMAlloc(sizeof(CWSMatrix));
WSSidesInit(ws_matrix);
"\n\nPass #2\n";
if (mask) WSMainFileLstTraverse(mask,2);
WSDWordsLoad;
WordStat(ON);
LBtr(&ws_flags,WSf_INIT_IN_PROGRESS);
}
I64 WordStatSize()
{
if (ws_hash_table)
return HashTableSize2(ws_hash_table)+ws_structs_size+
MSize2(ws_sorted_words)+MSize2(ws_matrix)+MSize2(ws_dict_word_lst);
else
return 0;
}
#help_index ""
Binary file not shown.
+93
View File
@@ -0,0 +1,93 @@
#help_index "WordStat"
#help_file "::/TempleOS/Doc/WordStat"
//See $LK-A,"::/TempleOS/Doc/WordStat.TXT"$
class CWSSub
{
I32 hits,repeats;
};
#define WS_SUBSTRUCTS_PER_STRUCT 8
class CWS
{
CWS *next,*last;
I64 substructs, //-1 means CWSMatrixSide
entries;
CWSSub subs[WS_SUBSTRUCTS_PER_STRUCT];
};
class CWSMatrixSide
{
CWS *next,*last;
I64 const_minus_one, //-1 used to header in que
row_hits,col_hits;
};
#define WS_MAX_MATRIX_WORDS 0x8000
class CWSMatrix
{
I64 n;
CWSMatrixSide side[WS_MAX_MATRIX_WORDS];
};
public I64 ws_num_words,ws_num_matrix_words;
CHashTable *ws_hash_table=NULL;
public U8 *ws_cur_word=NULL;
#define WSf_ENABLE 0
#define WSf_INIT_IN_PROGRESS 1
I64 ws_flags=0;
public CWSMatrix *ws_matrix=NULL;
public CHashWS **ws_sorted_words=NULL;
CTask *ws_task=NULL;
#define WS_MAX_FILLINS 10
I64 ws_prtial_len=0,ws_fillin_matches[WS_MAX_FILLINS+1];
I64 ws_num_fillins=0,ws_fillin_scores[WS_MAX_FILLINS+1],ws_fillin_hits[WS_MAX_FILLINS+1];
//**** Dictionary Stuff
#help_index "WordStat/Dictionary"
#define WSD_WORD_FILENAME "/TempleOS/Adam/WordStat/WSWords.DAT.Z"
#define WSD_DEF_FILENAME "/TempleOS/Adam/WordStat/WSDefs.DAT"
#define WSD_DEF_FILENAME_Z "/TempleOS/Adam/WordStat/WSDefs.DAT.Z"
#define WSD_H1 0
#define WSD_H1_END 1
#define WSD_DEF 2
#define WSD_DEF_END 3
#define WSD_PRONUNCIATION 4
#define WSD_PRONUNCIATION_END 5
#define WSD_POS 6
#define WSD_POS_END 7
#define WSD_EXTRA 8
#define WSD_EXTRA_END 9
#define WSD_BLK_SIZE 0x4000
#define WSD_END_CHAR 0x00
#define WSD_WORD_CHAR 0x01
#define WSD_DEF_CHAR 0x02
#define WSD_PRONUNCIATION_CHAR 0x03
#define WSD_POS_CHAR 0x04
#define WSD_EXTRA_CHAR 0x05
public U8 *ws_dict_word_lst=NULL;
public I64 ws_dict_word_lst_size=0,
ws_dict_num_words=0,ws_structs_size=0;
extern U0 WSDWordsLoad();
extern U0 WSDDictWordsAdd(CDoc *doc,U8 *st=NULL);
#define WSD_MAX_FILLINS 10
U8 *wsd_fillins[WSD_MAX_FILLINS];
I64 wsd_num_fillins=0;
// ************************************
#include "WSMain"
#include "WSDict"
#help_index ""