TempleOSTS_130315.ISO
This commit is contained in:
1 parent
e57428affb
commit
17b71f1a2d
958 files changed
+26043
-15907
No files matched your search
@@ -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"
|
||||
@@ -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();
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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 ""
|
||||
@@ -0,0 +1,8 @@
|
||||
#help_index "Ctrls"
|
||||
#help_file "::/TempleOS/Doc/Ctrls"
|
||||
|
||||
#include "Ctrls2a"
|
||||
#include "CtrlsButton"
|
||||
#include "CtrlsSlider"
|
||||
|
||||
#help_index ""
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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.
|
||||
|
||||
*/
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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
@@ -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"
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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 ""
|
||||
@@ -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");
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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
@@ -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
@@ -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"
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -0,0 +1,5 @@
|
||||
#include "Dsk2a"
|
||||
#include "Dsk2b"
|
||||
#include "DskCDDVD"
|
||||
#include "ChkDsk"
|
||||
#include "FileMgr"
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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
@@ -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
@@ -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 ""
|
||||
|
||||
@@ -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
@@ -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);
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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 ""
|
||||
@@ -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;
|
||||
|
||||
@@ -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"
|
||||
@@ -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"
|
||||
@@ -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 ""
|
||||
@@ -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);
|
||||
}
|
||||
@@ -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 ""
|
||||
@@ -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;
|
||||
@@ -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 ""
|
||||
@@ -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,"&");
|
||||
*_col=*_col+1;
|
||||
break;
|
||||
case '<':
|
||||
DocPutS(doc,"<");
|
||||
*_col=*_col+1;
|
||||
break;
|
||||
case '>':
|
||||
DocPutS(doc,">");
|
||||
*_col=*_col+1;
|
||||
break;
|
||||
case '"':
|
||||
DocPutS(doc,""");
|
||||
*_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 ""
|
||||
@@ -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 ""
|
||||
@@ -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");
|
||||
****/
|
||||
@@ -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.
@@ -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 ""
|
||||
@@ -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");
|
||||
@@ -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.
@@ -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 ""
|
||||
Reference in new issue
Block a user