Login | Register (Invite Only)
Title: Page Telegram of Amfile.org
Description: Brown Hats Collective F' Around and Find Out user of the Interwebs and Project Developer for a Cause Toward Insuring a Future of Liberty without Illusion.
@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@=:---#@@@#%@@@*=+#@%====@@@@..:--@#====@-==#@@@+===#@%=-+@... -@@@@*@@@=+@%-*@ @@@.*@-.@@@.:@@==@:=@+ -..*@@@:# @:@=.=. #%.#@@@@ ::..@.%#.@@ %+ %@@% #@@-.@+ #@ @@@.*@+.@@@:.@@.#@%*@*.@.-*@@%@#.@.@=.%..#% *@@@@ %:+:+:@@=@@ #+ %@@+..@@= %: @@ @@@..-.=@@:* %@.%#=+@+..:@@@@@@*.@@@=..:@@@ %@%%% :.@@+-@:=#@ ...@@@:+ @@+ :- @@ @@@.+@@@@@.- =@.#@.-@*.@:=@@@@@+ @@@+:@-:@% @@*=@ @=%#+-@-.#@ @*.%@@.- #@=. + @@ @@@.+@@@@+.@..@:*%.*@*.@%.@@@@%- +@@=:@%.@@.%@:=@ @@=*#:@::@@ *# =@--% -@:- * @@ @@-::#@@%::+::*@-:=%@::.::@@@@+-::@*:.:::@::...%:::::#@*:==@#==@+:*.:=::%:-=::=@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#-. .-#@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@*. .+@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@- :@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@: .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@: .++: .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@= :@@@@@@- -@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@# =@@@@@@@@+ #@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@: =@@@@@@@@@@+ .@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@# .@@@@@@@@@@@@. *@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@. %@@@@@@@@@@@@%. @@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@% -@@@@@@@@@@@@@@- #@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@= #@@@@@@@@@@@@@@% -@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@. .@@@@@@@@@@@@@@@@. .@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@ -@@@@%##***#%@@@@+ %@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@* %@#:.. .:+@% *@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@= =. : -@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@: .@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@. .@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@. .=%@@@@@@@+: .@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@# .%@@@@@@@@@@@@@- -@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@# .*@@@@@@@@@@@@@@@@%: -@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@%. .@@@@@@*%@@@@%#@@@@@@= *@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@. :@@@@@@@@:-@@*.%@@@@@@@+ %@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@+ :@@@@@@@@@@---.@@@@@@@@@@= :@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@. @@@@@@@@@@@. @@@@@@@@@@@: #@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@= #@@@+--#@@@@ #@@@@%#@@@@@. .@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@. :@%- .%@@- .@@@*. .+@@= #@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@# *+. .@@@#*@@@= .#@ -@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@- .# =@@-.@@%. += .@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@. -@. @@. %@: #% %@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@. #@- +% =% .@@. *@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@% %@% :+ .+ +@@. =@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@# @@@: .: .- .@@@: -@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@* .@@@% # .# =@@@: :@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@* .@@@@= -@ @- .@@@@: :@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@# @@@@@. .@@ @@. %@@@@: -@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@% %@@@@@: :@@@ @@@. .*@@@@@. =@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@. #@@@@@@#+#@@@@ @@@@=.:%@@@@@@. *@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@. :@@@@@@-..:*@@ @@#-..:%@@@@@# %@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@- .@@@@@: .@ @. .@@@@@- .@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@# *@@@% @. .@ *@@@@ -@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@. .@@@+ @- .@. -@@@= #@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@+ +@@%. .@* :@- .*@@%. .@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@. %@@@- *@% #@%. :%@@@. %@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@* .@@@@%=-+@@@. @@@*--#@@@@- -@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@: .@@@@@@@@@@*=@@@@@@@@@@: @@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@. .%@@@@@@@@@@@@@@@@@@@- .#@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@%. +@@@@@@@@@@@@@@@@#. +@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@%. .+@@@@@@@@@@@@%: +@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@%. -*%@@@@@#=. .*@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@: .%@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@#. +@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@+. .=@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@=. .-%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@%%###%@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
' Live EMF Plotter 3.0 by AmFile.org August 2025 ' Designed for exotic spectrum identification and abuse assessments using sensory and RF equipment data logging. ' This script enables interactive visualization of EMF data from CSV logs, allowing real-time adjustments for ' detailed analysis of magnetic field anomalies, potential interference patterns, and abuse indicators in RF environments. ' Adapt software as needed to live plot from any dataset. DEFINT A-Z OPTION BASE 1 DIM SHARED DataCount AS LONG DIM SHARED MaxData AS LONG DIM SHARED TimeStamp AS STRING * 20 DIM SHARED XVal AS SINGLE DIM SHARED YVal AS SINGLE DIM SHARED ZVal AS SINGLE DIM SHARED MagVal AS SINGLE DIM SHARED TempMag AS SINGLE DIM SHARED FileName AS STRING DIM SHARED HomeActive AS INTEGER DIM SHARED Multiplier AS INTEGER DIM SHARED GrayscaleMode AS INTEGER DIM SHARED AxesColor AS INTEGER DIM SHARED EMFPalette(0 TO 15) AS _UNSIGNED LONG Multiplier = 1 ' Default multiplier GrayscaleMode = 0 ' Default normal mode ' Colors for contrast: Blue (1) for X, Green (10) for Y, Cyan (11) for Z, Red (12) for Mag CONST COLORX = 1 CONST COLORY = 10 CONST COLORZ = 11 CONST COLORMAG = 12 ' Screen dimensions for SCREEN 12: 640x480 CONST SCREENWIDTH = 640 CONST SCREENHEIGHT = 480 CONST PLOTHEIGHT = 360 ' Plot area height, adjusted to avoid overlap CONST PLOTBOTTOM = SCREENHEIGHT - 80 ' Bottom margin for labels CONST PLOTLEFT = 50 ' Left margin for Y axis CONST PLOTRIGHT = SCREENWIDTH - 50 ' Right margin CONST MAX_PLOT_POINTS = 640 ' Max points to plot for performance on large scopes ' Initialize arrays with large initial size to reduce resizing REDIM SHARED TimeStamp(1 TO 100000) AS STRING * 20 REDIM SHARED XVal(1 TO 100000) AS SINGLE REDIM SHARED YVal(1 TO 100000) AS SINGLE REDIM SHARED ZVal(1 TO 100000) AS SINGLE REDIM SHARED MagVal(1 TO 100000) AS SINGLE SCREEN 12 CALL SetPalette(GrayscaleMode) ' Initialize to normal mode ' Cross-platform CSV file listing DIM SHARED CSVFiles(100) AS STRING DIM SHARED FileCount AS INTEGER FileCount = 0 IF _OS$ = "WINDOWS" THEN SHELL "dir *.csv /b > csvlist.txt" ELSE SHELL "dir *.csv /b > csvlist.txt" END IF OPEN "csvlist.txt" FOR INPUT AS #1 DO WHILE NOT EOF(1) FileCount = FileCount + 1 LINE INPUT #1, CSVFiles(FileCount) LOOP CLOSE #1 KILL "csvlist.txt" IF FileCount = 0 THEN PRINT "No CSV files found in current directory." END END IF ' Prompt user to select file PRINT "Select CSV file for EMF data analysis:" FOR i = 1 TO FileCount PRINT i; ": "; CSVFiles(i) NEXT i DO INPUT "Enter number: ", sel LOOP UNTIL sel >= 1 AND sel <= FileCount FileName = CSVFiles(sel) GOSUB LoadData MaxData = DataCount ' Initial scope: full dataset StartIdx& = 1 EndIdx& = DataCount HomeActive = 0 DO ' Handle auto-reload if Home active IF HomeActive THEN TIMER ON StartTime! = TIMER DO IF TIMER - StartTime! >= 2 THEN GOSUB LoadData MaxData = DataCount EndIdx& = MaxData StartIdx& = MaxData - 999 IF StartIdx& < 1 THEN StartIdx& = 1 EXIT DO END IF LOOP END IF CALL SetPalette(GrayscaleMode) ' Set palette based on mode ' Plot the data CLS ' Draw top and bottom lines for scope boundaries LINE (PLOTLEFT, PLOTBOTTOM)-(PLOTRIGHT, PLOTBOTTOM), AxesColor ' Bottom line LINE (PLOTLEFT, PLOTBOTTOM - PLOTHEIGHT)-(PLOTRIGHT, PLOTBOTTOM - PLOTHEIGHT), AxesColor ' Top line LOCATE 28, 1: PRINT "Time/Index" LOCATE 14, 1: PRINT "uT" ' Validate scope indices IF StartIdx& < 1 THEN StartIdx& = 1 IF EndIdx& > MaxData THEN EndIdx& = MaxData IF StartIdx& > EndIdx& THEN SWAP StartIdx&, EndIdx& IF EndIdx& < StartIdx& + 10 THEN EndIdx& = StartIdx& + 10 ' Find min/max for Y scaling and peaks MinY! = 1E+38 MaxY! = -1E+38 peakX! = -1E+38 peakY! = -1E+38 peakZ! = -1E+38 peakM! = -1E+38 FOR i& = StartIdx& TO EndIdx& IF XVal(i&) < MinY! THEN MinY! = XVal(i&) IF YVal(i&) < MinY! THEN MinY! = YVal(i&) IF ZVal(i&) < MinY! THEN MinY! = ZVal(i&) IF MagVal(i&) < MinY! THEN MinY! = MagVal(i&) IF XVal(i&) > MaxY! THEN MaxY! = XVal(i&) IF YVal(i&) > MaxY! THEN MaxY! = YVal(i&) IF ZVal(i&) > MaxY! THEN MaxY! = ZVal(i&) IF MagVal(i&) > MaxY! THEN MaxY! = MagVal(i&) IF XVal(i&) > peakX! THEN peakX! = XVal(i&) IF YVal(i&) > peakY! THEN peakY! = YVal(i&) IF ZVal(i&) > peakZ! THEN peakZ! = ZVal(i&) IF MagVal(i&) > peakM! THEN peakM! = MagVal(i&) NEXT i& IF MaxY! = MinY! THEN MaxY! = MinY! + 1 ' Avoid divide by zero ' Plot width based on downsampled points size& = EndIdx& - StartIdx& + 1 CONST MAX_PLOT_POINTS = 640 ' Max points to plot for performance on large scopes IF size& > MAX_PLOT_POINTS THEN stepSize! = size& / MAX_PLOT_POINTS PlotWidth! = (PLOTRIGHT - PLOTLEFT) / MAX_PLOT_POINTS ELSE stepSize! = 1 PlotWidth! = (PLOTRIGHT - PLOTLEFT) / size& END IF ' Plot each series with downsampling if needed LastX! = PLOTLEFT LastY_X! = PLOTBOTTOM - ((XVal(StartIdx&) - MinY!) / (MaxY! - MinY!)) * PLOTHEIGHT LastY_Y! = PLOTBOTTOM - ((YVal(StartIdx&) - MinY!) / (MaxY! - MinY!)) * PLOTHEIGHT LastY_Z! = PLOTBOTTOM - ((ZVal(StartIdx&) - MinY!) / (MaxY! - MinY!)) * PLOTHEIGHT LastY_Mag! = PLOTBOTTOM - ((MagVal(StartIdx&) - MinY!) / (MaxY! - MinY!)) * PLOTHEIGHT FOR p = 1 TO MAX_PLOT_POINTS - 1 CurrX! = PLOTLEFT + p * PlotWidth! binStart& = StartIdx& + (p - 1) * stepSize! binEnd& = binStart& + stepSize! - 1 IF binEnd& > EndIdx& THEN binEnd& = EndIdx& sumX! = 0: sumY! = 0: sumZ! = 0: sumMag! = 0 count& = 0 FOR j& = binStart& TO binEnd& sumX! = sumX! + XVal(j&) sumY! = sumY! + YVal(j&) sumZ! = sumZ! + ZVal(j&) sumMag! = sumMag! + MagVal(j&) count& = count& + 1 NEXT j& IF count& > 0 THEN avgX! = sumX! / count& avgY! = sumY! / count& avgZ! = sumZ! / count& avgMag! = sumMag! / count& ELSE avgX! = 0 avgY! = 0 avgZ! = 0 avgMag! = 0 END IF CurrY_X! = PLOTBOTTOM - ((avgX! - MinY!) / (MaxY! - MinY!)) * PLOTHEIGHT CurrY_Y! = PLOTBOTTOM - ((avgY! - MinY!) / (MaxY! - MinY!)) * PLOTHEIGHT CurrY_Z! = PLOTBOTTOM - ((avgZ! - MinY!) / (MaxY! - MinY!)) * PLOTHEIGHT CurrY_Mag! = PLOTBOTTOM - ((avgMag! - MinY!) / (MaxY! - MinY!)) * PLOTHEIGHT LINE (LastX!, LastY_X!)-(CurrX!, CurrY_X!), COLORX LINE (LastX!, LastY_Y!)-(CurrX!, CurrY_Y!), COLORY LINE (LastX!, LastY_Z!)-(CurrX!, CurrY_Z!), COLORZ LINE (LastX!, LastY_Mag!)-(CurrX!, CurrY_Mag!), COLORMAG LastX! = CurrX! LastY_X! = CurrY_X! LastY_Y! = CurrY_Y! LastY_Z! = CurrY_Z! LastY_Mag! = CurrY_Mag! NEXT p ' Title at top LOCATE 1, 1: PRINT "Live EMF Plotter 3.0 by AmFile.org August 2025" ' Date/time scope range at top tempStart$ = "" tempEnd$ = "" IF StartIdx& >= 1 AND StartIdx& <= MaxData THEN tempStart$ = TimeStamp(StartIdx&) IF EndIdx& >= 1 AND EndIdx& <= MaxData THEN tempEnd$ = TimeStamp(EndIdx&) LOCATE 2, 1: PRINT "Scope: "; StartIdx&; " to "; EndIdx&; " ("; tempStart$; " to "; tempEnd$; ")" ' All other labels at bottom below the chart scope LOCATE 26, 1: PRINT "Peak X: "; peakX!; " Y: "; peakY!; " Z: "; peakZ!; " M: "; peakM!; " uT" IF GrayscaleMode THEN LOCATE 27, 1: PRINT "X: Dark Gray, Y: Medium Gray, Z: Light Gray, Mag: Lighter Gray" ELSE LOCATE 27, 1: PRINT "X: Blue, Y: Green, Z: Cyan, Mag: Red" END IF LOCATE 28, 1: PRINT "[H]elp [P]rint Mode" IF HomeActive THEN LOCATE 29, 1: PRINT "(Home Active - Last 1000, Auto-Reload)" ' Handle input DO k$ = INKEY$ LOOP WHILE k$ = "" Inc& = Multiplier * 10 ' Base increment, adjust as needed CtrlDown = _KEYDOWN(100305) OR _KEYDOWN(100306) ' Ctrl key (left or right) SELECT CASE UCASE$(k$) CASE CHR$(27): END ' ESC CASE "S" ' Save screenshot as 24-bit BMP DateTime$ = MID$(DATE$, 7, 4) + MID$(DATE$, 1, 2) + MID$(DATE$, 4, 2) + "_" + MID$(TIME$, 1, 2) + MID$(TIME$, 4, 2) + MID$(TIME$, 7, 2) GOSUB SaveBMP CASE "H" GOSUB ShowHelp CASE "P" GrayscaleMode = NOT GrayscaleMode CASE CHR$(0) + CHR$(72) ' Up - Widen (zoom out) center& = (StartIdx& + EndIdx&) / 2 width& = EndIdx& - StartIdx& + 1 newWidth& = width& + Inc& * 2 ' Add to both sides StartIdx& = center& - newWidth& / 2 EndIdx& = center& + newWidth& / 2 - 1 IF StartIdx& < 1 THEN StartIdx& = 1 IF EndIdx& > MaxData THEN EndIdx& = MaxData CASE CHR$(0) + CHR$(80) ' Down - Thin (zoom in) center& = (StartIdx& + EndIdx&) / 2 width& = EndIdx& - StartIdx& + 1 newWidth& = width& - Inc& * 2 ' Subtract from both sides IF newWidth& < 10 THEN newWidth& = 10 StartIdx& = center& - newWidth& / 2 EndIdx& = center& + newWidth& / 2 - 1 IF StartIdx& < 1 THEN StartIdx& = 1 IF EndIdx& > MaxData THEN EndIdx& = MaxData CASE CHR$(0) + CHR$(75) ' Left - Shift left IF CtrlDown THEN Shift& = 1000 ELSE Shift& = Inc& StartIdx& = StartIdx& - Shift& EndIdx& = EndIdx& - Shift& IF StartIdx& < 1 THEN StartIdx& = 1 IF EndIdx& < StartIdx& + 10 THEN EndIdx& = StartIdx& + 10 IF EndIdx& > MaxData THEN EndIdx& = MaxData CASE CHR$(0) + CHR$(77) ' Right - Shift right IF CtrlDown THEN Shift& = 1000 ELSE Shift& = Inc& StartIdx& = StartIdx& + Shift& EndIdx& = EndIdx& + Shift& IF EndIdx& > MaxData THEN EndIdx& = MaxData IF StartIdx& > EndIdx& - 10 THEN StartIdx& = EndIdx& - 10 IF StartIdx& < 1 THEN StartIdx& = 1 CASE CHR$(0) + CHR$(79) ' End - Full dataset StartIdx& = 1 EndIdx& = MaxData HomeActive = 0 CASE CHR$(0) + CHR$(71) ' Home - Last 1000 EndIdx& = MaxData StartIdx& = MaxData - 999 IF StartIdx& < 1 THEN StartIdx& = 1 HomeActive = -1 CASE "1" TO "9" ' Numpad for multiplier Multiplier = VAL(k$) END SELECT LOOP LoadData: DataCount = 0 OPEN FileName FOR INPUT AS #2 DO WHILE NOT EOF(2) LINE INPUT #2, line$ IF line$ <> "" THEN comma1 = INSTR(line$, ",") comma2 = INSTR(comma1 + 1, line$, ",") comma3 = INSTR(comma2 + 1, line$, ",") comma4 = INSTR(comma3 + 1, line$, ",") comma5 = INSTR(comma4 + 1, line$, ",") IF comma1 > 0 AND comma2 > comma1 AND comma3 > comma2 AND comma4 > comma3 AND comma5 > comma4 THEN DataCount = DataCount + 1 IF DataCount > UBOUND(TimeStamp) THEN newSize& = DataCount * 1.5 + 10000 ' Grow dynamically REDIM _PRESERVE SHARED TimeStamp(1 TO newSize&) AS STRING * 20 REDIM _PRESERVE SHARED XVal(1 TO newSize&) AS SINGLE REDIM _PRESERVE SHARED YVal(1 TO newSize&) AS SINGLE REDIM _PRESERVE SHARED ZVal(1 TO newSize&) AS SINGLE REDIM _PRESERVE SHARED MagVal(1 TO newSize&) AS SINGLE END IF TimeStamp(DataCount) = LEFT$(line$, comma1 - 1) XVal(DataCount) = VAL(MID$(line$, comma1 + 1, comma2 - comma1 - 1)) YVal(DataCount) = VAL(MID$(line$, comma2 + 1, comma3 - comma2 - 1)) ZVal(DataCount) = VAL(MID$(line$, comma3 + 1, comma4 - comma3 - 1)) MagVal(DataCount) = VAL(MID$(line$, comma4 + 1, comma5 - comma4 - 1)) END IF END IF LOOP CLOSE #2 IF DataCount = 0 THEN PRINT "No valid data loaded from CSV." END END IF RETURN SaveBMP: DIM FileSize AS LONG DIM y AS INTEGER, x AS INTEGER, c AS INTEGER, r AS INTEGER, g AS INTEGER, b AS INTEGER DIM rgb AS _UNSIGNED LONG DIM Signature AS STRING * 2 DIM Reserved AS STRING * 4 DIM Offset AS STRING * 4 DIM HeaderSize AS STRING * 4 DIM Width AS STRING * 4 DIM Height AS STRING * 4 DIM Planes AS STRING * 2 DIM BitsPerPixel AS STRING * 2 DIM Compression AS STRING * 4 DIM ImageSize AS STRING * 4 DIM XPelsPerMeter AS STRING * 4 DIM YPelsPerMeter AS STRING * 4 DIM ColorsUsed AS STRING * 4 DIM ImportantColors AS STRING * 4 DIM Blue AS STRING * 1 DIM Green AS STRING * 1 DIM Red AS STRING * 1 ' Create a standard 24-bit Windows BMP file OPEN DateTime$ + ".bmp" FOR BINARY AS #3 ' BITMAPFILEHEADER (14 bytes) Signature = CHR$(66) + CHR$(77) ' "BM" signature PUT #3, , Signature FileSize = 54 + SCREENWIDTH * SCREENHEIGHT * 3 ' Header + pixel data (24-bit) FileSizeStr$ = MKL$(FileSize) ' Predefine MKL$ result PUT #3, , FileSizeStr$ ' File size Reserved = STRING$(4, 0) ' Reserved bytes PUT #3, , Reserved Offset = MKL$(54) ' Offset to pixel data PUT #3, , Offset ' BITMAPINFOHEADER (40 bytes) HeaderSize = MKL$(40) ' Header size PUT #3, , HeaderSize Width = MKL$(SCREENWIDTH) ' Width PUT #3, , Width Height = MKL$(SCREENHEIGHT) ' Height PUT #3, , Height Planes = MKI$(1) ' Planes PUT #3, , Planes BitsPerPixel = MKI$(24) ' Bits per pixel PUT #3, , BitsPerPixel Compression = MKL$(0) ' Compression (none) PUT #3, , Compression ImageSize = MKL$(SCREENWIDTH * SCREENHEIGHT * 3) ' Image size PUT #3, , ImageSize XPelsPerMeter = MKL$(2835) ' X pixels per meter (approx 72 DPI) PUT #3, , XPelsPerMeter YPelsPerMeter = MKL$(2835) ' Y pixels per meter PUT #3, , YPelsPerMeter ColorsUsed = MKL$(0) ' Colors used (0 for 24-bit) PUT #3, , ColorsUsed ImportantColors = MKL$(0) ' Important colors PUT #3, , ImportantColors ' Pixel data (bottom-up, 24-bit RGB) FOR y = SCREENHEIGHT - 1 TO 0 STEP -1 FOR x = 0 TO SCREENWIDTH - 1 c = POINT(x, y) ' Get pixel color index (0-15) IF c < 0 OR c > 15 THEN c = 0 ' Validate color index to prevent errors rgb = EMFPalette(c) ' Get RGB value from palette r = _RED32(rgb) ' Extract red using QB64 built-in g = _GREEN32(rgb) ' Extract green using QB64 built-in b = _BLUE32(rgb) ' Extract blue using QB64 built-in Blue = CHR$(b) Green = CHR$(g) Red = CHR$(r) PUT #3, , Blue PUT #3, , Green PUT #3, , Red ' Write BGR one byte at a time NEXT x NEXT y CLOSE #3 RETURN ShowHelp: CLS LOCATE 1, 1: PRINT "Key Mappings:" LOCATE 2, 1: PRINT "Up arrow: Widen scope (zoom out) by multiplier * 10 points" LOCATE 3, 1: PRINT "Down arrow: Thin scope (zoom in) by multiplier * 10 points" LOCATE 4, 1: PRINT "Left arrow: Shift left by multiplier * 10 points" LOCATE 5, 1: PRINT "Right arrow: Shift right by multiplier * 10 points" LOCATE 6, 1: PRINT "Ctrl + Left/Right: Shift by 1000 points" LOCATE 7, 1: PRINT "1-9: Set multiplier to 1-9" LOCATE 8, 1: PRINT "Home: View last 1000 points, enable auto-reload every 2s" LOCATE 9, 1: PRINT "End: View full dataset, disable auto-reload" LOCATE 10, 1: PRINT "S/s: Save screenshot as BMP (date_time.bmp)" LOCATE 11, 1: PRINT "H/h: This help screen" LOCATE 12, 1: PRINT "P/p: Toggle grayscale mode for printing (white background)" LOCATE 14, 1: PRINT "Press any key to continue..." DO k$ = INKEY$ LOOP WHILE k$ = "" RETURN SUB QuickSort (arr() AS SINGLE, low AS LONG, high AS LONG) DIM stack(1 TO 100) AS LONG ' Stack for iterative QuickSort, max depth 100 DIM top AS INTEGER top = 0 top = top + 1: stack(top) = low top = top + 1: stack(top) = high DO WHILE top > 0 high = stack(top): top = top - 1 low = stack(top): top = top - 1 IF low < high THEN pivot! = arr((low + high) \ 2) i& = low j& = high DO WHILE arr(i&) < pivot!: i& = i& + 1: WEND WHILE arr(j&) > pivot!: j& = j& - 1: WEND IF i& <= j& THEN tempSwap! = arr(i&): arr(i&) = arr(j&): arr(j&) = tempSwap! i& = i& + 1 j& = j& - 1 END IF LOOP WHILE i& <= j& IF low < j& THEN top = top + 1: stack(top) = low top = top + 1: stack(top) = j& END IF IF i& < high THEN top = top + 1: stack(top) = i& top = top + 1: stack(top) = high END IF END IF LOOP END SUB SUB SetPalette (mode AS INTEGER) IF mode = 0 THEN _PALETTECOLOR 0, _RGB32(0, 0, 0) ' Black _PALETTECOLOR 1, _RGB32(0, 0, 170) ' Blue _PALETTECOLOR 10, _RGB32(0, 170, 0) ' Green _PALETTECOLOR 11, _RGB32(0, 170, 170) ' Cyan _PALETTECOLOR 12, _RGB32(170, 0, 0) ' Red _PALETTECOLOR 15, _RGB32(255, 255, 255) ' White EMFPalette(0) = _RGB32(0, 0, 0) EMFPalette(1) = _RGB32(0, 0, 170) EMFPalette(10) = _RGB32(0, 170, 0) EMFPalette(11) = _RGB32(0, 170, 170) EMFPalette(12) = _RGB32(170, 0, 0) EMFPalette(15) = _RGB32(255, 255, 255) AxesColor = 15 ELSE _PALETTECOLOR 0, _RGB32(255, 255, 255) ' White background _PALETTECOLOR 1, _RGB32(50, 50, 50) ' Dark gray for X _PALETTECOLOR 10, _RGB32(100, 100, 100) ' Medium gray for Y _PALETTECOLOR 11, _RGB32(150, 150, 150) ' Light medium gray for Z _PALETTECOLOR 12, _RGB32(200, 200, 200) ' Light gray for Mag _PALETTECOLOR 15, _RGB32(0, 0, 0) ' Black for axes and text EMFPalette(0) = _RGB32(255, 255, 255) EMFPalette(1) = _RGB32(50, 50, 50) EMFPalette(10) = _RGB32(100, 100, 100) EMFPalette(11) = _RGB32(150, 150, 150) EMFPalette(12) = _RGB32(200, 200, 200) EMFPalette(15) = _RGB32(0, 0, 0) AxesColor = 15 END IF END SUB
Language: qBASIC 4.5