REM BBC BASIC Integrated Development Environment for SDL 2.0 platforms REM Version 1.44a by Richard Russell, www.rtrussell.co.uk, 20-Mar-2026 REM Copyright (C) R. T. Russell 2026 REM!Embed @lib$+"dlglib", @lib$+"sortlib", @lib$+"stringlib", @lib$+"fnusing", @lib$+"script" REM!Embed @dir$+"SDLIDE.bmp", @dir$+"SDLIDEdark.bmp", @dir$+"profiler", @dir$+"listvars" REM!Embed @dir$+"crossref", @dir$+"searchin", @dir$+"memmon", @dir$+"macrorec", @dir$+"addconst" REM!Embed @dir$+"versinfo", @lib$+"utf8lib", @lib$+"sdlconsts.db" Ver$ = "1.44a" Year$ = "2026" Title$ = "SDLIDE version " + Ver$ BB4W% = (INKEY(-256) == &57) *ESC OFF *SYS 4 *KEY 2 # HIMEM = PAGE + &1000000 REM!WC Windows and SDL constants: BS_BITMAP = &80 CP_UTF8 = &FDE9 ES_NUMBER = 8192 IDCANCEL = 2 IDNO = 7 IDYES = 6 MB_ICONWARNING = 48 MB_ICONQUESTION = 32 MB_ICONINFORMATION = 64 MB_YESNO = 4 MB_YESNOCANCEL = 3 SS_RIGHT = 2 SW_MAXIMIZE = 3 WM_SIZE = 5 SDL_MESSAGEBOX_ERROR = &10 SDL_MESSAGEBOX_INFORMATION = &40 WS_DISABLED = &8000000 WS_TABSTOP = 65536 WS_VSCROLL = &200000 IF BB4W% THEN SYS "SetWindowText", @hwnd%, Title$ SYS "QueryPerformanceCounter", ^N%% Session$ = STR$(N%% AND &7FFFFFF) GUIFont$ = "Segoe UI,10" EditFont$ = "Courier New,11,B" Platform$ = "BB4W" SYS "SetStretchBltMode", @memhdc%, 4 ELSE SYS "SDL_SetWindowTitle", @hwnd%, Title$, @memhdc% SYS "SDL_GetPerformanceCounter" TO N%% Session$ = STR$(N%% AND &7FFFFFF) GUIFont$ = """"+@lib$+"DejaVuSans"",12" EditFont$ = """"+@lib$+"DejaVuSansMono"",11" CASE @platform% AND &F OF WHEN 0: Platform$ = "Win32" WHEN 1: Platform$ = "Linux" WHEN 2: Platform$ = "MacOS" ENDCASE IF @platform% AND &40 Platform$ += " (64-bit)" ELSE Platform$ += " (32-bit)" SYS "SDL_SetHint", "SDL_RENDER_SCALE_QUALITY", "linear" ENDIF ON ERROR LOCAL IF FALSE THEN OSCLI "DELETE """ + @tmp$ + "sdldebug.dat""" OSCLI "DELETE """ + @tmp$ + "memusage.dat""" ENDIF : RESTORE ERROR REM Hotspot IDs (must be >= NBUTTONS): IDMENU1 = 21 IDMENU2 = 22 IDMENU3 = 23 IDMENU4 = 24 IDMENU5 = 25 IDMENU6 = 26 IDSCRLD = 27 IDPAGED = 28 IDVSCRL = 29 IDPAGEU = 30 IDSCRLU = 31 IDSCRLL = 32 IDPAGEL = 33 IDHSCRL = 34 IDPAGER = 35 IDSCRLR = 36 IDCOMBO = 37 IDPOPUP = 38 REM Auto repeat delay (deciseconds): DELAY = 5 REM Double-click time (centiseconds): DBLCLICK = 25 REM Colour numbers: COL_GUITEXT = 0 COL_KEYWD = 1 COL_STRING = 2 COL_DEF = 3 COL_REMARK = 4 COL_LABEL = 5 COL_THEREST = 6 COL_GUIBKGD = 7 COL_BORDERS = 8 COL_DISABLED = 9 COL_PRESSED = 10 COL_HILITEAND = 11 COL_HILITEOR = 12 COL_SELECT = 13 COL_ICONS = 14 COL_EDITPANE = 15 REM Comparator constants: OP_INSERT = 1 OP_DELETE = 2 REM Process command line: Cmd$ = @cmd$ : C% = INSTR(Cmd$, "-hidden") IF C% THEN Cmd$ = LEFT$(Cmd$, C%-1) + MID$(Cmd$, C%+7) C% = INSTR(Cmd$, "SDLIDE.bbc") IF C% Cmd$ = MID$(Cmd$, C%+10) : C% = INSTR(Cmd$, " ") : IF C% Cmd$ = MID$(Cmd$, C%+1) dashR% = 0 : dashA% = 0 : dashM% = 0 : dashT% = 0 : dashC% = 0 : dashD% = 0 : dashP% = 0 WHILE ASC(Cmd$)=&20 Cmd$ = MID$(Cmd$,2) : ENDWHILE WHILE ASC(Cmd$)=&2D CASE MID$(Cmd$,2,1) OF WHEN "r","R": dashR% = TRUE : Cmd$ = MID$(Cmd$,3) WHEN "a","A": dashA% = TRUE : Cmd$ = MID$(Cmd$,3) WHEN "m","M": dashM% = TRUE : Cmd$ = MID$(Cmd$,3) WHEN "t","T": dashT% = TRUE : Cmd$ = MID$(Cmd$,3) WHEN "c","C": dashC% = TRUE : Cmd$ = MID$(Cmd$,3) WHEN "d","D": dashD% = TRUE : Cmd$ = MID$(Cmd$,3) WHEN "p","P": dashP% = TRUE : Cmd$ = MID$(Cmd$,3) OTHERWISE: EXIT WHILE ENDCASE WHILE ASC(Cmd$)=&20 Cmd$ = MID$(Cmd$,2) : ENDWHILE ENDWHILE WHILE RIGHT$(Cmd$)=" " Cmd$ = LEFT$(Cmd$) : ENDWHILE IF ASC(Cmd$) = &22 Cmd$ = EVAL(Cmd$) REM Get INI file path: IniFile$ = @usr$ + "sdlide.ini" REM Load BBC BASIC libraries: INSTALL @lib$ + "fnusing" INSTALL @lib$ + "stringlib" INSTALL @lib$ + "sortlib" INSTALL @lib$ + "dlglib" INSTALL @lib$ + "script" INSTALL @lib$ + "utf8lib" Sort%% = FN_sortinit(0,2) REM Find address of string accumulator: IF NOT BB4W% IF @platform% AND &40 Accs%% = ]332 ELSE Accs%% = !332 REM Get window size and position: WindowW% = VALFNgetINIstring(IniFile$, "windowwidth", "960") WindowH% = VALFNgetINIstring(IniFile$, "windowheight", "600") IsMaximized% = VALFNgetINIstring(IniFile$, "maximized", "0") REM Initialise window: VDU 23,22,WindowW%;WindowH%;8,16,16,128+8 OFF IF IsMaximized% THEN IF BB4W% THEN SYS "ShowWindow", @hwnd%, SW_MAXIMIZE ELSE SYS "SDL_MaximizeWindow", @hwnd% : WAIT 10 ENDIF VDU 26 ENDIF REM Get remaining preferences: Overtype% = FALSE Colouring% = VALFNgetINIstring(IniFile$, "colouring", "-1") Indentation% = VALFNgetINIstring(IniFile$, "indentation", "-1") Lowercase% = VALFNgetINIstring(IniFile$, "lowercase", "0") Abbrev% = VALFNgetINIstring(IniFile$, "abbreviations", "0") Tooltips% = VALFNgetINIstring(IniFile$, "tooltips", "1") Darkmode% = VALFNgetINIstring(IniFile$, "darkmode", "0") Unicode% = VALFNgetINIstring(IniFile$, "unicode", "-1") IncludeON% = VALFNgetINIstring(IniFile$, "includeon", "-1") IncludeLab% = VALFNgetINIstring(IniFile$, "includelab", "-1") SortList% = VALFNgetINIstring(IniFile$, "sortlist", "-1") Hovertime% = VALFNgetINIstring(IniFile$, "hovertime", "4") WheelSpeed = VALFNgetINIstring(IniFile$, "wheelspeed", "1.0") GUIscale = VALFNgetINIstring(IniFile$, "guiscale", "2.0") newGUIFont$ = FNgetINIstring(IniFile$, "guifont", GUIFont$) newEditFont$ = FNgetINIstring(IniFile$, "editfont", EditFont$) REM Check whether fonts are valid: ON ERROR LOCAL IF FALSE THEN OSCLI "FONT " + newGUIFont$ GUIFont$ = newGUIFont$ ENDIF : RESTORE ERROR ON ERROR LOCAL IF FALSE THEN OSCLI "FONT " + newEditFont$ EditFont$ = newEditFont$ ENDIF : RESTORE ERROR REM Window furniture metrics: BREAKPTBARWIDTH = 16 * GUIscale SCROLLBARSIZE = 24 * GUIscale STATUSBARHEIGHT = 32 * GUIscale MINCOMBO = 150 * GUIscale GAPCOMBO = 50 * GUIscale REM Menu and toolbar metrics (must match SDLIDE.bmp image): NMENUS = 6 NBUTTONS = 21 BMPWIDTH = 690 * GUIscale BMPHEIGHT = 66 * GUIscale BUTTONWIDTH = 29 * GUIscale BUTTONHEIGHT = 29 * GUIscale MENUBARHEIGHT = 32 * GUIscale DIM MenuPos%(NMENUS), MenuKey&(NMENUS-1), ToolPos%(NBUTTONS), ToolTip$(NBUTTONS) DIM ToolCmd%(NBUTTONS-1), TBenable&(NBUTTONS-1), TBpressed&(NBUTTONS-1) TBenable&() = 1, 1, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 1 MenuPos%() = 0, 40, 84, 154, 233, 278, 328 MenuPos%() *= INT(GUIscale * 256) : MenuPos%() DIV= 256 MenuKey&() = 68, 35, 54, 55, 52, 85 ToolPos%() = 0, 31, 62, 93, 132, 163, 194, 225, 256, 295, 326, \ \ 365, 396, 435, 466, 497, 528, 559, 590, 621, 660, 691 ToolPos%() *= INT(GUIscale * 256) : ToolPos%() DIV= 256 ToolCmd%() = 310, 311, 312, 317, 320, 321, 322, 323, 324, 327, 329, \ \ 332, 333, 350, 351, 353, 354, 355, 356, 358, 369 ToolTip$() = "New", "Load", "Save", "Print", "Undo", "Redo", "Cut", "Copy", "Paste", \ \ "Find", "Replace", "Renumber", "Compile", "Run", "Debug", "Stop", \ \ "Pause", "Step Into", "Step Over", "Immediate", "About", "List FNs/PROCs" REM Declare global structures: DIM EditRect{l%,t%,r%,b%} DIM ComboBox{l%,t%,r%,b%} DIM BrkPtBar{l%,t%,r%,b%} DIM ScrlBarH{l%,t%,r%,b%,min%,max%,pos%,page%,thumb{l%,r%},scale} DIM ScrlBarV{l%,t%,r%,b%,min%,max%,pos%,page%,thumb{t%,b%},scale} REM Global arrays: DIM KeyWd$(159), GoBack%(100), Click%(2), InKey&(63), Script$(20) DIM Buffer$(&FFFF), BreakPt&(&FFFF), Indent%(&FFFF) DIM BBCPtr%(&FFFF), BBCTok&(&FFFF), Script&(&FFFF) GoBack%() = TRUE KeyWd$() = "AND","DIV","EOR","MOD","OR","ERROR","LINE","OFF", \ \"STEP","SPC","TAB(","ELSE","THEN"," ","OPENIN","PTR","PAGE", \ \"TIME","LOMEM","HIMEM","ABS","ACS","ADVAL","ASC","ASN","ATN", \ \"BGET","COS","COUNT","DEG","ERL","ERR","EVAL","EXP","EXT", \ \"FALSE","FN","GET","INKEY","INSTR(","INT","LEN","LN","LOG", \ \"NOT","OPENUP","OPENOUT","PI","POINT(","POS","RAD","RND", \ \"SGN","SIN","SQR","TAN","TO","TRUE","USR","VAL","VPOS","CHR$", \ \"GET$","INKEY$","LEFT$(","MID$(","RIGHT$(","STR$","STRING$(", \ \"EOF","SUM","WHILE","CASE","WHEN","OF","ENDCASE","OTHERWISE", \ \"ENDIF","ENDWHILE","PTR","PAGE","TIME","LOMEM","HIMEM", \ \"SOUND","BPUT","CALL","CHAIN","CLEAR","CLOSE","CLG","CLS", \ \"DATA","DEF","DIM","DRAW","END","ENDPROC","ENVELOPE","FOR", \ \"GOSUB","GOTO","GCOL","IF","INPUT","LET","LOCAL","MODE","MOVE",\ \"NEXT","ON","VDU","PLOT","PRINT","PROC","READ","REM","REPEAT", \ \"REPORT","RESTORE","RETURN","RUN","STOP","COLOUR","TRACE", \ \"UNTIL","WIDTH","OSCLI","","CIRCLE","ELLIPSE","FILL","MOUSE", \ \"ORIGIN","QUIT","RECTANGLE","SWAP","SYS","TINT","WAIT", \ \"INSTALL","","PRIVATE","BY","EXIT" InKey&() = 16, 66,101, 83, 51, 35, 68, 84, 85, 38, 70, 71, 87,102, 86, 55, \ \ 56, 17, 52, 82, 36, 54,100, 34, 67, 69, 98, 16, 16, 16, 16, 16, \ \ 99, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, \ \ 40, 49, 50, 18, 19, 20, 53, 37, 22, 39, 16, 16, 16, 16, 16, 16 Left$ = ":"+CHR$&85+CHR$&8B+CHR$&8C+CHR$&D9+CHR$&EC+CHR$&F5+CHR$4+CHR$9 Skip$ = ":"+CHR$214+CHR$220+CHR$228+CHR$229+CHR$231+CHR$238+CHR$243+CHR$244+"*\" Valid$ = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz" REM Set up right-to-left and complex scripts: Script$() = "Latn", "Deva", "Beng", "Guru", "Gujr", "Orya", "Taml", "Telu", "Knda", "Mlym", \ \ "Thai", "Laoo", "Tibt", "Mymr", "Hang", "Khmr", "Hebr", "Arab", "Syrc", "Nkoo", "Mong" Script&() = &FF : Script&(&22) = 0 : REM To quote RTL text correctly FOR I% = &0041 TO &005A : Script&(I%) = 0 : NEXT : REM Latin FOR I% = &0061 TO &007A : Script&(I%) = 0 : NEXT : REM Latin FOR I% = &0900 TO &097F : Script&(I%) = 1 : NEXT : REM Devanagari (Hindi) FOR I% = &0980 TO &09FF : Script&(I%) = 2 : NEXT : REM Bengali FOR I% = &0A00 TO &0A7F : Script&(I%) = 3 : NEXT : REM Gurmukhi (Punjabi) FOR I% = &0A80 TO &0AFF : Script&(I%) = 4 : NEXT : REM Gujarati FOR I% = &0B00 TO &0B7F : Script&(I%) = 5 : NEXT : REM Oriya FOR I% = &0B80 TO &0BFF : Script&(I%) = 6 : NEXT : REM Tamil FOR I% = &0C00 TO &0C7F : Script&(I%) = 7 : NEXT : REM Telugu FOR I% = &0C80 TO &0CFF : Script&(I%) = 8 : NEXT : REM Kannada FOR I% = &0D00 TO &0D7F : Script&(I%) = 9 : NEXT : REM Malayalam FOR I% = &0E00 TO &0E7F : Script&(I%) = 10 : NEXT : REM Thai FOR I% = &0E80 TO &0EFF : Script&(I%) = 11 : NEXT : REM Lao FOR I% = &0F00 TO &0FFF : Script&(I%) = 12 : NEXT : REM Tibetan FOR I% = &1000 TO &109F : Script&(I%) = 13 : NEXT : REM Myanmar FOR I% = &1100 TO &11FF : Script&(I%) = 14 : NEXT : REM Hangul (Korea) FOR I% = &1780 TO &17FF : Script&(I%) = 15 : NEXT : REM Khmer (Cambodia) FOR I% = &19E0 TO &19FF : Script&(I%) = 15 : NEXT : REM Khmer (Cambodia) FOR I% = &0590 TO &05FF : Script&(I%) = 16 : NEXT : REM Hebrew (RTL) FOR I% = &0600 TO &06FF : Script&(I%) = 17 : NEXT : REM Arabic (RTL) FOR I% = &0750 TO &077F : Script&(I%) = 17 : NEXT : REM Arabic (RTL) FOR I% = &0700 TO &074F : Script&(I%) = 18 : NEXT : REM Syriac (RTL) FOR I% = &07C0 TO &07FF : Script&(I%) = 19 : NEXT : REM N'Ko (RTL) FOR I% = &1800 TO &18AF : Script&(I%) = 20 : NEXT : REM Mongolian (RTL) REM Get recent files list: DIM Recent$(9) FOR i% = 1 TO 9 Recent$(i%) = FNgetINIstring(IniFile$, "recent" + STR$(i%), "") NEXT REM Get addins list: DIM Addin$(9) FOR i% = 1 TO 9 READ addin$ IF addin$ <> "" addin$ = @dir$ + addin$ + ".bbc" Addin$(i%) = FNgetINIstring(IniFile$, "addin" + STR$(i%), addin$) NEXT DATA "crossref", "searchin", "memmon", "macrorec", "addconst", "versinfo", "", "", "" REM Get tooltip strings from the 'keywords.txt' file: DIM KeywTip$(255) F% = OPENIN(@lib$ + "../examples/keywords.txt") IF F% THEN INPUT #F%,tip$ : INPUT #F%,tip$ FOR I% = 0 TO DIM(KeywTip$(),1) INPUT #F%, tip$ : IF ASCtip$ = &A tip$ = MID$(tip$, 2) KeywTip$(I%) = tip$ NEXT I% CLOSE #F% ENDIF REM Get function key macros: FOR i% = 1 TO 11 macro$ = FNgetINIstring(IniFile$, "macro" + STR$(i%), "") IF macro$ <> "" THEN OSCLI "KEY " + STR$i% + " " + macro$ NEXT REM Get Acorn token replacement list: DIM Acorn&(15) FOR i% = 0 TO 15 : READ Acorn&(i%) : NEXT DATA &C8,&01,&03,&05,&F0,&07,&08,&C7,&0B,&04,&06,&09,&0C,&0C,&0A,&02 REM Set colour palette: DIM Colours%(5) PROCsetpalette REM Create file and folder icons (must set font first): OSCLI "FONT " + GUIFont$ C% = (1.5 * @vdu%!220 + 7) AND -8 VDU 21 OSCLI "spool """ + @tmp$ + "bbfile.vdu""" GCOL 14+128 PLOT 0,C%,0 : PLOT 99,C%*0.75,-C%*0.75 : PLOT 0,C%/4,C%/4 : PLOT 0,-C%*0.75,0 PLOT 115,-C%/2,-C%/2 : PLOT 0,C%/4,C%/4 : PLOT 98,C%*0.75,C%*0.75 : PLOT 0,0,-C%/2 PLOT 1,C%/4,0 : PLOT 1,-C%/2,-C%/2 : PLOT 1,-C%*0.75,0 : PLOT 1,C%/4,C%/4 PLOT 0,C%*1.25,C%*0.75 : PLOT 0,0,0 OSCLI "spool """ + @tmp$ + "folder.vdu""" GCOL 14+128 PLOT 0,C%,0 : PLOT 0,C%*0.75,0 : PLOT 99,-C%*0.75,-C% PLOT 0,C%/2,-C%/4 : PLOT 0,0,C% : PLOT 115,-C%/2,C%/4 PLOT 1,0,-C% : PLOT 1,C%/2,-C%/4 : PLOT 1,0,C% : PLOT 1,-C%/2,C%/4 PLOT 1,C%*0.75,0 : PLOT 1,0,-C% : PLOT 1,-C%*0.25,0 : PLOT 0,C%*0.75,C% *spool VDU 6 F% = OPENIN(@tmp$ + "bbfile.vdu") BBfile$ = GET$#F% BY EXT#F% CLOSE #F% F% = OPENIN(@tmp$ + "folder.vdu") Folder$ = GET$#F% BY EXT#F% CLOSE #F% IF LEN(BBfile$) <> LEN(Folder$) ERROR 100, "Icons not equal size" REM Set up dialogue box templates: FileDlg% = FN_newdialog("Load File", 200, 200) PROC_textbox(FileDlg%, "", 104, 40, 169, 155, 10, 0) PROC_radiobutton(FileDlg%, "Tokenised", 106, 4, 185, 50, 11, 0) PROC_radiobutton(FileDlg%, "Text file", 107, 57, 185, 50, 11, 0) PROC_static(FileDlg%, "Folder:", 101, 3, 5, 35, 10, SS_RIGHT) PROC_static(FileDlg%, "File name:", 103, 3, 170, 35, 10, SS_RIGHT) PROC_radiobutton(FileDlg%, "BASIC programs", 108, 4, 185, 68, 11, 0) : REM Not contiguous PROC_radiobutton(FileDlg%, "All files", 109, 72, 185, 38, 11, 0) PROC_button(FileDlg%, "Open", 1, 110, 184, 40, 11, WS_DISABLED) PROC_button(FileDlg%, "Cancel", 2, 155, 184, 40, 11, 0) PROC_textbox(FileDlg%, "", 102, 40, 4, 155, 10, 0) IDlistbox% = FN_setproc(PROClistclick()) PROC_listbox(FileDlg%, "", IDlistbox%, 5, 18, 190, 146, WS_VSCROLL) RenumDlg% = FN_newdialog("Renumber", 128, 76) PROC_static(RenumDlg%, "First line:", 101, 10, 9, 50, 10, SS_RIGHT) PROC_static(RenumDlg%, "Increment:", 102, 10, 25, 50, 10, SS_RIGHT) PROC_textbox(RenumDlg%, "10", 103, 66, 8, 28, 10, ES_NUMBER) PROC_textbox(RenumDlg%, "10", 104, 66, 24, 28, 10, ES_NUMBER) PROC_checkbox(RenumDlg%, "Remove unused line numbers", 105, 8, 42, 120, 12, 0) PROC_button(RenumDlg%, "OK", 1, 19, 58, 40, 11, 0) PROC_button(RenumDlg%, "Cancel", 2, 69, 58, 40, 11, 0) FindDlg% = FN_newdialog("Find", 200, 40) PROC_static(FindDlg%, "Find what:", 101, 3, 8, 44, 10, SS_RIGHT) PROC_textbox(FindDlg%, "", 103, 50, 6, 96, 10, 0) PROC_checkbox(FindDlg%, "Match whole word only", 105, 4, 26, 90, 12, 0) PROC_checkbox(FindDlg%, "Match case", 106, 98, 26, 52, 12, 0) PROC_button(FindDlg%, "Find Next", 1, 152, 6, 42, 11, WS_DISABLED) PROC_button(FindDlg%, "Cancel", 2, 152, 23, 42, 11, 0) ReplDlg% = FN_newdialog("Replace", 200, 74) PROC_static(ReplDlg%, "Find what:", 101, 3, 8, 46, 10, SS_RIGHT) PROC_static(ReplDlg%, "Replace with:", 102, 3, 25, 46, 10, SS_RIGHT) PROC_textbox(ReplDlg%, "", 103, 52, 6, 94, 10, 0) PROC_textbox(ReplDlg%, "", 104, 52, 23, 94, 10, 0) PROC_checkbox(ReplDlg%, "Match whole word only", 105, 4, 43, 90, 12, 0) PROC_checkbox(ReplDlg%, "Match case", 106, 4, 60, 52, 12, 0) PROC_button(ReplDlg%, "Find Next", 1, 152, 6, 42, 11, WS_DISABLED) PROC_button(ReplDlg%, "Replace", 3, 152, 23, 42, 11, WS_DISABLED) PROC_button(ReplDlg%, "Replace All", 4, 152, 40, 42, 11, WS_DISABLED) PROC_button(ReplDlg%, "Cancel", 2, 152, 57, 42, 11, 0) FontDlg% = FN_newdialog("Set Font", 230, 84) PROC_static(FontDlg%, "Typeface:", 100, 4, 4, 50, 9, 0) PROC_listbox(FontDlg%, "", 101, 4, 14, 96, 64, WS_VSCROLL) PROC_static(FontDlg%, "Style:", 102, 104, 4, 40, 9, 0) PROC_listbox(FontDlg%, "", 103, 104, 14, 40, 64, 0) PROC_static(FontDlg%, "Size:", 104, 148, 4, 30, 9, 0) PROC_listbox(FontDlg%, "", 105, 148, 14, 32, 64, WS_VSCROLL) PROC_button(FontDlg%, "OK", 1, 185, 14, 40, 11, 0) PROC_button(FontDlg%, "Cancel", 2, 185, 30, 40, 11, 0) PROC_button(FontDlg%, "Apply", 3, 185, 46, 40, 11, 0) ColorDlg% = FN_newdialog("Set Colours", 119, 154) PROC_static(ColorDlg%, "Basic colours:", 100, 4, 4, 50, 9, 0) PROC_groupbox(ColorDlg%, "Syntax colouring", 100, 4, 86, 110, 48, 0) PROC_radiobutton(ColorDlg%, "Line numbers", 105, 6, 95, 57, 11, 0) PROC_radiobutton(ColorDlg%, "DEFinitions", 103, 64, 95, 49, 11, 0) PROC_radiobutton(ColorDlg%, "Keywords", 101, 6, 108, 57, 11, 0) PROC_radiobutton(ColorDlg%, "REMarks", 104, 64, 108, 49, 11, 0) PROC_radiobutton(ColorDlg%, "Strings", 102, 6, 121, 57, 11, 0) PROC_radiobutton(ColorDlg%, "The rest", 106, 64, 121, 49, 11, 0) PROC_button(ColorDlg%, "OK", 1, 4, 139, 34, 11, 0) PROC_button(ColorDlg%, "Apply", 3, 42, 139, 34, 11, 0) PROC_button(ColorDlg%, "Cancel", 2, 80, 139, 34, 11, 0) GotoDlg% = FN_newdialog("Go To Line", 120, 50) PROC_static(GotoDlg%, "Line number:", 100, 4, 4, 50, 9, 0) PROC_textbox(GotoDlg%, "0", 101, 4, 14, 111, 9, ES_NUMBER) PROC_button(GotoDlg%, "Go To", 1, 41, 30, 34, 11, 0) PROC_button(GotoDlg%, "Cancel", 2, 80, 30, 34, 11, 0) AboutBox% = FN_newdialog("About SDLIDE", 150, 72) PROC_static(AboutBox%, "BBC BASIC for SDL 2.0", 101, 4, 4, 142, 9, SS_CENTER) PROC_static(AboutBox%, "Integrated Development Environment", 102, 4, 14, 142, 9, SS_CENTER) PROC_static(AboutBox%, Platform$ + " Version " + Ver$, 103, 4, 24, 142, 9, SS_CENTER) PROC_static(AboutBox%, "Copyright © R. T. Russell " + Year$, 104, 4, 34, 142, 9, SS_CENTER) PROC_static(AboutBox%, "http://www.rtrussell.co.uk/", 105, 4, 44, 142, 9, SS_CENTER) PROC_button(AboutBox%, "OK", 1, 58, 56, 34, 11, 0) OSCLI "FONT " + EditFont$ Compare% = FN_newdialog("", 0, 0) PROC_listbox(Compare%, "", 400, BREAKPTBARWIDTH, \ \ BMPHEIGHT, 2 * @vdu%!208 - BREAKPTBARWIDTH, \ \ 2*@vdu%!212 - STATUSBARHEIGHT - BMPHEIGHT, \ \ WS_VSCROLL) REM Create a 48-colour palette for the Set Colours dialogue: IF BB4W% SYS "GetPaletteEntries", @hpal%, 0, 1, ^savpal% ELSE savpal% = !@hpal% DIM Palette%(5,7), gamma4&(3), gamma3&(2) gamma4&() = &00, &80, &C0, &FF : gamma3&() = &00, &C0, &FF FOR row% = 5 TO 0 STEP -1 FOR col% = 7 TO 0 STEP -1 r& = gamma4&(col% MOD 4) g& = gamma4&((row% DIV 3) * 2 + col% DIV 4) b& = gamma3&(row% MOD 3) Palette%(row%, col%) = (r& << 16) OR (g& << 8) OR b& COLOR 0, r&, g&, b& GCOL 0 : RECTANGLE FILL 0, 0, 32, 32 bmp$ = @tmp$ + "cc" + Session$ + STR$row% + STR$col% + ".tmp.bmp" OSCLI "gsave """ + bmp$ + """ 0, 0, 32, 32" PROC_button(ColorDlg%, bmp$, 200 + row% * 10 + col%, 4 + col% * 14, \ \ 14 + row% * 12, 12, 10, WS_TABSTOP OR BS_BITMAP) NEXT NEXT row% IF BB4W% SYS "SetPaletteEntries", @hpal%, 0, 1, ^savpal% ELSE !@hpal% = savpal% REM Set up menus: DIM FileMenu$(21), FileMenu%(21) FileMenu%() = 310,311,&1000+312,313,0,314,315,0,&1000+316, \ \ 317,0,381,382,383,384,385,386,387,388,389,0,319 FileMenu$() = "&New"+CHR$9+"Ctrl+N", \ \ "&Load..."+CHR$9+"Ctrl+L", \ \ "&Save"+CHR$9+"Ctrl+S", \ \ "Save &As...", \ \ "", \ \ "&Insert..."+CHR$9+"Ctrl+I", \ \ "&Compare...", \ \ "", \ \ "Page Se&tup...", \ \ "&Print..."+CHR$9+"Ctrl+P" FOR i% = 1 TO 9 FileMenu$(i%+10) = "&" + STR$(i%) + " " + FNnopath(Recent$(i%)) NEXT FileMenu$(21) = "E&xit" DIM EditMenu$(13), EditMenu%(13) EditMenu%() = &1000+320,&1000+321,0,&1000+322,&1000+323,&1000+324,&1000+325, \ \ 0,326,0,327,328,329,331 EditMenu$() = "&Undo"+CHR$9+"Ctrl+Z", \ \ "&Redo"+CHR$9+"Ctrl+Y", \ \ "", \ \ "Cu&t"+CHR$9+"Ctrl+X", \ \ "&Copy"+CHR$9+"Ctrl+C", \ \ "&Paste"+CHR$9+"Ctrl+V", \ \ "De&lete"+CHR$9+"Del", \ \ "", \ \ "Select &All"+CHR$9+"Ctrl+A", \ \ "", \ \ "&Find..."+CHR$9+"Ctrl+F", \ \ "Find &Next"+CHR$9+"F3", \ \ "R&eplace..."+CHR$9+"Ctrl+R", \ \ "&Go To..."+CHR$9+"Ctrl+G" DIM UtilMenu$(16), UtilMenu%(16) UtilMenu%() = &1000+332,&1000+333,0,&1000+334,335,336,337 UtilMenu$() = "&Renumber...", \ \ "&Compile...", \ \ "", \ \ "&List FNs/PROCs", \ \ "Include &ONs", \ \ "&Include Labels", \ \ "&Sort List" FOR i% = 1 TO 9 UtilMenu$(i%+7) = "&" + STR$(i%) + " " + FNnopath(Addin$(i%)) UtilMenu%(i%+7) = 390 + i% IF Addin$(i%) = "" UtilMenu%(i%+7) += &1000 NEXT DIM OptsMenu$(9), OptsMenu%(9) OptsMenu%() = 340,341,342,343,318,0,346,347,348,349 OptsMenu$() = "Synta&x Colouring", \ \ "&Lowercase Keywords", \ \ "&Indentation", \ \ "&Unicode", \ \ "&Abbreviations", \ \ "", \ \ "Set &Font...", \ \ "Set &Colours...", \ \ "&Hover Tooltips", \ \ "&Dark Mode" DIM RunMenu$(11), RunMenu%(11) RunMenu%() = 350,351,352,&1000+353,&1000+354,&1000+355,&1000+356,357,358,0,344,345 RunMenu$() = "&Run Program"+CHR$9+"F9", \ \ "&Debug Program", \ \ "Pro&file Program", \ \ "&Stop", \ \ "&Pause"+CHR$9+"F8", \ \ "St&ep Into"+CHR$9+"F7", \ \ "Step &Over"+CHR$9+"F5", \ \ "Run &To Cursor"+CHR$9+"F6", \ \ "&Immediate Mode", \ \ "", \ \ "Toggle &Breakpoint"+CHR$9+"Ctrl+B", \ \ "&Clear Breakpoints"+CHR$9+"F4" DIM HelpMenu$(8), HelpMenu%(8) HelpMenu%() = 360,361,362,363,364,365,366,0,369 HelpMenu$() = "&Help Topics"+CHR$9+"F1", \ \ "&Tutorial", \ \ "&Email", \ \ "&Website", \ \ "&Discussion group", \ \ "&Forum", \ \ "Wi&ki", \ \ "", \ \ "&About SDLIDE..." DIM BkPtMenu$(1), BkPtMenu%(1) : BkPtMenu%() = 1 BkPtMenu$() = "&Toggle breakpoint", \ \ "&Clear all breakpoints" REM Menu help messages: DIM MenuHelp$(379) MenuHelp$() = "", "New, load, save, print or exit", \ \ "Cut, copy, paste, delete, search or replace", \ \ "Renumber, compile or list FNs and PROCs", \ \ "Program options and customisation", \ \ "Run, stop or debug the BBC BASIC program", \ \ "Help information" MenuHelp$(310) = "Start a new BBC BASIC program" MenuHelp$(311) = "Load an existing BBC BASIC program" MenuHelp$(312) = "Save the current BBC BASIC program" MenuHelp$(313) = "Save the current program with a new name or in a different format" MenuHelp$(314) = "Insert a file before the current line" MenuHelp$(315) = "Show the differences from an earlier version of the program" MenuHelp$(316) = "Select paper size, orientation, margins etc." MenuHelp$(317) = "Print the current program" MenuHelp$(319) = "Exit SDLIDE" MenuHelp$(320) = "Undo the effect of the last editing operation" MenuHelp$(321) = "Reverse the effect of the last undo" MenuHelp$(322) = "Cut the selection and put it on the Clipboard" MenuHelp$(323) = "Copy the selection and put it on the Clipboard" MenuHelp$(324) = "Insert the Clipboard contents at the current point" MenuHelp$(325) = "Delete the selection" MenuHelp$(326) = "Select the entire program" MenuHelp$(327) = "Search the current program" MenuHelp$(328) = "Search for the next occurrence" MenuHelp$(329) = "Search for and replace a string" MenuHelp$(331) = "Move the cursor to the specified line (zero based)" MenuHelp$(332) = "Renumber the current program" MenuHelp$(333) = "Create a stand-alone application" MenuHelp$(334) = "List the program's functions and procedures" MenuHelp$(335) = "Include ON events in the FN/PROC list" MenuHelp$(336) = "Include labels in the FN/PROC list" MenuHelp$(337) = "Sort the list of functions and procedures" MenuHelp$(340) = "Highlight language elements in colour" MenuHelp$(341) = "Display and accept keywords in lower case" MenuHelp$(342) = "Enable or disable automatic indentation" MenuHelp$(343) = "Show literal strings as Unicode rather than ANSI" MenuHelp$(318) = "Accept keyword abbreviations" MenuHelp$(346) = "Select the screen font and size" MenuHelp$(347) = "Select the colours used for highlighting" MenuHelp$(348) = "Enable or disable tooltips when hovering" MenuHelp$(349) = "Enable or disable the dark colour scheme" MenuHelp$(350) = "Run the current program" MenuHelp$(351) = "Run the current program with debugging aids" MenuHelp$(352) = "Run the current program and generate a profiler report" MenuHelp$(353) = "Stop and quit the current program" MenuHelp$(354) = "Pause execution of the current program" MenuHelp$(355) = "Execute a single program statement" MenuHelp$(356) = "Execute statements and pause on the next line" MenuHelp$(357) = "Run and pause at the line containing the cursor" MenuHelp$(358) = "Enter commands for immediate execution" MenuHelp$(344) = "Set or clear a breakpoint on the current line" MenuHelp$(345) = "Clear all breakpoints" MenuHelp$(360) = "Find help for BBC BASIC" MenuHelp$(361) = "Open the BBC BASIC beginners' tutorial" MenuHelp$(362) = "Request help by email" MenuHelp$(363) = "Visit the BBC BASIC website" MenuHelp$(364) = "Get help and advice at the BBC BASIC discussion group" MenuHelp$(365) = "Discuss BBC BASIC at the forum" MenuHelp$(366) = "Find programming tips on the BBC BASIC Wiki" MenuHelp$(369) = "About this program" MenuHelp$(370) = "Add a REM to every selected line" MenuHelp$(371) = "Remove the REMs from the selected lines" MenuHelp$(372) = "Jump back to the place you last came from" MenuHelp$(373) = "Jump to the specified function or procedure" REM Initialise global variables: CurrentFile$ = "" Unsaved% = FALSE nLines% = 0 MaxLen% = 0 ScrollH% = 0 ScrollV% = 0 CaretX% = 0 CaretY% = 0 AnchorX% = 0 AnchorY% = 0 SelCol% = 0 Hover% = -10000 REM Handle command-line options (before ON ERROR): IF Cmd$<>"" PROCload(Cmd$, nLines%, MaxLen%, FALSE) IF dashC% PROCcompile IF dashR% PROCrun IF dashD% PROCdebug IF dashP% PROCprofile IF dashA% PROCcleanup : QUIT Changed% = FALSE Resized% = FALSE Refresh% = TRUE Pressed% = 0 UndoLevel% = 0 RedoLevel% = 0 BackLevel% = 0 FindFlags% = 0 Dragging% = 0 Repeating% = FALSE KeepSelection% = FALSE RepTimer% = 0 StaTimer% = 0 Typing% = FALSE oldCaretX% = -1 oldCaretY% = -1 oldAnchorX% = -1 oldAnchorY% = -1 oldScrollH% = -1 oldScrollV% = -1 ScrollTime% = 0 DblClkTime% = 0 SelWord$ = "" PROCdrawall(@vdu%!208, @vdu%!212) REM Set event interrupts: *TIMER 100 ON CLOSE IF @lparam%=0 IF FNoktoditch IF FNexit PROCcleanup : QUIT ELSE RETURN ON ERROR ON ERROR OFF PROCerror(ERR, REPORT$) : PROCcleanup : QUIT ON MOVE PROCmove(@msg%, @wparam%, @lparam%) : RETURN ON TIME PROCtimer(FALSE) : RETURN ON MOUSE PROCmouse(@wparam%, @lparam%) : RETURN ON SYS PROCscroll(@lparam%) : RETURN REM Main polling loop: DIM click%(2) Click%(0) = TRUE minx% = 0 maxy% = 0 REPEAT charx% = 2 * @vdu%!216 chary% = 2 * @vdu%!220 maxx% = EditRect.r% - EditRect.l% miny% = EditRect.b% - EditRect.t% + chary% rows% = (maxy% - miny%) DIV chary% click%(0) = TRUE SWAP click%(),Click%() IF click%(0)=TRUE click%(0) = INKEY(0) IF click%(0) = TRUE THEN StaTimer% += 1 IF StaTimer% >= 10 THEN StaTimer% = 0 PROCdrawstatusbar(0, TRUE, FALSE) ENDIF ELSE Hover% = -10000 : REM Don't popup tooltip F% = FALSE : REM Don't flush keyboard buffer T% = FALSE : REM Cancel 'currently typing' CASE click%(0) OF WHEN 128: PROCwordleft WHEN 129: PROCwordright WHEN 130: CaretX% = 0 WHEN 131: I% = Indent%(CaretY%) : CaretX% = FNlen(FNformat(Buffer$(CaretY%), I%)) WHEN 132: ScrollV% -= rows% * chary% : CaretY% -= rows% : F% = TRUE : T% = TRUE WHEN 133: ScrollV% += rows% * chary% : CaretY% += rows% : F% = TRUE : T% = TRUE WHEN 158: ScrollH% += maxx% - minx% : F% = TRUE : T% = TRUE WHEN 159: ScrollH% -= maxx% - minx% : F% = TRUE : T% = TRUE WHEN 136: IF INKEY(-3) PROCwordleft ELSE IF CaretX% CaretX% -= 1 : F% = TRUE WHEN 137: IF INKEY(-3) PROCwordright ELSE CaretX% += 1 : F% = TRUE WHEN 138: IF CaretY% < nLines% CaretY% += 1 : F% = TRUE WHEN 139: IF CaretY% CaretY% -= 1 : F% = TRUE WHEN 140: REPEAT ScrollV% += chary% * WheelSpeed : UNTIL INKEY(0) <> 140 : T% = TRUE WHEN 141: REPEAT ScrollV% -= chary% * WheelSpeed : UNTIL INKEY(0) <> 141 : T% = TRUE WHEN 142: ScrollH% -= charx% : T% = TRUE WHEN 143: ScrollH% += charx% : T% = TRUE WHEN 146: REPEAT ScrollV% += chary% : UNTIL INKEY(0) <> 146 : T% = TRUE WHEN 144: REPEAT ScrollV% -= chary% : UNTIL INKEY(0) <> 144 : T% = TRUE WHEN 156: CaretX% = 0 : CaretY% = 0 WHEN 157: CaretX% = 0 : CaretY% = nLines% WHEN 134: Overtype% = NOT Overtype% : T% = TRUE WHEN 135: PROCdelete(INKEY(-2) OR INKEY(-3)) : Changed% = TRUE : F% = TRUE : T% = TRUE WHEN 8,127: PROCbackspace(INKEY(-2) OR INKEY(-3)) : Changed% = TRUE : F% = TRUE : T% = TRUE WHEN 13: PROCreturn : Changed% = TRUE : F% = TRUE : T% = TRUE WHEN 310,14: IF FNoktoditch PROCnew WHEN 311,12: IF FNoktoditch PROCload WHEN 312,19: IF FNsave PROCunchanged WHEN 313: IF FNsaveas PROCunchanged WHEN 314,9: IF INKEY(-2) OR click%(0) = 314 THEN PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) IF FNinsertfile Changed% = TRUE ELSE PROCputkey(155) ENDIF WHEN 315: PROCcomparefile WHEN 317,16: PROCprintprogram WHEN 319: IF FNoktoditch IF FNexit PROCcleanup : QUIT WHEN 26,320: REM Undo IF UndoLevel% THEN IF RedoLevel% = 0 THEN PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) UndoLevel% -= 1 : RedoLevel% = UndoLevel% ENDIF UndoLevel% -= 1 PROCundoundo(Buffer$(), Indent%(), BreakPt&(), nLines%, UndoLevel%, CaretX%, CaretY%) Changed% = TRUE ENDIF WHEN 25,321: REM Redo IF RedoLevel% > UndoLevel% THEN UndoLevel% += 1 PROCundoundo(Buffer$(), Indent%(), BreakPt&(), nLines%, UndoLevel%, CaretX%, CaretY%) Changed% = TRUE ENDIF WHEN 24,322: REM Cut IF CaretX% <> AnchorX% OR CaretY% <> AnchorY% THEN PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) PROCcopytext(Buffer$(), Indent%(), CaretX%, CaretY%, AnchorX%, AnchorY%) PROCdeltext(Buffer$(), Indent%(), BreakPt&(), CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) Changed% = TRUE ENDIF WHEN 3,323: REM Copy IF CaretX% <> AnchorX% OR CaretY% <> AnchorY% THEN PROCcopytext(Buffer$(), Indent%(), CaretX%, CaretY%, AnchorX%, AnchorY%) ENDIF WHEN 22,324: REM Paste IF FNhascliptext THEN PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) PROCdeltext(Buffer$(), Indent%(), BreakPt&(), CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) PROCpaste(Buffer$(), Indent%(), BreakPt&(), CaretX%, CaretY%, nLines%, MaxLen%) Changed% = TRUE ENDIF WHEN 325: REM Delete IF CaretX% <> AnchorX% OR CaretY% <> AnchorY% THEN PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) PROCdeltext(Buffer$(), Indent%(), BreakPt&(), CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) Changed% = TRUE ENDIF WHEN 1,326: REM Select All AnchorX% = 0 : AnchorY% = 0 CaretX% = 0 : CaretY% = nLines% KeepSelection% = TRUE Refresh% = TRUE WHEN 6,327: PROCfind : KeepSelection% = TRUE WHEN 147,328: PROCfindnext : KeepSelection% = TRUE WHEN 18,329: PROCreplace : KeepSelection% = TRUE WHEN 7,331: PROCgotoline(nLines%) WHEN 332: PROCrenumber(Buffer$(), nLines%) WHEN 333: PROCcompile WHEN 334: PROClistdefs(Buffer$(), nLines%) WHEN 335: IncludeON% EOR= TRUE WHEN 336: IncludeLab% EOR= TRUE WHEN 337: SortList% EOR= TRUE WHEN 340: PROCtogglecolouring WHEN 341: PROCtogglelowercase WHEN 342: PROCtoggleindentation WHEN 343: PROCtoggleunicode WHEN 318: PROCtoggleabbrev WHEN 346: PROCsetfont WHEN 347: PROCsetcolours WHEN 348: Tooltips% EOR= TRUE WHEN 349: PROCtoggledarkmode WHEN 153,350: PROCrun WHEN 351: PROCdebug WHEN 352: PROCprofile WHEN 353: PROCstop WHEN 152,354: PROCpause WHEN 151,355: PROCstepinto WHEN 149,356: PROCstepover WHEN 150,357: PROCrununtil WHEN 358: PROCimmediate : ON WHEN 2,344: BreakPt&(CaretY%) EOR= 1 : Refresh% = TRUE WHEN 148,345: BreakPt&() = 0 : Refresh% = TRUE WHEN 360,145: PROCtopics WHEN 361: PROCtutorial WHEN 362: PROCemail WHEN 363: PROCwebsite WHEN 364: PROCdiscuss WHEN 365: PROCforum WHEN 366: PROCwiki WHEN 369: PROCabout : ON WHEN 370: REM Add REMs IF CaretX% <> AnchorX% OR CaretY% <> AnchorY% THEN PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) PROCaddrems(Buffer$(), Indent%(), CaretY%, AnchorY%, nLines%) Changed% = TRUE ENDIF WHEN 371: REM Remove REMs IF CaretX% <> AnchorX% OR CaretY% <> AnchorY% THEN PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) PROCremrems(Buffer$(), Indent%(), CaretY%, AnchorY%, nLines%) Changed% = TRUE ENDIF WHEN 372: PROCgoback WHEN 373: PROCjumpto(click%(1)) WHEN 374: ScrollV% -= maxy% - miny% WHEN 375: ScrollV% += maxy% - miny% WHEN 376: REM click PROCpointtochar(click%(1), click%(2)) CaretX% = click%(1) CaretY% = click%(2) IF NOT INKEY(-1) THEN AnchorX% = CaretX% AnchorY% = CaretY% SelWord$ = "" ENDIF WHEN 377: REM drag select PROCpointtochar(click%(1), click%(2)) CaretX% = click%(1) CaretY% = click%(2) WHEN 378: REM drag scroll ScrollH% -= click%(1) ScrollV% -= click%(2) T% = TRUE WHEN 379: PROCcontextmenu(click%(1), click%(2)) : REM Right click WHEN 154: PROCcontextmenu(2*@vdu.c.x%, 2*(@vdu%!212-@vdu.c.y%)-@vdu%!220) : REM F10 WHEN 402: PROCtooltip(click%(1), click%(2)) : REM Hover WHEN 5: PROCtooltip(2*@vdu.c.x%, 2*(@vdu%!212-@vdu.c.y%)-@vdu%!220) : REM Ctrl+E WHEN 380,155: REM Double-click or F11 SelWord$ = FNselword Refresh% = TRUE KeepSelection% = TRUE WHEN 390: REM Double-click in breakpoint bar BreakPt&((ScrollV% + BrkPtBar.t% - click%(2)) DIV (@vdu%!220 * 2)) EOR= 1 Refresh% = TRUE OTHERWISE: IF click%(0) >= 32 IF click%(0) < 127 PROCtyped(click%(0)) : Changed% = TRUE : T% = TRUE IF click%(0) >= 160 IF click%(0) <= 255 PROCtyped(click%(0)) : Changed% = TRUE : T% = TRUE IF click%(0) >= 381 IF click%(0) <= 389 IF FNoktoditch THEN PROCload(Recent$(click%(0) MOD 10), nLines%, MaxLen%, FALSE) ScrollH% = 0 ScrollV% = 0 CaretX% = 0 CaretY% = 0 AnchorX% = 0 AnchorY% = 0 SelWord$ = "" Refresh% = TRUE ENDIF IF click%(0) >= 391 IF click%(0) <= 399 PROCrunaddin(Addin$(click%(0) MOD 10)) ENDCASE IF F% IF INKEY$(-256) = "s" IF !436 = 0 REPEAT UNTIL INKEY(0) = -1 IF F% IF INKEY$(-256) <> "s" IF @vdu%?207 = 0 REPEAT UNTIL INKEY(0) = -1 IF NOT T% Typing% = FALSE ENDIF IF nLines% = 0 CaretX% = 0 : CaretY% = 0 : AnchorX% = 0 : AnchorY% = 0 IF CaretX% > MaxLen% MaxLen% = CaretX% IF CaretY% < 0 CaretY% = 0 IF CaretY% > nLines% CaretY% = nLines% IF AnchorY% < 0 AnchorY% = 0 IF AnchorY% > nLines% AnchorY% = nLines% IF CaretX%<>oldCaretX% OR CaretY%<>oldCaretY% THEN REM Select if drag or shift held down: IF NOT INKEY(-1) IF NOT INKEY(-10) IF NOT KeepSelection% THEN AnchorX% = CaretX% AnchorY% = CaretY% SelWord$ = "" ENDIF REM If caret is moved vertically scroll if necessary to make it visible: WHILE ScrollV% - CaretY% * chary% < miny% ScrollV% += chary% : ENDWHILE WHILE ScrollV% - CaretY% * chary% > maxy% ScrollV% -= chary% : ENDWHILE Refresh% = TRUE ENDIF KeepSelection% = FALSE IF ScrollH% < (maxx% - minx%) - MaxLen% * charx% THEN ScrollH% = (maxx% - minx%) - MaxLen% * charx% ENDIF IF ScrollV% > nLines% * chary% - (maxy% - miny%) THEN ScrollV% = nLines% * chary% - (maxy% - miny%) ENDIF IF ScrollH% > 0 ScrollH% = 0 IF ScrollV% < 0 ScrollV% = 0 IF ScrollH%<>oldScrollH% OR ScrollV%<>oldScrollV% THEN oldScrollH% = ScrollH% : oldScrollV% = ScrollV% Refresh% = TRUE ENDIF IF AnchorX%<>oldAnchorX% OR AnchorY%<>oldAnchorY% THEN oldAnchorX% = AnchorX% : oldAnchorY% = AnchorY% Refresh% = TRUE ENDIF IF Changed% THEN Changed% = FALSE Unsaved% = TRUE Refresh% = TRUE ENDIF IF Resized% THEN Resized% = FALSE WAIT 5 VDU 26 IF POS REM SDL thread sync. PROCdrawall(@vdu%!208, @vdu%!212) Refresh% = TRUE ENDIF IF click%(0) = 137 THEN ELSE IF Refresh% THEN; Refresh% = FALSE *REFRESH OFF PROCrefresh(ScrollH%, ScrollV%, CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) VDU 24,BrkPtBar.l%;BrkPtBar.b%;BrkPtBar.r%;BrkPtBar.t%; GCOL COL_GUIBKGD + 128 : CLG : GCOL COL_SELECT T% = @vdu%!220 * 2 I% = ScrollV% DIV T% Y% = BrkPtBar.t% + ScrollV% MOD T% - T% DIV 3 REPEAT IF BreakPt&(I%) RECTANGLE FILL 8,Y%,12,-12 I% += 1 Y% -= T% UNTIL Y% < BrkPtBar.b% VDU 24,0;0;@vdu%!208*2-2;@vdu%!212*2-2; REM If caret is moved horizontally scroll if necessary to make it visible: IF CaretX%<>oldCaretX% OR CaretY%<>oldCaretY% THEN oldCaretX% = CaretX% : oldCaretY% = CaretY% caretxpos% = @vdu.c.x% * 2 - EditRect.l% - ScrollH% WHILE ScrollH% + caretxpos% < minx% ScrollH% += charx% : Refresh% = TRUE : ENDWHILE WHILE ScrollH% + caretxpos% > maxx% ScrollH% -= charx% : Refresh% = TRUE : ENDWHILE ENDIF IF NOT Refresh% THEN *REFRESH *REFRESH ON ENDIF ELSE WAIT 1 : REM For minimum ON SYS and ON MOUSE latency WAIT 1 WAIT 1 WAIT 1 WAIT 1 ENDIF UNTIL FALSE END REM!Eject -------------------------------------------------------------------------- DEF ___Event_Handlers___ REM ON MOUSE handler: DEF PROCmouse(W%, L%) LOCAL X%, Y% IF TIME < ScrollTime% ENDPROC ON TIME LOCAL OFF X% = 2*(L% AND &FFFF) : Y% = 2*(@vdu%!212 - (L% >>> 16)) IF FN_ptinrect(X%, Y%, EditRect{}) THEN IF W% AND 2 THEN Click%() = 379, X%, Y% ELSE IF TIME > DblClkTime% THEN Dragging% = 1 Click%() = 376, X%, Y% ELSE Dragging% = 0 Click%() = 380, X%, Y% ENDIF ENDIF DblClkTime% = TIME + DBLCLICK ELSE IF FN_ptinrect(X%, Y%, BrkPtBar{}) THEN; IF TIME <= DblClkTime% Click%() = 390, X%, Y% DblClkTime% = TIME + DBLCLICK ELSE PROCclick(FNhotspot(X%, Y%)) ENDIF ENDPROC DEF PROCclick(L%) LOCAL H%, Y% Y% = 2*@vdu%!212 - MENUBARHEIGHT + 2 REPEAT H% = 0 CASE L% OF WHEN IDVSCRL: Dragging% = 2 WHEN IDHSCRL: Dragging% = 3 WHEN IDPAGER: Repeating% = 158 : RepTimer% = 0 : Click%() = 158,0,0 WHEN IDPAGEL: Repeating% = 159 : RepTimer% = 0 : Click%() = 159,0,0 WHEN IDPAGED: Repeating% = 374 : RepTimer% = 0 : Click%() = 374,0,0 WHEN IDPAGEU: Repeating% = 375 : RepTimer% = 0 : Click%() = 375,0,0 WHEN IDSCRLL: Repeating% = 142 : RepTimer% = 0 : Click%() = 142,0,0 WHEN IDSCRLR: Repeating% = 143 : RepTimer% = 0 : Click%() = 143,0,0 WHEN IDSCRLU: Repeating% = 146 : RepTimer% = 0 : Click%() = 146,0,0 WHEN IDSCRLD: Repeating% = 144 : RepTimer% = 0 : Click%() = 144,0,0 WHEN IDCOMBO: Click%() = 334,0,0 WHEN IDMENU1: H% = FNmenu(L%,FileMenu$(),FileMenu%(),MenuPos%(0),Y%) WHEN IDMENU2: H% = FNmenu(L%,EditMenu$(),EditMenu%(),MenuPos%(1),Y%) WHEN IDMENU3: H% = FNmenu(L%,UtilMenu$(),UtilMenu%(),MenuPos%(2),Y%) WHEN IDMENU4: H% = FNmenu(L%,OptsMenu$(),OptsMenu%(),MenuPos%(3),Y%) WHEN IDMENU5: H% = FNmenu(L%,RunMenu$(), RunMenu%(), MenuPos%(4),Y%) WHEN IDMENU6: H% = FNmenu(L%,HelpMenu$(),HelpMenu%(),MenuPos%(5),Y%) OTHERWISE: IF L% >= 0 IF L% < NBUTTONS Pressed% = ToolCmd%(L%) ENDCASE IF H% > 0 Click%() = H%,0,0 : H% = 0 IF H% = -136: L% = (L%-IDMENU1+NMENUS-1) MOD NMENUS + IDMENU1 : PROChilite(L%) IF H% = -137: L% = (L%-IDMENU1+NMENUS+1) MOD NMENUS + IDMENU1 : PROChilite(L%) UNTIL H% = 0 ENDPROC REM ON TIME handler: DEF PROCtimer(F%) : LOCAL $$Accs%% : REM For tokenizer LOCAL B%, X%, Y%, olddebug% PRIVATE oldx%, oldy%, oldb%, oldalt%, oldlin%, olderr%, selection%, telltale%, hilerr% PRIVATE cliptext%, unsaved%, canundo%, canredo%, anyprog%, debugging%, oldpause%, drag% REM Check for ALT key state change: B% = INKEY(-6) AND NOT INKEY(-5) IF B% <> oldalt% THEN oldalt% = B% IF B% PROCaltmode ENDIF REM Test for any program: B% = nLines% <> 0 IF B% <> anyprog% THEN anyprog% = B% TBenable&(11) = B% : REM Renumber button TBenable&(12) = B% : REM Compile button UtilMenu%(0) = UtilMenu%(0) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Renumber menu UtilMenu%(1) = UtilMenu%(1) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Compile menu UtilMenu%(3) = UtilMenu%(3) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM List DEFs menu ENDIF REM Test for selection: B% = CaretX% <> AnchorX% OR CaretY% <> AnchorY% IF B% <> selection% THEN selection% = B% TBenable&(6) = B% : REM Cut button TBenable&(7) = B% : REM Copy button EditMenu%(3) = EditMenu%(3) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Cut menu EditMenu%(4) = EditMenu%(4) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Copy menu EditMenu%(6) = EditMenu%(6) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Delete menu F% = TRUE ENDIF REM Test for clipboard text: B% = FNhascliptext IF B% <> cliptext% THEN cliptext% = B% TBenable&(8) = B% : REM Paste button EditMenu%(5) = EditMenu%(5) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Paste menu F% = TRUE ENDIF REM Test for program being unsaved: B% = Unsaved% IF B% <> unsaved% THEN unsaved% = B% TBenable&(2) = B% : REM Save button FileMenu%(2) = FileMenu%(2) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Save menu F% = TRUE ENDIF REM Test for being able to undo: B% = UndoLevel% <> 0 IF B% <> canundo% THEN canundo% = B% TBenable&(4) = B% : REM Undo button EditMenu%(0) = EditMenu%(0) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Undo menu F% = TRUE ENDIF REM Test for being able to redo: B% = RedoLevel% > UndoLevel% IF B% <> canredo% THEN canredo% = B% TBenable&(5) = B% : REM Redo button EditMenu%(1) = EditMenu%(1) AND NOT &1000 OR &1000 AND (B%=FALSE) : REM Redo menu F% = TRUE ENDIF REM Check menu items: OptsMenu%(0) = OptsMenu%(0) AND NOT &2000 OR &2000 AND Colouring% OptsMenu%(1) = OptsMenu%(1) AND NOT &2000 OR &2000 AND Lowercase% OptsMenu%(2) = OptsMenu%(2) AND NOT &2000 OR &2000 AND Indentation% OptsMenu%(3) = OptsMenu%(3) AND NOT &2000 OR &2000 AND Unicode% OptsMenu%(4) = OptsMenu%(4) AND NOT &2000 OR &2000 AND Abbrev% OptsMenu%(8) = OptsMenu%(8) AND NOT &2000 OR &2000 AND Tooltips% OptsMenu%(9) = OptsMenu%(9) AND NOT &2000 OR &2000 AND Darkmode% UtilMenu%(4) = UtilMenu%(4) AND NOT &2000 OR &2000 AND IncludeON% UtilMenu%(5) = UtilMenu%(5) AND NOT &2000 OR &2000 AND IncludeLab% UtilMenu%(6) = UtilMenu%(6) AND NOT &2000 OR &2000 AND SortList% REM Check for trace and list variables: olddebug% = (debugging% <> 0) B% = OPENIN(@tmp$ + "sdldebug.dat") IF B% THEN X% = BGET#B% OR (BGET#B% << 8) OR (BGET#B% << 16) OR (BGET#B% << 24) Y% = BGET#B% OR (BGET#B% << 8) OR (BGET#B% << 16) OR (BGET#B% << 24) IF debugging% IF X% <> oldlin% OR Y% <> olderr% THEN oldlin% = X% IF Y% <> olderr% IF Y% > BBCPtr%(0) hilerr% = 10 IF hilerr% hilerr% -= 1 : X% = Y% : REM Error has priority in highlighting olderr% = Y% Y% = FNchop(BBCPtr%(), X%) IF Y% < &FFFF THEN CaretX% = 0 : CaretY% = Y% AnchorX% = 0 : AnchorY% = Y%+1 KeepSelection% = TRUE ELSE AnchorX% = CaretX% AnchorY% = CaretY% ENDIF Refresh% = TRUE ENDIF X% = BGET#B% OR 1 : REM Must be non-zero Y% = BGET#B% AND 3 : REM Single-step and profiling flags IF X% <> telltale% THEN IF telltale% debugging% = 20 telltale% = X% ENDIF CLOSE #B% ELSE Y% = oldpause% ENDIF IF debugging% debugging% -= 1 REM Test for debugging: IF olddebug% <> (debugging% <> 0) THEN TBenable&(15) = debugging% <> 0 : REM Stop button TBenable&(16) = debugging% <> 0 : REM Pause button RunMenu%(3) = RunMenu%(3) AND NOT &1000 OR &1000 AND debugging%=0 : REM Stop menu RunMenu%(4) = RunMenu%(4) AND NOT &1000 OR &1000 AND debugging%=0 : REM Pause menu IF debugging% THEN IF (Y% AND 1) = 0 PROCexecute(@dir$ + "listvars.bbc", "-hidden" + FNdark) ELSE IF (Y% AND 1) = 1 PROCexecute(@dir$ + "profiler.bbc", "-hidden" + FNdark) AnchorY% = CaretY% : Refresh% = TRUE oldlin% = 0 : olderr% = 0 : hilerr% = 0 ENDIF F% = TRUE ENDIF REM Check for pause: IF debugging% = 0 Y% = 0 B% = (Y% AND 2) <> 0 IF B% <> oldpause% THEN oldpause% = B% TBpressed&(16) = B% TBenable&(17) = B% : REM Step into button TBenable&(18) = B% : REM Step over button RunMenu%(5) = RunMenu%(5) AND NOT &1000 OR &1000 AND NOT B% : REM Step into menu RunMenu%(6) = RunMenu%(6) AND NOT &1000 OR &1000 AND NOT B% : REM Step over menu F% = TRUE PROChilite(-1) ENDIF REM Check mouse: MOUSE X%, Y%, B% IF ABS(X% - oldx%) < 5 IF ABS(Y% - oldy%) < 5 Hover% += 1 ELSE Hover% = 0 IF Tooltips% IF Hover% > Hovertime% Hover% = -10000 : Click%() = 402, X%, Y% IF B% = 0 Dragging% = 0 : Repeating% = FALSE IF B% = 0 IF Pressed% Click%() = Pressed%,0,0 : Pressed% = FALSE IF Repeating% THEN RepTimer% += 1 IF RepTimer% > DELAY Click%() = Repeating%,0,0 ENDIF CASE Dragging% OF WHEN 1: IF Click%(0) = TRUE IF X% <> oldx% OR Y% <> oldy% Click%() = 377, X%, Y% WHEN 2: Click%() = 378, 0, (Y% - oldy%) * ScrlBarV.scale WHEN 3: Click%() = 378, (X% - oldx%) * ScrlBarH.scale, 0 ENDCASE IF NOT F% IF X% = oldx% IF Y% = oldy% IF B% = oldb% ENDPROC oldx% = X% : oldy% = Y% : oldb% = B% IF FN_ptinrect(X%, Y%, EditRect{}) THEN PROCcursor(1) ELSE IF X% >= 0 IF X% <= 2*@vdu%!208 IF Y% >= 0 IF Y% < 2*@vdu%!212 PROCcursor(0) ENDIF IF Dragging% <> drag% THEN drag% = Dragging% IF NOT BB4W% SYS "SDL_CaptureMouse", Dragging% <> 0, @memhdc% ENDIF IF Dragging% = 0 PROChilite(FNhotspot(X%, Y%)) ENDPROC REM ON MOVE handler: DEF PROCmove(M%, W%, L%) IF M% <> WM_SIZE ENDPROC Resized% = TRUE ENDPROC DEF PROCaltmode LOCAL K%,L%,M% ON TIME LOCAL OFF ON MOUSE LOCAL OFF L% = IDMENU1 REPEAT IF BB4W% SYS "GetForegroundWindow" TO K% : IF K% <> @hwnd% ENDPROC IF NOT BB4W% SYS "SDL_GetWindowFlags", @hwnd%, @memhdc% TO K% : IF (K% AND &200)=0 ENDPROC IF M% = 0 IF INKEY(-18) OR INKEY(-26) OR INKEY(-122) OR INKEY(-48) OR INKEY(-90) ENDPROC IF NOT INKEY(-3) IF M% = 0 M% = 1 : PROChilite(L%) IF INKEY(-3) IF M% = 1 M% = 2 : PROChilite(-1) IF NOT INKEY(-3) IF M% = 2 EXIT REPEAT IF M% = 1 THEN CASE INKEY(1) OF WHEN 27: PROChilite(-1) : ENDPROC WHEN 13,138: PROCclick(L%) : ENDPROC WHEN 136: L% = (L%-IDMENU1+NMENUS-1) MOD NMENUS + IDMENU1 : PROChilite(L%) WHEN 137: L% = (L%-IDMENU1+NMENUS+1) MOD NMENUS + IDMENU1 : PROChilite(L%) ENDCASE ENDIF FOR K% = 0 TO NMENUS-1 IF INKEY(-MenuKey&(K%)) PROChilite(IDMENU1+K%) : PROCclick(IDMENU1+K%) : ENDPROC NEXT UNTIL FALSE ENDPROC DEF PROCscroll(L%) PRIVATE oldx%, oldy%, sema4% IF sema4% ENDPROC sema4% = TRUE LOCAL X%, Y% X% = (L% << 16) >> 16 Y% = L% >> 16 IF TIME < ScrollTime% THEN ScrollH% += (X% - oldx%) * 2 ScrollV% -= (Y% - oldy%) * 2 ENDIF oldx% = X% : oldy% = Y% ScrollTime% = TIME + 10 sema4% = FALSE ENDPROC REM!Eject -------------------------------------------------------------------------- DEF __Text_Editing__ DEF PROCwordleft LOCAL I%, a$, l$, r$ I% = Indent%(CaretY%) a$ = FNstrip(FNformat(Buffer$(CaretY%), I%)) PROCsplit(a$, CaretX%, l$, r$) WHILE CaretX% > 0 AND RIGHT$(l$) = " " CaretX% -= 1 PROCsplit(a$, CaretX%, l$, r$) ENDWHILE IF CaretX% = 0 ENDPROC REPEAT CaretX% -= 1 PROCsplit(a$, CaretX%, l$, r$) UNTIL INSTR(Valid$, RIGHT$(l$)) = 0 ENDPROC DEF PROCwordright LOCAL I%, a$, l$, r$ I% = Indent%(CaretY%) a$ = FNstrip(FNformat(Buffer$(CaretY%), I%)) REPEAT IF CaretX% >= FNlen(a$) ENDPROC PROCsplit(a$, CaretX%, l$, r$) CaretX% += 1 UNTIL INSTR(Valid$, LEFT$(r$,1)) = 0 WHILE CaretX% < FNlen(a$) AND MID$(r$,2,1) = " " PROCsplit(a$, CaretX%, l$, r$) CaretX% += 1 ENDWHILE ENDPROC REM Selected word is allowed to contain colour-change codes, except at start DEF FNselword LOCAL I%, a$, l$, r$ I% = Indent%(CaretY%) a$ = FNformat(Buffer$(CaretY%), I%) AnchorX% = CaretX% : AnchorY% = CaretY% PROCsplit(a$, CaretX%, l$, r$) WHILE CaretX% < FNlen(a$) AND INSTR(Valid$ + "@_`#$%&", LEFT$(r$,1)) CaretX% += 1 PROCsplit(a$, CaretX%, l$, r$) ENDWHILE PROCsplit(a$, AnchorX%, l$, r$) WHILE AnchorX% > 0 AND INSTR(Valid$ + "@_`", RIGHT$(l$)) AnchorX% -= 1 PROCsplit(a$, AnchorX%, l$, r$) ENDWHILE PROCsplit(r$, CaretX% - AnchorX%, l$, r$) IF ASCl$ = &12 l$ = MID$(l$,4) = l$ DEF PROCbackspace(F%) : IF nLines% = 0 ENDPROC LOCAL D%, I%, p%%, a$, l$, r$ IF NOT Typing% THEN Typing% = TRUE PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) ENDIF IF F% PROCwordleft IF AnchorX%<>CaretX% OR AnchorY%<>CaretY% THEN PROCdeltext(Buffer$(), Indent%(), BreakPt&(), CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) ELSE IF CaretX% THEN; I% = Indent%(CaretY%) a$ = FNformat(Buffer$(CaretY%), I%) PROCsplit(a$, CaretX%-1, l$, r$) PROCsplit(a$, CaretX%, a$, r$) CaretX% -= 1 PROCreformat(l$ + r$, CaretX%, CaretY%, Buffer$(), Indent%(), TRUE) ELSE IF CaretY% IF CaretY% <= nLines% THEN; I% = Indent%(CaretY%-1) l$ = FNformat(Buffer$(CaretY%-1), I%) r$ = FNformat(Buffer$(CaretY%), I%) D% = I% - Indent%(CaretY%) PROCreformat(l$ + r$, CaretX%, CaretY%-1, Buffer$(), Indent%(), TRUE) CaretX% = FNlen(l$) p%% = ^Buffer$(CaretY%) FOR I% = CaretY% TO nLines% Indent%(I%) = Indent%(I%+1) - D% BreakPt&(I%) = BreakPt&(I%+1) p%%!0 = p%%!8 : p%%!4 = p%%!12 p%% += 8 NEXT p%%!0 = 0 : p%%!4 = 0 IF CaretY% < nLines% OR LENBuffer$(nLines%-1) <= 4 THEN nLines% -= 1 CaretY% -= 1 ELSE CaretX% = 0 ENDIF ENDIF Buffer$(nLines%) = "" AnchorX% = CaretX% AnchorY% = CaretY% ENDPROC DEF PROCdelete(F%) : IF nLines% = 0 ENDPROC LOCAL I%, a$, l$, r$ IF NOT Typing% THEN Typing% = TRUE PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) ENDIF IF F% PROCwordright IF AnchorX%<>CaretX% OR AnchorY%<>CaretY% THEN PROCdeltext(Buffer$(), Indent%(), BreakPt&(), CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) ELSE I% = Indent%(CaretY%) a$ = FNformat(Buffer$(CaretY%), I%) PROCsplit(a$, CaretX%, l$, r$) PROCsplit(a$, CaretX%+1, a$, r$) PROCreformat(l$ + r$, CaretX%, CaretY%, Buffer$(), Indent%(), FALSE) ENDIF ENDPROC DEF PROCreturn : IF nLines% = 0 ENDPROC LOCAL I%, p%%, a$, l$, r$ IF NOT Typing% THEN Typing% = TRUE PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) ENDIF PROCdeltext(Buffer$(), Indent%(), BreakPt&(), CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) I% = Indent%(CaretY%) a$ = FNformat(Buffer$(CaretY%), I%) PROCsplit(a$, CaretX%, l$, r$) p%% = ^Buffer$(nLines%) FOR I% = nLines% TO CaretY% STEP -1 Indent%(I%+1) = Indent%(I%) BreakPt&(I%+1) = BreakPt&(I%) p%%!8 = p%%!0 : p%%!12 = p%%!4 p%% -= 8 NEXT p%%!8 = 0 : p%%!12 = 0 nLines% += 1 PROCreformat(l$, CaretX%, CaretY%, Buffer$(), Indent%(), FALSE) CaretY% += 1 PROCreformat(r$, CaretX%, CaretY%, Buffer$(), Indent%(), FALSE) CaretX% = 0 AnchorX% = CaretX% AnchorY% = CaretY% ENDPROC DEF PROCtyped(K%) LOCAL U%, k$ IF NOT Typing% THEN Typing% = TRUE PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) ENDIF PROCdeltext(Buffer$(), Indent%(), BreakPt&(), CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) U% = K% REPEAT k$ += CHR$K% K% = INKEY(1) UNTIL K% < &20 OR K% >= &80 AND K% < &A0 AND U% < &C0 IF K% <> -1 Click%() = K%, 0, 0 IF BB4W% OR Unicode% ELSE k$ = FN_utf8_to_ansi(k$) IF BB4W% IF Unicode% THEN k$ = FN_ansi_to_utf8(k$) IF Overtype% THEN PROCovertype(Buffer$(), Indent%(), CaretX%, CaretY%, k$) ELSE PROCinsert(Buffer$(), Indent%(), CaretX%, CaretY%, k$) ENDIF IF CaretY% >= nLines% nLines% = CaretY% + 1 AnchorX% = CaretX% AnchorY% = CaretY% ENDPROC REM!Eject -------------------------------------------------------------------------- DEF __Menu_Handlers__ DEF __File_Menu__ REM File... New DEF PROCnew CurrentFile$ = "" Buffer$() = "" Indent%() = 0 BreakPt&() = 0 MaxLen% = 0 CaretX% = 0 CaretY% = 0 AnchorX% = 0 AnchorY% = 0 nLines% = 0 Refresh% = TRUE PROCundoclear(UndoLevel%, RedoLevel%) PROCtitle("(untitled)") PROC_setdlgitemtext(FileDlg%, 104, "") ENDPROC REM File... Load DEF PROCload LOCAL f$ f$ = FNfileselector("Load File") IF f$ = "" ENDPROC PROCload(f$, nLines%, MaxLen%, FALSE) BreakPt&() = 0 ScrollH% = 0 ScrollV% = 0 CaretX% = 0 CaretY% = 0 AnchorX% = 0 AnchorY% = 0 Hover% = -10000 ENDPROC REM File... Insert DEF FNinsertfile LOCAL f$ f$ = FNfileselector("Insert File") IF f$ = "" THEN = FALSE PROCload(f$, nLines%, MaxLen%, TRUE) = TRUE REM File... Compare DEF PROCcomparefile LOCAL f$ f$ = FNfileselector("Compare File") IF f$ = "" ENDPROC PROCcompare(f$) ENDPROC REM File... Print DEF PROCprintprogram LOCAL F%, I%, N%, R%, a$, file$ IF CurrentFile$ = "" THEN file$ = @tmp$ + "untitled.txt" ELSE file$ = @tmp$ + FNnopath(CurrentFile$) + ".txt" ENDIF F% = OPENOUT(file$) I% = Indent%(0) FOR N% = 0 TO nLines% - 1 a$ = FNstrip(FNformat(Buffer$(N%), I%)) PRINT #F%, a$ BPUT #F%, 10 IF INSTR(a$, "REM!Eject") BPUT #F%,12 NEXT CLOSE #F% R% = FNmessagebox("SDLIDE", "Send listing to default printer?", MB_ICONQUESTION + MB_YESNO) IF R% = IDYES THEN PROCcursor(2) IF NOT BB4W% IF @platform% AND &F THEN OSCLI "RUN lp -c """ + file$ + """" ELSE SYS "ShellExecuteA", @hwnd%, "print", file$, 0, 0, 0 ENDIF WAIT 200 PROCcursor(0) ENDIF OSCLI "DELETE """ + file$ + """" ENDPROC REM File... Save DEF FNsave LOCAL R% IF CurrentFile$ = "" THEN = FNsaveas R% = FNsave(CurrentFile$) IF R% PROCupdaterecent(CurrentFile$) = R% REM File... Save As DEF FNsaveas LOCAL F%, R%, a$ F% = FNinstrr(Recent$(1), "/", 0) IF F% = 0 F% = FNinstrr(Recent$(1), "\", 0) ON ERROR LOCAL IF FALSE THEN IF F% THEN OSCLI "cd """ + LEFT$(Recent$(1), F%-1) + """" ELSE OSCLI "cd """ + LEFT$(@usr$) + """" ENDIF ENDIF : RESTORE ERROR a$ = FNfileselector("Save File") IF a$ = "" THEN = FALSE F% = OPENIN(a$) IF F% THEN CLOSE #F% R% = FNmessagebox("SDLIDE", FNnopath(a$) + " already exists," + CHR$13 + CHR$10 + \ \ "do you want to replace it?", MB_ICONQUESTION + MB_YESNO) IF R% <> IDYES THEN = FALSE ENDIF CurrentFile$ = a$ PROCtitle(CurrentFile$) = FNsave REM File... Exit DEF FNexit LOCAL maximized% IF BB4W% THEN SYS "IsZoomed", @hwnd% TO maximized% ELSE SYS "SDL_GetWindowFlags", @hwnd% TO maximized% maximized% AND= &80 ENDIF IF maximized% THEN PROCputINIstring(IniFile$, "maximized", "1") ELSE PROCputINIstring(IniFile$, "maximized", "0") PROCputINIstring(IniFile$, "windowwidth", STR$@vdu%!208) PROCputINIstring(IniFile$, "windowheight", STR$@vdu%!212) ENDIF PROCputINIstring(IniFile$, "colouring", STR$(Colouring% <> 0)) PROCputINIstring(IniFile$, "indentation", STR$(Indentation% <> 0)) PROCputINIstring(IniFile$, "lowercase", STR$(Lowercase% <> 0)) PROCputINIstring(IniFile$, "abbreviations", STR$(Abbrev% <> 0)) PROCputINIstring(IniFile$, "tooltips", STR$(Tooltips% <> 0)) PROCputINIstring(IniFile$, "darkmode", STR$(Darkmode% <> 0)) PROCputINIstring(IniFile$, "unicode", STR$(Unicode% <> 0)) PROCputINIstring(IniFile$, "includeon", STR$(IncludeON% <> 0)) PROCputINIstring(IniFile$, "includelab", STR$(IncludeLab% <> 0)) PROCputINIstring(IniFile$, "sortlist", STR$(SortList% <> 0)) PROCputINIstring(IniFile$, "guiscale", STR$(GUIscale)) PROCputINIstring(IniFile$, "guifont", GUIFont$) PROCputINIstring(IniFile$, "editfont", EditFont$) FOR i% = 1 TO 9 PROCputINIstring(IniFile$, "recent" + STR$(i%), Recent$(i%)) NEXT FOR i% = 1 TO 6 IF Darkmode% THEN PROCputINIstring(IniFile$, "dark" + STR$(i%), STR$(Colours%(i%-1))) ELSE PROCputINIstring(IniFile$, "colour" + STR$(i%), STR$(Colours%(i%-1))) ENDIF NEXT = TRUE DEF __Edit_Menu__ REM Edit... Undo REM Edit... Redo DEF PROCundoundo(f$(), i%(), b&(), RETURN nl%, ul%, RETURN cx%, RETURN cy%) LOCAL F%,I%,L%,N% ON TIME LOCAL OFF PROCcursor(2) f$() = "" F% = OPENIN(@tmp$ + "undo" + Session$ + STR$ul% + ".tmp.bbc") REPEAT i%(N%) = I% L% = BGET#F% : IF L% = 0 EXIT REPEAT f$(N%) = CHR$L% + GET$#F% BY 2 + GET$#F% TO &D + CHR$&D PROCindent(f$(N%), I%, L%) N% += 1 UNTIL FALSE INPUT #F%, cx%, cy%, $^b&(0) : b&(LEN$^b&(0)) = 0 CLOSE #F% nl% = N% PROCcursor(1) ENDPROC REM Edit... Copy: DEF PROCcopytext(f$(), i%(), x1%, y1%, x2%, y2%) LOCAL H%, T%, a$ a$ = FNseltext(f$(), i%(), x1%, y1%, x2%, y2%) IF NOT Unicode% a$ = FN_ansi_to_utf8(a$) IF BB4W% THEN SYS "GlobalAlloc", &2000, 2*LEN(a$)+2 TO H% SYS "GlobalLock", H% TO T% SYS "MultiByteToWideChar", CP_UTF8, 0, a$, -1, T%, LEN(a$)+1 SYS "GlobalUnlock", H% SYS "OpenClipboard", @hwnd% SYS "EmptyClipboard" SYS "SetClipboardData", 13, H% SYS "CloseClipboard" ELSE SYS "SDL_SetClipboardText", a$ ENDIF ENDPROC REM Edit... Paste DEF PROCpaste(f$(), i%(), b&(), RETURN cx%, RETURN cy%, RETURN nl%, RETURN ml%) LOCAL H%, I%, N%, p%%, T%, Y%, t%%, a$, l$, r$ IF cy% < nl% THEN I% = i%(cy%) a$ = FNstrip(FNformat(f$(cy%), I%)) PROCsplitx(a$, cx%, l$, r$) ENDIF IF BB4W% THEN SYS "OpenClipboard", @hwnd% SYS "GetClipboardData", 13 TO H% IF H% THEN SYS "GlobalLock", H% TO T% SYS "WideCharToMultiByte", CP_UTF8, 0, T%, -1, FALSE, 0, FALSE, FALSE TO I% a$ = STRING$(I%, " ") SYS "WideCharToMultiByte", CP_UTF8, 0, T%, -1, PTR(a$), LEN(a$), FALSE, FALSE a$ = LEFT$(a$) SYS "GlobalUnlock", H% ENDIF SYS "CloseClipboard" ELSE SYS "SDL_GetClipboardText" TO t%% IF NOT BB4W% IF @platform% AND &40 ELSE t%% = !^t%% a$ = $$t%% ENDIF IF NOT Unicode% a$ = FN_utf8_to_ansi(a$) REPEAT I% = FNinstrq(a$, CHR$&C2+CHR$&A0, 0) IF I% a$ = LEFT$(a$, I%-1) + " " + MID$(a$, I%+2) UNTIL I% = 0 IF NOT Unicode% THEN REPEAT I% = INSTR(a$, CHR$&A0) IF I% MID$(a$, I%, 1) = " " UNTIL I% = 0 ENDIF REPEAT I% = INSTR(a$, CHR$&A, I%+1) IF I% N% += 1 UNTIL I% = 0 IF N% = 0 THEN cx% += FNlen(a$) PROCreformat(l$ + a$ + r$, cx%, cy%, f$(), i%(), FALSE) IF cy% >= nl% nl% = cy% + 1 ELSE nl% += N% IF N% THEN p%% = ^f$(&FFFF) FOR Y% = &FFFF TO cy%+N% STEP -1 p%%!0 = p%%!(-N%*8) p%%!4 = p%%!(4-N%*8) i%(Y%) = i%(Y%-N%) b&(Y%) = b&(Y%-N%) p%% -= 8 NEXT FOR Y% = 1 TO N% p%%!0 = 0 : p%%!4 = 0 p%% -= 8 NEXT ENDIF Y% = cy% cx% = 0 cy% += N% I% = i%(Y%) REPEAT T% = INSTR(a$, CHR$&A) IF T% THEN f$(Y%) = FNtokenise(FNstrip(l$ + LEFT$(a$, T%-1))) i%(Y%) = I% l$ = FNformat(f$(Y%), I%) l$ = "" a$ = MID$(a$, T%+1) Y% += 1 ENDIF UNTIL T% = 0 i%(Y%) = I% IF a$ <> "" IF Y% = nl% nl% += 1 : cy% += 1 f$(Y%) = FNtokenise(FNstrip(a$ + r$)) WHILE Y% <= nl% i%(Y%) = I% PROCindent(f$(Y%), I%, ml%) Y% += 1 ENDWHILE ENDIF ENDPROC REM Edit... Delete: DEF PROCdeltext(f$(), i%(), b&(), RETURN cx%, RETURN cy%, RETURN ax%, RETURN ay%, RETURN nl%) LOCAL D%, I%, p%%, Y%, a$, l$, r$, x1%, y1%, x2%, y2% x1% = cx% : y1% = cy% : x2% = ax% : y2% = ay% IF x1% > x2% SWAP x1%,x2% IF y1% > y2% SWAP y1%,y2% CASE TRUE OF WHEN y1% <> y2%: D% = y2% - y1% I% = i%(y2%) - i%(y1%) p%% = ^f$(y1%) FOR Y% = y1% TO nl%-1-D% p%%!0 = p%%!(8 * D%) p%%!4 = p%%!(8 * D% + 4) i%(Y%) = i%(Y% + D%) - I% b&(Y%) = b&(Y% + D%) p%% += 8 NEXT i%(Y%) = i%(Y% + D%) - I% b&(Y%) = b&(Y% + D%) nl% -= D% FOR Y% = nl% TO nl%+D%-1 p%%!0 = 0 : p%%!4 = 0 p%% += 8 NEXT WHEN x1% <> x2%: I% = i%(y1%) a$ = FNformat(f$(y1%), I%) PROCsplit(a$, x1%, l$, r$) PROCsplit(a$, x2%, a$, r$) PROCreformat(l$ + r$, x1%, y1%, f$(), i%(), FALSE) ENDCASE IF cy% <> ay% THEN cx% = 0 : ax% = 0 ELSE cx% = x1% : ax% = x1% ENDIF cy% = y1% : ay% = y1% ENDPROC REM Edit... Find REM Edit... Replace DEF PROCfind : LOCAL dlg% : dlg% = FindDlg% DEF PROCreplace : LOCAL dlg% : dlg% = ReplDlg% LOCAL H%, R%, X%, Y%, W%, charx%, chary%, minx%, maxx%, miny%, maxy%, crtx%, find$, repl$ charx% = 2 * @vdu%!216 chary% = 2 * @vdu%!220 minx% = 0 maxx% = EditRect.r% - EditRect.l% miny% = EditRect.b% - EditRect.t% + chary% maxy% = 0 ON TIME LOCAL OFF ON MOUSE LOCAL OFF OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width find$ = FNseltext(Buffer$(), Indent%(), CaretX%, CaretY%, AnchorX%, AnchorY%) IF find$ <> "" THEN PROC_setdlgitemtext(dlg%, 103, find$) PROC_enabledlgitem(dlg%, 1, TRUE) PROC_enabledlgitem(dlg%, 3, TRUE) PROC_enabledlgitem(dlg%, 4, TRUE) ENDIF PROC_registerdlgcallback(dlg%, FNfrcb()) PROC_getdlgrect(dlg%, X%, Y%, W%, H%) X% = EditRect.r% - W% : Y% = EditRect.t% REPEAT R% = FN_showdialogex(dlg%, X%, Y%, Darkmode%) PROC_getdlgrect(dlg%, X%, Y%, W%, H%) IF R% <> 2 THEN FindFlags% = R% : REM 1 = find next, 3 = replace, 4 = replace all find$ = FN_getdlgitemtext(dlg%, 103) repl$ = FN_getdlgitemtext(dlg%, 104) IF FN_isdlgitemchecked(dlg%, 105) FindFlags% OR= &10000 IF FN_isdlgitemchecked(dlg%, 106) FindFlags% OR= &20000 PROCsavejump(GoBack%(), ScrollV%, BackLevel%) IF (FindFlags% AND 7) = 1 OR (FindFlags% AND 7) = 4 OR CaretX% = AnchorX% THEN IF NOT FNsearch(find$, Buffer$(), Indent%(), nLines%, FindFlags%, \ \ AnchorX%, AnchorY%, CaretX%, CaretY%) THEN FindFlags% AND= &30000 PROCmessagebox("SDLIDE", "String not found", MB_ICONINFORMATION) CaretX% = 0 : CaretY% = 0 : AnchorX% = 0 : AnchorY% = 0 ENDIF ENDIF IF (FindFlags% AND 7) >= 3 THEN PROCundosave(Buffer$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) REPEAT crtx% = CaretX% PROCinsert(Buffer$(), Indent%(), CaretX%, CaretY%, repl$) PROCdeltext(Buffer$(), Indent%(), BreakPt&(), crtx%, CaretY%, AnchorX%, AnchorY%, nLines%) CaretX% = crtx% + FNlen(repl$) IF NOT FNsearch(find$, Buffer$(), Indent%(), nLines%, FindFlags%, \ \ AnchorX%, AnchorY%, CaretX%, CaretY%) FindFlags% AND= &30000 Changed% = TRUE UNTIL (FindFlags% AND 7) < 4 ENDIF *REFRESH OFF PROC_closedialog(dlg%) OSCLI "FONT " + EditFont$ WHILE ScrollV% - CaretY% * chary% < miny% ScrollV% += chary% : ENDWHILE WHILE ScrollV% - CaretY% * chary% > maxy% ScrollV% -= chary% : ENDWHILE WHILE ScrollH% + CaretX% * charx% < minx% ScrollH% += charx% : ENDWHILE WHILE ScrollH% + CaretX% * charx% > maxx% ScrollH% -= charx% : ENDWHILE PROCrefresh(ScrollH%, ScrollV%, CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width ENDIF UNTIL R% = 2 *REFRESH ON Refresh% = TRUE PROC_closedialog(dlg%) OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width ENDPROC DEF FNfrcb(D%, K%) LOCAL R%, a$ PRIVATE E% R% = FN_getdlgfocus(D%) : IF R% > 9 R% = 1 IF K% = 13 THEN = R% IF K% = 27 THEN = 2 a$ = FN_getdlgitemtext(D%, 103) IF E% <> (a$ <> "") THEN E% = (a$ <> "") PROC_enabledlgitem(D%, 1, E%) PROC_enabledlgitem(D%, 3, E%) PROC_enabledlgitem(D%, 4, E%) PROC_refreshdialog(D%) ENDIF = 0 REM Edit... Find Next DEF PROCfindnext PROCsavejump(GoBack%(), ScrollV%, BackLevel%) LOCAL find$ find$ = FN_getdlgitemtext(FindDlg%, 103) IF find$ = "" ENDPROC IF NOT FNsearch(find$, Buffer$(), Indent%(), nLines%, FindFlags%, \ \ AnchorX%, AnchorY%, CaretX%, CaretY%) THEN PROCmessagebox("SDLIDE", "String not found", MB_ICONINFORMATION) CaretX% = 0 : CaretY% = 0 : AnchorX% = 0 : AnchorY% = 0 ENDIF Refresh% = TRUE ENDPROC REM Edit... Go To DEF PROCgotoline(nl%) LOCAL L%, R% ON TIME LOCAL OFF ON MOUSE LOCAL OFF OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width PROC_registerdlgcallback(GotoDlg%, FNdlgcb()) PROC_setdlgitemtext(GotoDlg%, 101, STR$(CaretY%)) R% = FN_showdialogex(GotoDlg%, &80000000, &80000000, Darkmode%) *REFRESH ON IF R% = 1 THEN L% = VAL(FN_getdlgitemtext(GotoDlg%, 101)) IF L% < nl% THEN PROCsavejump(GoBack%(), ScrollV%, BackLevel%) CaretX% = 0 : CaretY% = L% : AnchorX% = 0 : AnchorY% = L% ENDIF ENDIF PROC_closedialog(GotoDlg%) OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width Refresh% = TRUE : REM To reset caret ENDPROC DEF __Utilities_Menu__ REM Utilities... Compile DEF PROCcompile LOCAL bbcfile$, dir$, exe$, ch% dir$ = FNpath(CurrentFile$) exe$ = FNnoext(FNnopath(CurrentFile$)) IF dir$ = "" dir$ = FNgetcwd + RIGHT$(@lib$) IF BB4W% THEN bbcfile$ = dir$ + "compiler.tmp.bbc" exe$ += ".exe, encrypt" ELSE bbcfile$ = @tmp$ + "compiler.tmp.bbc" ENDIF ch% = OPENOUT(bbcfile$) IF ch% = 0 PROCmessagebox("SDLIDE", "Couldn't create " + bbcfile$, &30) : ENDPROC BPUT #ch%, FNtokenise("REM!Exefile " + dir$ + "exe" + RIGHT$(@tmp$) + exe$); BPUT #ch%, SUM(Buffer$()); BPUT #ch%, CHR$0+CHR$&FF+CHR$&FF; CLOSE #ch% IF BB4W% THEN SYS "WinExec", """" + @lib$ + "../bbcwin6.exe"" -c """ + bbcfile$ + """", 0 WAIT 100 : OSCLI "del """ + bbcfile$ + """" ELSE PROCexecute(@dir$ + "compiler.bbc", FNdark) : REM Not -hidden because of error box ENDIF ENDPROC REM Utilities... Renumber DEF PROCrenumber(f$(), nl%) IF nl% = 0 ENDPROC LOCAL a$, c&, l&, h&, I%, L%, N%, R%, t%%, first%, incr%, remove%, lino%(), flag&() DIM lino%(nl%-1), flag&(nl%-1) ON TIME LOCAL OFF ON MOUSE LOCAL OFF OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width PROC_registerdlgcallback(RenumDlg%, FNdlgcb()) REPEAT R% = FN_showdialogex(RenumDlg%, &80000000, &80000000, Darkmode%) first% = VAL(FN_getdlgitemtext(RenumDlg%, 103)) incr% = VAL(FN_getdlgitemtext(RenumDlg%, 104)) remove% = FN_isdlgitemchecked(RenumDlg%, 105) IF R% = 1 IF first% + (nl%-1) * incr% > 65535 THEN PROCmessagebox("SDLIDE", "These values would result in a " + \ \ "line number greater than 65535", MB_ICONWARNING) *REFRESH OFF PROC_closedialog(RenumDlg%) R% = 0 ENDIF UNTIL R% *REFRESH ON PROC_closedialog(RenumDlg%) IF R% = 1 THEN PROCundosave(f$(), BreakPt&(), nLines%, UndoLevel%, RedoLevel%, CaretX%, CaretY%) FOR L% = 0 TO nl%-1 lino%(L%) = !(PTR(f$(L%)) + 1) AND &FFFF NEXT FOR L% = 0 TO nl%-1 a$ = f$(L%) R% = 3 REPEAT R% = FNinstrq(a$, CHR$&8D, R%+1) IF R% THEN t%% = PTR(a$) + R% - 1 c& = t%%?1 l& = ((c& << 2) AND &C0) EOR t%%?2 h& = ((c& << 4) AND &C0) EOR t%%?3 N% = l& + 256*h& FOR I% = 0 TO nl%-1 IF N% = lino%(I%) EXIT FOR NEXT IF I% < nl% THEN flag&(I%) = 1 N% = first% + I% * incr% l& = N% MOD 256 h& = N% DIV 256 t%%?1 = &54 EOR (((h& AND &C0) >> 4) OR ((l& AND &C0) >> 2)) t%%?2 = &40 OR (l& AND &3F) t%%?3 = &40 OR (h& AND &3F) ELSE PROCmessagebox("SDLIDE", "No line " + STR$N% + \ \ " referenced in (new) line " + STR$(first% + L%*i%), \ \ MB_ICONWARNING) ENDIF ENDIF UNTIL R% = 0 f$(L%) = a$ NEXT L% FOR L% = 0 TO nl%-1 a$ = f$(L%) IF remove% IF flag&(L%) = 0 THEN MID$(a$,2,2) = CHR$0+CHR$0 ELSE N% = first% + L% * incr% MID$(a$,2,2) = CHR$(N% MOD 256) + CHR$(N% DIV 256) ENDIF f$(L%) = a$ NEXT Changed% = TRUE ENDIF OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width Refresh% = TRUE : REM To reset caret ENDPROC DEF FNdlgcb(D%, K%) : LOCAL R% R% = FN_getdlgfocus(D%) : IF R% > 9 R% = 1 IF K% = 13 THEN = R% IF K% = 27 THEN = 2 = 0 REM Utilities... List FNs/PROCs DEF PROClistdefs(f$(), nl%) LOCAL A%,C%,I%,N%,T%,a$,d$(),l%() FOR I% = 0 TO nl%-1 T% = ASCMID$(f$(I%),4) IF T%=&DD N% += 1 IF IncludeON% IF T%=&EE THEN C% = 4 : REPEAT C% += 1 : UNTIL ASCMID$(f$(I%),C%) <> 32 IF ASCMID$(f$(I%),C%) < 13 OR ASCMID$(f$(I%),C%) > 127 N% += 1 ENDIF IF IncludeLab% IF T%=&28 N% += 1 NEXT IF N% = 0 THEN ENDPROC DIM d$(N%), l%(N%) N% = 0 FOR I% = 0 TO nl%-1 T% = ASCMID$(f$(I%),4) IF T%=&DD THEN A% = 0 a$ = MID$(FNstrip(FNformat(f$(I%),A%)),7) a$ = MID$(a$,4) A% = INSTR(a$,"(") : IF A% a$ = LEFT$(a$,A%) + ")" A% = INSTR(a$,":") : IF A% a$ = LEFT$(a$,A%-1) N% += 1 d$(N%) = FN_trim(a$) l%(N%) = I% ENDIF IF IncludeON% IF T%=&EE THEN C% = 4 : REPEAT C% += 1 : UNTIL ASCMID$(f$(I%),C%) <> 32 IF ASCMID$(f$(I%),C%) < 13 OR ASCMID$(f$(I%),C%) > 127 THEN A% = 0 a$ = MID$(FNstrip(FNformat(f$(I%),A%)),7) C% -= 3 : REPEAT C% += 1 : UNTIL ASCMID$(a$,C%) < 64 IF INSTR(f$(I%),CHR$&EA,4) THEN REPEAT C% += 1 : UNTIL ASCMID$(a$,C%) > 32 REPEAT C% += 1 : UNTIL ASCMID$(a$,C%) < 64 ENDIF N% += 1 d$(N%) = FN_trim(LEFT$(a$,C%)) l%(N%) = I% ENDIF ENDIF IF IncludeLab% IF T%=&28 THEN A% = 0 a$ = MID$(FNstrip(FNformat(f$(I%),A%)),7) C% = INSTR(a$, ")") N% += 1 d$(N%) = FN_trim(LEFT$(a$,C%)) l%(N%) = I% ENDIF NEXT IF SortList% C% = N% : CALL Sort%%, d$(1), l%(1) I% = FNcombo(d$(), N%, ComboBox.l%, ComboBox.t% + 2, ComboBox.r%-ComboBox.l%+2) *REFRESH ON IF I% THEN PROCsavejump(GoBack%(), ScrollV%, BackLevel%) ScrollV% = l%(I%) * @vdu%!220 * 2 ENDIF ENDPROC REM Utilities... Addins DEF PROCrunaddin(addin$) LOCAL bbcfile$, ch% IF addin$ = "" ENDPROC bbcfile$ = @tmp$ + "program.tmp.bbc" ch% = OPENOUT(bbcfile$) BPUT #ch%, SUM(Buffer$()); BPUT #ch%, CHR$0+CHR$&FF+CHR$&FF; CLOSE #ch% PROCexecute(addin$, "-hidden " + FNdark + " -file " + CurrentFile$) ENDPROC DEF __Options_Menu__ REM Options... Syntax Colouring DEF PROCtogglecolouring LOCAL C%, I% Colouring% EOR= TRUE IF Colouring% THEN FOR I% = 1 TO 6 C% = Colours%(I%-1) COLOR I%, (C% AND &FF0000) >> 16, (C% AND &FF00) >> 8, C% AND &FF NEXT ELSE FOR I% = 1 TO 6 IF Darkmode% COLOR I%, &FF, &FF, &FF ELSE COLOR I%, 0, 0, 0 NEXT ENDIF Refresh% = TRUE ENDPROC REM Options... Lowercase Keywords DEF PROCtogglelowercase Lowercase% EOR= TRUE IF Lowercase% Abbrev% = FALSE Refresh% = TRUE ENDPROC REM Options... Indentation DEF PROCtoggleindentation Indentation% EOR= TRUE Refresh% = TRUE ENDPROC REM Options... Keyword abbreviations DEF PROCtoggleabbrev Abbrev% EOR= TRUE Refresh% = TRUE ENDPROC REM Options... Unicode Support DEF PROCtoggleunicode Unicode% EOR= TRUE Refresh% = TRUE ENDPROC REM Options... Set Font DEF PROCsetfont LOCAL F%, H%, I%, N%, R%, W%, X%, Y%, face$, style$, size$ PRIVATE face$(), style$(), size$() DIM face$(1000), style$(4), size$(20) style$() = "", "Regular", "Italic", "Bold", "Bold Italic" size$() = "", "8", "9", "10", "11", "12", "13", "14", "16", "18", "20", "22", \ \ "24", "28", "32", "36", "40", "48", "56", "64", "72" face$() = "", "Arial,ttf", "Consolas.ttf", "Courier New.ttf", "Lucida Console.ttf" ON TIME LOCAL OFF ON MOUSE LOCAL OFF OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width PROC_setlistboxarray(FontDlg%, 103, style$(), 4) PROC_setlistboxarray(FontDlg%, 105, size$(), 20) I% = INSTR(EditFont$, ",") IF I% THEN face$ = LEFT$(EditFont$, I% - 1) PROC_setlistboxselect(FontDlg%, 105, VALMID$(EditFont$, I%+1) - 7) I% = INSTR(EditFont$, ",", I% + 1) IF I% THEN IF INSTR(EditFont$, "I", I% + 1) N% OR= 1 IF INSTR(EditFont$, "B", I% + 1) N% OR= 2 ENDIF PROC_setlistboxselect(FontDlg%, 103, N% + 1) I% = FNinstrr(face$, "/", 0) IF I% = 0 I% = FNinstrr(face$, "\", 0) IF I% face$ = MID$(LEFT$(face$), I% + 1) ENDIF IF BB4W% N% = 4 ELSE N% = FNdirscan(face$(), "dir """ + @lib$ + "*.*""", "*.ttf;*.otf", "", "") FOR I% = 1 TO N% IF BB4W% face$(I%) = LEFT$(face$(I%), LEN(face$(I%)) - 4) IF face$(I%) = face$ F% = I% NEXT IF N% = 0 face$(1) = face$ : N% = 1 : F% = 1 PROC_setlistboxarray(FontDlg%, 101, face$(), N%) PROC_setlistboxselect(FontDlg%, 101, F%) PROC_registerdlgcallback(FontDlg%, FNdlgcb()) X% = &80000000 : Y% = &80000000 REPEAT OFF R% = FN_showdialogex(FontDlg%, X%, Y%, Darkmode%) PROC_getdlgrect(FontDlg%, X%, Y%, W%, H%) face$ = FN_getdlgitemtext(FontDlg%, 101) style$ = FN_getdlgitemtext(FontDlg%, 103) size$ = FN_getdlgitemtext(FontDlg%, 105) style$ = LEFT$("B",INSTR(style$,"B")) + LEFT$("I",INSTR(style$,"I")) IF R% = 3 THEN *REFRESH OFF PROC_closedialog(FontDlg%) IF BB4W% THEN OSCLI "FONT " + face$ + "," + size$ + "," + style$ ELSE OSCLI "FONT """ + @lib$ + face$ + """," + size$ + "," + style$ ENDIF PROCrefresh(ScrollH%, ScrollV%, CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width ENDIF UNTIL R% = 1 OR R% = 2 IF R% = 1 THEN IF BB4W% THEN EditFont$ = face$ + "," + size$ + "," + style$ ELSE EditFont$ = """" + @lib$ + face$ + """," + size$ + "," + style$ ENDIF ENDIF *REFRESH ON Refresh% = TRUE PROC_closedialog(FontDlg%) OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width ENDPROC REM Options... Set Colours DEF PROCsetcolours LOCAL H%, I%, N%, R%, W%, X%, Y% ON TIME LOCAL OFF ON MOUSE LOCAL OFF OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width PROC_checkdlgitem(ColorDlg%, 101, 0) PROC_checkdlgitem(ColorDlg%, 102, 0) PROC_checkdlgitem(ColorDlg%, 103, 0) PROC_checkdlgitem(ColorDlg%, 104, 0) PROC_checkdlgitem(ColorDlg%, 105, 0) PROC_checkdlgitem(ColorDlg%, 106, 1) PROC_registerdlgcallback(ColorDlg%, FNclrcb()) X% = &80000000 : Y% = &80000000 REPEAT OFF R% = FN_showdialogex(ColorDlg%, X%, Y%, Darkmode%) PROC_getdlgrect(ColorDlg%, X%, Y%, W%, H%) IF R% = 1 OR R% = 3 THEN FOR I% = 101 TO 106 IF FN_isdlgitemchecked(ColorDlg%, I%) EXIT FOR NEXT N% = Palette%(SelCol% DIV 10, SelCol% MOD 10) Colours%(I% - 101) = N% COLOR I% - 100, N% >> 16, (N% AND &FF00) >> 8, N% AND &FF ENDIF IF R% = 3 THEN PROC_setdlgitemtext(ColorDlg%, 2, "Close") *REFRESH OFF PROC_closedialog(ColorDlg%) OSCLI "FONT " + EditFont$ PROCrefresh(ScrollH%, ScrollV%, CaretX%, CaretY%, AnchorX%, AnchorY%, nLines%) OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width ENDIF UNTIL R% = 1 OR R% = 2 *REFRESH ON Refresh% = TRUE PROC_closedialog(ColorDlg%) OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width ENDPROC REM Options... Dark Mode DEF PROCtoggledarkmode Darkmode% EOR= TRUE PROCsetpalette Resized% = TRUE ENDPROC DEF FNclrcb(D%, K%) LOCAL C%, F%, I%, P%, R% PRIVATE S% F% = FN_getdlgfocus(D%) IF F% >= 200 SelCol% = F% - 200 IF F% > 9 F% = 1 FOR I% = 101 TO 106 IF FN_isdlgitemchecked(D%, I%) EXIT FOR NEXT IF S% <> I% THEN S% = I% P% = Colours%(S% - 101) FOR R% = 0 TO 5 FOR C% = 0 TO 7 IF Palette%(R%, C%) = P% PROC_setdlgfocus(D%, 200 + R%*10 + C%) NEXT NEXT R% ENDIF R% = SelCol% DIV 10 C% = SelCol% MOD 10 CASE K% OF WHEN 13: = F% WHEN 27: = 2 WHEN 136: C% = (C% + 7) MOD 8 WHEN 137: C% = (C% + 1) MOD 8 WHEN 138: R% = (R% + 1) MOD 6 WHEN 139: R% = (R% + 5) MOD 6 OTHERWISE: = 0 ENDCASE PROC_setdlgfocus(D%, 200 + R%*10 + C%) = 0 DEF __Run_Menu__ REM Run... Run Program REM Run... Debug Program REM Run... Profile Program REM Run... Immediate DEF PROCimmediate : LOCAL debug%, imm% : imm% = 1 DEF PROCprofile : LOCAL debug%, imm% : debug% = 1 DEF PROCdebug : LOCAL debug%, imm% : debug% = TRUE DEF PROCrun : LOCAL debug%, imm% LOCAL breakpt$, bbcfile$, dir$, ch%, I% dir$ = FNpath(CurrentFile$) IF dir$ = "" dir$ = FNgetcwd + RIGHT$(@lib$) bbcfile$ = @tmp$ + FNnopath(CurrentFile$) + ".tmp" ch% = OPENOUT(bbcfile$) IF ch% = 0 PROCmessagebox("SDLIDE", "Couldn't create " + bbcfile$, &30) : ENDPROC IF debug% THEN IF debug% > 0 THEN BPUT #ch%, FNtokenise("P% = TRUE : CALL @lib$+""sdldebug"""); ELSE BPUT #ch%, FNtokenise("P% = FALSE : CALL @lib$+""sdldebug"""); ENDIF ENDIF BPUT #ch%, FNtokenise("dir$ = """ + dir$ + """"); BPUT #ch%, FNtokenise("$PTR(@dir$) = dir$ : !(^@dir$+4) = LEN(dir$)"); BPUT #ch%, FNtokenise("OSCLI ""cd """""" + dir$ + """""""""); IF imm% THEN BPUT #ch%, FNtokenise("PAGE = PAGE + &200 : CLEAR : END"); ELSE BPUT #ch%, FNtokenise("PAGE = PAGE + &200 : CLEAR : RUN"); ENDIF BPUT #ch%, FNtokenise("REM" + STRING$((502 - PTR#ch%) DIV 2, "x")); BPUT #ch%, FNtokenise("REM" + STRING$(507 - PTR#ch%, "x")); IF debug% THEN breakpt$ = CHR$6 + CHR$0 + CHR$0 + CHR$&FC + CHR$&88 FOR I% = 0 TO DIM(Buffer$(),1) BBCPtr%(I%) = PTR#ch% BBCTok&(I%) = ASCMID$(Buffer$(I%),4) BPUT #ch%, Buffer$(I%); IF debug%<0 IF BreakPt&(I%) PRINT #ch%, breakpt$ NEXT ELSE BPUT #ch%, SUM(Buffer$()); ENDIF BPUT #ch%, CHR$0+CHR$&FF+CHR$&FF; CLOSE #ch% PROCexecute(bbcfile$, "") ENDPROC REM Run... Stop DEF PROCstop PROCdebugcmd(TRUE, FALSE) ENDPROC REM Run... Pause DEF PROCpause LOCAL paused% paused% = TBpressed&(16) <> 0 IF paused% THEN PROCdebugcmd(0, &10000000) ELSE PROCdebugcmd(1, &10000000) ENDIF ENDPROC REM Run... Step Into DEF PROCstepinto PROCdebugcmd(1, &10000000) ENDPROC REM Run... Step Over DEF PROCstepover LOCAL F%, I%, curlin%, lin1%, lin2% FOR I% = 1 TO 10 F% = OPENIN(@tmp$ + "sdldebug.dat") IF F% EXIT FOR WAIT RND(3) NEXT IF F% = 0 ENDPROC curlin% = BGET#F% OR (BGET#F% << 8) OR (BGET#F% << 16) OR (BGET#F% << 24) CLOSE #F% lin1% = FNchop(BBCPtr%(), curlin%) + 1 : lin2% = lin1% IF lin1% > &FFFF ENDPROC REPEAT lin2% += 1 UNTIL INSTR(Skip$, CHR$BBCTok&(lin2%)) = 0 PROCdebugcmd(BBCPtr%(lin1%), BBCPtr%(lin2%)) ENDPROC REM Run... Run to Cursor DEF PROCrununtil LOCAL lin2% PROCdebug lin2% = CaretY% REPEAT lin2% += 1 UNTIL INSTR(Skip$, CHR$BBCTok&(lin2%)) = 0 PROCdebugcmd(BBCPtr%(CaretY%), BBCPtr%(lin2%)) ENDPROC DEF __Help_Menu__ REM Help... Help Topics DEF PROCtopics IF BB4W% THEN PROCopenurl("https://www.bbcbasic.co.uk/bbcwin/manual/index.html") ELSE PROCopenurl("https://www.bbcbasic.co.uk/bbcsdl/manual/index.html") ENDIF ENDPROC REM Help... Tutorial DEF PROCtutorial IF BB4W% THEN PROCopenurl("https://www.bbcbasic.co.uk/bbcwin/tutorial/index.html") ELSE PROCopenurl("https://www.bbcbasic.co.uk/bbcsdl/tutorial/index.html") ENDIF ENDPROC REM Help... Website DEF PROCwebsite IF BB4W% THEN PROCopenurl("https://www.bbcbasic.co.uk/bbcwin/index.html") ELSE PROCopenurl("https://www.bbcbasic.co.uk/bbcsdl/index.html") ENDIF ENDPROC REM Help... Email DEF PROCemail PROCopenurl("mailto:info@rtrussell.co.uk?subject=BBC%20BASIC%20for%20SDL%202.0") ENDPROC REM Help... Discussion Group DEF PROCdiscuss PROCopenurl("https://groups.io/g/bb4w/") ENDPROC REM Help... Message Board DEF PROCforum PROCopenurl("https://www.bbcbasic.co.uk/forum/") ENDPROC REM Help... Wiki DEF PROCwiki PROCopenurl("https://www.bbcbasic.co.uk/wiki/") ENDPROC REM Help... About BBC BASIC DEF PROCabout ON TIME LOCAL OFF ON MOUSE LOCAL OFF LOCAL R% OSCLI "FONT " + GUIFont$ PROC_registerdlgcallback(AboutBox%, FNdlgcb()) R% = FN_showdialog(AboutBox%, &80000000, &80000000) OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width Refresh% = TRUE : REM To reset caret ENDPROC DEF __Context_Menu__ REM Right-click menu: DEF PROCcontextmenu(X%, Y%) LOCAL A%, C%, I%, J%, N%, R%, S%, U%, fnproc$, menu$(), menu%() A% = FNisallrems(Buffer$(), CaretY%, AnchorY%) C% = FNhascliptext J% = BackLevel% <> 0 R% = CaretY% <> AnchorY% S% = R% OR CaretX% <> AnchorX% fnproc$ = FNisfnproc(Buffer$(), Indent%(), X%, Y%, nLines%, I%) U% = fnproc$ <> "" N% = - S%*2 - R% - C% - J% - U% IF N% = 0 ENDPROC DIM menu$(N% - 1), menu%(N% - 1) N% = 0 IF S% menu$() = "Cut", "Copy" : menu%() = 322, 323 : N% += 2 IF C% menu$(N%) = "Paste" : menu%(N%) = 324 : N% += 1 IF R% THEN IF A% THEN menu$(N%) = "Remove REMs" : menu%(N%) = 371 : N% += 1 ELSE menu$(N%) = "Add REMs" : menu%(N%) = 370 : N% += 1 ENDIF ENDIF IF J% menu$(N%) = "Go back" : menu%(N%) = 372 : N% += 1 IF U% menu$(N%) = "Jump to " + fnproc$ : menu%(N%) = 373 : N% += 1 Click%() = FNmenu(IDPOPUP, menu$(), menu%(), X%, Y%), I% * @vdu%!220 * 2, 0 ENDPROC REM Add REMs to selected block: DEF PROCaddrems(f$(), i%(), cy%, ay%, nl%) LOCAL a$,I%,M%,T%,Y% IF ay% = cy% THEN = FALSE IF ay% < cy% SWAP ay%,cy% I% = i%(cy%) FOR Y% = cy% TO ay%-1 T% = 0 a$ = FNstrip(FNformat(f$(Y%),T%)) a$ = LEFT$(a$,6) + "REM " + MID$(a$,7) f$(Y%) = FNtokenise(a$) i%(Y%) = I% PROCindent(f$(Y%),I%,M%) NEXT I% -= i%(Y%) IF I%=0 ENDPROC WHILE Y% <= nl% i%(Y%) += I% Y% += 1 ENDWHILE ENDPROC REM Remove REMs from selected block: DEF PROCremrems(f$(), i%(), cy%, ay%, nl%) LOCAL a$,I%,M%,T%,Y% IF ay% = cy% THEN = FALSE IF ay% < cy% SWAP ay%,cy% I% = i%(cy%) FOR Y% = cy% TO ay%-1 T% = 0 a$ = FNstrip(FNformat(f$(Y%),T%)) a$ = LEFT$(a$,6) + MID$(a$,10) f$(Y%) = FNtokenise(a$) i%(Y%) = I% PROCindent(f$(Y%),I%,M%) NEXT I% -= i%(Y%) IF I%=0 ENDPROC WHILE Y% < nl% i%(Y%) += I% Y% += 1 ENDWHILE ENDPROC DEF PROCgoback IF BackLevel% = 0 ENDPROC BackLevel% -= 1 ScrollV% = GoBack%(BackLevel%) Refresh% = TRUE ENDPROC DEF PROCjumpto(L%) IF L% = -1 ENDPROC PROCsavejump(GoBack%(), ScrollV%, BackLevel%) ScrollV% = L% Refresh% = TRUE ENDPROC REM Hover toolbar or keyword tooltip: DEF PROCtooltip(X%, Y%) LOCAL H%, I%, P%, V%, W%, Z%, f$, k$, t$ IF Y% > EditRect.t% THEN V% = X% : W% = EditRect.t% + BUTTONHEIGHT + 10 IF Y% > W% ENDPROC I% = FNchop(ToolPos%(), X%) IF I% <= DIM(ToolTip$(),1) t$ = ToolTip$(I%) ELSE ENDPROC t$ = " " + t$ + " " : P% = WIDTH(t$) : H% = @char.y% * 3 IF V% + P% > @size.x% * 2 V% = @size.x% * 2 - P% IF W% + H% > @size.y% * 2 W% = @size.y% * 2 - H% ELSE V% = X% : W% = Y% + @char.y% PROCpointtochar(X%, Y%) I% = Indent%(Y%) f$ = FNformat(Buffer$(Y%), I%) k$ = CHR$18 + CHR$0 + CHR$COL_KEYWD I% = INSTR(f$, CHR$18 + CHR$0 + CHR$COL_DEF) REPEAT P% = I% I% = INSTR(f$, k$, I% + 1) UNTIL I% = 0 OR LENFNstrip(LEFT$(f$,I%)) > X% IF P% = 0 ENDPROC I% = INSTR(f$, CHR$18 + CHR$0, P%+1) : IF I% = 0 I% = LEN(f$) + 1 IF X% > LENFNstrip(LEFT$(f$,I%)) ENDPROC k$ = MID$(f$, I% + 3, 1) f$ = FN_trim(FN_upper(MID$(f$,P% + 3,I% - P% - 3))) IF k$ = "#" OR k$ = "=" OR k$ = "~" OR k$ = "$" f$ += k$ I% = FNchops(KeywTip$(), f$ + " ") : H% = @char.y% WHILE ASCKeywTip$(I%) = 9 : I% -= 1 : ENDWHILE : P% = 0 REPEAT f$ = KeywTip$(I%) REPEAT Z% = INSTR(f$, CHR$9 + CHR$9) : IF Z% MID$(f$, Z%, 1) = CHR$0 UNTIL Z% = 0 REPEAT Z% = INSTR(f$, CHR$9, 2) : IF Z% MID$(f$, Z%, 1) = ":" UNTIL Z% = 0 IF ASCf$ = 9 f$ = CHR$&D + CHR$&A + STRING$(INSTR(t$, ":"), " ") + MID$(f$, 2) IF WIDTH(f$) > P% P% = WIDTH(f$) WHILE P% > @size.x% * 2 f$ = LEFT$(f$) : P% = WIDTH(f$) : ENDWHILE t$ += " " + f$ : H% += @char.y% * 2 : I% += 1 UNTIL ASCKeywTip$(I%) <> 9 : P% += 20 + WIDTH(" ") IF V% + P% > EditRect.r% V% = EditRect.r% - P% : IF V% < 0 V% = 0 IF W% + H% > EditRect.t% W% = EditRect.t% - H% : IF W% < 0 W% = 0 ENDIF OSCLI "GSAVE """ + @tmp$ + "tooltip" + Session$ + """" + STR$V% + "," + STR$W% + \ \ "," + STR$P% + "," + STR$(H%+1) VDU 24, V%; W%; V% + P% - 2; W% + H% - 2; 5 GCOL 128 + COL_GUIBKGD : GCOL 0 : CLG : RECTANGLE V%, W%, P% - 2, H% - 2 VDU 30 : MOVE BY 0, -@char.y% DIV 2 : PRINT t$; VDU 24, 0; 0; @size.x%*2-2; @size.y%*2-2; 4 MOUSE H%, I%, P% : REPEAT MOUSE X%, Y%, P% : Z% = INKEY(1) UNTIL X% <> H% OR Y% <> I% OR Z% <> -1 OR INKEY(-10) OR INKEY(-12) IF Z% <> -1 Click%(0) = Z% OSCLI "DISPLAY """ + @tmp$ + "tooltip" + Session$ + """" + STR$V% + "," + STR$W% ENDPROC REM!Eject -------------------------------------------------------------------------- DEF __GUI_Widgets__ DEF FNmenu(D%, m$(), m%(), X%, Y%) LOCAL B%, H%, I%, K%, L%, N%, O%, P%, Q%, R%, S%, T%, U%, W%, Z%, a$, click% ON TIME LOCAL OFF ON MOUSE LOCAL click% = TRUE : RETURN PROCcursor(0) OSCLI "FONT " + GUIFont$ FOR I% = 0 TO DIM(m$(),1) a$ = " " + m$(I%) T% = INSTR(a$,"&") IF T% a$ = LEFT$(a$,T%-1) + MID$(a$,T%+1) IF m%(I%) = 0 H% += 20 ELSE H% += @vdu%!220 * 2 T% = INSTR(a$, CHR$9) IF T% THEN N% = FN_stringwidth(LEFT$(a$,T%-1)) IF N% > L% L% = N% N% = FN_stringwidth(MID$(a$,T%+1)) + 20 IF N% > R% R% = N% ELSE N% = FN_stringwidth(a$) IF N% > L% L% = N% ENDIF NEXT H% += 10 L% += 20 W% = L% + R% IF Y% - H% < STATUSBARHEIGHT Y% = STATUSBARHEIGHT + H% OSCLI "GSAVE """ + @tmp$ + "bbc" + Session$ + ".tmp.bmp" + """ " + STR$X% + "," + STR$(Y%-H%) + \ \ "," + STR$(W%+2) + "," + STR$(H%+2) GCOL COL_BORDERS RECTANGLE X%, Y%, W%, -H% S% = -1 O% = -2 Z% = TIME + 50 MOUSE P%, Q%, B% REPEAT UNTIL INKEY(0) = -1 REPEAT *REFRESH OFF GCOL 128 + COL_GUIBKGD VDU 24,X%+2;Y%-H%+2;X%+W%-2;Y%-2;5 VDU 16,30,23,16,64| FOR I% = 0 TO DIM(m$(),1) GCOL 128 + COL_BORDERS a$ = " " + m$(I%) U% = INSTR(a$,"&") IF U% a$ = LEFT$(a$,U%-1) + MID$(a$,U%+1) IF m%(I%) = 0 THEN PLOT 0,0,-10 : PLOT 3,W%,0 : PLOT 0,-W%,-10 ELSE T% = INSTR(a$,CHR$9) IF T% THEN PRINT LEFT$(a$,T%-1); VDU 13 : PLOT 0,L%,0 : PRINT MID$(a$,T%+1) ELSE PRINT a$ ENDIF IF U% THEN T% = FN_stringwidth(LEFT$(a$,U%-1)) U% = FN_stringwidth(MID$(a$,U%,1)) - 2 PLOT 0,T%,4 PLOT 1,U%,0 PLOT 0,-(T%+U%),-4 ENDIF IF m%(I%) AND &2000 THEN N% = @vdu%!220 DIV 2 VDU 23,23,3| PLOT 0,N%*2,N%*2 PLOT 9,N%,-N% VDU 23,23,2| PLOT 9,N%,N%*2 + 4 PLOT 0,-N%*4,-N%*3 - 4 VDU 23,23,1| ENDIF IF I% = S% THEN GCOL 2,128 + COL_HILITEAND PLOT 99,W%,@vdu%!220*2 GCOL 1,128 + COL_HILITEOR PLOT 99,-W%,-@vdu%!220*2 GCOL 0,128 + COL_SELECT PLOT 3,0,@vdu%!220*2 : PLOT 3,W%,0 PLOT 3,0,-@vdu%!220*2 : PLOT 3,-W%,0 ENDIF IF m%(I%) AND &1000 THEN IF Darkmode% GCOL 2,128 + COL_DISABLED ELSE GCOL 1,128 + COL_DISABLED PLOT 99,W%,@vdu%!220*2 PLOT 0,-W%,-@vdu%!220*2 ENDIF ENDIF NEXT *REFRESH N% = DIM(m%(),1) + 1 K% = INKEY(4) CASE K% OF WHEN 13: IF S% >= 0 IF (m%(S%) AND &1000) = 0 S% = m%(S%) AND &FFF : EXIT REPEAT WHEN 27: S% = 0 : EXIT REPEAT WHEN 136: S% = -136 : EXIT REPEAT WHEN 137: S% = -137 : EXIT REPEAT WHEN 138: REPEAT S% = (S% + N% + 1) MOD N% : UNTIL m%(S%) WHEN 139: REPEAT S% = (S% + N% + (S%>=0)) MOD N% : UNTIL m%(S%) OTHERWISE: FOR I% = 0 TO N% - 1 a$ = m$(I%) U% = INSTR(a$,"&") IF U% IF (m%(I%) AND &1000) = 0 THEN T% = ASCMID$(a$, U%+1) IF (K% AND &5F) = (T% AND &5F) S% = m%(I%) AND &FFF : EXIT REPEAT IF INKEY(-InKey&(T% AND &3F)) IF TIME > Z% S% = m%(I%) AND &FFF : EXIT REPEAT ENDIF NEXT ENDCASE MOUSE I%, T%, B% IF I%<>P% OR T%<>Q% THEN P% = I% : Q% = T% IF Q% > Y% THEN N% = FNhotspot(P%, Q%) IF N% >= 0 IF N% < D% S% = -136 : EXIT REPEAT IF N% >= 0 IF N% > D% S% = -137 : EXIT REPEAT ENDIF IF P% > X% IF P% < X%+W% IF Q% < Y% IF Q% > Y%-H% THEN T% = Y% : N% = 0 FOR I% = 0 TO DIM(m$(),1) IF Q% > T% - 2*@vdu%!220 IF Q% < T% S% = I% IF m%(I%) = 0 T% -= 20 ELSE T% -= 2*@vdu%!220 : N% += 1 NEXT ELSE S% = -1 ENDIF ENDIF IF click% THEN click% = FALSE IF S% >= 0 THEN IF (m%(S%) AND &1000) = 0 S% = m%(S%) AND &FFF : EXIT REPEAT ELSE S% = 0 EXIT REPEAT ENDIF ENDIF IF S% <> O% THEN O% = S% VDU 24,0;0;@vdu%!208*2-2;@vdu%!212*2-2; IF S% >= 0 THEN PROCdrawstatusbar(m%(S%) AND &FFF, FALSE, FALSE) ELSE PROCdrawstatusbar(D% - IDMENU1 + 1, FALSE, FALSE) ENDIF ENDIF UNTIL FALSE *REFRESH ON VDU 24,0;0;@vdu%!208*2-2;@vdu%!212*2-2; IF S% >= -1 PROCdrawstatusbar(0, FALSE, FALSE) OSCLI "FONT " + EditFont$ OSCLI "DISPLAY """ + @tmp$ + "bbc" + Session$ + ".tmp.bmp" + """ " + STR$X% + "," + STR$(Y%-H%) VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0;5 : REM Set cursor width IF D% = IDPOPUP PROCcursor(1) Refresh% = TRUE : REM To reset caret = S% DEF FNcombo(m$(), N%, X%, Y%, W%) LOCAL A%, B%, C%, D%, H%, I%, K%, L%, M%, P%, Q%, R%, S%, T%, U%, click% LOCAL sb{} : DIM sb{} = ScrlBarV{} ON TIME LOCAL OFF ON MOUSE LOCAL click% = TRUE : RETURN OSCLI "FONT " + GUIFont$ C% = @vdu%!220 * 2 H% = N% * C% + 8 IF (Y% - H%) < C% H% = Y% - C% W% = (W% + 1) AND -2 : REM must be even sb.l% = X% + W% - SCROLLBARSIZE sb.t% = Y% - SCROLLBARSIZE + 2 sb.r% = X% + W% - 4 sb.b% = Y% - H% + SCROLLBARSIZE OSCLI "GSAVE """ + @tmp$ + "bbc" + Session$ + ".tmp.bmp" + """ " + STR$X% + "," + STR$(Y%-H%) + \ \ "," + STR$(W%+2) + "," + STR$(H%+2) VDU 24,X%;Y%-H%+2;X%+W%-2;Y%-2;5 M% = H% DIV C% S% = 0 L% = 0 MOUSE P%, Q%, B% REPEAT *REFRESH OFF PROCcursor(0) GCOL COL_GUITEXT GCOL 128 + COL_EDITPANE VDU 16,30,23,16,64| FOR I% = L% + 1 TO L% + M% IF I% > DIM(m$(),1) EXIT FOR GCOL COL_GUITEXT PRINT " " m$(I%) IF I% = S% THEN GCOL 2,128 + COL_HILITEAND PLOT 99,W%,C% GCOL 1,128 + COL_HILITEOR PLOT 99,-W%,-C% GCOL 0,128 + COL_SELECT PLOT 3,0,C% : PLOT 3,W%,0 PLOT 3,0,-C% : PLOT 3,-W%,0 ENDIF NEXT sb.max% = N% * C% sb.pos% = L% * C% sb.page% = M% * C% PROC_drawscrollbar(0, sb{}) RECTANGLE X%, Y% - 2, W% - 2, -H% + 6 LINE sb.l%-2, Y%, sb.l%-2, Y%-H% MOUSE I%, T%, B% IF B% = 0 D% = 0 : A% = 0 IF I%<>P% OR T%<>Q% THEN IF D% = 2 THEN A% += (T% - Q%) * sb.scale ELSE A% = 0 ENDIF P% = I% : Q% = T% IF D% = 0 THEN P% = I% : Q% = T% IF P% > X% IF P% < X%+W%-SCROLLBARSIZE THEN T% = Y% FOR I% = L% TO L% + M% IF Q% > T% IF Q% < T% + C% THEN S% = I% IF S% < 1 S% = 1 IF S% > N% S% = N% WHILE S% <= L% L% -= 1 : ENDWHILE WHILE S% > (L% + M%) L% += 1 : ENDWHILE ENDIF T% -= C% NEXT ENDIF ENDIF IF P% < X% OR P% > X%+W% OR Q% > Y% OR Q% < Y%-H% S% = 0 ENDIF WHILE A% > C% L% -= 1 : A% -= C% : ENDWHILE WHILE A% < 0 L% += 1 : A% += C% : ENDWHILE IF L% > N% - M% L% = N% - M% IF L% < 0 L% = 0 I% = P% : T% = Q% IF D% = 2 I% = (sb.l% + sb.r%) DIV 2 : T% = (sb.thumb.t% + sb.thumb.b%) DIV 2 B% = FN_sbhotspot(0, sb{}, I%, T%) IF B% >= 0 THEN S% = 0 PROC_sbhotspot(B%, sb{}, I%, T%, R%, U%) IF R% IF U% THEN GCOL 2, COL_HILITEAND RECTANGLE FILL I%, T%, R%, U% GCOL 1, COL_HILITEOR RECTANGLE FILL I%, T%, R%, U% ENDIF ENDIF *REFRESH IF click% THEN click% = FALSE CASE B% OF WHEN 0,1,3,4: D% = 1 RepTimer% = 0 WHEN 2: D% = 2 RepTimer% = 0 OTHERWISE: EXIT REPEAT ENDCASE ENDIF IF D% IF RepTimer% = 0 OR RepTimer% > 8 THEN CASE B% OF WHEN 0: L% -= 1 : IF L% < 0 L% = 0 WHEN 1: L% -= M% : IF L% < 0 L% = 0 WHEN 3: L% += M% : IF L% > N% - M% L% = N% - M% WHEN 4: L% += 1 : IF L% > N% - M% L% = N% - M% ENDCASE ENDIF RepTimer% += 1 K% = INKEY(4) CASE K% OF WHEN 13: EXIT REPEAT WHEN 27: S% = 0 : EXIT REPEAT WHEN 138: S% = (S% + N%) MOD N% + 1 WHEN 139: S% = (S% + N% - 2) MOD N% + 1 WHEN 140: L% += 1 : IF L% > N% - M% L% = N% - M% WHEN 141: L% -= 1 : IF L% < 0 L% = 0 WHEN 132: L% -= M% : IF L% < 0 L% = 0 WHEN 133: L% += M% : IF L% > N% - M% L% = N% - M% ENDCASE IF K% <> -1 IF K% < 140 IF K% > 133 THEN WHILE S% <= L% L% -= 1 : ENDWHILE WHILE S% > (L% + M%) L% += 1 : ENDWHILE ENDIF UNTIL FALSE OSCLI "FONT " + EditFont$ OSCLI "DISPLAY """ + @tmp$ + "bbc" + Session$ + ".tmp.bmp" + """ " + STR$X% + "," + STR$(Y%-H%) VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width VDU 24,0;0;@vdu%!208*2-2;@vdu%!212*2-2;4 Refresh% = TRUE : REM To reset caret = S% DEF FNfileselector(t$) LOCAL C%, H%, W%, X%, Y%, a$, d$ ON TIME LOCAL OFF ON MOUSE LOCAL OFF OSCLI "FONT " + GUIFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width OFF IF INSTR(t$,"Save") THEN PROC_setdialogtitle(FileDlg%, t$) PROC_setdlgitemtext(FileDlg%, 1, "Save") PROC_showdlgitem(FileDlg%, 106, 1) PROC_showdlgitem(FileDlg%, 107, 1) PROC_showdlgitem(FileDlg%, 108, 0) PROC_showdlgitem(FileDlg%, 109, 0) IF FN_lower(RIGHT$(CurrentFile$, 4)) = ".bbc" OR CurrentFile$ = "" THEN PROC_checkdlgitem(FileDlg%, 106, 1) PROC_checkdlgitem(FileDlg%, 107, 0) ELSE PROC_checkdlgitem(FileDlg%, 106, 0) PROC_checkdlgitem(FileDlg%, 107, 1) ENDIF ELSE PROC_setdialogtitle(FileDlg%, t$) PROC_setdlgitemtext(FileDlg%, 1, "Open") PROC_showdlgitem(FileDlg%, 106, 0) PROC_showdlgitem(FileDlg%, 107, 0) PROC_showdlgitem(FileDlg%, 108, 1) PROC_showdlgitem(FileDlg%, 109, 1) PROC_checkdlgitem(FileDlg%, 106, 0) PROC_checkdlgitem(FileDlg%, 107, 0) PROC_checkdlgitem(FileDlg%, 108, 1) PROC_checkdlgitem(FileDlg%, 109, 0) ENDIF a$ = FNgetcwd + RIGHT$(@lib$) PROC_setdlgitemtext(FileDlg%, 102, a$) PROC_registerdlgcallback(FileDlg%, FNfscb()) X% = &80000000 : Y% = &80000000 REPEAT C% = FN_showdialogex(FileDlg%, X%, Y%, Darkmode%) PROC_getdlgrect(FileDlg%, X%, Y%, W%, H%) a$ = FN_getdlgitemtext(FileDlg%, 104) d$ = FN_getdlgitemtext(FileDlg%, 102) UNTIL C% = 1 OR C% = 2 PROC_closedialog(FileDlg%) IF FN_isdlgitemchecked(FileDlg%, 106) IF FN_lower(RIGHT$(a$,4)) <> ".bbc" a$ += ".bbc" IF FN_isdlgitemchecked(FileDlg%, 107) IF FN_lower(RIGHT$(a$,4)) <> ".bas" a$ += ".bas" IF INSTR(a$,".") = 0 a$ += "." PROC_closedialog(FileDlg%) OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width Refresh% = TRUE : REM To reset caret IF C% = 2 THEN = "" IF ASCa$ = &2F OR ASCa$ = &5C THEN = a$ = d$ + a$ DEF FNfscb(D%,K%) LOCAL N%, R%, a$, t$ PRIVATE B%, E%, F%, T%, d$, f$, s$, n$() DIM n$(10000) IF F% <> FN_isdlgitemchecked(D%,109) THEN F% = NOT F% d$ = "" ENDIF a$ = FN_getdlgitemtext(D%,102) IF a$ <> d$ IF RIGHT$(a$) = "/" OR RIGHT$(a$) = "\" THEN d$ = a$ ON ERROR LOCAL IF FALSE THEN OSCLI "cd """ + a$ + """" IF FN_isdlgitemchecked(D%,109) THEN N% = FNdirscan(n$(), "dir *.*", "", Folder$, BBfile$) ELSE N% = FNdirscan(n$(), "dir *.*", ".bas;.bbc", Folder$, BBfile$) ENDIF PROC_setdlgitemtext(D%, 102, n$(0)) ELSE N% = 3 ENDIF : RESTORE ERROR PROC_setlistboxarray(D%, IDlistbox%, n$(), N%) IF FN_getdlgitemtext(D%, 1) = "Open" THEN PROC_setdlgitemtext(D%, 104, "") ENDIF PROC_setlistboxselect(D%, IDlistbox%, -1) PROC_refreshdialog(D%) ENDIF a$ = FN_getdlgitemtext(D%,IDlistbox%) IF a$ <> s$ THEN s$ = a$ IF LEFT$(a$, LEN(BBfile$)) = BBfile$ THEN PROC_setdlgitemtext(D%, 104, FN_trim(MID$(a$, LEN(BBfile$) + 1))) PROC_refreshdialog(D%) ENDIF ENDIF a$ = FN_getdlgitemtext(D%,104) IF a$ <> f$ IF a$ <> "" THEN f$ = a$ IF BBfile$ + a$ <> FN_getdlgitemtext(D%, IDlistbox%) THEN N% = FNchops(n$(), BBfile$ + a$) + 1 PROC_setlistboxselect(D%, IDlistbox%, N%) PROC_refreshdialog(D%) s$ = n$(N%) ENDIF ENDIF IF E% <> (a$ = "") THEN E% = (a$ = "") PROC_enabledlgitem(D%,1,NOT E%) PROC_refreshdialog(D%) ENDIF t$ = a$ N% = FNinstrr(t$, ".", 0) IF N% = 0 B% = 0 : T% = 0 IF B% <> FN_isdlgitemchecked(D%,106) THEN B% = NOT B% IF B% t$ = LEFT$(t$, N%-1) + ".bbc" : f$ = t$ ENDIF IF T% <> FN_isdlgitemchecked(D%,107) THEN T% = NOT T% IF T% t$ = LEFT$(t$, N%-1) + ".bas" : f$ = t$ ENDIF IF a$ <> t$ IF a$ <> "" THEN PROC_setdlgitemtext(D%, 104, t$) PROC_refreshdialog(D%) ENDIF R% = FN_getdlgfocus(D%) : IF R% > 9 R% = 1 IF K% = 27 THEN = 2 IF NOT E% IF K% = 13 THEN = R% = 0 DEF PROClistclick(D%, I%) LOCAL a$, d$, t$ t$ = FN_getdlgitemtext(D%, I%) a$ = FN_trim(MID$(t$, LEN(BBfile$) + 1)) d$ = FN_getdlgitemtext(D%, 102) IF a$ = "" ENDPROC IF LEFT$(t$, LEN(BBfile$)) = BBfile$ THEN PROC_setdlgitemtext(D%, 104, a$) ELSE IF ASC(a$) = &40 a$ = EVAL(a$) ELSE a$ = d$ + a$ + RIGHT$(@lib$) PROC_setdlgitemtext(D%, 102, a$) PROC_setlistboxselect(D%, I%, 0) ENDIF PROC_refreshdialog(D%) ENDPROC REM Scan a directory and return list of directory and file names REM icon1$ is a directory prefix, icon2$ is a file prefix DEF FNdirscan(name$(), dircmd$, filter$, icon1$, icon2$) LOCAL C%, F%, I%, N%, a$, d$, type&() DIM type&(DIM(name$(),1)) REM Spool *DIR output to a temporary file: WIDTH 20 VDU 21 ON ERROR LOCAL IF FALSE THEN OSCLI "spool """ + @tmp$ + "dir.tmp.txt""" OSCLI dircmd$ ENDIF : RESTORE ERROR *spool VDU 6 WIDTH 0 REM Parse the file to extract directory names and filenames. REM Cope with long filenames if they have split between lines N% = 0 type&() = 0 name$() = "" F% = OPENIN(@tmp$ + "dir.tmp.txt") REPEAT INPUT #F%,a$ IF ASCa$ = &A a$ = MID$(a$,2) IF LEFT$(a$,2)=" " OR LEFT$(a$,2)="* " OR EOF#F% IF a$<>STRING$(20," ") THEN IF N% = 0 THEN d$ = name$(0) C% = FN_instrr(d$, "/", 0) : IF C% IF MID$(d$, C% - 1, 1) = "/" C% -= 1 IF C% = 0 C% = FN_instrr(d$, "\", 0) : IF MID$(d$, C% - 1, 1) = "\" C% -= 1 name$(0) = MID$(d$, 14, C% - 13) N% += 1 : REM Zeroth index holds directory name ELSE name$(N%) = FN_trim(name$(N%)) d$ = FN_lower(name$(N%)) ON ERROR LOCAL IF FALSE THEN OSCLI "cd """ + name$(0) + name$(N%) + """" OSCLI "cd """ + name$(0) + """" IF d$<>"." IF d$<>".." IF filter$="" OR ASCd$<>&2E type&(N%) = 1 : N% += 1 ELSE IF filter$="" OR INSTR(filter$,RIGHT$(d$,4)) type&(N%) = 2 : N% += 1 ENDIF : RESTORE ERROR ENDIF name$(N%) = MID$(a$,3) ELSE name$(N%) += a$ ENDIF UNTIL EOF#F% OR N% >= DIM(name$(),1) CLOSE #F% IF icon1$ <> "" THEN IF N% < DIM(name$(),1) name$(N%) = "@lib$" : type&(N%) = 0 : N% += 1 IF N% < DIM(name$(),1) name$(N%) = "@usr$" : type&(N%) = 0 : N% += 1 name$(N%) = ".." : type&(N%) = 0 : N% += 1 ENDIF N% -= 1 REM Sort the array so directories are listed before programs: C% = N% CALL Sort%%, type&(1), name$(1) REM Add icons: FOR I% = 1 TO N% IF type&(I%) = 2 name$(I%) = icon2$ + name$(I%) ELSE name$(I%) = icon1$ + name$(I%) NEXT = N% REM!Eject -------------------------------------------------------------------------- DEF __Helper_Routines__ DEF PROCinsert(f$(), i%(), RETURN cx%, cy%, k$) LOCAL a$, l$, r$, I% I% = i%(cy%) a$ = FNformat(f$(cy%), I%) PROCsplitx(a$, cx%, l$, r$) cx% += FNlen(k$) PROCreformat(l$ + k$ + r$, cx%, cy%, f$(), i%(), FALSE) ENDPROC DEF PROCovertype(f$(), i%(), RETURN cx%, cy%, k$) LOCAL a$, l$, r$, I% I% = i%(cy%) a$ = FNformat(f$(cy%), I%) PROCsplitx(a$, cx%, l$, r$) PROCsplitx(a$, cx% + LENk$, a$, r$) cx% += FNlen(k$) PROCreformat(l$ + k$ + r$, cx%, cy%, f$(), i%(), FALSE) ENDPROC DEF PROCundosave(f$(), b&(), nl%, RETURN ul%, RETURN rl%, cx%, cy%) LOCAL F% PROCredoclear(ul%, rl%) F% = OPENOUT(@tmp$ + "undo" + Session$ + STR$ul% + ".tmp.bbc") BPUT#F%, SUM(f$()); b&(DIM(b&(),1)) = &D BPUT#F%,0 : PRINT #F%, cx%, cy%, LEFT$($^b&(0), nl%) CLOSE #F% ul% += 1 ENDPROC DEF PROCundoclear(RETURN ul%, RETURN rl%) PROCredoclear(ul%, rl%) WHILE ul% ul% -= 1 OSCLI "DEL """ + @tmp$ + "undo" + Session$ + STR$ul% + ".tmp.bbc""" ENDWHILE ENDPROC DEF PROCredoclear(ul%, RETURN rl%) IF rl% THEN WHILE rl% >= ul% OSCLI "DEL """ + @tmp$ + "undo" + Session$ + STR$rl% + ".tmp.bbc""" rl% -= 1 ENDWHILE rl% = 0 ENDIF ENDPROC DEF PROCsetpalette LOCAL C%, I%, key$ IF Darkmode% THEN key$ = "dark" Colours%() = &FFC000, &FF80FF, &FF0000, &80C000, &0080FF, &FFFFFF COLOR COL_GUITEXT, &FF, &FF, &FF : REM GUI text colour (white) COLOR COL_GUIBKGD, &40, &40, &40 : REM Primary GUI background colour COLOR COL_BORDERS, &80, &80, &80 : REM Primary GUI foreground colour COLOR COL_DISABLED, &7F, &7F, &7F : REM Disabled menus/buttons (ANDed) COLOR COL_PRESSED, &60, &60, &60 : REM Pressed buttons (ORed) COLOR COL_HILITEAND, &FF, &FF, &FF : REM Hotspot highlight AND (first) COLOR COL_HILITEOR, &00, &7F, &7F : REM Hotspot highlight OR (second) COLOR COL_SELECT, &00, &7F, &FF : REM Selected text background COLOR COL_ICONS, &C0, &C0, &00 : REM Folder and BBfile icon yellow COLOR COL_EDITPANE, &10, &10, &10 : REM Edit background & scrollbars ELSE key$ = "colour" Colours%() = &FF8000, &FF00FF, &FF0000, &008000, &0000FF, &000000 COLOR COL_GUITEXT, &00, &00, &00 : REM GUI text colour (black) COLOR COL_GUIBKGD, &F0, &F0, &F0 : REM Primary GUI background colour COLOR COL_BORDERS, &80, &80, &80 : REM Primary GUI foreground colour COLOR COL_DISABLED, &B0, &B0, &B0 : REM Disabled menus/buttons (ORed) COLOR COL_PRESSED, &D0, &D0, &D0 : REM Pressed buttons (ANDed) COLOR COL_HILITEAND, &80, &E0, &FF : REM Hotspot highlight AND (first) COLOR COL_HILITEOR, &00, &1F, &3F : REM Hotspot highlight OR (second) COLOR COL_SELECT, &00, &80, &FF : REM Selected text background COLOR COL_ICONS, &C0, &C0, &00 : REM Folder and BBfile icon yellow COLOR COL_EDITPANE, &FF, &FF, &FF : REM Edit background & scrollbars ENDIF FOR I% = 1 TO 6 C% = VALFNgetINIstring(IniFile$, key$ + STR$(I%), STR$(Colours%(I%-1))) Colours%(I%-1) = C% IF Colouring% THEN COLOR I%, (C% AND &FF0000) >> 16, (C% AND &FF00) >> 8, C% AND &FF ELSE IF Darkmode% COLOR I%, &FF, &FF, &FF ELSE COLOR I%, 0, 0, 0 ENDIF NEXT ENDPROC REM Search program for a given string: DEF FNsearch(s$, f$(), i%(), nl%, fl%, RETURN ax%, RETURN ay%, RETURN cx%, RETURN cy%) LOCAL a$, C%, I%, M%, W%, Y% W% = (fl% AND &10000) <> 0 C% = (fl% AND &20000) <> 0 IF NOT C% s$ = FN_lower(s$) Y% = cy% I% = i%(Y%) REPEAT a$ = FNstrip(FNformat(f$(Y%), I%)) IF NOT C% a$ = FN_lower(a$) IF Y% = cy% M% = cx% ELSE M% = 0 REPEAT IF Unicode% M% = FN_upos(a$, M%) M% = INSTR(a$, s$, M%+1) IF M% THEN IF W% IF INSTR(Valid$,(MID$(a$,M%-1,1))) OR INSTR(Valid$,MID$(a$,M%+LENs$,1)) THEN ELSE a$ = LEFT$(a$, M%-1) M% += FNlen(a$) - LEN(a$) : REM UTF-8 adjustment ax% = M%-1 : ay% = Y% cx% = M%+FNlen(s$)-1 : cy% = Y% = TRUE ENDIF ENDIF UNTIL M%=0 Y% += 1 UNTIL Y% >= nl% = FALSE REM Return selected text: DEF FNseltext(f$(), i%(), x1%, y1%, x2%, y2%) LOCAL I%, Y%, a$, b$ IF x1% > x2% SWAP x1%,x2% IF y1% > y2% SWAP y1%,y2% CASE TRUE OF WHEN y1% <> y2%: FOR Y% = y1% TO y2%-1 I% = i%(Y%) a$ += FNstrip(FNformat(f$(Y%), I%)) + CHR$&D + CHR$&A NEXT WHEN x1% <> x2%: I% = i%(y1%) a$ = FNformat(f$(y1%), I%) PROCsplitx(a$, x1%, b$, a$) PROCsplitx(a$, x2%-x1%, a$, b$) a$ = FNstrip(a$) ENDCASE = a$ REM Test if clipboard text is available: DEF FNhascliptext LOCAL F% IF BB4W% THEN SYS "IsClipboardFormatAvailable", 1 TO F% ELSE IF (@platform% AND &F) <> 5 THEN; SYS "SDL_HasClipboardText" TO F% ENDIF = F% <> 0 REM Test if all selected lines begin with REM DEF FNisallrems(f$(), cy%, ay%) LOCAL F%,I% IF ay% = cy% THEN = FALSE IF ay% < cy% SWAP ay%,cy% F% = TRUE FOR I% = cy% TO ay%-1 IF ASCMID$(f$(I%), 4) <> &F4 F% = FALSE NEXT = F% DEF FNisfnproc(f$(), i%(), X%, Y%, N%, RETURN I%) LOCAL A%, a$, f$ PROCpointtochar(X%, Y%) I% = i%(Y%) f$ = FNstrip(FNformat(f$(Y%), I%)) FOR I% = 0 TO N%-1 IF ASCMID$(f$(I%),4)=&DD THEN A% = 0 a$ = MID$(FNstrip(FNformat(f$(I%),A%)),7) a$ = MID$(a$,4) A% = INSTR(a$,"(") : IF A% a$ = LEFT$(a$,A%) A% = INSTR(a$,":") : IF A% a$ = LEFT$(a$,A%-1) a$ = FN_trim(a$) A% = INSTR(f$, a$) IF RIGHT$(a$) <> "(" IF MID$(f$, A%+LENa$, 1) = "(" A% = 0 IF RIGHT$(a$) = "(" a$ += ")" ELSE IF INSTR(Valid$ + "@_`", MID$(f$, A% + LENa$, 1)) A% = 0 IF A% IF X% >= A% IF X% < (A% + LENa$) THEN = a$ ENDIF NEXT I% = -1 = "" DEF PROCsavejump(goback%(), scrolly%, RETURN glevel%) LOCAL I% goback%(glevel%) = scrolly% IF glevel% < DIM(goback%(),1) THEN glevel% += 1 ELSE FOR I% = 0 TO glevel%-1 goback%(I%) = goback%(I%+1) NEXT ENDIF ENDPROC DEF PROCexecute(bbcfile$, flag$) ON ERROR LOCAL IF FALSE THEN IF BB4W% THEN OSCLI "RUN """ + @lib$ + "..\bbcwrun6.exe"" """ + bbcfile$ + """ " + flag$ + ";" ELSE CASE @platform% AND &F OF WHEN 0: SYS "WinExec", """" + @lib$ + "..\bbcsdl"" """ + bbcfile$ + """ " + flag$, 1 OTHERWISE: OSCLI "RUN """ + @lib$ + "../bbcsdl"" """ + bbcfile$ + """ " + flag$ + ";" ENDCASE ENDIF ENDIF : RESTORE ERROR ENDPROC DEF PROCopenurl(url$) IF BB4W% THEN SYS "ShellExecute", @hwnd%, "open", url$, 0, 0, 1 ELSE CASE @platform% AND &F OF WHEN 0: SYS "WinExec", "cmd /cstart " + url$ + "&", 0 WHEN 1: SYS "system", "xdg-open " + url$ + "&" WHEN 2: SYS "system", "open " + url$ + "&" WHEN 5: SYS "emscripten_run_script_string", "window.open(""" + url$ + """, ""_blank"")", @memhdc% ENDCASE ENDIF ENDPROC DEF PROCtitle(name$) name$ += " - " + Title$ IF BB4W% THEN SYS "SetWindowText", @hwnd%, name$ ELSE SYS "SDL_SetWindowTitle", @hwnd%, name$, @memhdc% ENDIF ENDPROC DEF PROCload(file$, RETURN nl%, RETURN ml%, in%) LOCAL B%, F%, H%, I%, L%, N%, T%, a$ F% = FN_instrr(file$, ".", 0) B% = FN_instrr(file$, "/", 0) : IF B% = 0 B% = FN_instrr(file$, "\", 0) IF F% <= B% file$ += ".bbc" F% = OPENIN(file$) IF F% = 0 THEN PROCmessagebox("SDLIDE", "Couldn't open file '" + file$ + "'", 0) ENDPROC ENDIF ON TIME LOCAL OFF : REM Prevent mouse cursor change IF in% THEN LOCAL t$() DIM t$(nl% - CaretY%) FOR I% = 0 TO nl% - CaretY% SWAP t$(I%), Buffer$(CaretY% + I%) NEXT I% = CaretY% N% = Indent%(I%) ELSE ml% = 0 Buffer$() = "" Indent%() = 0 ENDIF PROCcursor(2) T% = SGN(FNvalidbbc(F%) - FNvalidacorn(F%)) IF T% = TRUE B% = BGET#F% WHILE NOT EOF#F% CASE T% OF WHEN +1: B% = BGET#F% : IF B% = 0 Buffer$(I%) = "" : EXIT WHILE Buffer$(I%) = CHR$B% + GET$#F% BY (B%-1) WHEN -1: H% = BGET#F% : IF H% = &FF Buffer$(I%) = "" : EXIT WHILE L% = BGET#F% : B% = BGET#F% : a$ = GET$#F% BY (B%-3) WHILE ASCa$=&20 a$ = MID$(a$,2) : B% -= 1 : ENDWHILE IF FNinstrq(a$, CHR$&7F, 1) OR FNinstrq(a$, CHR$&CC, 1) a$ = FNacorntoken1(a$) IF FNinstrq(a$, CHR$&C6, 1) OR FNinstrq(a$, CHR$&C8, 1) a$ = FNacorntoken2(a$, B%) IF FNinstrq(a$, "BY", 1) a$ = FNacorntoken3(a$) Buffer$(I%) = CHR$B% + CHR$L% + CHR$H% + a$ OTHERWISE: a$ = GET$#F% IF a$="" IF PTR#F%>1 THEN PTR#F%=PTR#F%-2 : IF BGET#F%<>BGET#F% a$ = GET$#F% REPEAT H% = INSTR(a$,CHR$9) : IF H% MID$(a$,H%,1) = " " UNTIL H% = 0 IF a$<>"" IF ASCa$<&20 PROCmessagebox("SDLIDE", "Invalid file format", 0) : EXIT WHILE IF EOF#F% IF a$ = "" Buffer$(I%) = "" : EXIT WHILE Buffer$(I%) = FNtokenise(a$) ENDCASE Indent%(I%) = N% PROCindent(Buffer$(I%), N%, ml%) I% += 1 ENDWHILE CLOSE #F% IF in% THEN FOR B% = 0 TO nl% - CaretY% Buffer$(I%) = t$(B%) Indent%(I%) = N% PROCindent(Buffer$(I%), N%, ml%) I% += 1 NEXT PROCcursor(0) ENDIF nl% = I% WHILE I% <= DIM(Indent%(),1) Indent%(I%) = N% I% += 1 ENDWHILE IF in% ENDPROC F% = 0 FOR I% = 0 TO nl% - 1 F% OR= FNansi_or_utf8(Buffer$(I%)) NEXT IF Unicode% THEN IF F% = 1 IF FNmessagebox("SDLIDE", "Switching to ANSI", 1) = 1 Unicode% = FALSE ELSE IF F% = 2 IF FNmessagebox("SDLIDE", "Switching to Unicode", 1) = 1 Unicode% = TRUE ENDIF F% = FNinstrr(file$, "/", 0) IF F% = 0 F% = FNinstrr(file$, "\", 0) IF F% = 0 THEN file$ = FNgetcwd + RIGHT$(@lib$) + file$ ELSE OSCLI "cd """ + LEFT$(file$, F%-1) + """" ENDIF CurrentFile$ = file$ PROCtitle(CurrentFile$) PROCupdaterecent(CurrentFile$) IF T% = TRUE CurrentFile$ = "" : REM Disable 'Save' if Acorn format PROCundoclear(UndoLevel%, RedoLevel%) PROCcursor(0) ENDPROC DEF FNsave(file$) LOCAL F%, I%, N% F% = OPENOUT(file$) IF F% = 0 THEN PROCmessagebox("SDLIDE", "Couldn't create file '" + file$ + "'", 0) = FALSE ENDIF IF FN_lower(RIGHT$(file$,4)) = ".bbc" THEN BPUT#F%, SUM(Buffer$()); BPUT#F%, 0 BPUT#F%, &FF BPUT#F%, &FF ELSE I% = Indent%(0) FOR N% = 0 TO nLines% - 1 PRINT #F%, FNstrip(FNformat(Buffer$(N%), I%)) BPUT #F%, 10 NEXT ENDIF CLOSE #F% = TRUE DEF FNgetcwd LOCAL F%, a$, f$ f$ = @tmp$ + "cwd.tmp.txt" VDU 21 OSCLI "spool """ + f$ + """" ON ERROR LOCAL IF FALSE THEN *cd ENDIF : RESTORE ERROR *spool VDU 6 F% = OPENIN(f$) a$ = FNstrip(GET$#F%) CLOSE #F% = a$ DEF FNnopath(f$) LOCAL N% N% = FNinstrr(f$, "/", 0) IF N%=0 N% = FNinstrr(f$, "\", 0) IF N% f$ = MID$(f$, N%+1) = f$ DEF FNpath(f$) LOCAL N% N% = FNinstrr(f$, "/", 0) IF N%=0 N% = FNinstrr(f$, "\", 0) = LEFT$(f$, N%) DEF FNnoext(f$) LOCAL N% N% = FNinstrr(f$, ".", 0) = LEFT$(f$, N%-1) DEF FNvalidbbc(F%) LOCAL L%, P% REPEAT L% = BGET#F% IF L%=0 THEN PTR#F% = 0 : = P% P% += L% PTR#F% = P% - 1 UNTIL BGET#F%<>&D OR EOF#F% PTR#F% = 0 = FALSE DEF FNvalidacorn(F%) LOCAL L%, P% : L% = 1 WHILE BGET#F%=&D AND L%<>0 AND NOT EOF#F% IF BGET#F%=&FF THEN PTR#F% = 0 : = P% L% = BGET#F% : L% = BGET#F% P% += L% PTR#F% = P% ENDWHILE PTR#F% = 0 = FALSE DEF FNacorntoken1(a$) LOCAL I% REPEAT I% = FNinstrq(a$, CHR$&CC, I% + 1) : IF I% MID$(a$, I%, 1) = CHR$&8B : REM multiline ELSE UNTIL I% = 0 REPEAT I% = FNinstrq(a$, CHR$&7F, I% + 1) : IF I% MID$(a$, I%, 1) = CHR$&CC : REM OTHERWISE UNTIL I% = 0 = a$ DEF FNacorntoken2(a$, RETURN B%) LOCAL I%, T% REPEAT I% = FNinstrq(a$, CHR$&C6 + CHR$&8E, I% + 1) IF I% a$ = LEFT$(a$, I%) + MID$(a$, I% + 2) : B% -= 1 : REM SUM UNTIL I% = 0 REPEAT I% = FNinstrq(a$, CHR$&C8, I% + 1) IF I% THEN T% = ASCMID$(a$, I% + 1, 1) - &8E IF T% >= 0 IF T% <= 15 THEN a$ = LEFT$(a$, I% - 1) + CHR$Acorn&(T%) + MID$(a$, I% + 2) : B% -= 1 ENDIF ENDIF UNTIL I% = 0 = a$ DEF FNacorntoken3(a$) LOCAL I%, J% REPEAT I% = FNinstrq(a$, "BY", I% + 1) IF I% THEN J% = I% : REPEAT J% -= 1 UNTIL MID$(a$, J%, 1) <> " " IF INSTR(CHR$&DF + CHR$&03 + CHR$&EC + CHR$&F0, MID$(a$, J%, 1)) THEN a$ = LEFT$(a$, I% - 1) + CHR$(&0F) + " " + MID$(a$, I% + 2) : REM BY ENDIF ENDIF UNTIL I% = 0 =a$ DEF PROCdebugcmd(W%, L%) LOCAL F% REPEAT F% = OPENOUT(@tmp$ + "sdldebug.cmd") IF F% = 0 WAIT RND(3) UNTIL F% BPUT#F%,W% : BPUT#F%,W% >> 8 : BPUT#F%,W% >> 16 : BPUT#F%,W% >> 24 BPUT#F%,L% : BPUT#F%,L% >> 8 : BPUT#F%,L% >> 16 : BPUT#F%,L% >> 24 CLOSE #F% ENDPROC DEF PROChilite(N%) LOCAL H%, I%, W%, X%, Y% PROChotspot(N%, X%, Y%, W%, H%) IF POS REM SDL thread sync. LOCAL @vdu%!64, @vdu.l.x%, @vdu.l.y%, @vdu.p.x%, @vdu.p.y% *REFRESH OFF IF Darkmode% THEN OSCLI "DISPLAY """+@dir$+"SDLIDEdark"" 0," + STR$INT(2*@vdu%!212 - BMPHEIGHT) + \ \ "," + STR$INT(BMPWIDTH) + "," + STR$INT(BMPHEIGHT) ELSE OSCLI "DISPLAY """+@dir$+"SDLIDE"" 0," + STR$INT(2*@vdu%!212 - BMPHEIGHT) + \ \ "," + STR$INT(BMPWIDTH) + "," + STR$INT(BMPHEIGHT) ENDIF GCOL COL_EDITPANE RECTANGLE FILL ComboBox.l%, ComboBox.b%, ComboBox.r%-ComboBox.l%, ComboBox.t%-ComboBox.b% GCOL COL_BORDERS RECTANGLE ComboBox.l%-2, ComboBox.b%, ComboBox.r%-ComboBox.l%+2, ComboBox.t%-ComboBox.b% PROC_drawscrollbar(0, ScrlBarV{}) PROC_drawscrollbar(1, ScrlBarH{}) FOR I% = 0 TO 20 IF TBenable&(I%) = FALSE THEN IF Darkmode% GCOL 2, COL_DISABLED ELSE GCOL 1, COL_DISABLED RECTANGLE FILL ToolPos%(I%), 2 * @vdu%!212 - BMPHEIGHT + 8, \ \ BUTTONWIDTH, BUTTONHEIGHT ENDIF IF TBpressed&(I%) THEN IF Darkmode% GCOL 1, COL_PRESSED ELSE GCOL 2, COL_PRESSED RECTANGLE FILL ToolPos%(I%), 2 * @vdu%!212 - BMPHEIGHT + 8, \ \ BUTTONWIDTH, BUTTONHEIGHT GCOL COL_SELECT RECTANGLE ToolPos%(I%), 2 * @vdu%!212 - BMPHEIGHT + 8, \ \ BUTTONWIDTH, BUTTONHEIGHT ENDIF NEXT IF N% >= 0 IF W% IF H% THEN IF INKEY(-10) AND N% < NBUTTONS THEN IF Darkmode% GCOL 1, COL_PRESSED ELSE GCOL 2, COL_PRESSED RECTANGLE FILL X%, Y%, W%, H% RECTANGLE FILL X%, Y%, W%, H% TO X% + 2, Y% - 2 ELSE GCOL 2, COL_HILITEAND RECTANGLE FILL X%, Y%, W%, H% GCOL 1, COL_HILITEOR RECTANGLE FILL X%, Y%, W%, H% ENDIF GCOL COL_SELECT IF N% < NBUTTONS + NMENUS RECTANGLE X%, Y%, W%, H% ENDIF *REFRESH ON *REFRESH ENDPROC DEF PROCrefresh(sh%, sv%, cx%, cy%, ax%, ay%, nl%) LOCAL B%, D%, H%, I%, J%, K%, L%, N%, P%, S%, X%, a$, b$, l$, r$ LOCAL minx%, maxx%, miny%, maxy%, charx%, chary%, nrows% ON TIME LOCAL OFF minx% = EditRect.l% maxx% = EditRect.r% miny% = EditRect.b% maxy% = EditRect.t% charx% = 2 * @vdu%!216 chary% = 2 * @vdu%!220 nrows% = (maxy% - miny%) DIV chary% + 2 IF cy%<>ay% THEN ax% = cx% L% = cy% : H% = ay% IF L% > H% SWAP L%,H% ELSE L% = -1 H% = -1 ENDIF S% = SelWord$ <> "" IF Unicode% @vdu.m.c& OR= &80 ELSE @vdu.m.c& AND= &7F VDU 5,24,minx%;miny%;maxx%;maxy%;23,16,64| GCOL 128 + COL_EDITPANE CLG : OFF GCOL 128 + COL_SELECT MOVE minx% + sh%, maxy% + sv% MOD chary% N% = sv% DIV chary% FOR I% = N% TO N% + nrows% - 1 IF I% > nl% EXIT FOR D% = Indent%(I%) b$ = FNformat(Buffer$(I%), D%) X% = FNlen(b$) IF X% > MaxLen% MaxLen% = X% B% = 0 : K% = 1 REPEAT J% = INSTR(b$, CHR$17, K%) IF J% THEN a$ = MID$(b$, K%, J%-K%) ELSE a$ = MID$(b$, K%) P% = FNlen(LEFT$(b$, K% - 1)) : K% = J% + 2 IF B% THEN PROCbidi(a$, B%, I%, H%, L%, cx%-P%, cy%, ax%-P%, ay%) ELSE IF I% < H% IF I% >= L% THEN; PROCinvert(a$) ELSE IF I% = cy% THEN IF J%=0 PROCsplitx(a$, cx%-P%, l$, r$) ELSE PROCsplit(a$, cx%-P%, l$, r$) IF ax% < cx% THEN PROCsplit(l$, ax%-P%, l$, a$) IF S% THEN PROChiline(l$) PRINT l$; PROCinvert(a$) ELSE IF S% THEN PROChiline(l$) PRINT l$; ENDIF IF cx% >= P% THEN IF POS REM SDL thread sync @vdu.c.x% = @vdu.l.x% @vdu.c.y% = @vdu.l.y% ON ELSE cx% = P% ENDIF IF ax% > cx% THEN IF J%=0 PROCsplitx(r$, ax%-cx%, l$, a$) ELSE PROCsplit(r$, ax%-cx%, l$, a$) PROCinvert(l$) IF S% THEN PROChiline(a$) PRINT a$; ELSE IF S% THEN PROChiline(r$) PRINT r$; ENDIF ELSE IF S% THEN PROChiline(a$) PRINT a$; ENDIF ENDIF B% = ASCMID$(b$, J%+1, 1) UNTIL J% = 0 PRINT PLOT 0,sh%,0 NEXT IF POS REM SDL thread sync. VDU 24,0;0;@vdu%!208*2-2;@vdu%!212*2-2;4 ScrlBarV.max% = nl% * chary% ScrlBarV.pos% = sv% ScrlBarV.page% = EditRect.t% - EditRect.b% - chary% ScrlBarH.max% = MaxLen% * charx% ScrlBarH.pos% = -sh% ScrlBarH.page% = EditRect.r% - EditRect.l% PROC_drawscrollbar(0, ScrlBarV{}) PROC_drawscrollbar(1, ScrlBarH{}) IF Dragging% = 2 PROChilite(IDVSCRL) IF Dragging% = 3 PROChilite(IDHSCRL) @vdu.m.c& OR= &80 ENDPROC REM Output (possibly) bi-directional text: DEF PROCbidi(a$, S%, N%, H%, L%, cx%, cy%, ax%, ay%) IF N% <> cy% ax% = TRUE : cx% = TRUE IF N% < H% IF N% >= L% ax% = 0 : cx% = FNlen(a$) PROC_scriptsel(a$, Script$(S%), S% >> 4, ax%, cx%, Darkmode%) PROC_script("", "Latn", 0) ENDPROC REM Adjust indentation according to contents of program line: DEF PROCindent(f$, RETURN I%, RETURN M%) LOCAL C%, F%, L%, p%% IF f$="" THEN ENDPROC p%% = PTR(f$) + 3 F% = 5 : REM initialise to "left" and "first" L% = 6 + 2 * I% CASE ?p%% OF WHEN &ED: I%-=1 : REM NEXT WHEN &FD: I%-=1 : REM UNTIL WHEN &CE: I%-=1 : REM ENDWHILE WHEN &CB: I%-=2 : REM ENDCASE WHEN &CD: I%-=1 : REM ENDIF WHEN &E3: I%+=1 : REM FOR WHEN &F5: I%+=1 : REM REPEAT WHEN &C7: I%+=1 : REM WHILE WHEN &C8: I%+=2 : REM CASE WHEN &28: F% OR= 8 : REM ( ENDCASE WHILE ?p%% <> &D C% = ?p%% p%% += 1 IF C% = &22 IF (F% AND &60) = FALSE F% EOR= &80 IF F% AND &E0 THEN L% += 1 ELSE CASE C% OF WHEN &8D: p%% += 3 : REM line number WHEN &2A: IF F% AND 1 F% OR= &50 : REM * WHEN &DC: IF F% AND 1 F% OR= &20 : REM DATA WHEN &F4: F% OR= &40 : REM REM ENDCASE IF C%<32 OR C%>127 L% += LENKeyWd$((C%+128)MOD256) ELSE L% += 1 ENDIF IF C%<>32 F% AND= &FC : REM right mode, clear EXIT flag IF C%=&10 F% OR= 2 : REM set EXIT flag IF INSTR(Left$,CHR$C%) F% OR= &01 : REM left mode IF F% AND 8 IF C%=&29 F% AND= &F7 : REM end of label IF C%=&5C IF (F% AND &F4)=FALSE F% OR= &40 : REM \ comment F% AND= &FB : REM clear "first" IF (F% AND &F2) = FALSE THEN CASE ?p%% OF WHEN &ED: I%-=1 : REM NEXT WHEN &E3: I%+=1 : REM FOR WHEN &FD: I%-=1 : REM UNTIL WHEN &F5: I%+=1 : REM REPEAT WHEN &CE: I%-=1 : REM ENDWHILE WHEN &C7: I%+=1 : REM WHILE WHEN &C8: I%+=2 : REM CASE ENDCASE ENDIF ENDWHILE IF C% = &8C I%+=1 : REM THEN IF L% > M% M% = L% ENDPROC REM De-tokenise a program line and add syntax-colouring + indentation: DEF FNformat(f$, RETURN I%) LOCAL C%, F%, N%, S%, U%, p%%, a$, k$ IF f$="" THEN = "" k$ = FNcolour(-1) : REM To force initial colour p%% = PTR(f$) N% = p%%?1 + 256*p%%?2 : p%% += 3 IF N% THEN a$ = FNcolour(COL_LABEL) + RIGHT$(" " + STR$N%, 5) + " " ELSE a$ = FNcolour(COL_THEREST) + " " ENDIF F% = 5 : REM initialise to "left" and "first" CASE ?p%% OF WHEN &ED: I%-=1 : REM NEXT WHEN &FD: I%-=1 : REM UNTIL WHEN &CE: I%-=1 : REM ENDWHILE WHEN &CB: I%-=2 : REM ENDCASE WHEN &CD: I%-=1 : REM ENDIF WHEN &8B: I%-=1 : REM ELSE WHEN &C9: I%-=1 : REM WHEN WHEN &CC: I%-=1 : REM OTHERWISE ENDCASE IF NOT Indentation% I% = 0 a$ += STRING$(2*I%, " ") CASE ?p%% OF WHEN &E3: I%+=1 : REM FOR WHEN &F5: I%+=1 : REM REPEAT WHEN &C7: I%+=1 : REM WHILE WHEN &C8: I%+=2 : REM CASE WHEN &8B: I%+=1 : REM ELSE WHEN &C9: I%+=1 : REM WHEN WHEN &CC: I%+=1 : REM OTHERWISE ENDCASE IF ?p%% = ASC"(" THEN F% OR= 8 : a$ += FNcolour(COL_LABEL) WHILE ?p%% <> 13 C% = ?p%% p%% += 1 IF F% AND &C0 IF Unicode% THEN CASE TRUE OF WHEN C% >= &E0: U% = (C% << 12) AND &F000 OR (?p%% << 6) AND &FC0 OR p%%?1 AND &3F WHEN C% >= &C0: U% = (C% << 6) AND &07C0 OR ?p%% AND &3F OTHERWISE: U% = C% ENDCASE U% = Script&(U%) : IF U% = &FF U% = S% ELSE U% = 0 ENDIF IF S% <> U% S% = U% : a$ += CHR$17 + CHR$S% IF C% = &22 IF (F% AND &60) = 0 F% EOR= &80 : IF F% AND &80 a$ += FNcolour(COL_STRING) IF F% AND &E8 THEN a$ += CHR$C% ELSE CASE C% OF WHEN &8D: REM line number N% = (((?p%% << 2) AND &C0) EOR p%%?1) + 256*(((?p%% << 4) AND &C0) EOR p%%?2) a$ += FNcolour(COL_LABEL) + STR$N% : p%% += 3 WHEN &2A: IF F% AND 1 F% OR= &50 : REM * WHEN &DC: a$ += FNcolour(COL_KEYWD) : IF F% AND 1 F% OR= &20 : REM DATA WHEN &F4: a$ += FNcolour(COL_REMARK) : F% OR= &40 : REM REM WHEN &DD: a$ += FNcolour(COL_DEF) : REM DEF OTHERWISE: IF C%<&20 OR C%>=&80 a$ += FNcolour(COL_KEYWD) ENDCASE IF C%<&80 IF C%>=&20 THEN IF C%<>&20 IF C%<>&22 a$ += FNcolour(COL_THEREST) a$ += CHR$C% ELSE IF C%<>&8D THEN; IF Lowercase% k$ = FN_lower(KeyWd$(C% EOR &80)) ELSE k$ = KeyWd$(C% EOR &80) IF RIGHT$(k$) = "(" a$ += LEFT$(k$) + FNcolour(COL_THEREST) + "(" ELSE a$ += k$ ENDIF ENDIF IF C%<>32 F% AND= &FC : REM right mode, clear EXIT flag IF C%=&10 F% OR= 2 : REM set EXIT flag IF INSTR(Left$,CHR$C%) F% OR= &01 : REM left mode IF F% AND 8 IF C%=ASC")" F% AND= &F7 : a$ += FNcolour(COL_THEREST) IF C%=&DC IF F% AND &20 a$ += FNcolour(COL_THEREST) IF C%=&5C IF (F% AND &F4)=0 F% OR= &40 : a$ += FNcolour(COL_REMARK) F% AND= &FB : REM clear "first" IF (F% AND &F2) = 0 THEN CASE ?p%% OF WHEN &ED: I%-=1 : REM NEXT WHEN &E3: I%+=1 : REM FOR WHEN &FD: I%-=1 : REM UNTIL WHEN &F5: I%+=1 : REM REPEAT WHEN &CE: I%-=1 : REM ENDWHILE WHEN &C7: I%+=1 : REM WHILE WHEN &C8: I%+=2 : REM CASE ENDCASE ENDIF ENDWHILE IF (F% AND &F2) = 0 IF C% = &8C I%+=1 : REM THEN WHILE RIGHT$(a$)=" " a$ = LEFT$(a$) : ENDWHILE = a$ REM Insert a GCOL colour-change command if required: DEF FNcolour(C%) PRIVATE D% IF D% = C% THEN = "" D% = C% = CHR$18 + CHR$0 + CHR$D% REM Split a string, taking account of UTF-8 and control characters: DEF PROCsplit(a$, N%, RETURN l$, RETURN r$) LOCAL I%, l%%, p%% p%% = PTR(a$) : l%% = p%% + LENa$ WHILE I% < N% AND p%% < l%% CASE TRUE OF WHEN ?p%%<&20: p%% += 1 WHEN ?p%%>&BF: I% += 1 : IF Unicode% p%% += (?p%% >>> 5) - 4 ELSE p%% += 1 OTHERWISE: I% += 1 : p%% += 1 ENDCASE ENDWHILE l%% = PTR(a$) l$ = LEFT$(a$, p%%-l%%) r$ = MID$(a$, p%%-l%% + 1) ENDPROC REM Split and if necessary extend DEF PROCsplitx(a$, N%, RETURN l$, RETURN r$) LOCAL I%, l%%, p%% p%% = PTR(a$) : l%% = p%% + LENa$ WHILE I% < N% AND p%% < l%% CASE TRUE OF WHEN ?p%%<&20: p%% += 1 WHEN ?p%%>&BF: I% += 1 : IF Unicode% p%% += (?p%% >>> 5) - 4 ELSE p%% += 1 OTHERWISE: I% += 1 : p%% += 1 ENDCASE ENDWHILE l%% = PTR(a$) l$ = LEFT$(a$, p%%-l%%) + STRING$(N%-I%, " ") r$ = MID$(a$, p%%-l%% + 1) ENDPROC DEF PROCinvert(a$) IF POS REM SDL thread sync. LOCAL C%, F%, X%, Y% : C% = @vdu%!64 F% = FNinstrr(a$, CHR$18, 0) IF F% C% = C% AND &FFFF00FF OR (ASCMID$(a$, F%+2) << 8) a$ = FNstrip(a$) IF a$="" ENDPROC X% = FN_stringwidth(a$) Y% = 2 * @vdu%!220 GCOL 128 + COL_SELECT GCOL COL_EDITPANE PLOT 99,X%,-Y% PLOT 0,-X%,Y% PRINT a$; IF POS REM SDL thread sync. @vdu%!64 = C% ENDPROC DEF PROChiword(a$) LOCAL X%, Y% X% = FN_stringwidth(a$) Y% = 2 * @vdu%!220 IF Darkmode% GCOL 1, 128 + COL_HILITEOR ELSE GCOL 2, 128 + COL_HILITEAND PLOT 99,X%,-Y% PLOT 0,-X%,Y% PRINT a$; GCOL 128 + COL_EDITPANE ENDPROC DEF PROChiline(RETURN a$) LOCAL I%, L% L% = LEN(SelWord$) REPEAT I% = INSTR(a$, SelWord$, I%+1) IF I% = FALSE EXIT REPEAT IF INSTR(Valid$, MID$(a$,I%-1,1)) = FALSE THEN PRINT LEFT$(a$, I%-1); PROChiword(MID$(a$, I%, L%)) a$ = MID$(a$, I% + L%) I% = 0 ENDIF UNTIL FALSE ENDPROC REM Strip all control characters (<&20) from a string: DEF FNstrip(a$) LOCAL l%%, p%%, s$ p%% = PTR(a$) : l%% = p%% + LENa$ WHILE p%% < l%% IF ?p%%>=&20 s$ += CHR$?p%% p%% += 1 ENDWHILE = s$ REM Return string length, taking acount of UTF-8 and control chars: DEF FNlen(a$) LOCAL I%, p%% IF a$ = "" THEN = 0 FOR p%% = PTR(a$) TO PTR(a$) + LENa$ - 1 IF ?p%% >= &20 THEN IF NOT Unicode% I% += 1 ELSE IF ?p%% AND &C0 EOR &80 I% += 1 ENDIF NEXT = I% REM Check whether a quoted string (if any) is probably ANSI or UTF-8: DEF FNansi_or_utf8(a$) LOCAL Q%, p%% Q% = INSTR(a$, CHR$&22, 4) IF Q% = 0 THEN = 0 REPEAT p%% = PTR(a$) + Q% - 1 REPEAT p%% += 1 IF ?p%% = &D THEN = 0 IF ?p%% >= &C0 IF p%%?1 >= &80 IF p%%?1 < &C0 THEN = 2 : REM UTF-8 IF ?p%% >= &80 THEN = 1 : REM ANSI UNTIL ?p%% = &22 Q% = INSTR(a$, CHR$&22, p%% - PTR(a$) + 2) UNTIL Q% = 0 = 0 REM Tokenise a program line: DEF FNtokenise(a$) IF Lowercase% THEN *lowercase LOCAL I%,n,t$ n = VAL(a$) IF n < 0 OR n > 65535 THEN n = 0 WHILE ASCa$=&20 a$ = MID$(a$,2) : ENDWHILE ELSE WHILE ASCa$=&20 OR ASCa$>=&30 AND ASCa$<=&39 a$ = MID$(a$,2) : ENDWHILE ENDIF WHILE RIGHT$(a$) = " " a$ = LEFT$(a$) : ENDWHILE I% = FNinstrq(a$, "\", 2) IF I% t$ = MID$(a$,I%+1) : a$ = LEFT$(a$,I%) IF NOT Abbrev% THEN REPEAT I% = INSTR(a$, ".") IF I% MID$(a$,I%,1) = CHR$17 UNTIL I% = 0 ENDIF REPEAT I% = INSTR(a$, "\") IF I% MID$(a$,I%,1) = CHR$18 UNTIL I% = 0 IF EVAL("1RECTANGLERECTANGLE:"+a$) a$ = $(Accs%%+4) REPEAT I% = INSTR(a$, CHR$17) IF I% MID$(a$,I%,1) = "." UNTIL I% = 0 REPEAT I% = INSTR(a$, CHR$18) IF I% MID$(a$,I%,1) = "\" UNTIL I% = 0 a$ += t$ *lowercase off IF LENa$ > 251 THEN PROCmessagebox("SDLIDE", "Line too long: truncated", 0) a$ = LEFT$(a$,251) ENDIF = CHR$(LENa$+4)+CHR$(n MOD256)+CHR$(n DIV256)+a$+CHR$&D REM Reformat an edited program line: DEF PROCreformat(a$, RETURN X%, Y%, f$(), i%(), B%) LOCAL D%, F%, I%, L%, M%, N%, O% L% = i%(Y%) a$ = FNstrip(a$) IF MID$(a$, X%-4, 5) = "COLOR" D% = LEN(a$) - X% + 1 IF Lowercase% IF MID$(a$, X%-4, 5) = "color" D% = LEN(a$) - X% + 1 IF Abbrev% IF MID$(a$, X%, 1) = "." D% = LEN(a$) - X% + 1 F% = 5 - (INSTR("0123456789", MID$(a$, 6, 1)) <> 0) REPEAT M% += 1 : UNTIL MID$(a$, M%, 1) <> " " : O% = M% IF O% < 7 IF X% > F% IF VAL(a$)<>0 M% = 5 : REPEAT M% += 1 : UNTIL MID$(a$, M%, 1) <> " " f$(Y%) = FNtokenise(a$) a$ = FNstrip(FNformat(f$(Y%), L%)) REPEAT N% += 1 : UNTIL MID$(a$, N%, 1) <> " " IF O% < 7 IF X% > F% IF VAL(a$)<>0 N% = 5 : REPEAT N% += 1 : UNTIL MID$(a$, N%, 1) <> " " IF B% = FALSE OR M% <> N% - 1 OR M% < 6 X% += N% - M% : IF X% < 0 X% = 0 IF D% X% += LEN(a$) - X% + 1 - D% L% -= i%(Y%+1) IF L% = 0 ENDPROC FOR I% = Y%+1 TO DIM(i%(),1) i%(I%) += L% NEXT ENDPROC DEF PROCupdaterecent(file$) LOCAL I%, J% IF file$ = Recent$(1) THEN ENDPROC FOR I% = 2 TO 8 IF file$ = Recent$(I%) THEN FOR J% = I% TO 8 Recent$(J%) = Recent$(J%+1) NEXT Recent$(9) = "" ENDIF NEXT FOR I% = 9 TO 2 STEP -1 Recent$(I%) = Recent$(I%-1) NEXT Recent$(1) = file$ FOR I% = 1 TO 9 FileMenu$(I%+10) = "&" + STR$(I%) + " " + FNnopath(Recent$(I%)) NEXT ENDPROC REM Draw statusbar: REM Setting the second parameter to TRUE forces the font to be changed; REM don't do this frequently since it flushes the font cache and is slow. DEF PROCdrawstatusbar(N%, F%, force%) LOCAL S%, X% PRIVATE oldn%, olds%, oldx%, oldy%, oldo%, oldu% S% = SUMLEN(Buffer$()) + 3 IF oldn% = N% IF olds% = S% IF oldx% = CaretX% IF oldy% = CaretY% \ \ IF oldo% = Overtype% IF oldu% = Unicode% IF NOT force% ENDPROC oldn% = N% : olds% = S% : oldx% = CaretX% : oldy% = CaretY% oldo% = Overtype% : oldu% = Unicode% IF F% OSCLI "FONT " + GUIFont$ : VDU 5 *REFRESH OFF GCOL COL_GUIBKGD RECTANGLE FILL 0, 0, @vdu%!208 * 2, STATUSBARHEIGHT - 2 GCOL COL_GUITEXT MOVE 10, STATUSBARHEIGHT DIV 2 + @vdu%!220 CASE TRUE OF WHEN N% = 0: X% = @vdu%!208 * 2 PRINT Title$ + ", © R.T.Russell " + Year$ + ". Press F1 for Help"; PROCcentretext(X%, FN_stringwidth(" OVR "), LEFT$("OVR", oldo%)) PROCcentretext(X%, FN_stringwidth(" 999,99999 "), STR$(oldx%)+","+STR$(oldy%)) PROCcentretext(X%, FN_stringwidth(" 999999 "), STR$(olds%)) PROCcentretext(X%, FN_stringwidth(" Unicode "), MID$("UnicodeANSI", 8+7*oldu%, 7)) WHEN N% <= DIM(MenuHelp$(),1): PRINT MenuHelp$(N%); WHEN N% = 400: PRINT "Comparing... please wait" WHEN N% = 401: PRINT "Press F8 for next difference, F7 for previous difference. " + \ \ "Press Esc or click here to dismiss." WHEN N% >= 391: PRINT "Run " + Addin$(N% MOD 10); WHEN N% >= 381: PRINT Recent$(N% MOD 10); ENDCASE *REFRESH *REFRESH ON IF F% THEN OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width VDU 4 ENDIF Refresh% = TRUE : REM To reset caret ENDPROC DEF PROCcentretext(RETURN X%, W%, a$) LOCAL L% WHILE ASCa$ = &20 a$ = MID$(a$,2) : ENDWHILE X% -= W% GCOL COL_BORDERS LINE X%, 0, X%, STATUSBARHEIGHT L% = FN_stringwidth(a$) PLOT 0, (W% - L%) DIV 2, @vdu%!220 - STATUSBARHEIGHT DIV 2 GCOL COL_GUITEXT : PRINT a$; PLOT 0, -(W% - L%) DIV 2, STATUSBARHEIGHT DIV 2 - @vdu%!220 ENDPROC DEF PROCdrawall(W%, H%) REM Clear screen: COLOR 128 + COL_GUIBKGD CLS VDU 5 REM Define edit viewport: EditRect.l% = BREAKPTBARWIDTH EditRect.t% = 2 * H% - BMPHEIGHT - 4 EditRect.r% = 2 * W% - SCROLLBARSIZE - 2 EditRect.b% = STATUSBARHEIGHT + SCROLLBARSIZE REM Breakpoint bar: BrkPtBar.l% = 0 BrkPtBar.t% = EditRect.t% BrkPtBar.r% = EditRect.l% - 4 BrkPtBar.b% = EditRect.b% REM List DEFs combobox: ComboBox.l% = ToolPos%(NBUTTONS) + 10 ComboBox.t% = 2 * H% - (MENUBARHEIGHT + BMPHEIGHT) DIV 2 + @vdu%!220 ComboBox.r% = 2 * W% - GAPCOMBO ComboBox.b% = 2 * H% - (MENUBARHEIGHT + BMPHEIGHT) DIV 2 - @vdu%!220 IF (ComboBox.r% - ComboBox.l%) < MINCOMBO ComboBox.r% = ComboBox.l% + MINCOMBO REM Scrollbars: ScrlBarH.l% = EditRect.l% + SCROLLBARSIZE - 6 ScrlBarH.r% = EditRect.r% - SCROLLBARSIZE + 6 ScrlBarH.t% = STATUSBARHEIGHT + SCROLLBARSIZE - 4 ScrlBarH.b% = STATUSBARHEIGHT + 2 ScrlBarV.l% = 2 * W% - SCROLLBARSIZE + 2 ScrlBarV.r% = 2 * (W% - 1) ScrlBarV.t% = EditRect.t% - SCROLLBARSIZE + 6 ScrlBarV.b% = EditRect.b% + SCROLLBARSIZE - 6 REM Draw borders: GCOL COL_BORDERS LINE EditRect.l%-2,EditRect.t%+2,EditRect.l%-2,STATUSBARHEIGHT LINE EditRect.l%-2,EditRect.t%+2,2*W%-2,EditRect.t%+2 LINE EditRect.l%-2,STATUSBARHEIGHT,2*W%-2,STATUSBARHEIGHT LINE EditRect.r%+2,EditRect.t%+2,EditRect.r%+2,STATUSBARHEIGHT LINE EditRect.l%-2,EditRect.b%-2,2*W%-2,EditRect.b%-2 LINE EditRect.l%-2,2*H%-MENUBARHEIGHT+2,2*W%-2,2*H%-MENUBARHEIGHT+2 PROCdrawstatusbar(0, TRUE, TRUE) PROCtimer(TRUE) ENDPROC REM Search, skipping quoted text: DEF FNinstrq(A$, B$, S%) LOCAL I%, Q% REPEAT I% = INSTR(A$, B$, S%) Q% = INSTR(A$, """", S%) IF Q%=0 OR I% S% = O% DEF FNoktoditch LOCAL R% IF NOT Unsaved% THEN = TRUE R% = FNmessagebox("SDLIDE", "Save changes?", MB_ICONQUESTION + MB_YESNOCANCEL) IF R% = IDYES IF FNsave PROCunchanged : = TRUE IF R% = IDNO PROCunchanged : = TRUE = FALSE DEF PROCunchanged Unsaved% = FALSE Changed% = FALSE ENDPROC DEF PROCpointtochar(RETURN X%, RETURN Y%) LOCAL B%, C%, H%, I%, J%, K%, P%, W%, a$, b$, l$, r$ Y% = (ScrollV% + EditRect.t% - Y%) DIV (2 * @vdu%!220) X% -= EditRect.l% + ScrollH% - @vdu%!216 IF Y% < 0 Y% = 0 IF nLines% = 0 X% = 0 : Y% = 0 : ENDPROC I% = Indent%(Y%) b$ = FNformat(Buffer$(Y%), I%) IF Unicode% @vdu.m.c& OR= &80 ELSE @vdu.m.c& AND= &7F B% = 0 : K% = 1 REPEAT J% = INSTR(b$, CHR$17, K%) IF J% THEN a$ = MID$(b$, K%, J%-K%) ELSE a$ = MID$(b$, K%) P% = FNlen(LEFT$(b$, K% - 1)) : K% = J% + 2 IF B% PROC_script("", Script$(B%), B% >> 4) X% -= W% : W% = WIDTH(a$) IF J% = 0 OR W% > X% EXIT REPEAT B% = ASCMID$(b$, J%+1, 1) UNTIL FALSE IF B% AND &10 X% = W% - X% : P% += 1 : REM RTL C% = 1 : WHILE C% <= FNlen(a$) C% *= 2 : ENDWHILE REPEAT C% DIV= 2 PROCsplitx(a$, H% + C%, l$, r$) IF X% > WIDTH(l$) H% += C% UNTIL C% = 0 X% = H% + P% @vdu.m.c& OR= &80 PROC_script("", "Latn", 0) VDU 4 ENDPROC DEF FNchop(a%(), S%) LOCAL B%, H%, T% T% = DIM(a%(),1) H% = 2 WHILE H%=a%(B%+H%) B% += H% H% /= 2 UNTIL H%=0 = B% DEF FNchops(a$(), s$) LOCAL B%, H%, L%, P%, a$ H% = DIM(a$(),1) REPEAT B% = (L% + H%) DIV 2 : a$ = a$(B%) : P% = B% WHILE ASCa$ = 9 : P% -= 1 : a$ = a$(P%) : ENDWHILE IF a$ <> "" IF s$ > a$ L% = B% ELSE H% = B% UNTIL (H% - L%) <= 1 = L% DEF PROCcursor(C%) PRIVATE O% IF C%=O% ENDPROC ELSE O% = C% LOCAL B%, X%, Y% MOUSE ON C% MOUSE X%, Y%, B% MOUSE TO X%, Y% ENDPROC DEF FNhotspot(X%, Y%) LOCAL B% B% = FN_sbhotspot(0, ScrlBarV{}, X%, Y%) IF B% <> -1 THEN = IDVSCRL - 2 + B% B% = FN_sbhotspot(1, ScrlBarH{}, X%, Y%) IF B% <> -1 THEN = IDHSCRL - 2 + B% CASE TRUE OF WHEN FN_ptinrect(X%, Y%, ComboBox{}): B% = IDCOMBO WHEN Y% < 2*@vdu%!212 - BMPHEIGHT OR Y% >= 2*(@vdu%!212 - 1) OR X% <= 0: B% = -1 WHEN Y% > 2*@vdu%!212 - MENUBARHEIGHT: B% = 0 WHILE X% > MenuPos%(B%+1) AND B% < NMENUS-1 : B% += 1 : ENDWHILE IF X% > MenuPos%(NMENUS) THEN B% = -1 ELSE B% += IDMENU1 ENDIF WHEN X% > 0: B% = 0 WHILE X% > ToolPos%(B%+1) AND B% < NBUTTONS-1 : B% += 1 : ENDWHILE IF X% > ToolPos%(NBUTTONS) THEN B% = -1 ELSE IF TBenable&(B%) = FALSE B% = -1 ENDIF ENDCASE = B% DEF PROChotspot(N%, RETURN X%, RETURN Y%, RETURN W%, RETURN H%) CASE N% OF WHEN -1: Pressed% = FALSE WHEN IDMENU1,IDMENU2,IDMENU3,IDMENU4,IDMENU5,IDMENU6: X% = MenuPos%(N%-IDMENU1) Y% = 2 * @vdu%!212 - MENUBARHEIGHT + 8 W% = MenuPos%(N%+1-IDMENU1) - X% H% = MENUBARHEIGHT - 16 WHEN IDSCRLD,IDPAGED,IDVSCRL,IDPAGEU,IDSCRLU: PROC_sbhotspot(N% - IDSCRLD, ScrlBarV{}, X%, Y%, W%, H%) WHEN IDSCRLL,IDPAGEL,IDHSCRL,IDPAGER,IDSCRLR: PROC_sbhotspot(N% - IDSCRLD, ScrlBarH{}, X%, Y%, W%, H%) WHEN IDCOMBO: X% = ComboBox.l% Y% = ComboBox.b% + 2 W% = ComboBox.r% - ComboBox.l% - 2 H% = ComboBox.t% - ComboBox.b% - 4 OTHERWISE: X% = ToolPos%(N%) Y% = 2 * @vdu%!212 - BMPHEIGHT + 8 W% = BUTTONWIDTH H% = BUTTONHEIGHT ENDCASE ENDPROC DEF PROCcompare(file$) LOCAL H%, I%, L%, N%, R%, W%, X%, Y%, d%, k%, new%%, start%%, link%% LOCAL col%, file%, lower%, upper%, nline%, oline%, origin%, maxlines%, row% LOCAL D$, new$, old$, script%%(), last_d%(), ntotal%, ototal%, format% LOCAL ahead{}, behind{}, ep{}, hash{}, new{}, click%(), result$() PRIVATE edit{} : DIM click%(2) ON SYS LOCAL OFF ON TIME LOCAL OFF ON MOVE LOCAL Resized% OR= (@msg% == WM_SIZE) : RETURN ON MOUSE LOCAL click%() = @msg%,@wparam%,@lparam% : RETURN REM This program compares hashes rather than the source data. A REM 'collision' will result in a false match, but that would only REM alter the final result if it created or extended a 'diagonal' REM in the 'virtual matrix', which is unlikely. file% = OPENIN(file$) IF file% = 0 THEN PROCmessagebox("SDLIDE", "Couldn't open file '" + file$ + "'", 0) ENDPROC ENDIF REM Inform user of a possible wait: PROCdrawstatusbar(400, TRUE, TRUE) REM Count lines in 'new' version: ntotal% = nLines% REM Count lines in 'old' version: ototal% = 0 format% = 0 : REM .BBC (tokenised) REPEAT IF format% = 0 THEN N% = BGET#file% L% = BGET#file% H% = BGET#file% ENDIF INPUT #file%, D$ IF N% ototal% += 1 : IF N% <> LEN(D$)+4 format% = 1 : REM .BAS (ASCII) IF format% R% = BGET#file% UNTIL EOF#file% OR N%=0 PTR#file% = 0 REM Allocate arrays: DIM hash{new%(ntotal%), old%(ototal%)} REM Build hash table for earlier (file) program: FOR I% = 0 TO ototal%-1 hash.old%(I%) = FNhash(FNtok(file%, format%)) NEXT PTR#file% = 0 REM Build hash table for current (IDE) program: FOR I% = 0 TO ntotal%-1 hash.new%(I%) = FNhash(LEFT$(MID$(Buffer$(I%), 4))) NEXT REM Walk the virtual matrix: DIM edit{link%%, line1%, line2%, op&} DIM new{}=edit{}, ep{}=edit{}, behind{}=edit{}, ahead{}=edit{} IF ototal%>ntotal% maxlines% = ototal% ELSE maxlines% = ntotal% origin% = maxlines% DIM last_d%(2*maxlines%+2), script%%(2*maxlines%+2) REM Skip Matching lines at start of files: row% = 0 WHILE hash.old%(row%) = hash.new%(row%) row% += 1 IF row% >= ototal% OR row% >= ntotal% EXIT WHILE ENDWHILE last_d%(origin%+1) = row% IF row% = ototal% lower% = origin% + 1 ELSE lower% = origin% - 1 IF row% = ntotal% upper% = origin% - 1 ELSE upper% = origin% + 1 IF lower% > upper% THEN CLOSE #file% PROCmessagebox("SDLIDE", "The programs are identical", 0) ENDPROC ENDIF start%% = 0 REM For each value of the edit distance: FOR d% = 1 TO ototal% + ntotal% IF INKEY(0) = 27 ENDPROC REM For each relevant diagonal: FOR k% = lower% TO upper% STEP 2 REM Get space for the next edit instruction: SYS FNmalloc, DIM(edit{}) TO new%% IF NOT BB4W% IF @platform% AND &40 ELSE new%% = !^new%% PROC_setptr(new{}, new%%) REM Find a d on diagonal k: IF k% = origin%-d% OR k% <> origin%+d% AND last_d%(k%+2) >= last_d%(k%) THEN row% = last_d%(k%+2) + 1 new.link%% = script%%(k%+2) new.op& = OP_DELETE ELSE row% = last_d%(k%) new.link%% = script%%(k%) new.op& = OP_INSERT ENDIF REM Code common to the two cases: col% = row% + k% - origin% new.line1% = row% new.line2% = col% script%%(k%+1) = new%% REM Slide down the diagonal: IF row%=ototal% OR col%>=ntotal% EXIT WHILE ENDWHILE ENDIF last_d%(k%+1) = row% REM Hit southeast corner, have the answer: IF row% = ototal% IF col% = ntotal% start%% = script%%(k%+1) : EXIT FOR d% REM Hit last row; don't look to the left: IF row% = ototal% lower% = k%+2 REM Hit last column; don't look to the right: IF col% = ntotal% upper% = k%-2 NEXT k% lower% -= 1 upper% += 1 NEXT d% REM Reverse the pointers: PROC_setptr(ahead{}, start%%) PROC_setptr(ep{}, 0) WHILE ahead{} PROC_setptr(behind{}, ep{}) PROC_setptr(ep{}, ahead{}) PROC_setptr(ahead{}, ahead.link%%) ep.link%% = behind{} ENDWHILE REM List the differences: DIM result$(ototal% + ntotal%) N% = 1 oline% = 0 nline% = 0 WHILE ep{} WHILE nline% < (ep.line2%-1) OR oline% < (ep.line1%-1) old$ = FNasc(file%,format%) L% = nline% : I% = 0 : new$ = FNstrip(FNformat(Buffer$(L%), I%)) result$(N%) = CHR$18+CHR$0+CHR$0+"= "+new$ N% += 1 oline% += 1 nline% += 1 ENDWHILE IF ep.op& = OP_DELETE THEN old$ = FNasc(file%,format%) result$(N%) = CHR$18+CHR$0+CHR$3+"< "+old$ N% += 1 oline% = ep.line1% ELSE L% = nline% : I% = 0 : new$ = FNstrip(FNformat(Buffer$(L%), I%)) result$(N%) = CHR$18+CHR$0+CHR$4+"> "+new$ N% += 1 nline% = ep.line2% ENDIF link%% = ep{} PROC_setptr(ep{}, ep.link%%) IF link%% < PAGE OR link%% > HIMEM SYS FNfree, link%% ENDWHILE WHILE nline% < ntotal% OR oline% < ototal% L% = nline% : I% = 0 : new$ = FNstrip(FNformat(Buffer$(L%), I%)) result$(N%) = CHR$18+CHR$0+CHR$0+"= "+new$ N% += 1 oline% += 1 nline% += 1 ENDWHILE CLOSE #file% Resized% = TRUE PROCdrawstatusbar(401, TRUE, TRUE) PROC_setlistboxarray(Compare%, 400, result$(), N%) FOR d% = 1 TO N% IF MID$(result$(d%),4,1) <> "=" THEN PROC_setlistboxselect(Compare%, 400, d%) EXIT FOR ENDIF NEXT IF FN_polldialog(Compare%, 9, click%()) OFF REPEAT k% = INKEY(4) CASE k% OF WHEN 27: EXIT REPEAT WHEN 151: IF d% > 1 REPEAT d% -= 1 UNTIL MID$(result$(d%),4,1) <> "=" OR d% = 1 PROC_setlistboxselect(Compare%, 400, d%) PROC_refreshdialog(Compare%) WHEN 152: IF d% < N% REPEAT d% += 1 UNTIL MID$(result$(d%),4,1) <> "=" OR d% = N% PROC_setlistboxselect(Compare%, 400, d%) PROC_refreshdialog(Compare%) ENDCASE IF Resized% THEN Resized% = FALSE VDU 26 : IF POS REM SDL thread sync PROCdrawall(@vdu%!208, @vdu%!212) OSCLI "GSAVE """ + @tmp$ + "bbc" + Session$ + ".tmp.bmp""" PROCdrawstatusbar(401, TRUE, TRUE) PROC_setdlgrect(Compare%, 0, @vdu%!212 * 2 - 2, 0, 0) PROC_getdlgitemrect(Compare%, 400, X%, Y%, W%, H%) PROC_setdlgitemrect(Compare%, 400, X%, Y%, \ \ 2*@vdu%!208 - BREAKPTBARWIDTH, \ \ 2*@vdu%!212 - STATUSBARHEIGHT - BMPHEIGHT) PROC_refreshdialog(Compare%) ENDIF UNTIL FN_polldialog(Compare%, k%, click%()) = TRUE ON OSCLI "DISPLAY """ + @tmp$ + "bbc" + Session$ + ".tmp.bmp""" VDU 24,0;0;@vdu%!208*2-2;@vdu%!212*2-2; PROCdrawstatusbar(0, TRUE, TRUE) OSCLI "FONT " + EditFont$ VDU 23,0,10,0,0;0;0; : REM Set start line VDU 23,0,11,@vdu%!220,0;0;0; : REM Set end line VDU 23,0,18,2,0;0;0; : REM Set cursor width Refresh% = TRUE ENDPROC DEF FNhash(a$) LOCAL H%,p%% IF a$="" THEN = 0 FOR p%% = PTR(a$) TO PTR(a$) + LENa$ - 1 H% = H% * &21 AND &7FFFFFFF EOR ?p%% NEXT = H% DEF FNtok(F%,T%) LOCAL a$,I% IF T% THEN INPUT #F%,a$ IF ASCa$ = &A a$ = MID$(a$,2) a$ = LEFT$(MID$(FNtokenise(a$),4)) ELSE IF BGET#F% I% = BGET#F%+256*BGET#F% INPUT #F%,a$ ENDIF = a$ DEF FNasc(F%,T%) LOCAL a$,I% IF T% THEN INPUT #F%,a$ IF ASCa$ = &A a$ = MID$(a$,2) ELSE a$ = CHR$BGET#F% + CHR$BGET#F% + CHR$BGET#F% + GET$#F% TO &D + CHR$&D a$ = FNstrip(FNformat(a$,I%)) ENDIF = a$ DEF FNdark LOCAL s$ IF Darkmode% s$ = " -dark" IF GUIscale > 2 s$ += " -scale " + STR$GUIscale = s$ DEF FNmalloc IF NOT BB4W% THEN = SYS("SDL_malloc") PRIVATE malloc% IF malloc% THEN = malloc% LOCAL msvcrt% SYS "LoadLibraryA", "MSVCRT.DLL" TO msvcrt% SYS "GetProcAddress", msvcrt%, "malloc" TO malloc% = malloc% DEF FNfree IF NOT BB4W% THEN = SYS("SDL_free") PRIVATE free% IF free% THEN = free% LOCAL msvcrt% SYS "LoadLibraryA", "MSVCRT.DLL" TO msvcrt% SYS "GetProcAddress", msvcrt%, "free" TO free% = free% DEF PROCputkey(K%) LOCAL A%, B% B% = @vdu%?203 : A% = (B% + 1) AND &FF IF NOT BB4W% IF @platform% AND &40 THEN IF A% <> @vdu%?204 ?(]428 + B%) = K% : @vdu%?203 = A% ELSE IF A% <> @vdu%?204 ?(!428 + B%) = K% : @vdu%?203 = A% ENDIF ENDPROC DEF FNgetINIstring(f$, k$, d$) LOCAL F%, I%, a$ F% = OPENIN(f$) IF F% = 0 THEN = d$ k$ = FN_lower(FN_trim(k$)) WHILE NOT EOF#F% a$ = GET$#F% I% = INSTR(a$, "=") IF I% IF FN_lower(FN_trim(LEFT$(a$,I%-1))) = k$ d$ = FN_trim(MID$(a$,I%+1)) : EXIT WHILE ENDWHILE CLOSE #F% IF ASC(d$) = &22 IF RIGHT$(d$) = """" d$ = EVAL(d$) = d$ DEF PROCputINIstring(f$, k$, v$) LOCAL I%, P%, a$, d$ PRIVATE F% : IF F% ENDPROC F% = OPENUP(f$) IF F% = 0 F% = OPENOUT(f$) IF F% = 0 ERROR 100, "Couldn't create INI file" k$ = FN_lower(FN_trim(k$)) WHILE NOT EOF#F% P% = PTR#F% a$ = GET$#F% I% = INSTR(a$, "=") IF I% IF FN_lower(FN_trim(LEFT$(a$,I%-1))) = k$ d$ = MID$(a$,I%+1) : EXIT WHILE IF a$ = "" THEN PTR#F% = P% : IF BGET#F% = 0 THEN PTR#F% = P% : EXIT WHILE ENDWHILE IF d$ <> v$ THEN a$ = GET$#F% TO 0 PTR#F% = P% BPUT #F%, k$ + "=" + v$ BPUT #F%, a$ + CHR$0 ; WHILE PTR#F% < EXT#F% BPUT#F%,0 : ENDWHILE ENDIF CLOSE #F% F% = FALSE ENDPROC DEF PROCerror(code%, message$) IF code% <> 100 message$ = "Internal error "+STR$code% PROCmessagebox("Line "+STR$ERL, message$, SDL_MESSAGEBOX_ERROR) ENDPROC DEF PROCmessagebox(title$, message$, flags%) LOCAL R% R% = FNmessagebox(title$, message$, flags%) ENDPROC DEF FNmessagebox(title$, message$, flags%) ON TIME LOCAL OFF ON MOUSE LOCAL OFF IF POS REM SDL thread sync LOCAL F%, H%, I%, L%, M%, N%, R%, S%, W%, X%, Y% : F% = @flags% LOCAL @char.x%, @char.y%, pal{}, svdu{} : DIM pal{0%(15)}, svdu{} = @vdu{} : svdu{} = @vdu{} IF BB4W% SYS "GetPaletteEntries", @hpal%, 0, 16, pal{} ELSE SYS "SDL_memcpy", pal{}, @hpal%, 64 IF NOT BB4W% IF @vdu.hr% THEN LOCAL rc{} : DIM rc{0%(3)} : SYS "SDL_memcpy", rc{}, @vdu.hr%, 16 @vdu.hf% = 0 : @vdu.hr% = 0 : OFF : *ESC OFF OSCLI "FONT " + GUIFont$ PROC_setdialogpalette(Darkmode%) PRIVATE D% : IF D% = 0 THEN D% = FN_newdialog("", 160, 40) PROC_static(D%, "", 101, 4, 8, 40, 11, 0) PROC_button(D%, "OK", 1, 0, 22, 40, 11, 0) PROC_button(D%, "Abort", 3, 0, 22, 40, 11, 0) PROC_button(D%, "Retry", 4, 0, 22, 40, 11, 0) PROC_button(D%, "Ignore", 5, 0, 22, 40, 11, 0) PROC_button(D%, "Yes", 6, 0, 22, 40, 11, 0) PROC_button(D%, "No", 7, 0, 22, 40, 11, 0) PROC_button(D%, "Cancel", 2, 0, 22, 40, 11, 0) : REM Must be last (focus) PROC_button(D%, "Hidden", 8, 0, 22, 40, 11, &10000000) ENDIF REPEAT I% = INSTR(message$, CHR$&D+CHR$&A, R%) IF I% L% = WIDTH(MID$(message$, R%, I%-R%)) ELSE L% = WIDTH(MID$(message$, R%)) IF I% N% += 2 * @char.y% R% = I% + 2 : IF L% > M% M% = L% UNTIL I% = 0 PROC_getdlgrect(D%, L%, Y%, W%, H%) PROC_getdlgitemrect(D%, 8, X%, Y%, W%, H%) CASE flags% AND &F OF WHEN 1: R% = 2 : S% = %11000000000 : REM MB_OKCANCEL WHEN 2: R% = 3 : S% = %00000111000 : REM MB_ABORTRETRYIGNORE WHEN 3: R% = 3 : S% = %10011000000 : REM MB_YESNOCANCEL WHEN 4: R% = 2 : S% = %00011000000 : REM MB_YESNO WHEN 5: R% = 2 : S% = %10000010000 : REM MB_RETRYCANCEL OTHERWISE: R% = 1 : S% = %01000000000 : REM Just OK ENDCASE R% = R% * (W% + 20) + 20 : X% = L% + 20 IF R% < M% + 50 X% += (M% + 50 - R%) DIV 2 : R% = M% + 50 FOR I% = 3 TO 10 IF S% AND (1 << I%) THEN PROC_showdlgitem(D%, I% AND 7, TRUE) PROC_setdlgitemrect(D%, I% AND 7, X%, Y% - N%, W%, H%) X% += W% + 20 ELSE PROC_showdlgitem(D%, I% AND 7, FALSE) ENDIF NEXT PROC_getdlgitemrect(D%, 101, X%, Y%, W%, W%) PROC_setdlgitemrect(D%, 101, L% + (R% - M%) DIV 2, Y%, M% + 10, H% + N%) PROC_getdlgrect(D%, X%, Y%, W%, W%) PROC_setdlgrect(D%, L%, Y%, R%, 3.5 * H% + N%) PROC_setdlgitemtext(D%, 101, message$) PROC_setdialogtitle(D%, title$) PROC_registerdlgcallback(D%, FNdlgcb()) R% = FN_showdialogex(D%, &FFFFFFFF80000000, &FFFFFFFF80000000, Darkmode%) PROC_closedialog(D%) VDU 26 : *FONT IF BB4W% IF @vdu.hr% SYS "DeleteObject", @vdu.hr% @vdu{} = svdu{} IF NOT BB4W% IF @vdu.hr% SYS "SDL_memcpy", @vdu.hr%, rc{}, 16 IF BB4W% IF @vdu.hf% SYS "SelectObject", @memhdc%, @vdu.hf% IF BB4W% SYS "SetPaletteEntries", @hpal%, 0, 16, pal{} ELSE SYS "SDL_memcpy", @hpal%, pal{}, 64 IF BB4W% SYS "SendMessage", @hwnd%, &402, 0, 0 : REM Update caret shape IF F% AND &40000000 ELSE *ESC ON = R% DEF PROCcleanup LOCAL R%,C% ON ERROR LOCAL IF FALSE THEN IF TBpressed&(16) PROCdebugcmd(0, &10000000) ENDIF : RESTORE ERROR FOR R% = 0 TO 5 FOR C% = 0 TO 7 ON ERROR LOCAL IF FALSE THEN OSCLI "DEL """ + @tmp$ + "cc" + Session$ + STR$R% + STR$C% + ".tmp.bmp""" ENDIF : RESTORE ERROR NEXT NEXT R% ON ERROR LOCAL IF FALSE THEN OSCLI "DEL """ + @tmp$ + "bbc" + Session$ + ".tmp.bmp""" ENDIF : RESTORE ERROR ON ERROR LOCAL IF FALSE THEN PROCundoclear(UndoLevel%, RedoLevel%) ENDIF : RESTORE ERROR ENDPROC REM!Crunch spaces,lines,rems REM!Resource @dir$+"sdlide.res" REM!Embed @lib$+"../bbcwrun6.exe", @lib$+"../bbcwin6.exe", @lib$+"../aplib.dll" REM!Embed @lib$+"../lib/treeview.bbc", @lib$+"../lib/filedlg.bbc", @lib$+"../lib/dlglib.bbc" REM!Embed @lib$+"../lib/sdldebug.bbc", @lib$+"../lib/memusage.bbc", @lib$+"../lib/msgbox.bbc" REM!Embed @lib$+"../lib/menulib.bbc", @lib$+"../lib/editbox.bbc", @lib$+"../lib/winconsts.db" REM!Embed @lib$+"../examples/keywords.txt" REM!Embed @lib$+"../lib/ARRAYLIB.BBC", @lib$+"../lib/ASMLIB.BBC", @lib$+"../lib/ASMLIB2.BBC" REM!Embed @lib$+"../lib/ASMLIBC.BBC", @lib$+"../lib/BOX2DDBG.BBC", @lib$+"../lib/BOX2DGFX.BBC" REM!Embed @lib$+"../lib/BOX2DLIB.BBC", @lib$+"../lib/CALLBACK.BBC", @lib$+"../lib/CLASSLIB.BBC" REM!Embed @lib$+"../lib/COMLIB.BBC", @lib$+"../lib/COMLIBA.BBC", @lib$+"../lib/D3D9LIB.BBC" REM!Embed @lib$+"../lib/D3D9LIBA.BBC", @lib$+"../lib/D3DLIB.BBC", @lib$+"../lib/D3DLIBA.BBC" REM!Embed @lib$+"../lib/DATELIB.BBC", @lib$+"../lib/ELLIPSE.BBC", @lib$+"../lib/EVENTLIB.BBC" REM!Embed @lib$+"../lib/FNUSING.BBC", @lib$+"../lib/GDIPLIB.BBC", @lib$+"../lib/HQSOUND.BBC" REM!Embed @lib$+"../lib/IMGLIB.BBC", @lib$+"../lib/MDILIB.BBC", @lib$+"../lib/MODE7LIB.BBC" REM!Embed @lib$+"../lib/MULTIWIN.BBC", @lib$+"../lib/NOWAIT.BBC", @lib$+"../lib/ODBCLIB.BBC" REM!Embed @lib$+"../lib/SHADERLIB.BBC",@lib$+"../lib/SOCKLIB.BBC", @lib$+"../lib/SORTLIB.BBC" REM!Embed @lib$+"../lib/SORTSALIB.BBC",@lib$+"../lib/SPRITELIB.BBC",@lib$+"../lib/STRINGLIB.BBC" REM!Embed @lib$+"../lib/SUBCLASS.BBC", @lib$+"../lib/SUBCLASSW.BBC",@lib$+"../lib/TIMERLIB.BBC" REM!Embed @lib$+"../lib/UTF8LIB.BBC", @lib$+"../lib/WINLIB.BBC", @lib$+"../lib/WINLIB2.BBC" REM!Embed @lib$+"../lib/WINLIB2A.BBC", @lib$+"../lib/WINLIB2B.BBC", @lib$+"../lib/WINLIB2U.BBC" REM!Embed @lib$+"../lib/WINLIB3.BBC", @lib$+"../lib/WINLIB4.BBC", @lib$+"../lib/WINLIB4U.BBC" REM!Embed @lib$+"../lib/WINLIB5.BBC", @lib$+"../lib/WINLIB5A.BBC", @lib$+"../lib/WINLIB5U.BBC" REM!Embed @lib$+"../lib/WINLIB5W.BBC", @lib$+"../lib/WINLIBU.BBC", @lib$+"../lib/XMLLIB.BBC" REM!Embed @lib$+"../lib/BOX2D221.DLL", @lib$+"../lib/D3DX8BBC.DLL", @lib$+"../lib/BBCMODE7.FNT" REM!Embed @lib$+"../lib/AAGFXLIB.BBC", @lib$+"../lib/SCRIPT.BBC", @lib$+"../lib/WEBGLLIB.BBC"