The MASM Forum

Projects => MasmBasic & the RichMasm IDE => Topic started by: jj2007 on August 20, 2017, 08:02:31 AM

Title: Miscellaneous snippets
Post by: jj2007 on August 20, 2017, 08:02:31 AM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dim MyInts() As DWORD
  For_ ct=0 To 999
        mov MyInts(ct), Rand(100)       ; 0...99
  Next
  Open "O", #0, "even.txt"
  Open "O", #1, "odd.txt"
  For_ ct=0 To MyInts(?)-1
        test MyInts(ct), 1
        setne al
        movsx ecx, al
        Print #ecx, Str$("%__i ", MyInts(ct))
  Next
  Close
  PrintLine     "even.txt: ", FileRead$("even.txt"), CrLf$
  Inkey         "odd.txt:  ", FileRead$("odd.txt")
EndOfCode


Output (shortened):
Code: [Select]
even.txt:  86  82  22  78   2  56  36  14  58  46  68  16  84  12  94  42   0  16  90  42   8  94  90  52  92  90  42  60  88  86  10  64  3
8  92  16  24  92  10  46  34  28  66  74  92  88  82  40  44  26  84  94  48  32   8   0  44  68  40  50   0   2  12  38  12  82  80   0  7
2  76   0  74   8   0  76  64   8  28  46  10  48   6  94  90  10  84  68  62   2  82  96   0  98  20  36  12  96  14  98   8  96

odd.txt:   45   7  13  65  51  57  67  25  97  63  23  77  87  95  39  57  33  87  55  99   5  47  69  79  87  67  19  95  83  49  21  85  4
9  53   7  39  25  31  49  83  17  65  29  27  99  61  19  67  67  77  49  61  73  79  29  47  31  95  49  45  55  81  71  29   7  79  65  2
3  89  93  19  81  17  19  87  83  63  93  25  75  51  79  75  99   7  55  17  19  57  45  33  83  81  87  51  75  81  79  55  93
Title: A suicide proggie
Post by: jj2007 on November 10, 2017, 09:39:13 PM
Ever tried to kill the current executable? It's not that straightforward, for security reasons, but it can be done with little helpers:
Code: [Select]
include \masm32\include\masm32rt.inc ; pure Masm32

.data?
ThisExe db MAX_PATH dup(?)

.code
start:
  mov edi, offset ThisExe
  invoke lstrcpy, edi, chr$("KillMe.exe ")
  invoke lstrcat, edi, rv(GetCommandLine)  ; this returns the path of the current exe
  invoke WinExec, edi, SW_MINIMIZE
  add edi, 11 ; advance to compensate for <KillMe.exe >
  print "check your disk to see if "
  print edi
  print " was killed"
  exit

end start

Source and binaries attached, must sit in the same folder as the current exe.
Title: Re: Miscellaneous snippets
Post by: jj2007 on November 12, 2017, 09:14:40 PM
Playing with inline assembly in FreeBasic, source attached; see discussion (https://www.freebasic.net/forum/viewtopic.php?f=7&t=25305&p=239205#p239205). Watch out for the red calls below...

Code: [Select]
Function LeapYearJ(ByVal yea As ULong) As ULong
Asm
  mov ecx, dword ptr [yea]
  test ecx, 3
  setz al
  jne 0f
  mov eax, ecx
  cdq
  push 100
  idiv dword ptr [esp] ' 0, 4, 8, ..., 96, 0
  test edx, edx ' mod 100=0 should set zero flag
  jne 1f
  mov eax, ecx
  cdq
  push 400
  idiv dword ptr [esp]
  pop eax
  dec edx '*** invert the zero flag ***
  sets dl ' sign set if edx was zero
  test dl, dl
1:
  pop eax
  setnz al
0:
  movsx eax, al
  mov [function], eax ' MichaelW
End Asm
End Function
...
Code: [Select]
for i = 1 to years ' assembly function, inlined by compiler
asm int 3 ' forum
lyears=lyears+LeapYearJ(i)
asm nop
asm nop
asm nop
asm nop
next

00407C20        �> �CC                �int3
00407C21        �. �8B45 D0           �mov eax, [ebp-30]
00407C24        �. �8945 D8           �mov [ebp-28], eax
00407C27        �. �C745 DC 00000000  �mov dword ptr [ebp-24], 0
00407C2E        �. �C70424 24A04000   �mov dword ptr [esp], offset 0040A02 ; ASCII "C:\FreeBasic\tmp\TmpFile.bas"
00407C35        �. �E8 169EFFFF       �call 00401A50                       ; �TmpFile.00401A50
00407C3A        �. �56                �push esi                            ; �Arg1
00407C3B        �. �8945 C0           �mov [ebp-40], eax                   ; �
00407C3E        �. �C70424 80A04000   �mov dword ptr [esp], offset 0040A08 ; �ASCII "LEAPYEARJ"
00407C45        �. �E8 669EFFFF       �call 00401AB0                       ; �TmpFile.00401AB0
00407C4A        �. �57                �push edi
00407C4B        �. �8945 BC           �mov [ebp-44], eax
00407C4E        �. �8B4D D8           �mov ecx, [ebp-28]
00407C51        �. �F7C1 03000000     �test ecx, 00000003
00407C57        �. �0F94C0            �setz al
00407C5A        �.�75 22             �jnz short 00407C7E
00407C5C        �. �89C8              �mov eax, ecx
00407C5E        �. �99                �cdq
00407C5F        �. �6A 64             �push 64
00407C61        �. �F73C24            �idiv dword ptr [esp]
00407C64        �. �85D2              �test edx, edx
00407C66        �.�75 12             �jnz short 00407C7A
00407C68        �. �89C8              �mov eax, ecx
00407C6A        �. �99                �cdq
00407C6B        �. �68 90010000       �push 190
00407C70        �. �F73C24            �idiv dword ptr [esp]
00407C73        �. �58                �pop eax
00407C74        �. �4A                �dec edx
00407C75        �. �0F98C2            �sets dl
00407C78        �. �84D2              �test dl, dl
00407C7A        �> �58                �pop eax
00407C7B        �. �0F95C0            �setnz al
00407C7E        �> �0FBEC0            �movsx eax, al
00407C81        �. �8945 DC           �mov [ebp-24], eax
00407C84        �. �8B7D BC           �mov edi, [ebp-44]
00407C87        �. �893C24            �mov [esp], edi
00407C8A        �. �E8 219EFFFF       �call 00401AB0                       ; �TmpFile.00401AB0
00407C8F        �. �50                �push eax                            ; �Arg1
00407C90        �. �8B45 C0           �mov eax, [ebp-40]                   ; �
00407C93        �. �890424            �mov [esp], eax                      ; �
00407C96        �. �E8 B59DFFFF       �call 00401A50                       ; �TmpFile.00401A50
00407C9B        �. �50                �push eax                            ; �Arg1
00407C9C        �. �8B45 DC           �mov eax, [ebp-24]                   ; �
00407C9F        �. �0145 D4           �add [ebp-2C], eax                   ; �
00407CA2        �. �90                �nop                                 ; �
00407CA3        �. �90                �nop                                 ; �
00407CA4        �. �90                �nop                                 ; �
00407CA5        �. �90                �nop                                 ; �
00407CA6        �. �8B45 D0           �mov eax, [ebp-30]                   ; �
00407CA9        �. �40                �inc eax                             ; �
00407CAA        �. �8945 D0           �mov [ebp-30], eax                   ; �
00407CAD        �. �3D 80969800       �cmp eax, 989680                     ; �
00407CB2        �.�0F86 68FFFFFF     �jbe 00407C20                        ; �
Title: List of files in a zip archive
Post by: jj2007 on November 26, 2017, 10:55:33 PM
Build it, then drag an archive over the exe:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  UnzipInit CL$()
  .if !Sign?
        For_ ecx=0 To edx-1
                PrintLine Files$(ecx)
        Next
  .endif
  Inkey CrLf$, "Now copy the names from the console menu"
EndOfCode


Output e.g. from the COM interface archive (http://masm32.com/board/index.php?topic=6313.msg71823#msg71823):
Code: [Select]
GetComInterface.asc
GetComInterface.dll
Title: Re: A suicide proggie
Post by: AW on November 27, 2017, 02:08:34 AM
Ever tried to kill the current executable? It's not that straightforward, for security reasons, but it can be done with little helpers:
Code: [Select]
include \masm32\include\masm32rt.inc ; pure Masm32

.data?
ThisExe db MAX_PATH dup(?)

.code
start:
  mov edi, offset ThisExe
  invoke lstrcpy, edi, chr$("KillMe.exe ")
  invoke lstrcat, edi, rv(GetCommandLine)  ; this returns the path of the current exe
  invoke WinExec, edi, SW_MINIMIZE
  add edi, 11 ; advance to compensate for <KillMe.exe >
  print "check your disk to see if "
  print edi
  print " was killed"
  exit

end start

Source and binaries attached, must sit in the same folder as the current exe.

Come on, JJ  :badgrin: :badgrin:

Try this instead: http://masm32.com/board/index.php?topic=6713.0
Title: Set wallpaper with IActiveDesktop::SetWallpaper
Post by: jj2007 on December 13, 2017, 10:45:07 AM
This should work but it doesn't :(

It builds fine and returns S_OK, no error, but it does not set the wallpaper. MSDN says it's supported for XP and earlier - seriously? But even on XP it has no effect.

include \masm32\MasmBasic\MasmBasic.inc
include IActiveDesktop.inc      ; IActiveDesktop STRUCT, CLSID_ActiveDesktop, IID_IActiveDesktop (attached)
.code
SetMyWallpaper proc pDesktopImg  ; adapted from johnsa's code (http://masm32.com/board/index.php?topic=6736.msg72310#msg72310)
LOCAL pAD
  invoke CoCreateInstance, addr CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, addr IID_IActiveDesktop, addr pAD
  .if eax==S_OK
       CoInvoke pAD, IActiveDesktop.SetWallpaper, pDesktopImg, 0
       deb 4, "SetWp", $Err$()         ; OK, operation completed - but no effect
       CoInvoke pAD, IActiveDesktop.Release
  .endif
  ret
SetMyWallpaper endp
  Init
  If_ Not rv(CoInitializeEx, 0, COINIT_APARTMENTTHREADED) Then invoke SetMyWallpaper, wChr$("\Masm32\examples\exampl04\car\car.jpg")
  invoke CoUninitialize
EndOfCode
Title: Re: Miscellaneous snippets
Post by: Vortex on December 14, 2017, 05:41:02 AM
Hi Jochen,

Can you try the attached sample?
Title: Re: Miscellaneous snippets
Post by: jj2007 on December 14, 2017, 06:56:10 AM
Hi Erol,
Your example changed slightly the position of the existing wallpaper, but the old image remained...
To be continued ;-)
Title: Re: Miscellaneous snippets
Post by: Vortex on December 14, 2017, 07:07:05 AM
Hi Jochen,

Not sure but maybe specifying the full path of the image can solve the problem.

Code: [Select]
WSTR        DesktopImg,"test.bmp"
.
.
coinvoke    pAD,IActiveDesktop,SetWallpaper,OFFSET DesktopImg,0

GetFullPathName can retrieve the full path.
Title: Re: Miscellaneous snippets
Post by: jj2007 on December 14, 2017, 08:09:15 AM
Hi Erol,

Full path works, thanks a lot! Now I'll try my version 8)

P.S.: It works ;)

include \masm32\MasmBasic\MasmBasic.inc
include IActiveDesktop.inc      ; IActiveDesktop STRUCT, CLSID_ActiveDesktop, IID_IActiveDesktop
.code
SetMyWallpaper proc pDesktopImg         ; adapted from Vortex (http://masm32.com/board/index.php?topic=6483.msg72338#msg72338) and johnsa's code (http://masm32.com/board/index.php?topic=6736.msg72310#msg72310)
LOCAL pAD, wpo:WALLPAPEROPT
  ClearLocals
  .if !rv(CoCreateInstance, addr CLSID_ActiveDesktop, NULL, CLSCTX_INPROC_SERVER, addr IID_IActiveDesktop, addr pAD)
        add wpo.dwSize, WALLPAPEROPT
        add wpo.dwStyle, WPSTYLE_CENTER or WPSTYLE_STRETCH
        CoInvoke pAD, IActiveDesktop.SetWallpaper, wRec$(pDesktopImg), 0
        CoInvoke pAD, IActiveDesktop.SetWallpaperOptions, addr wpo, 0
        CoInvoke pAD, IActiveDesktop.ApplyChanges, AD_APPLY_ALL
        CoInvoke pAD, IActiveDesktop.Release
  .endif
  ret
SetMyWallpaper endp
  Init
  Let esi=wCL$()
  .if !rv(CoInitializeEx, 0, COINIT_APARTMENTTHREADED)
        wMsgBox 0, esi, "Set as wallpaper?", MB_OKCANCEL or MB_ICONQUESTION
        If_ eax==IDOK Then <invoke SetMyWallpaper, Qtrim$(Utf8$(esi))>
        invoke CoUninitialize
  .endif
EndOfCode


Full project attached, including a really nice wallpaper - a very special view of a European city. Extract all files to a folder, then drag the jpg over the exe :biggrin:
Title: Delay until
Post by: jj2007 on December 16, 2017, 02:51:15 PM
I am testing a new syntax for Delay (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1212) and would appreciate some results for other Windows versions:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
uselib ntdll
  SetGlobals resMin, resMax, resCurrent
  Init
  invoke NtQueryTimerResolution, addr resMin, addr resMax, addr resCurrent
  deb 4, "Timer resolution", resMin, resMax, resCurrent

  PrintLine CrLf$, "These lines should print about one second after the start, at ", fTime$(0, "HH:mm:??.123"), " millisecs"
  For_ ecx=0 To 4
        Delay Rand(500)         ; sleep 0..499 milliseconds
        NanoTimer()
        PrintLine fTime$(0, "HH:mm:ss.fff"), Tb$, "started"
        Delay until fTime$(s:1, "HH:mm:ss.123")         ; use time$(current plus one second)
        PrintLine fTime$(0, "HH:mm:ss.fff "), Tb$, NanoTimer$(), " passed", CrLf$
  Next
  Inkey Str$("This is Windows version %i", MbWinVersion()), Str$(".%i", ecx)
EndOfCode


Output:
Code: [Select]
Timer resolution
resMin          156001
resMax          5000
resCurrent      10000

These lines should print about one second after the start, at 04:47:??.123 millisecs
04:47:16.057    started
04:47:17.123    1066 ms passed

04:47:17.159    started
04:47:18.123    964 ms passed

04:47:18.191    started
04:47:19.123    932 ms passed

04:47:19.554    started
04:47:20.123    569 ms passed

04:47:20.450    started
04:47:21.123    673 ms passed

This is Windows version 6.1

The new version of the fTime$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1268) macro can display milliseconds using the fff format specifier. See Microsoft: How to: Display Milliseconds in Date and Time Values (https://docs.microsoft.com/en-us/dotnet/standard/base-types/how-to-display-milliseconds-in-date-and-time-values) for details.
Title: Re: Miscellaneous snippets
Post by: felipe on December 16, 2017, 02:54:37 PM
Timer resolution
resMin          156250
resMax          5000
resCurrent      156255

These lines should print about one second after the start, at 23:52:??.123 milli
secs
23:52:37.774    started
23:52:38.123    348 ms passed

23:52:38.161    started
23:52:39.123    962 ms passed

23:52:39.193    started
23:52:40.124    930 ms passed

23:52:40.556    started
23:52:41.123    567 ms passed

23:52:41.451    started
23:52:42.123    672 ms passed

This is Windows version 6.3

From windows 8.1
Title: Re: Miscellaneous snippets
Post by: jj2007 on December 16, 2017, 07:36:52 PM
Thanks, Felipe :t
Here are Win10 results:
Code: [Select]
Timer resolution
resMin          156250
resMax          5000
resCurrent      5007

These lines should print about one second after the start, at 09:35:??.123 millisecs
09:35:03.858    started
09:35:04.123    264 ms passed

09:35:04.159    started
09:35:05.123    964 ms passed

09:35:05.191    started
09:35:06.123    931 ms passed

09:35:06.554    started
09:35:07.123    568 ms passed

09:35:07.450    started
09:35:08.123    672 ms passed

This is Windows version 10.0

Note that even after a reboot, the current resolution is 0.5 milliseconds:
Code: [Select]
resMax          5000
resCurrent      5007

Your Windows 8.1 results are still at the 15.6 ms resolution. It seems they changed it definitely with Win10, which makes sense because a) the hardware got faster and b) even an ordinary browser like FF or PaleMoon sets it to 10000 when you visit YouTube.

So has GetTickCount finally become a high resolution timer?

NOPE. Have a look at these GetTickCount results:
Code: [Select]
ticks   systime
   0    10:02:51.678
   0    10:02:51.679
   0    10:02:51.681
   0    10:02:51.682
   0    10:02:51.683
   0    10:02:51.684
   0    10:02:51.686
  15    10:02:51.688
  15    10:02:51.689
  15    10:02:51.690
  15    10:02:51.691
  15    10:02:51.692
  15    10:02:51.693
  15    10:02:51.695
  15    10:02:51.696
  15    10:02:51.697
  15    10:02:51.698
  15    10:02:51.700
  15    10:02:51.701
  15    10:02:51.702
  31    10:02:51.703
  31    10:02:51.705
  31    10:02:51.706

Between each line, there is a Sleep(1), and the high resolution timer shows that the systemtime gets adjusted in one milliseconds increments; but GetTickCount keeps reporting with its low 15.625 ms granularity 8)
Title: Re: Miscellaneous snippets
Post by: Vortex on December 16, 2017, 09:11:50 PM
Hi Jochen,

Here are my results, XP 64-bit :

Code: [Select]
Timer resolution
resMin          156250
resMax          10000
resCurrent      156250

These lines should print about one second after the start, at 13:11:??.123 milli
secs
13:11:17.531    started
13:11:18.125    591 ms passed

13:11:18.156    started
13:11:19.125    966 ms passed

13:11:19.187    started
13:11:20.125    935 ms passed

13:11:20.562    started
13:11:21.125    560 ms passed

13:11:21.453    started
13:11:22.109    669 ms passed

This is Windows version 5.2
Title: Re: Miscellaneous snippets
Post by: jj2007 on December 16, 2017, 09:15:25 PM
Thanks, Erol. So it starts always 2 ms later, 125 instead of 123... ::)

Similar for XP-32, a Virtual Machine:
Code: [Select]
Timer resolution
resMin          100144
resMax          10032
resCurrent      100144

These lines should print about one second after the start, at 11:16:??.123 milli
secs
11:16:29.859    started
11:16:30.129    254 ms passed

11:16:30.159    started
11:16:31.121    963 ms passed

11:16:31.191    started
11:16:32.122    931 ms passed

11:16:32.553    started
11:16:33.124    570 ms passed

11:16:33.454    started
11:16:34.125    669 ms passed

This is Windows version 5.1
Title: Deleting selected elements from a string array
Post by: jj2007 on December 18, 2017, 08:28:38 AM
A little exercise in deleting elements from a string array:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  void NanoTimer()              ; start the timer
  Recall "TestFile.txt", b$()   ;
  PrintLine NanoTimer$(), " for loading the file into the b$() text array"
  void NanoTimer()              ; start the timer
  xor ecx, ecx
  .Repeat
        If_ Instr_(b$(ecx), "devil", 5) Then <mcs Delete b$(ecx) : dec ecx>
        inc ecx
  .Until ecx>=b$(?)
  Inkey NanoTimer$(), " for deleting the devil. Save the file (y)?"
  If_ eax=="y" Then Store "NoDevil.txt", b$()
EndOfCode


Result on an i5:
Code: [Select]
3458 µs for loading the file into the b$() text array
4954 µs for deleting the devil. Save the file (y)?


The required text file is here (http://www.webalice.it/jj2006/pics/testfile.zip) - unzip to the folder where the attached exe sits.
Title: Deleting selected elements from a text file
Post by: jj2007 on December 19, 2017, 10:00:07 PM
Same as above, but not line-based. Words are removed with Replace$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1079):

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  void NanoTimer()              ; start the timer
  Let esi=FileRead$("TestFile.txt")
  PrintLine NanoTimer$(), " for loading the file"
  void NanoTimer()              ; start the timer
  Let esi=Replace$(esi, "devil", 0, 5)         ; mode 5: case-insensitive, full word, i.e. devils & devilish still there ;-)
  Inkey NanoTimer$(), " for deleting the devil. Save & see the file (y)?"
  If_ eax=="y" Then <mcs FileWrite "NoDevil.txt", esi : ShEx "NoDevil.txt">
EndOfCode


Code: [Select]
2392 µs for loading the file
6269 µs for deleting the devil. Save & see the file (y)?
Title: Mirror$() for UTF-8 strings
Post by: jj2007 on December 24, 2017, 05:21:24 AM
Work in progress, looks fine so far:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
include uMirror$.inc
  SetGlobals a$="Enter text here"
  SetGlobals r$="Введите текст здесь"         ; "Enter text here" in Russian
  SetGlobals cm$, c$="在這裡輸入文字", c4$="<see attached source>"        ; "Enter text here" and some 4-byte encoded string in Chinese
  Init
  PrintLine uMirror$(a$)
  PrintLine uMirror$(r$)
  Let cm$=uMirror$(c$)
  uMsgBox 0, cm$, c$, MB_OK
 EndOfCode


Code: [Select]
ereh txet retnE
ьседз тскет етидевВ

P.S.: For the first time, I see the SMF software (or the browser??) choke over a UTF-8 string, see the red part above. It works fine in RichMasm, see attached *.asc source. This is a rare type of UTF-8 using 4-byte encoding.
Title: ClearFileCache for timings and benchmarks involving disk I/O
Post by: jj2007 on December 24, 2017, 11:07:08 PM
Just learned a new trick from deltarho[1859] (https://www.freebasic.net/forum/viewtopic.php?f=7&t=26208&sid=cce04fa09c9fca354830eeb043f64a98#p241539) - clear the file cache for better testing:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)

ClearFileCache MACRO fname
  push ecx
  ClearLastError
  invoke CreateFile, repargA(f$), GENERIC_READ, 0, 0, OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN or FILE_FLAG_NO_BUFFERING, 0
  invoke CloseHandle, eax
  pop ecx
ENDM

  SetGlobals f$
  Init
  PrintLine "with file caching, ", Cpu$(), ":"  ; OPT_Arg1 C:\Masm32\MasmBasic\AscUser\FatFile.txt
  Let f$=CL$()
  PrintLine "Reading ", f$
  .if !Exist(f$)
        Let f$="\Masm32\include\Windows.inc"
        MsgBox 0, Cat$("Commandline empty or invalid - using this file now:"+CrLf$+f$), "Hi", MB_OK
  .endif
  For_ ecx=0 To 9
        NanoTimer()
        Recall f$, L$()                                                 ; file to array L$() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1172)
        Print Str$("%i strings, ", eax), NanoTimer$()
        NanoTimer()
        Let esi=FileRead$(f$)                                           ; file to buffer esi (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1075)
        PrintLine Str$("\t%i bytes, ", LastFileSize), NanoTimer$()
  Next
  PrintLine CrLf$, "no caching:"
  For_ ecx=0 To 9

        ClearFileCache f$
        NanoTimer()
        Recall f$, L$()
        Print Str$("%i strings, ", eax), NanoTimer$()

        ClearFileCache f$
        NanoTimer()
        Let esi=FileRead$(f$)
        PrintLine Str$("\t%i bytes, ", LastFileSize), NanoTimer$()
  Next
  Inkey "--- hit any key ---"
EndOfCode


The results are pretty clear - upper half uses the cache, lower half doesn't:
Code: [Select]
with file caching, Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz:
Reading C:\Masm32\MasmBasic\AscUser\FatFile.txt
3038300 strings, 294 ms 404739200 bytes, 209 ms
3038300 strings, 354 ms 404739200 bytes, 237 ms
3038300 strings, 337 ms 404739200 bytes, 231 ms
3038300 strings, 346 ms 404739200 bytes, 229 ms
3038300 strings, 328 ms 404739200 bytes, 235 ms
3038300 strings, 332 ms 404739200 bytes, 229 ms
3038300 strings, 339 ms 404739200 bytes, 236 ms
3038300 strings, 337 ms 404739200 bytes, 238 ms
3038300 strings, 339 ms 404739200 bytes, 237 ms
3038300 strings, 334 ms 404739200 bytes, 239 ms

no caching:
3038300 strings, 4999 ms        404739200 bytes, 4903 ms
3038300 strings, 4998 ms        404739200 bytes, 4938 ms
3038300 strings, 5011 ms        404739200 bytes, 5061 ms
3038300 strings, 5010 ms        404739200 bytes, 4919 ms
3038300 strings, 5002 ms        404739200 bytes, 4897 ms
3038300 strings, 5003 ms        404739200 bytes, 4903 ms
3038300 strings, 5025 ms        404739200 bytes, 4923 ms
3038300 strings, 5016 ms        404739200 bytes, 4921 ms
3038300 strings, 4994 ms        404739200 bytes, 4906 ms
3038300 strings, 5038 ms        404739200 bytes, 4904 ms

Project attached. You can drag any plain text or Unicode file over the exe, but note that on Win7-64, for example, HeapAlloc begins to choke at around 900MB. If you haven't used the file for a while, the very first line will show a higher time - it needs to be cached...
Title: Spreadsheet editor
Post by: jj2007 on December 28, 2017, 04:15:40 AM
Work in progress, an extension of this post. (http://masm32.com/board/index.php?topic=5976.msg72774#msg72774)

Fearless and José put me on the right track, see Select a single cell in a listview (http://masm32.com/board/index.php?topic=6788.msg72804#msg72804). So here is the proof that it is indeed possible to use a listview control as a replacement for Excel :icon_mrgreen:

You may have to click two or three times on a cell to select it. Hitting Return does not work. Saving the edits works, provided that you selected another cell before; the resulting temp file will open with your user-defined *.tab viewer, Excel or LibreOffice, whatever. Note that both Excel and OpenCalc are too dumb to recognise that it's a UTF-8 coded *.tab file. RichMasm shows it correctly, though.

The control is Unicode-aware, as you can see in cell R3C1 ;)

P.S.: There is a little mystery about the order of the header columns. I swear it's not my fault.
Title: Re: Miscellaneous snippets
Post by: fearless on December 28, 2017, 05:25:03 AM
return in the listview or return in the editbox doesnt work?

Might be possible to get NM_RETURN and handle last known cell (row,col) to "edit" with the editbox placement. Or maybe some handling of WM_CHAR / WM_KEYDOWN directly in a subclass of listview parent, or NM_RETURN in that subclass. Might require IsDialogMessage in messageloop and handle want all keys or want return thing from dlg message thing (forget exact name of the msg event)
Title: Re: Miscellaneous snippets
Post by: jj2007 on December 28, 2017, 06:49:10 AM
Slow down, man :P

Seriously: I will check what is available. Just discovered a very old article: Easy Navigation Through an Editable List (https://www.codeguru.com/cpp/controls/listview/editingitemsandsubitem/article.php/c937/Easy-Navigation-Through-an-Editable-List-View.htm) Posted by Lee Nowotny on June 19th, 1999 - just a bit over 18 years ago. Good to see that I'm not the first one to attack this. Fortunately I have a nice tool called deb (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1019):
Code: [Select]
Event Message
  inc msgCount
  deb 4, "main WndProc", chg:msgCount

With another one for the listview subproc, you can wade through tons of stuff like this:
Code: [Select]
main WndProc    810     WM_NOTIFY: -121
SubListview     811     WM_NOTIFY: -121
main WndProc    813     WM_PARENTNOTIFY
SubListview     817     WM_MOUSEACTIVATE
SubListview     819     WM_LBUTTONDOWN
main WndProc    821     WM_MOUSEACTIVATE
main WndProc    823     WM_NOTIFY: NM_TOOLTIPSCREATED
main WndProc    825     WM_KILLFOCUS
SubListview     826     WM_CAPTURECHANGED
SubListview     827     WM_IME_SETCONTEXT
main WndProc    829     WM_IME_SETCONTEXT
SubListview     832     WM_SETFOCUS
main WndProc    874     WM_NOTIFY: -121
main WndProc    881     WM_NOTIFY: -121
main WndProc    888     WM_NOTIFY: -121
main WndProc    895     WM_NOTIFY: -121
main WndProc    902     WM_NOTIFY: -121
main WndProc    909     WM_NOTIFY: -121
main WndProc    911     WM_NOTIFY: -121
main WndProc    913     WM_NCACTIVATE
main WndProc    915     WM_GETTEXT
main WndProc    917     WM_ACTIVATE
SubListview     918     WM_CAPTURECHANGED
main WndProc    920     WM_ACTIVATEAPP
SubListview     921     WM_KILLFOCUS

I will need SubListview     5030    WM_LBUTTONDOWN, the built-in activation is too clumsy. And there are many more interesting messages to exploit...
Title: Table control
Post by: jj2007 on December 29, 2017, 10:40:18 AM
Playtime :P

The main features are implemented: Loading, editing, navigation and saving. Let me know if it works on your machine.

There will be two ways to create it:

  if 0
       Recall "FatTable.tab", some$(), tab
        GuiControl MyData, "table", y500, h500, some$()
  else
       GuiControl MyData, "table", y500, h500, "FatTable.tab"
  endif


The first one assumes that you have already a two-dimensional array, so you pass it as some$().
The second one simply passed a filename.

Confused source, exe and two other files attached. Extract to a folder and launch the exe.
Title: Re: Miscellaneous snippets
Post by: HSE on December 29, 2017, 10:56:12 AM
Working JJ :t

Still don't work ESC nor Ctrl-Z  :biggrin:
Title: Floating point comparisons
Post by: jj2007 on December 29, 2017, 11:08:45 AM
Still don't work ESC nor Ctrl-Z  :biggrin:

Thanks - it's work in progress and needs a lot of cleanup.

Another topic, floating point comparisons:

include \masm32\MasmBasic\MasmBasic.inc
  SetGlobals REAL10 MyPI=3.141592653589793238, hiPI=3.141592653589793239, loPI=3.141592653589793237
  SetGlobals REAL10 MyPI30=3.141592653589793238e30, hiPI30=3.141592653589793239e30, loPI30=3.141592653589793237e30
  SetGlobals REAL10 MyPIm30=3.141592653589793238e-30, hiPIm30=3.141592653589793239e-30, loPIm30=3.141592653589793237e-30
  Init
  PrintLine Str$("\nPI=%Jf", MyPI), " - top precision:"
  Fcmp hiPI, PI, top
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "hiPi is greater"
  .else
        PrintLine "hiPi is lesser"
  .endif
  Fcmp loPI, PI, top
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "loPi is greater"
  .else
        PrintLine "loPi is lesser"
  .endif

  PrintLine "---- high precision:"
  Fcmp hiPI, PI, hi
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "hiPi is greater"
  .else
        PrintLine "hiPi is lesser"
  .endif

  Fcmp loPI, MyPI, hi
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "loPi is greater"
  .else
        PrintLine "loPi is lesser"
  .endif

  PrintLine Str$("\nPI30=%Jf", MyPI30), " - top precision:"

  Fcmp hiPI30, MyPI30, top
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "hiPi is greater"
  .else
        PrintLine "hiPi is lesser"
  .endif
  Fcmp loPI30, MyPI30, top
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "loPi is greater"
  .else
        PrintLine "loPi is lesser"
  .endif

  PrintLine "---- high precision:"
  Fcmp hiPI30, MyPI30, hi
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "hiPi is greater"
  .else
        PrintLine "hiPi is lesser"
  .endif
  Fcmp loPI30, MyPI30, hi
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "loPi is greater"
  .else
        PrintLine "loPi is lesser"
  .endif

  PrintLine Str$("\nPI-30=%Jf", MyPIm30), " - top precision:"

  Fcmp hiPIm30, MyPIm30, top
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "hiPi is greater"
  .else
        PrintLine "hiPi is lesser"
  .endif
  Fcmp loPIm30, MyPIm30, top
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "loPi is greater"
  .else
        PrintLine "loPi is lesser"
  .endif

  PrintLine "---- high precision:"
  Fcmp hiPIm30, MyPIm30, hi
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "hiPi is greater"
  .else
        PrintLine "hiPi is lesser"
  .endif
  Fcmp loPIm30, MyPIm30, hi
  .if Zero?
        PrintLine "they are equal"
  .elseif FcmpGreater
        PrintLine "loPi is greater"
  .else
        PrintLine "loPi is lesser"
  .endif

  Inkey
EndOfCode


Output (as expected):
Code: [Select]
PI=3.141592653589793238 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal

PI30=3.141592653589793238e+30 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal

PI-30=3.141592653589793238e-30 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal
Title: Re: Miscellaneous snippets
Post by: LiaoMi on December 29, 2017, 11:34:53 AM
Theoretically, if the source code is a template like in Delphi, then it's time to start writing a good decompiler for a MasmBasic  :P

Code: [Select]
PI=3.141592653589793238 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal

PI30=3.141592653589793238e+30 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal

PI-30=3.141592653589793238e-30 - top precision:
hiPi is greater
loPi is lesser
---- high precision:
they are equal
they are equal
Title: Get size of a file over 4 GB
Post by: jj2007 on January 05, 2018, 07:15:54 AM
For syntax and options, see Lof() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1036)

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  .if !Exist("GigaTest.txt")
        Inkey "Are you sure you want to create a 4 GB file in ", CurDir$(), "(y)?", CrLf$
        .if eax=="y"
                ClearLastError
                Open "O", #1, "GigaTest.txt"
                .if eax==INVALID_HANDLE_VALUE
                                Print "Open:  ", Err$()
                .else
                                ClearLastError
                                Let edi=FileRead$("\Masm32\include\Windows.inc")+FileRead$("\Masm32\include\WinExtra.inc")
                                PrintLine Str$("Len=%i bytes\n", Len(edi))      ; 2045966 bytes
                                Print "Read:  ", Err$()
                                ClearLastError
                                For_ ecx=0 To 2500      ; 2501*2045966=5116960966
                                       PrintLine #1, edi
                                Next
                                Print "Write: ", Err$()
                                Close
                .endif
        .endif
  .endif
  Inkey Str$("Filesize = %u bytes", edx::Lof("GigaTest.txt")), Str$(" = %3f GB", edx::Lof("GigaTest.txt")/(1 shl 30))
EndOfCode


Output: Filesize = 5116965968 bytes = 4.77 GB
Title: Re: Miscellaneous snippets
Post by: HSE on January 12, 2018, 12:10:41 AM
Hi JJ!

I extract part of the program. Still not working very well, but the main features are there (I think).

Regards

LATER: New file. I forget a little problem if first column is activated.

A lot later: New file. I forget something else.
Title: Re: Miscellaneous snippets
Post by: jj2007 on January 12, 2018, 01:24:04 AM
Very nice work :t
Title: Send mail with attachments
Post by: jj2007 on March 12, 2018, 08:55:41 PM
Drag files over the exe and tell me how your mail client reacts. I've tested it on Win7-64 and Win10 Home with Thunderbird.

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
mapiMsg         MapiMessage <>

  Init
  Dll "Mapi32"
  Declare MAPISendMail, 5

  mov edi, offset mapiMsg
  Mapi equ [edi.MapiMessage]
  mov Mapi.ulReserved, CP_UTF8   ; does not work *)
  mov Mapi.lpszSubject, Chr$("Greetings from Masm")
  mov Mapi.lpszNoteText, cfm$("Hi folks,\nNever was sending mails easier!\nSincerely,\njj2007")
  GetFiles CL                           ; get a list of files from the commandline
  mov Mapi.nFileCount, eax
  xchg eax, ecx
  Dim MapiFiles(ecx) As MapiFileDesc
  or MapiFiles(ecx, nPosition), -1
  For_ ecx=0 To ecx-1
        push Files$(ecx)
        lea eax, MapiFiles(ecx, lpszPathName)
        pop [eax]
  Next
  lea eax, MapiFiles(0, ulReserved)
  mov Mapi.lpFiles, eax
  .if MAPISendMail(0, 0, addr mapiMsg, MAPI_DIALOG, 0)
        MsgBox 0, Str$("Mapi error %i", eax), "An error occurred:", MB_OK
  .endif
EndOfCode



Project attached. Note that there is a blank line before the "Hi folks"; in theory, the nPosition member of the MapiFileDesc structure could influence that, but according to this post on ExpertExchange (https://www.experts-exchange.com/questions/28399412/MapiSendMail-attachments-don%27t-display.html), "It appears that MapiSendMail does not perform as Microsoft has stated in their documentation" 8)

*) MapiMessage structure (https://msdn.microsoft.com/en-us/library/windows/desktop/dd296732%28v=vs.85%29.aspx):

Quote
ulReserved

    Reserved; must be zero or CP_UTF8. If CP_UTF8, the following are UTF-8 instead of ANSI strings: lpszSubject, lpszNoteText, lpszMessageType, lpszDateReceived, lpszConversationID.

And this is simply not true, Redmond - see https://stackoverflow.com/questions/9943314/windows-mapi-unicode-issue  :icon_redface:
Title: GetRandomStrings
Post by: jj2007 on March 15, 2018, 01:30:08 AM
Could be useful for testing sort algos etc:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dll "RandomStrings"                   ; the DLL must be in the same folder
  Declare RandomString
  .Repeat
        For_ ecx=0 To 5
                Print RandomString(), " "
        Next
        Inkey cfm$("- more (no=n)?\n")
  .Until eax=="n" || eax==VK_ESCAPE
EndOfCode


Output:
Code: [Select]
imprisoning barked channel superstitious practical spectre - more (no=n)?
currants shower agitation lions motherly forces - more (no=n)?
negus proofs devil chose observation individuals - more (no=n)?
quarrelled whistled place commanded stipulation cannot - more (no=n)?
deeds settled taught verdict unsocial goeth - more (no=n)?
nefarious herald extinguishes accounted system military - more (no=n)?
worse colouring attacks transfixed hearts binding - more (no=n)?
instruments rally singly sword until profit - more (no=n)?
tranquilly luring convinced unchecked trade hears - more (no=n)?
violent packet sternly tearing kneeled crumbled - more (no=n)?
... etc ...
Title: Re: Miscellaneous snippets
Post by: anunitu on March 15, 2018, 03:33:13 AM
i am thinking JJ is the REAL MASM Wizard for sure.
Title: Re: Miscellaneous snippets
Post by: jj2007 on March 15, 2018, 05:37:33 AM
Thanks - too much honour :icon_redface:

Here is version 2, with pseudo and real random modes (and 20,000 words for choice):

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dll "RandomStrings"                   ; the DLL must be in the same folder
  Declare RandomString, 1
  .Repeat
        For_ ecx=0 To 5
                Print RandomString(0), " "      ; 0=pseudo, 1=real random
        Next
        Inkey cfm$("- more (no=n)?\n")
  .Until eax=="n" || eax==VK_ESCAPE
EndOfCode


In mode 0, the sequence is always identical. It looks random, and is random according to some popular measures of randomness, but you'll always see the same strings. This is particular useful if, for example, your sort algo stumbles over a specific word, and you want to debug that event. It's also a bit faster - in "real" mode, one Million strings need almost one second on my i5. The pseudo mode is 70 times faster.
Title: Tweety rotates
Post by: jj2007 on April 26, 2018, 12:24:16 PM
Little demo for image rotation (strangely enough, this GdiPlus function has never been used in this forum ::)):

GuiParas equ "Image rotation demo", w400, h440
include \masm32\MasmBasic\Res\MbGui.asm
  GuiImageCallback Rotate       ; user-defined function
  SetGlobals halfWidth, halfHeight, REAL4:rotateAngle, movX, movY
Event Paint
  imul eax, GuiWidth, 100       ; width*100/128
  sar eax, 8
  add eax, 20
  mov halfWidth, eax
  imul eax, GuiHeight, 100      ; height*100/128
  sar eax, 8
  mov halfHeight, eax
  GuiImage 99, 0, 0, halfWidth, halfHeight      ; res ID, x, y, w, h 
  GuiCls                               ; trigger next paint event
EndOfEvents
Rotate:
  fild halfWidth                        ; an integer
  fadd FP4(35.0)                        ; add a fixed x offset
  fstp movX                             ; Gdi+ needs a float
  fild halfHeight
  fadd FP4(32.0)
  fstp movY
  gdi+ GdipTranslateWorldTransform, giGraphics, movX, movY, MatrixOrderPrepend  ; move to the middle
  gdi+ GdipRotateWorldTransform, giGraphics, rotateAngle, MatrixOrderPrepend    ; rotate
  fld rotateAngle                       ; add one degree for next paint event
  fadd FP4(1.0)
  fstp rotateAngle
  ret
GuiEnd
Title: Where do you live?
Post by: jj2007 on May 03, 2018, 09:39:29 AM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
include Geo.inc
  Init
  PrintLine "GEO_LCID:   ", Tb$, Geo$(GEO_LCID)
  PrintLine "GEO_RFC1766:", Tb$, Geo$(GEO_RFC1766), CrLf$
  Inkey "I live in ", Geo$(), " (aka ", Geo$(GEO_OFFICIALNAME), ") at ", Geo$(GEO_LATITUDE), " North, ", Geo$(GEO_LONGITUDE), " East"
EndOfCode


Output:
Code: [Select]
GEO_LCID:       00000809
GEO_RFC1766:    en-it

I live in Italia (aka Repubblica italiana) at 42.768 North, 12.492 East
Title: Push & Pop xmm registers
Post by: jj2007 on May 06, 2018, 08:03:06 PM
Inspired by the Campus post PUSH & POP question (http://masm32.com/board/index.php?topic=7113.msg76861#msg76861) by DayDreamer:

include \Masm32\MasmBasic\Res\JBasic.inc        ; ## builds in 32- or 64-bit mode with ML and UAsm
include PushPopXmm.inc
.code
xvalue0         OWORD 11111111222222223333333344444444h
xvalue1         OWORD 55555555666666667777777788888888h
Init           ; OPT_64 1      ; put 0 for 32 bit, 1 for 64 bit assembly
  PrintLine Chr$("This code was assembled with ", @AsmUsed$(1), " in ", jbit$, "-bit format")
  movups xmm0, xvalue0
  movups xmm7, xvalue1
  usedeb=1
  deb 4, "before", x:xmm0, x:xmm7
  ppxInit
  PushX xmm0
  PushX xmm7
  PopX xmm0                     ; note the order: we
  PopX xmm7                     ; are swapping values
  deb 4, "popped & swapped", x:xmm0, x:xmm7
  ; PopX xmm0                           ; uncomment to see the error handling
  MsgBox 0, "Wow, it works!!!!", "Hi", MB_OK or MB_SETFOREGROUND
EndOfCode


Output:
Code: [Select]
This code was assembled with UAsm64 in 64-bit format
before
x:xmm0  3333333344444444h
x:xmm7  7777777788888888h
popped & swapped
x:xmm0  7777777788888888h
x:xmm7  3333333344444444h

Attached the macro and a standard MasmBasic example.
Title: Re: Miscellaneous snippets
Post by: daydreamer on May 07, 2018, 01:02:13 AM
great macros :t
Title: Re: Where do you live?
Post by: HSE on May 07, 2018, 05:44:32 AM

Output:
Code: [Select]
GEO_LCID:       00000809
GEO_RFC1766:    en-it

I live in Italia (aka Repubblica italiana) at 42.768 North, 12.492 East
Are tou sure?

 :biggrin:
Code: [Select]
GEO_LCID:       00000C0A
GEO_RFC1766:    es-es

I live in España (aka Reino de España) at 40.396 North, -3.551 East
Title: GeoInfo
Post by: jj2007 on May 07, 2018, 08:08:04 AM
Well, I do live in Italy, but I haven't check how exact the LatLong figures are. Any idea how the OS determines a user's position?
Title: Re: GeoInfo
Post by: HSE on May 07, 2018, 09:28:14 AM
Any idea how the OS determines a user's position?

OS don't know user's position. I think it's just a point in country center. You declare country when setting language and location. In spanish language España it's default country. In italian language... let me think... mmh  ::)
Title: Re: GeoInfo
Post by: daydreamer on May 07, 2018, 02:47:29 PM
Well, I do live in Italy, but I haven't check how exact the LatLong figures are. Any idea how the OS determines a user's position?
Same as timezone= the capital of your country?cant you check Rome in google maps and see if its same long and latitude?
Title: Re: GeoInfo
Post by: jj2007 on May 07, 2018, 05:08:02 PM
Same as timezone= the capital of your country?cant you check Rome in google maps and see if its same long and latitude?

Yes, you can: Enter the result as e.g. 42.768, 12.492 into Google Maps. It seems that the Geo$() function returns the middle of the country. In theory, you can fine-tune your location, but it's a per user setting in the Control Panel, be careful.
Title: Re: Miscellaneous snippets
Post by: LordAdef on May 09, 2018, 04:30:36 PM
Quote
GEO_LCID:       00000416
GEO_RFC1766:    pt-us

I live in Estados Unidos (aka Estados Unidos da América) at 39.450 North, -98.908 East

Hey, the little guy placed me in the US!
Title: Re: Miscellaneous snippets
Post by: daydreamer on May 11, 2018, 04:17:15 AM
Curious if masm or masm basic also supports print in hexadecimal like c++  cout has?
Title: Re: Miscellaneous snippets
Post by: jj2007 on May 11, 2018, 06:28:44 AM
Curious if masm or masm basic also supports print in hexadecimal like c++  cout has?

Sure:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  mov ecx, 123456789
  Print Str$("Decimal:\t%i\n", ecx)
  mov esi, 12345678h
  PrintLine "Hexadecimal:", Tb$, Hex$(esi)
  movd xmm0, esi
  pshufd xmm0, xmm0, 0
  deb 4, "for debugging", ecx, x:esi, x:xmm0
  Inkey "-- hit any key --"
EndOfCode


Code: [Select]
Decimal:        123456789
Hexadecimal:    12345678

for debugging
ecx             123456789
x:esi           12345678
x:xmm0          12345678 12345678 12345678 12345678

The Masm32 SDK has the hex$() macro, e.g. as print hex$(esi), 13, 10
Title: Create a temp web page to save a link
Post by: jj2007 on May 14, 2018, 06:37:05 AM
Sometimes I need to save a webpage but don't want to open it. So I copy the URL and run this proggie (source+exe attached):

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi=Clip$()               ; get URL from clipboard, e.g. http://masm32.com/board/index.php?action=unread
  .if Instr_(esi, "://")
        FileWrite "SaveLinkAsTemp.html", Cat$(Chr$("<html><head><title>Temporary link</title></head>", 13, 10, "<body>", 60, "a href=", 34)+esi+Chr$(34, 62, "Right-click here and choose 'Save Link as...' to download ")+esi+Chr$(60, "/a", 62, "</body></html>"))
        ShEx "SaveLinkAsTemp.html"      ; launch the browser
  .else
        MsgBox 0, esi, "No URL found:", MB_OK
  .endif
EndOfCode


Title: Check a file for http:// and friends
Post by: jj2007 on May 18, 2018, 11:59:07 AM
Attached a little file DownloadMasm32.exe that does something entirely harmless:
Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc
  Init
  Let esi="0.75=draob?php.xedni/draob/moc.23msam//:ptth"
  PrintLine esi
  Let edi=FileRead$(Mirror$(esi))
  Inkey NoTag$(edi)
EndOfCode

In addition, the attachment contains a project that finds http:// and https:// in files, even if they are mirrored; just drag a file over SpyWareScanMB.exe 8)

Warning: While SpyWareScanMB.exe finds interesting http:// and https:// matches in exes and dlls, it is not a replacement for an AntiVirus. Malware writers use more sophisticated tricks to hide their URLs.
Title: Print formatted text
Post by: jj2007 on June 25, 2018, 03:55:17 AM
This snippet
- reads a text file into a RichEdit control (its name is supplied by the commandline)
- formats the first line in bold
- on request via the menu, prints the text.

To test it, extract all files to a temporary folder and drag the text file over the exe (the *.asc file is the source as RTF).

If needed, the whole process can be automated, i.e. eliminate the Event Menu step and just run the exe with the commandline argument, then exit automatically. See PrintRtf (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1384) for printer dialog handling options.


GuiMenu equ @File, &Open, &Print, E&xit
GuiParas equ "Print formatted text demo", x100, y100, w400, h200; , cblack, b00FFFFD0h
include \masm32\MasmBasic\Res\MbGui.asm

  MakeFont hMyFont, Height:20, "Lucida Handwriting"
  GuiControl MyEdit, "RichEdit", font hMyFont
  SetGlobals f$, charfmt:CHARFORMAT2
  Let f$=FileRead$(CL$())               ; read the text file passed in the commandline
  SetWin$ hMyEdit=f$
  .if Instr_(f$, CrLf$)
       dec edx                         ; index of CrLf-1
       invoke SendMessage, hMyEdit, EM_SETSEL, 0, edx
       m2m charfmt.cbSize, CHARFORMAT2
       m2m charfmt.dwMask, CFM_BOLD            ; CharFtMask
       m2m charfmt.dwEffects, CFE_BOLD         ; Character effects
       invoke SendMessage, hMyEdit, EM_SETCHARFORMAT, SCF_SELECTION, ADDR charfmt
       invoke SendMessage, hMyEdit, EM_SETSEL, 0, 0
  .endif

Event Menu
  .if MenuID==1
        void PrintRtf(hMyEdit, 1)     ; 0=use default printer, 1=ask for printer dialog
  .endif
GuiEnd
Title: Launcher
Post by: jj2007 on June 27, 2018, 02:54:41 PM
Code: [Select]
include \masm32\include\masm32rt.inc

.data
txFile db "extracted.exe", 0
bytesWritten dd ?

.code
start:
  invoke FindResource, 0, 99, RT_RCDATA
  .if eax
xchg eax, ebx ; hRes
push rv(SizeofResource, 0, ebx)
push rv(LoadResource, 0, ebx) ; returns pointer to content in eax
invoke CreateFile, addr txFile, GENERIC_WRITE, 0, 0, CREATE_ALWAYS, 0, 0
xchg eax, esi
pop eax ; pointer to content
pop ecx ; size in bytes
invoke WriteFile, esi, eax, ecx, addr bytesWritten, 0
invoke CloseHandle, esi
invoke WinExec, addr txFile, SW_SHOW
  .endif
  exit
end start
Title: Re: Miscellaneous snippets
Post by: HSE on June 27, 2018, 11:36:18 PM
 :t
Title: Check if a file is older than a specified date
Post by: jj2007 on July 07, 2018, 08:20:15 PM
Just encountered a case where I had to check if a file was older than dd.month.year, and needed a snippet to perform this check:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  .if Exist(CL$())
        sub esp, 2*FILETIME             ; create two structures on the stack
        movlps QWORD ptr [esp], TimeSF (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1328)("02.07.2018 11:16:50")   ; European format!
        lea ecx, [esp+QWORD]
        movlps QWORD ptr [ecx], GfLastWrite (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1067)(-1)         ; the lower QWORD returns the FILETIME
        invoke CompareFileTime, ecx, esp
        add esp, 2*FILETIME             ; correct the stack
        .if signed eax<0
                wMsgBox 0, wCL$(), "File is older. Process?", MB_YESNOCANCEL
                .if eax==IDYES
                                ; ... do stuff ...
               .endif
        .else
                wMsgBox 0, wCL$(), "File is younger:", MB_OK
        .endif
  .else
        wMsgBox 0, wCL$(), "No such file:", MB_OK
  .endif
EndOfCode
Title: Create a hundred folders
Post by: jj2007 on July 11, 2018, 09:26:40 PM
Create a hundred folders, write a testfile to each of them:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  For_ ecx=0 To 99
        Let esi=Str$("New Folder%i", ecx)
        MakeDir esi
        .Break .if !Zero?
        Print "+"
        Let esi=esi+"\test.txt"
        PrintLine Str$(ecx), Tb$, esi
        FileWrite esi, Str$("Test %i", ecx)
  Next
EndOfCode

Title: Numbers only
Post by: jj2007 on July 14, 2018, 05:10:28 AM
An edit control that allows to enter only valid decimal numbers. Bug feedback welcome :biggrin:

P.S.: PNG_LoadFile à la MasmBasic attached, using GuiImage (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1362). The *.asc source opens in WordPad, but here it is anyway for those who can't find WordPad or RichMasm (http://masm32.com/board/index.php?topic=5314.0):

include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
GuiImage "car.png", fit
GuiEnd
Title: Re: Numbers only
Post by: zedd151 on July 19, 2018, 09:20:26 AM
An edit control that allows to enter only valid decimal numbers. Bug feedback welcome :biggrin:


oops!    :greensml: 


You did say 'decimal' numbers, not integers, right?




Also for the png image 'fit' viewer, when resizing from either side or from the top, the image resizes reflecting the new dimensions of the window.
But when resizing the window from the bottom, it crops or cuts off the image.
Title: Re: Numbers only
Post by: jj2007 on July 19, 2018, 10:26:39 AM
You did say 'decimal' numbers, not integers, right?

Thanks for the feedback. Try 1234567890.123456784 vs 1234567890.123456785 - this is REAL10 precision, and it has its limits, i.e. around 18 digits.

        MovVal ST(0), Win$(@hWnd)
        SetWin$ hMyResult=Str$("Result=%Jf", ST(0)v)

If you replace the "J" with an "I", it displays one digit less, and all numbers will be correct.

Quote
when resizing the window from the bottom, it crops or cuts off the image.

Interesting. It works correctly on this Win7-64 machine. Just made a test with my WinXP VM, and you are right: When resizing from left or top, it works (but with tremendous flicker - on Win7, it's smooth); when resizing from right or bottom, it crops. Hmmm :(
Title: Re: Miscellaneous snippets
Post by: zedd151 on July 19, 2018, 10:34:20 AM
Windows XP Pro SP3  in VirtualBox <-- may have something to do with it?


The screen capture shows the top image resized from lower right upward


The bottom shows resized from top left downward.


Windows 7 32 bit works as advertised.


With the newer hardware that is out these days, it's a shame to have to run xp in a virtual machine.
Title: Re: Miscellaneous snippets
Post by: jj2007 on July 19, 2018, 10:52:06 AM
Windows XP Pro SP3  in VirtualBox <-- may have something to do with it?

I doubt it, VM and real machine will probably behave the same. Googling for "wm_sizing" "xp" yields lots of results, it could be a known problem.
Title: Re: Miscellaneous snippets
Post by: zedd151 on July 19, 2018, 11:01:25 AM


Googling for "wm_sizing" "xp" yields lots of results, it could be a known problem.


Only way to know for sure is to get someone that has XP installed natively on their system to test the program.

Title: Re: Miscellaneous snippets
Post by: FORTRANS on July 20, 2018, 01:12:44 AM
Hi,

   Tested the ShowPng on Windows XP.  Seems to crop on resizing.
maximize and restore causes the image to fit the window.  Is
that what was wanted?

Regards,

Steve
Title: Re: Miscellaneous snippets
Post by: jj2007 on July 20, 2018, 04:06:05 AM
on Windows XP.  Seems to crop on resizing.... Is that what was wanted?

Steve,
No, not really, see reply #53+#54. It's limited to XP, though. Apparently one message is not being sent correctly in XP.
Title: Re: Miscellaneous snippets
Post by: FORTRANS on July 20, 2018, 04:42:33 AM
Hi Jochen,

   Okay, how about:

Upper left  Resize
Top         Resize
Upper right Resize
Right       Crop
Lower right Crop
Bottom      Crop
Lower left  Resize
Left        Resize
Cropped to maximize, Resize
Maximum to restore, Resize


   More useful I hope?  Or am I still missing things as usual?

Regards,

Steve N.
Title: Re: Miscellaneous snippets
Post by: jj2007 on July 20, 2018, 04:53:05 AM
Your analysis is absolutely correct: XP behaves like that. Those resizing attempts that actually move the window trigger the resizing of the image. All others don't. But I would have to dig deep into the code to find a workaround, and I am not sure if XP is important enough to justify that effort :icon_mrgreen:
Title: Len, wLen, uLen
Post by: jj2007 on July 20, 2018, 12:17:04 PM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi="Нажмите на эту кнопку"              ; "Click on this button" in Russian
  Print Str$("Len(esi)=\t%i\n", Len(esi))      ; treated as Ansi
  Print Str$("uLen(esi)=\t%i\n", uLen(esi))    ; treated as Utf8
  Print Str$("wLen(esi)=\t%i\n", wLen(wRec$(esi)))     ; treated as Unicode (wRec$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1381): convert Utf8 to wide string)
  Print
  Let esi="在這裡輸入文字"                       ; "Enter text here" in Chinese
  Print Str$("Len(esi)=\t%i\n", Len(esi))      ; treated as Ansi
  Print Str$("uLen(esi)=\t%i\n", uLen(esi))    ; treated as Utf8
  Print Str$("wLen(esi)=\t%i\n", wLen(wRec$(esi)))     ; treated as Unicode
EndOfCode


Code: [Select]
Len(esi)=       39
uLen(esi)=      21
wLen(esi)=      21

Len(esi)=       21
uLen(esi)=      7
wLen(esi)=      7

Note that the uLen macro does not check whether the string is valid Utf8 (credits to PaulSquires (https://www.freebasic.net/forum/viewtopic.php?f=6&t=26888&sid=a194cedab48d078a6e22d2eca6cae2f7#p249682)). Example:

  Let esi="Click on this button"+Chr$(169)      ; Ansi with one extra character
  .if rv(MultiByteToWideChar, CP_UTF8, MB_ERR_INVALID_CHARS, esi, Len(esi), NULL, 0) == 0
        PrintLine "[", esi, "] is not a valid Utf8 string"
  .else
        Print "[", esi, "]", Str$("has %i bytes and is a valid Utf8 string\n", eax)
  .endif


Code: [Select]
[Click on this button©] is not a valid Utf8 string
Len(esi)=       21
uLen(esi)=      21
wLen(esi)=      21

Full project attached.
Title: Re: Miscellaneous snippets
Post by: Antariy on July 21, 2018, 06:53:12 AM
Hi Jochen

You wondered why strlen for UTF8 should be different proc than regular (single-byte encodings like ASCII/ANSI/ISO/etc) strlen.
Now probably you can review that thread just for fun :biggrin:

http://masm32.com/board/index.php?topic=2369.msg24543#msg24543
Title: Utf8 macros
Post by: jj2007 on July 21, 2018, 07:12:05 AM
Welcome back, my friend! Yes, that thread was interesting - almost 5 years ago. Time flies. In the meantime, I had forgotten that exchange of views, but MasmBasic does have some dedicated macros, like uLen, uLeft$ and uMid$...
Title: Re: Miscellaneous snippets
Post by: Antariy on July 21, 2018, 07:21:32 AM
Welcome back, my friend! Yes, that thread was interesting - almost 5 years ago. Time flies. In the meantime, I had forgotten that exchange of views, but MasmBasic does have some dedicated macros, like uLen, uLeft$ and uMid$...

Yes, that was purpose of that thread and algo research (making utf8 chars walking faster if possible)... strlen is the simplest usage of that implementation, but more important are string-manipulation functions like basic-like ones you mentioned :biggreen: It is harder to Mid$ something from the random dataflow of utf8 string than from other - fixed-width (length/size) - encodings like ASCII/ANSI/UTF16/32/etc are.
Title: Re: Miscellaneous snippets
Post by: Antariy on July 21, 2018, 07:25:44 AM
So, you implemented those in your MB project, very cool and nice :T :t
Title: Re: Miscellaneous snippets
Post by: jj2007 on July 21, 2018, 07:52:21 AM
I rolled my own, actually. Your code is too complex for my old brain. But we could organise a speed test ;-)
Code: [Select]
uLen MACRO arg
  push esi
  push edx
  ifdifi <esi>, <arg>
mov esi, repargA(arg)
  endif
  xor edx, edx
  .While 1
lodsb
.Break .if !al
inc edx
.if al>=10000000b ; 128
inc esi
.if al>=11100000b
inc esi
.if al>=11110000b
inc esi
.if al>=11111000b
    inc esi
.endif
.endif
.endif
.endif
  .Endw
  xchg eax, edx
  pop edx
  pop esi
  EXITM <eax>
ENDM
Title: MRU: Most Recently Used
Post by: jj2007 on July 25, 2018, 09:30:58 AM
Attached a little demo project; I'd like to get some feedback on the behaviour of the MRU menu. The archive has source code (*.asc), but it won't build with the current MasmBasic version.

I am testing three macros:
- SetMru "somefile.ini": reads recently used files from disk and adds them to the menu
- AddMru SomeFile$: adds opened or saved filename to the menu
- MenuText$(): returns the full file path in response to a menu event

Finally,

Event Close
  StoreUtf8 Cat$(MbExeFolder$+"\EditorDemo.ini"), Mru$(), 8     ; write up to 8 strings to file


... serves to store the MRU list to disk. Note that only a few functions of the toolbar are actually implemented - use at your own risk, test it with non-important files 8)

This is work in progress, grateful for feedback, especially also from people using non-Latin alphabets.
Title: Input$
Post by: jj2007 on July 31, 2018, 10:11:23 AM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals MyString
  Init
  PrintLine "You can hit keys as you like, but when the countdown approaches zero, you should stop"
  For_ ecx=1000 To 0 Step -1
        Print At(0, 3) Str$(ecx), "   "
        Delay 2
  Next
  Let MyString=Input$ (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1041)("Your hobby: ", "Basic programming (this string is editable)", flush)
  MsgBox 0, MyString, "The string:", MB_OK or MB_SETFOREGROUND
EndOfCode
Title: Creating and erasing a numerical array
Post by: jj2007 on August 02, 2018, 06:32:53 PM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  N=500000000                           ; 500 Mio
  PrintCpu 0
  For_ outerloop=0 To 5

        NanoTimer()
        Dim MyBytes(N) As BYTE
        PrintLine "allocating took ", NanoTimer$()
       
        NanoTimer()
        For_ ecx=0 To N-1
                mov MyBytes(ecx), cl
        Next
        PrintLine "filling took ", NanoTimer$()
       
        NanoTimer()
        % Erase MyBytes()
        PrintLine "erasing took ", NanoTimer$(), CrLf$
  Next
  Inkey
EndOfCode


Code: [Select]
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
allocating took 13 µs
filling took 1228 ms
erasing took 40 ms

allocating took 24 µs
filling took 1229 ms
erasing took 40 ms

allocating took 22 µs
filling took 1228 ms
erasing took 38 ms

allocating took 23 µs
filling took 1227 ms
erasing took 37 ms

allocating took 23 µs
filling took 1229 ms
erasing took 38 ms

allocating took 18 µs
filling took 1232 ms
erasing took 40 ms

Writing the bytes to file costs an extra 7-9 seconds:

        NanoTimer()
        Open "O", #1, "MyBytes.dat"
        Store #1, MyBytes()
        Close
        PrintLine "writing took ", NanoTimer$()
Title: Converting a *.csv file to a fixed size file
Post by: jj2007 on August 12, 2018, 10:26:55 AM
Usage: Drag a csv file over the attached exe. The required fixed size is calculated automatically, see results below.

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals f$, records, maxcol, record$, endreached   ; see FB thread: CSV to fixlength data files (https://www.freebasic.net/forum/viewtopic.php?f=3&t=26946&p=250502&sid=bedd271c83f18dff8305ce58a49aa5fb#p250499)
  Init
  NanoTimer()
  Dim MxLen() As DWORD          ; OxPT_Arg1 J:\Masm32\MasmBasic\BugTests\TableControl\FatTable.csv
  Dim fix$()
  Let f$=CL$()
  .if !Exist(f$)
        GetFiles *.csv
        SortFiles
        Let f$=Files$(0)
  .endif
  Recall f$, L$(), csv
  mov records, eax
  For_ ct=0 To eax-1
        For_ ecx=0 To 99
                xchg Len(L$(ct, ecx)), eax
                .if eax>MxLen(ecx)
                                mov MxLen(ecx), eax
                                Print "*"
                .endif
       Next
  Next
  Print CrLf$, "Length of records: "
  For_ ecx=0 To 127
        mov eax, MxLen(ecx)
        .Break .if !eax
        add esi, eax
        Print Str$(eax), " "    ; record length
  Next
  mov maxcol, ecx
  lea esi, [esi+ecx+1]
  Print Str$("\nLen of full record=%i", esi), Str$(", %i columns", maxcol)
  Let edi=Space$(esi)
ComposeString MACRO maxcol
  mov ecx, maxcol
  Clr endreached
  .Repeat
        lodsb
        .if !al
                inc endreached
        .endif
        .if endreached || !al || !ecx
                mov al, 32
        .endif
        stosb
        dec ecx
  .Until Sign?
ENDM
  For_ ct=0 To records-1
        push edi
        mov esi, L$(ct, 0)
        ComposeString MxLen(0)
        For_ col=1 To maxcol-1
                mov esi, L$(ct, col)
                ComposeString MxLen(col)
       Next
        xor eax, eax
        stosb
        pop edi
        Let fix$(ct)=edi
  Next
  .if Instr_(f$, ".csv", 1)
        mov [eax], Mirror$(".fix")
        PrintLine CrLf$, "Storing to ", f$
        Store f$, fix$()
  .endif
  Inkey "Converting ", f$, " took ", NanoTimer$()
EndOfCode


For a 19MB csv database, the whole process takes about 2 seconds, but the resulting file gets bloated to >100MB:
Code: [Select]
Length of records: 11 646 348 13 141 82 20 4 10 20 4 10 28 4 10 20 4 10 25 4 10 25 4 11 25 4 11 25 4 11 25 4 11 25 4 11 25 4 10 27 4 11 26 4
 11 28 4 11 27 4 11 23 4 11 23 4 15 23 4 15 23 4 15 23 4 15 25 4 15 23 4 15 23 4 11 22 4 10 12 4 6 9 4 4 9 4 4 9 4 4 9 4
Len of full record=2376, 92 columns
Storing to C:\Masm32\MasmBasic\BugTests\TableControl\FatTable.fix
Converting C:\Masm32\MasmBasic\BugTests\TableControl\FatTable.fix took 2367 ms
Title: Subclassing a RichEdit control (dual 64-/32-bit code)
Post by: jj2007 on August 12, 2018, 10:16:52 PM
Numbers only in a RichEdit control (full project attached):
Code: [Select]
SubEdit proc <cb> uses rbx hWnd, uMsg, wParam, lParam ; <cb> indicates that it is a callback function
  mov ebx, wParam ; default: process wParam
  cmp uMsg, WM_CHAR
  jne @F
  cmp wParam, "9"
  jle @F
  Print Str$("char %i not allowed\n", ebx)
  xor ebx, ebx ; don't process
@@: jinvoke CallWindowProc, PreviousWndProc, hWnd, uMsg, ebx, lParam
  ret
SubEdit endp
Title: The console isn't completely dead yet
Post by: jj2007 on August 14, 2018, 09:31:20 AM
(http://www.webalice.it/jj2006/pics/DosSymbols.png)

Full project attached (the exe includes the fake database). Use cursor up/down to scroll among the records, hit Escape to quit.

Here is the source (50 lines of code):

include \masm32\MasmBasic\MasmBasic.inc         ; symbols (https://altcodeunicode.com/windows-alt-codes-symbols/)
include NewAtMacro.inc
  SetGlobals TopRecord
  Init
  invoke ShowWindow, rv(GetConsoleWindow), SW_MAXIMIZE
  StringToArray 100, d$(), tab
  ConsoleColor cDarkGray, cBlack
  Print 0                               ; override codepage setting
  $Data 11C #, 91C LastName, O1C FirstName, Z1C Street, s1C City, 6+1A ProdCode, A+1A UnitPrice
  Read Header$()       ; create a string array
  invoke SetConsoleOutputCP, 437        ; we need that codepage for the graphic characters
  Print ConvertCp$(ResFile$(101), CP_UTF16, 437)        ; resource 101 (boxes.txt) is Unicode and needs to be converted
  invoke SetConsoleOutputCP, 1252      ; Windows default
  For_ ecx=0 To Header$(?)-1
        xchg Header$(ecx), esi
        Print At(#esi) esi      ; the new At() macro has some goodies... it can set xy and colours based on the start of the string
  Next
  Print At(0, 20) "Use cursor up/down to scroll, Escape to quit"                ; override codepage setting
  .While 1
        m2m ecx, 3              ; start displaying data in row 3
        For_ ct=TopRecord To TopRecord+6
                mov esi, Cat$(Chr$("1", ecx+48, "F ")+Str$("%______i", ct))     ; right-aligned record number
                Print At(#esi) Left$(esi, 19)
                mov esi, Cat$(Chr$("9", ecx+48, "F ")+d$(ct, 0)+String$(20, " "))
                Print At(#esi) Left$(esi, 19)
                mov esi, Cat$(Chr$("O", ecx+48, "F ")+d$(ct, 1)+String$(10, " "))
                Print At(#esi) Left$(esi, 10)
                mov esi, Cat$(Chr$("Z", ecx+48, "E ")+d$(ct, 2)+String$(20, " "))
                Print At(#esi) Left$(esi, 18)
                mov esi, Cat$(Chr$("s", ecx+48, "E ")+d$(ct, 3)+String$(10, " "))
                Print At(#esi) Left$(esi, 10)
                mov esi, Cat$(Chr$("6+", ecx+48, "F9 ")+d$(ct, 4)+String$(10, " "))
                Print At(#esi) Left$(esi, 10)
                mov esi, Cat$(Chr$("A+", ecx+48, "C ")+d$(ct, 5)+String$(9, " "))
                Print At(#esi) Left$(esi, 9)
                add ecx, 2      ; next data two rows down
       Next
        Inkey
        .Break .if eax==VK_ESCAPE
        mov edx, TopRecord
        .if eax==VK_UP
                dec edx
        .elseif eax==VK_DOWN
                inc edx
        .endif
        mov TopRecord, Max(0, edx)
        sub d$(?), 7                   
        mov TopRecord, Min(eax, TopRecord)
  .Endw
EndOfCode
Title: The console isn't completely dead yet (part II)
Post by: jj2007 on August 15, 2018, 05:44:43 PM
How does it work?

mov esi, Cat$(Chr$("z", ecx+48, "EC ")+d$(ct, 3))  ; City: Column z (=10+26+26), row ecx, foregroundcolour E (yellow), bg C (red)
Print At(#esi) Left$(esi, 13, "_")     ; for short strings, fill right half with "_"


esi points to a string with a specific format:
ABCD this is a string

A is the print column, where
0   0
9   9
A   10+0=10
Z   10+25=35
a   10+26+0=36
z   10+26+25=61

B is the print row, using the same scheme.
C and B are the foreground and background colours, with
Code: [Select]
cBlack = 0 ; http://support.microsoft.com/kb/319883
cDarkBlue = 1
cDarkGreen = 2
cDarkCyan = 3
cDarkRed = 4
cDarkMagenta = 5
cDarkYellow = 6
cGray = 7
cDarkGray = 8
cBlue = 9
cGreen = 10 ; A
cCyan = 11 ; B
cRed = 12 ; C
cMagenta = 13 ; D
cYellow = 14 ; E
cWhite = 15 ; F

The attachment contains sources and files to build this; including a new Left$() macro:

Print Left$("some string", 20, "_")  ; prints some string_________

The third optional argument is a fill char for padding the string to the right in case it's shorter than 20 chars. Can be quite useful in some situations, inter alia for overwriting the previous field when filling the screen as shown above. In the attached exe, the Street column does not have padding, and when scrolling through the database you can see the effect.
Title: Re: Miscellaneous snippets
Post by: HSE on August 15, 2018, 10:14:30 PM
Not exactly perfect here:
Title: Re: Miscellaneous snippets
Post by: jj2007 on August 16, 2018, 01:15:44 AM
Interesting ::)

Which OS version? Console is maximised, I suppose?

Just checked with Win XP, and that looks indeed like what you posted. Unlike Win7 & Win10, the console isn't enlarged enough by the invoke ShowWindow, rv(GetConsoleWindow), SW_MAXIMIZE. You have to enlarge it manually in the console properties, then save "for all future windows with the same name", and restart. Then it works.

On Win7, the display refreshes immediately, i.e. in milliseconds. With Win10, it seemed initially very slow, but now it has become fast. I have yet to find out if there is a pattern - mysteries of Windows 8)
Title: Re: Miscellaneous snippets
Post by: HSE on August 19, 2018, 10:59:37 AM
In 7-32 I changed console properties and that look a lot better. Some characters are not intended ones, I think.
Title: Re: Miscellaneous snippets
Post by: jj2007 on August 19, 2018, 11:38:56 AM
Weird, codepage 437 should be pretty standard. Which language is your OS?
Title: Re: Miscellaneous snippets
Post by: HSE on August 20, 2018, 01:43:37 AM
Spanish. Selected: Español(España)

Code: [Select]
UASM v2.46, Jan  8 2018, Masm-compatible assembler.
Portions Copyright (c) 1992-2002 Sybase, Inc. All Rights Reserved.
Source code is available under the Sybase Open Watcom Public License.

*** MasmBasic version 25.12.2017 ***
** SetProcessUserModeExceptionPolicy
** read Header$()
DosSymbols.asm(69) : Error A2228: Missing right parenthesis in expression
 MbFor(218)[MasmBasic.inc]: Macro called from
  DosSymbols.asm(69): Main line code
DosSymbols.asm(69) : Error A2228: Missing right parenthesis in expression
 MbFor(243)[MasmBasic.inc]: Macro called from
  DosSymbols.asm(69): Main line code
DosSymbols.asm(69) : Error A2210: Syntax error: ]
 MbFor(256)[MasmBasic.inc]: Macro called from
  DosSymbols.asm(69): Main line code
DosSymbols.asm: 100 lines, 1 passes, 199 ms, 0 warnings, 3 errors

There is a problem moving up and down because Quantity doesn't stop when reach limits.
Title: Re: Miscellaneous snippets
Post by: jj2007 on August 20, 2018, 05:13:40 AM
Spanish. Selected: Español(España)
...
There is a problem moving up and down because Quantity doesn't stop when reach limits.

Weird. Sorry for the build errors, it seems the current MasmBasic version is not compatible with my newest one.
Re Quantity, that's by design: It is set by Rand() and does its job even if the position does not change. Just for testing...
Title: The console isn't completely dead yet (part III)
Post by: jj2007 on August 22, 2018, 07:39:08 AM
In 7-32 I changed console properties and that look a lot better. Some characters are not intended ones, I think.

Can you check the attached version, please? I replaced codepage 437 with another one.
Title: Re: Miscellaneous snippets
Post by: HSE on August 24, 2018, 11:43:26 PM
Worst !

Still not posible to assemble  :eusa_naughty:

Except first character, I see perfectly boxes.txt with MASM32 Unicode Editor .
Title: Re: Miscellaneous snippets
Post by: jj2007 on August 25, 2018, 12:06:20 AM
Yes, it won't build, sorry. I am working on a major MasmBasic update, and that will take some time.

Still, the exe should work OK. It's now codepage UTF8, and your machine should understand that. Anybody else having such problems?
Title: Re: Miscellaneous snippets
Post by: HSE on August 25, 2018, 01:43:33 AM
Ja!

Default font configuration here is "Fuentes de mapas de bits".

Changing that to "Lucida Console" work perfect, also previous version  :t

With third option Nidud's "Doszip Console" letters dont' look so well.
Title: Re: Miscellaneous snippets
Post by: jj2007 on August 25, 2018, 01:49:39 AM
Thanks :biggrin:
One day I will find a way to set the console font programmatically ;)
Title: Dll problems
Post by: jj2007 on August 25, 2018, 05:08:26 AM
Attached an archive with
- an exe compiled with FreeBasic
- that needs the second file, a DLL using Input$("prompt", "prefilled for editing") (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1041)
Title: Pcg32
Post by: jj2007 on September 11, 2018, 04:12:10 AM
All three are brilliant with the FourmiLab ENT (http://www.fourmilab.ch/random/) test, but only the first two have been tested with PractRand. If you need a very good hi-speed PRNG, stick with MasmBasic Rand() (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1030).
Code: [Select]
Testing 32000000 numbers generated, CPU: Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz

833 ms for Pcg32  FB, last result: 817EEE81
390 ms for Pcg32 Asm, last result: 817EEE81
107 ms for MB Rand(), last result: 8E1531E8

771 ms for Pcg32  FB, last result: 15670CA0
378 ms for Pcg32 Asm, last result: 15670CA0
107 ms for MB Rand(), last result: C44145CE

764 ms for Pcg32  FB, last result: D422CFAD
398 ms for Pcg32 Asm, last result: D422CFAD
118 ms for MB Rand(), last result: 2C03A5D1

840 ms for Pcg32  FB, last result: ECD79C2B
377 ms for Pcg32 Asm, last result: ECD79C2B
107 ms for MB Rand(), last result: BFFA6298

766 ms for Pcg32  FB, last result: 5248B397
377 ms for Pcg32 Asm, last result: 5248B397
107 ms for MB Rand(), last result: 675D19A4

766 ms for Pcg32  FB, last result: 54A9248A
382 ms for Pcg32 Asm, last result: 54A9248A
110 ms for MB Rand(), last result: E59BD461
202     bytes for Pcg32
111     bytes for Pcg
26      bytes for MbRand

ENT results:
Code: [Select]
Testing 8000000 numbers generated, CPU: Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz

############ ENT results Pcg32 (FB):
Entropy = 7.999994 bits per byte.

Optimum compression would reduce the size
of this 32000000 byte file by 0 percent.

Chi square distribution for 32000000 samples is 274.62, and randomly
would exceed this value 25.00 percent of the times.

Arithmetic mean value of data bytes is 127.4936 (127.5 = random).
Monte Carlo value for Pi is 3.141756196 (error 0.01 percent).
Serial correlation coefficient is 0.000371 (totally uncorrelated = 0.0).

############ ENT results Pcg32 (MB):
Entropy = 7.999994 bits per byte.

Optimum compression would reduce the size
of this 32000000 byte file by 0 percent.

Chi square distribution for 32000000 samples is 274.62, and randomly
would exceed this value 25.00 percent of the times.

Arithmetic mean value of data bytes is 127.4936 (127.5 = random).
Monte Carlo value for Pi is 3.141756196 (error 0.01 percent).
Serial correlation coefficient is 0.000371 (totally uncorrelated = 0.0).

############ ENT results MB Rand(-1):
Entropy = 7.999995 bits per byte.

Optimum compression would reduce the size
of this 32000000 byte file by 0 percent.

Chi square distribution for 32000000 samples is 213.24, and randomly
would exceed this value 95.00 percent of the times.

Arithmetic mean value of data bytes is 127.4976 (127.5 = random).
Monte Carlo value for Pi is 3.141366946 (error 0.01 percent).
Serial correlation coefficient is -0.002006 (totally uncorrelated = 0.0).
Title: Pcg32, spreadsheet control, GCC version info
Post by: jj2007 on September 14, 2018, 07:23:41 PM
* PCG32.zip: Comparing SIMD vs FPU-based methods for mapping a QWORD (0...-1) to a double (0.0 ... 1.0)

* GuiTableControl.zip: latest tests with a spreadsheet control

* GetGccVersion.zip: echo a short version string to your FB output window. Source:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let edi=MbExeFolder$+"Win32\gcc.exe --version"
  Let esi=Launch$(edi)
  .if dword ptr [esi]==Mirror$("La$?")
        PrintLine edi, Chr$(": no answer.", 13, 10, 10, "Check if GetGccVersion.exe sits above the bin\Win32 folder")
  .else
        PrintLine esi
        Let ebx=Extract$(esi, "project)", 0)
        Let ecx=Extract$(esi, "(C)", "Free Soft")
        PrintLine "gcc version", ebx, " (", Trim$(ecx), ")"
  .endif
EndOfCode


Sample output of gcc.exe --version:
gcc.exe (i686-win32-sjlj-rev2, Built by MinGW-W64 project) 4.9.2
Copyright (C) 2014 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.


Sample output of the attached batch file:
Code: [Select]
** compiling somefile.bas with -t 2000 -gen gcc -Wc -Ofast -s console **
gcc version 8.1.0 (2018)
Title: Re: Miscellaneous snippets
Post by: hutch-- on September 14, 2018, 08:19:31 PM
This is what I got running it the second time. Could not read the fonts as they were so small, copied it into my text editor first.

-8910786331291756801  0.5169453050529669    0.5169453050529669718
6730337785313497944   0.3648523424199086    0.3648523424199086505
-5974524377861002328  0.6761203844977746    0.6761203844977747243
2695508904680093984   0.1461238305204089    0.1461238305204090194
8502576381364090992   0.4609255892199442    0.4609255892199443155
-385216515766393995   0.9791173708364389    0.9791173708364389530
3034485871582637989   0.1644998087173231    0.1644998087173232765
2286379689918253082   0.1239448913468051    0.1239448913468051986
-4131041815082152639  0.7760557744729732    0.7760557744729734316
-853861575098310801   0.9537120712638256    0.9537120712638258368
7275931949313747423   0.3944290613151327    0.3944290613151328044
7844949285505684199   0.4252755529191934    0.4252755529191934295
140239247804428540    0.007602384856864708  0.007602384856864721546

timings for 100 Mio loops:
280 ms for SIMD
414 ms for FPU

197 ms for SIMD
409 ms for FPU

212 ms for SIMD
431 ms for FPU

223 ms for SIMD
378 ms for FPU

201 ms for SIMD
363 ms for FPU
Title: Search and dump
Post by: jj2007 on November 01, 2018, 10:04:36 PM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Let esi=FileRead$(CL$())
  Let edi="SendMessage"         ; just a proposal
  .While 1
        PrintLine "Hit Escape, Return to exit", Space$(40)
        Let edi=Input$("Search for ", edi)
        .Break .if !Len(edi)
        xor ebx, ebx
        NextMatch:
        inc ebx
        .if !Instr_(ebx, esi, edi, 1)
                PrintLine "No match for [", edi, "]                 "
        .else
                mov ebx, edx
                xchg eax, ecx
                sub ecx, 4*16
                ConsoleColor cBlue
                Print HexDump$(ecx, 64)
                ConsoleColor cWhite
                add ecx, 4*16
                .Repeat
                                PrintLine HexDump$(ecx)
                                add ecx, 512
                                Inkey "more? (Return: continue, F3: next match)", Cr$
                                cmp eax, VK_F3
                                je NextMatch
                .Until eax!=13
                ConsoleColor
        .endif
  .Endw
EndOfCode


Output:
Hit Escape, Return to exit
Search for SendMessage
002A899C  6E 65 64 09 65 71 75 20 73 64 77 6F 72 64 20 70 ned.equ sdword p
002A89AC  74 72 20 0D 0A 73 74 61 63 6B 09 65 71 75 20 3C tr ..stack.equ <
002A89BC  44 57 6F 72 64 20 50 74 72 20 5B 65 73 70 5D 3E DWord Ptr [esp]>
002A89CC  0D 0A 73 6D 09 65 71 75 20 69 6E 76 6F 6B 65 20 ..sm.equ invoke
002A89DC  53 65 6E 64 4D 65 73 73 61 67 65 2C 20 0D 0A 4C SendMessage, ..L
002A89EC  61 73 74 46 69 6C 65 4E 61 6D 65 24 09 65 71 75 astFileName$.equ
002A89FC  20 6F 66 66 73 65 74 20 77 66 64 2E 63 46 69 6C  offset wfd.cFil
002A8A0C  65 4E 61 6D 65 0D 0A 4C 61 73 74 46 69 6C 65 53 eName..LastFileS
002A8A1C  69 7A 65 09 65 71 75 20 77 66 64 2E 6E 46 69 6C ize.equ wfd.nFil
002A8A2C  65 53 69 7A 65 4C 6F 77 0D 0A 77 43 72 4C 66 24 eSizeLow..wCrLf$
002A8A3C  09 65 71 75 20 6F 66 66 73 65 74 20 77 43 72 4C .equ offset wCrL
002A8A4C  66 5F 74 78 74 0D 0A 77 4C 66 24 09 65 71 75 20 f_txt..wLf$.equ
002A8A5C  6F 66 66 73 65 74 20 77 4C 66 5F 74 78 74 0D 0A offset wLf_txt..
002A8A6C  77 54 62 24 09 65 71 75 20 6F 66 66 73 65 74 20 wTb$.equ offset
002A8A7C  77 54 61 62 5F 74 78 74 0D 0A 43 72 4C 66 09 65 wTab_txt..CrLf.e
002A8A8C  71 75 20 31 33 2C 31 30 0D 0A 0D 0A 4D 62 45 76 qu 13,10....MbEv
002A8A9C  43 74 3D 30 0D 0A 45 6E 64 4F 66 43 6F 64 65 20 Ct=0..EndOfCode
002A8AAC  4D 41 43 52 4F 20 61 72 67 64 0D 0A 20 20 69 66 MACRO argd..  if
002A8ABC  65 20 4D 62 45 78 69 74 0D 0A 09 45 78 69 74 20 e MbExit...Exit
002A8ACC  61 72 67 64 0D 0A 20 20 65 6E 64 69 66 0D 0A 20 argd..  endif..
002A8ADC  20 69 66 20 54 63 6C 43 74 43 20 67 74 20 31 0D  if TclCtC gt 1.
002A8AEC  0A 09 54 72 79 43 61 74 63 68 45 6E 64 0D 0A 20 ..TryCa.,., dungu .,.,.,d..
002A8AFC  20 65 6E 64 69 66 0D 0A 20 20 69 66 20 4D 62 45  endif..  if MbE
002A8B0C  76 43 74 0D 0A 09 47 75 69 45 6E 64 20 30 0D 0A vCt...GuiEnd 0..
002A8B1C  20 20 65 6E 64 69 66 0D 0A 20 20 69 66 20 4D 62   endif..  if Mb
002A8B2C  4E 61 54 69 43 74 20 61 6E 64 20 31 0D 0A 09 65 NaTiCt and 1...e
002A8B3C  63 68 6F 0D 0A 09 65 63 68 6F 20 23 23 23 20 63 cho...echo ### c
002A8B4C  68 65 63 6B 20 79 6F 75 72 20 4E 61 6E 6F 54 69 heck your NanoTi
002A8B5C  6D 65 72 20 63 61 6C 6C 73 20 23 23 23 0D 0A 20 mer calls ###..
002A8B6C  20 65 6E 64 69 66 0D 0A 20 20 65 6E 64 20 73 74  endif..  end st
002A8B7C  61 72 74 0D 0A 45 4E 44 4D 0D 0A 43 6C 65 61 72 art..ENDM..Clear
002A8B8C  4C 61 73 74 45 72 72 6F 72 20 4D 41 43 52 4F 0D LastError MACRO.
002A8B9C  0A 20 20 69 66 20 75 73 65 64 65 62 0D 0A 09 70 .  if usedeb...p
002A8BAC  75 73 68 61 64 0D 0A 09 69 6E 76 6F 6B 65 20 53 ushad...invoke S
002A8BBC  65 74 4C 61 73 74 45 72 72 6F 72 2C 20 30 0D 0A etLastError, 0..
002A8BCC  09 70 6F 70 61 64 0D 0A 20 20 65 6E 64 69 66 0D .popad..  endif.

more? (Return: continue, F3: next match)
Title: Re: Miscellaneous snippets
Post by: jj2007 on November 03, 2018, 04:43:25 AM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals left, right, row   ; geeks for geeks: Print string of odd length in 'X' format (https://www.geeksforgeeks.org/print-string-of-odd-length-in-x-format/)
  Init
  Let edi="Assembly is a great language"
  .While 1
        Let edi=Input$("\n\n\n\nGimme a string please: ", edi)
        .Break .if !Len(edi)
        Clr left, row
        mov right, eax
        Cls
        .Repeat
                mov edx, left
                movzx eax, byte ptr [edi+edx]
                Print At(left, row) Chr$(eax)
                inc left
                dec right
                mov edx, right
                movzx eax, byte ptr [edi+edx]
                Print At(right, row) Chr$(eax)
                inc row
        .Until right<=0
  .Endw
EndOfCode


Code: [Select]
A                          e
 s                        g
  s                      a
   e                    u
    m                  g
     b                n
      l              a
       y            l

         i        t
          s      a
                e
            a  r
              g
              g
            a  r
                e
          s      a
         i        t

       y            l
      l              a
     b                n
    m                  g
   e                    u
  s                      a
 s                        g
A                          e
Title: Re: Miscellaneous snippets
Post by: TimoVJL on November 03, 2018, 08:01:55 AM
So you spotted G-point with MasmBasic 8)
Title: Changing the file date and time based on the filename
Post by: jj2007 on November 07, 2018, 10:11:00 PM
I've got a video converter (DVDVideoSoft) that works fine but it has the bad habit to set the time stamp of the output file to "right now". Fortunately, it creates new file names that contain the original date and time, e.g. C:\Users\Jochen\Videos\VID_20170621_153022.mp4 meaning original file was created 21 June 2017, 15:30:22

Here is a little program that touches the file and sets the time stamp back (source & exe attached, use at your own risk). Just drag any file from the folder over the exe:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  SetGlobals gfMatch$, pathLeft
  Init
  Let gfMatch$=CL$()
  mov pathLeft, Rinstr(eax, "\")
  .Repeat
        inc eax
  .Until byte ptr [eax]<="."
  xchg eax, ecx
  Let gfMatch$=Left$(gfMatch$, pathLeft)+"*"+ecx
  PrintLine gfMatch$
  GetFiles gfMatch$
  deb 4, "matches", eax
  SortFiles                             ; optional: latest files first
  For_ ecx=0 To eax-1
        mov esi, Files$(ecx)
        .if InstrOr(esi, ".mp4" or ".avi" or ".gp", 1)
                PrintLine GfDate$(ecx), Spc2$, GfTime$(ecx), Tb$, Files$(ecx)
                .if Instr_(esi, "201")  ; 20160602_170844
                                xchg eax, esi
                                .if byte ptr [esi+8]=="_"
                                        Let edi=Mid$(esi, 7, 2)+"."+Mid$(esi, 5, 2)+"."+Left$(esi, 4)+Spc2$+Mid$(esi, 10, 2)+":"+Mid$(esi, 12, 2)+":"+Mid$(esi, 14, 2)
                                        ; ClearLastError
                                       Touch Files$(ecx), TimeSF(edi)
                                        ; deb 4, "Touch", eax, $Err$()
                                       .if Exist(Files$(ecx))
                                        PrintLine GfDate$(-1), Spc2$, GfTime$(-1)
                                        .endif
                                .else
                                        PrintLine "skipped, unknown date format: ", Tb$, esi
                                .endif
                .else
                                PrintLine "skipped, no 201 detected: ", Tb$, esi
                .endif
        .else
                PrintLine "skipped, not a video file: ", Tb$, esi
        .endif
  Next
  Inkey "ok?"
EndOfCode


Typical output (the second, shorter line shows the changed date):
Code: [Select]
C:\Users\Jochen\Videos\*.mp4
matches eax             18
07.11.2018  12:27:53    C:\Users\Jochen\Videos\20160602_170844.mp4
02.06.2016  17:08:44
07.11.2018  12:27:42    C:\Users\Jochen\Videos\VID_20170531_195446.mp4
31.05.2017  19:54:46
07.11.2018  12:12:22    C:\Users\Jochen\Videos\VID_20170621_153022.mp4
Title: Sorting strings
Post by: jj2007 on November 19, 2018, 03:06:10 AM
Generates two Million random strings and sorts them using QSort (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1175) (which is an in-place mergesort).
Source & binaries attached: Extract exe and dll to the same folder, then run the exe. Typical result for a Core i5:
Code: [Select]
11 s for writing 2 Millon strings
106 ms for reading 5 Million strings
3.2 seconds for sorting 5 Million strings
Title: Re: Miscellaneous snippets
Post by: TimoVJL on November 20, 2018, 01:59:09 AM
With my slow AMD:
Code: [Select]
62 s for writing 2 Millon strings
383 ms for reading 5 Million strings
12. seconds for sorting 5 Million strings
Title: Re: Miscellaneous snippets
Post by: jj2007 on November 20, 2018, 01:21:13 PM
Where has your code gone? I've tested it (attached), and that's a really fast sort, Timo - interesting :t
Title: TitleCase$
Post by: jj2007 on November 21, 2018, 01:43:12 PM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  NoTitleCase$ equ <Chr$(".a.an.and.are.as.but.by.for.is.in.or.the.that.")>        ; this is the default, inspired by Lauren Ipsum (https://writing.stackexchange.com/questions/4621/which-words-should-not-be-capitalized-in-title-case), but you can use others
  Init 
  Let ecx="World bank and OECD are organisations that - as a rule - i consider very powerful"
  PrintLine ecx
  Inkey TitleCase$(ecx)
EndOfCode


Output:
Code: [Select]
World bank and OECD are organisations that - as a rule - i consider very powerful
World Bank and OECD are Organisations that - as a Rule - I Consider Very Powerful

Inspired by Munair on the FreeBasic forum (https://www.freebasic.net/forum/viewtopic.php?f=7&t=27174) :icon14:
Title: PSHUFB
Post by: jj2007 on December 05, 2018, 08:56:48 PM
Just for fun, a little demo showing the use of the PSHUFB instruction, and some macro tricks:
Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc

SwapBytes MACRO pBytes
  if type(pBytes) eq REAL8
movlps xmm0, pBytes
  else
mov edx, pBytes
movups xmm0, oword ptr [edx]
  endif
  mov eax, esp
  and esp, -16
  push 00010203h ; the magic numbers
  push 04050607h
  push 08090a0bh
  push 0c0d0e0fh
  PSHUFB xmm0, oword ptr [esp] ; shuffle the bytes! (will crash on very old CPUs, sorry...)
  movups oword ptr [esp], xmm0
  if type(pBytes) eq REAL8
fld qword ptr [esp]
xchg eax, esp
EXITM <ST(0)> ; leave the double in the FPU
  else
xchg eax, esp
EXITM <> ; the bytes are in xmm0, but the macro is not used as a function
  endif
ENDM
 
.data
MyReal8 REAL8 1234567890.1234567890
thestring db "!taerg si 23msaM", 0
.data?
SwappedR8 REAL8 ?
out$ db 20 dup(?)

  Init
  PrintLine "Original:", Tb$, offset thestring
  SwapBytes(offset thestring) ; return 16 bytes in xmm0
  movups oword ptr out$, xmm0
  PrintLine "Swapped:", Tb$, offset out$
 
  Print Str$("\nMyReal8  \t%Hf", MyReal8), Str$("\nas BigEndian\t%Hf", SwapBytes(MyReal8)) ; SwapBytes leaves the double in the FPU
  fstp SwappedR8
  Inkey Str$("\nreconverted\t%Hf\n", SwapBytes(SwappedR8)v)
EndOfCode

Note that the macro can be used either as a function:
Print Str$(SwapBytes(MyReal8))

or "standalone":
SwapBytes(offset thestring)

Output:
Code: [Select]
Original:       !taerg si 23msaM
Swapped:        Masm32 is great!

MyReal8         1234567890.1234567
as BigEndian    3.5842524504192598e+246
reconverted     1234567890.1234567
Title: Two-dimensional string arrays
Post by: jj2007 on December 08, 2018, 01:23:31 AM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  Dim My$(tab)                          ; create a two-dimensional string array
  For_ ecx=0 To 7
        Let edi=Str$("Test %i\t", ecx)
        Let My$(ecx)=String$(8, edi)    ; create a string with 8 columns
  Next
  For_ ecx=0 To 7
        Let My$(ecx, ecx)="Hello!!"     ; set individual elements
        Let My$(ecx, 7-ecx)="*Ciao*"
  Next
  For_ ecx=0 To 7
        For_ ct=0 To 7
                Print My$(ecx, ct), Spc2$
        Next
        Print
  Next
EndOfCode


Output:
Code: [Select]
Hello!  Test 0  Test 0  Test 0  Test 0  Test 0  Test 0  *Ciao*
Test 1  Hello!  Test 1  Test 1  Test 1  Test 1  *Ciao*  Test 1
Test 2  Test 2  Hello!  Test 2  Test 2  *Ciao*  Test 2  Test 2
Test 3  Test 3  Test 3  Hello!  *Ciao*  Test 3  Test 3  Test 3
Test 4  Test 4  Test 4  *Ciao*  Hello!  Test 4  Test 4  Test 4
Test 5  Test 5  *Ciao*  Test 5  Test 5  Hello!  Test 5  Test 5
Test 6  *Ciao*  Test 6  Test 6  Test 6  Test 6  Hello!  Test 6
*Ciao*  Test 7  Test 7  Test 7  Test 7  Test 7  Test 7  Hello!

Purest assembly :bgrin:
Title: Good ol' EOF(#1) and User-Defined Types
Post by: jj2007 on January 13, 2019, 01:58:51 PM
Strange - I had forgotten to code the Eof() macro, here it is:

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)

SOMEUDT STRUCT  ; a user-defined type
  mydouble      REAL8 ?
  mydword       DWORD ?
  myfloat       REAL4 ?
SOMEUDT ENDS

MyUDT SOMEUDT <?>

Eof MACRO arg
  push Loc(arg)
  void Lof(arg)
  pop edx
  cmp edx, eax
  exitm <!Sign?>
ENDM

  Init
  Open "O", #1, "TypeTest.udt"
  For_ ecx=101 To 103
       mov MyUDT.mydword, ecx  ; 101, 102, ...
       lea eax, [ecx+900]
       SetFloat MyUDT.myfloat=eax      ; 1001, 1002, ...
       add eax, 9000
       SetFloat MyUDT.mydouble=eax     ; 10001, 10002, ...
       Store #1, MyUDT         ; save UDT to file
  Next
  Close
  Open "I", #1, "TypeTest.udt"
  .Repeat
        Recall #1, MyUDT
        deb 4, "Test", MyUDT.mydouble, MyUDT.myfloat, MyUDT.mydword
  .Until Eof(#1)
  Close
  Inkey CrLf$, "Yep, that's purest assembler ;-)"
EndOfCode



Output:
Code: [Select]
Test
MyUDT.mydouble  10001.00000000000
MyUDT.myfloat   1001.000
MyUDT.mydword   101

Test
MyUDT.mydouble  10002.00000000000
MyUDT.myfloat   1002.000
MyUDT.mydword   102

Test
MyUDT.mydouble  10003.00000000000
MyUDT.myfloat   1003.000
MyUDT.mydword   103

Yep, that's purest assembler ;-)

P.S.: To get random access to some record, use this before closing the file:

  m2m eax, 1                   ; get record #1
  imul eax, SOMEUDT            ; calculate position in file
  Seek #1, eax
  Recall #1, MyUDT
  deb 4, "Test with Seek", MyUDT.mydouble, MyUDT.myfloat, MyUDT.mydword
  Close
Title: Re: Good ol' EOF(#1) and User-Defined Types
Post by: TimoVJL on January 13, 2019, 11:50:18 PM
P.S.: To get random access to some record, use this before closing the file:

  m2m eax, 1                   ; get record #1
  imul eax, SOMEUDT            ; calculate position in file
I didn't understood that :icon_rolleyes:
Code: [Select]
  mov eax, 1
  imul eax, sizeof SOMEUDT
EDIT:
OK
push 1 / pop eax is two bytes shorter.
imul eax, SOMEUDT is same as imul eax, sizeof SOMEUDT
Title: Re: Miscellaneous snippets
Post by: ragdog on January 14, 2019, 12:56:07 AM
Quote
I didn't understood that :icon_rolleyes:
Code: [Select]

  mov eax, 1
  imul eax, sizeof SOMEUDT

Hello Timo

1 * size of  SOMEUDT structur
Title: Re: Good ol' EOF(#1) and User-Defined Types
Post by: jj2007 on January 14, 2019, 02:05:30 AM
push 1 / pop eax is two bytes shorter.
imul eax, SOMEUDT is same as imul eax, sizeof SOMEUDT

Yes, as ragdog already noted. It took me years to realise that mov eax, sizeof SOMESTRUCT is the same as mov eax, SOMESTRUCT ;)

And m2m eax, n is simply some bytes shorter for n=-128 ... +127, so I always use it, except perhaps for a really speed-critical innermost loop.
Title: Download URL with UTF8
Post by: jj2007 on January 15, 2019, 11:16:20 PM
include \masm32\MasmBasic\MasmBasic.inc
  Init
  Inkey NoTag$(FileRead$("https://de.wikipedia.org/wiki/Spezial:Zufällige_Seite"))
EndOfCode
Title: Animated GIF
Post by: jj2007 on January 16, 2019, 02:26:28 AM
include \masm32\MasmBasic\Res\MbGui.asm
Event Paint
  .if !Exist("test.img")
        Let esi=FileRead$("https://i.gifer.com/6H3K.gif")
        FileWrite "test.img", esi, LastFileSize
  .endif
  GuiImage "test.img", fit
EndOfCode
Title: Creating a matrix of doubles and store it to a text file
Post by: jj2007 on February 08, 2019, 09:14:05 PM
This snippet
- generates a 512*512 matrix of random double values
- writes all values to a string array
- saves the strings to disk

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  elements=512
  PrintCpu 0
  NanoTimer()
  Dim matrix(elements,elements) As REAL8
  For_ ct=0 To elements-1
        For_ ecx=0 To elements-1
                Rand(-12345.6789, 12345.6789, matrix(ct, ecx))
        Next
  Next
  PrintLine NanoTimer$(), Str$(" for generating %i random doubles", matrix(?))
  NanoTimer()
  Dim out$()                    ; create a zstring array
  Let edi=New$(16*elements)    ; prepare for long numbers, e.g. 12345.6789
  For_ ct=0 To elements-1
        push edi
       For_ ecx=0 To elements-1
                invoke MbCopy, edi, Str$("%9f\t", matrix(ct, ecx)), -2
                xchg eax, edi
        Next
        and dword ptr [edi-1], 0
        pop edi
       Let out$(ct)=edi
  Next
  PrintLine NanoTimer$(), Str$(" for %i strings", ct)
  Store "Matrix.txt", out$()    ; save to disk
  Inkey "wanna see the result? (y)"
  If_ eax=="y" Then ShEx "Matrix.txt"   ; show it in Notepad etc
EndOfCode


Typical output:
Code: [Select]
Intel(R) Core(TM) i5-2450M CPU @ 2.50GHz
5078 µs for generating 262144 random doubles
66 ms for 512 strings
Title: Duplicate bits
Post by: jj2007 on February 17, 2019, 02:34:07 PM
include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)

DuplicateBits MACRO arg
Local Lb0, Lb1, Lb2
  mov edx, arg
  xor eax, eax
  push ecx
  mov ecx, 11000000000000000000000000000000b
Lb0:
  rol ecx, 2                            ; in the first round, ecx will be 11b
  shr edx, 1                            ; get the carry flag
  je Lb1
  jnc Lb0
  or eax, ecx
  jmp Lb0
Lb1:
  jnc Lb2
  or eax, ecx
Lb2:
  pop ecx
  EXITM <eax>
ENDM

  Init
  m2m ecx, 1
  mov edi, 256
  .Repeat
        mov esi, ecx
        shr edi, 1
        or esi, edi
        Print Right$(Cat$(Replace$(Bin$(esi), "0", " ")), 8 ), Spc4$     ; print the original without the 0s
        Print Right$(Cat$(Replace$(Bin$(DuplicateBits(esi)), "0", " ")), 16), CrLf$  ; print the duplicate
        shl ecx, 1
  .Until ecx>255
  Inkey CrLf$, "-- hit any key --"
EndOfCode


Output:
Code: [Select]
1      1    11            11
 1    1       11        11
  1  1          11    11
   11             1111
   11             1111
  1  1          11    11
 1    1       11        11
1      1    11            11

Source attached. The macro will also work for plain Masm32 sources.
Title: FizzBuzz
Post by: jj2007 on May 09, 2019, 12:33:31 AM
The "Fizz-Buzz test" (http://wiki.c2.com/?FizzBuzzTest) is an interview question designed to help filter out the 99.5% of programming job candidates who can't seem to program their way out of a wet paper bag. The text of the programming assignment is as follows:

Quote
"Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”."

include \masm32\MasmBasic\MasmBasic.inc         ; download (http://masm32.com/board/index.php?topic=94.0)
  Init
  For_ ct=1 To 100
        xor esi, esi            ; flag Fizz or Buzz
        mov eax, ct
        cdq
        mov ecx, 3
        div ecx
        test edx, edx
        .if Zero?
                inc esi
                Print "Fizz"
        .endif
        mov eax, ct
        cdq
        mov ecx, 5
        div ecx
        test edx, edx
        .if Zero?
                inc esi
                Print "Buzz"
        .endif
        .if !esi
                Print Str$(ct)
        .endif
        Print " "
  Next
  Inkey "ok?"
EndOfCode
Title: Re: Miscellaneous snippets
Post by: TimoVJL on May 09, 2019, 01:50:29 AM
In C, perhaps it works ::)
Code: [Select]
int __cdecl main(void)
{
char *Fizz = "Fizz";
char *Buzz = "Buzz";
char *pF, *pB;
for (int i=0; i<100; i++) {
pF = 0;
pB = 0;
if (i) {
if (i % 3 == 0) pF = Fizz;
if (i % 5 == 0) pB = Buzz;
}
if (pF || pB) {
if (pF) printf(pF);
if (pB) printf(pB);
printf("\n");
} else printf("%d\n", i);
}
return 0;
}
Title: Re: Miscellaneous snippets
Post by: AW on May 09, 2019, 02:21:18 AM
Another C version (may be can be made shorter   ::)):

int main()
{
   char buff[16];
   for (int i = 1; i <= 100; i++)
      printf("%s\n", !(i % 3) && !(i % 5) ? "FizzBuff": (!(i % 5) ? "Buzz": (!(i % 3) ? "Fizz": itoa(i,buff,10))));
}
Title: Re: Miscellaneous snippets
Post by: TimoVJL on May 09, 2019, 02:59:28 AM
Nice!
4 bytes shorter, but not C99.

Jose's version unpacked:
Code: [Select]
#pragma comment(lib, "msvcrt.lib")
char *_itoa(int value, char *dst, int base);
void __cdecl mainCRTStartup(void)
{
__declspec(dllimport) void __cdecl exit(int status);
int __cdecl main(void);
exit(main());
}
int main(void)
{
   char buff[16];
char *p;
   for (int i = 1; i <= 100; i++) {
if (!(i % 3) && !(i % 5)) p = "FizzBuff";
else if (!(i % 5)) p = "Buzz";
else if (!(i % 3)) p =  "Fizz";
else p = _itoa(i,buff,10);
puts(p);
}
return 0;
}
EDIT:
Code: [Select]
#pragma comment(lib, "msvcrt.lib")
char *_itoa(int value, char *dst, int base);
void __cdecl mainCRTStartup(void)
{
__declspec(dllimport) void __cdecl exit(int status);
int __cdecl main(void);
exit(main());
}
int __cdecl main(void)
{
char *Fizz = "Fizz";
char *Buzz = "Buzz";
char *pF, *pB;
char buf[16];
for (int i=0; i<100; i++) {
pF = 0;
pB = 0;
if (i % 3 == 0) pF = Fizz;
if (i % 5 == 0) pB = Buzz;
if (pF || pB) {
if (pF) printf(pF);
if (pB) printf(pB);
puts("");
} else {
puts(_itoa(i, buf, 10));
}
}
return 0;
}
Title: Re: Miscellaneous snippets
Post by: jj2007 on May 09, 2019, 03:30:54 AM
Choose (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm#Mb1289) is purest Assembly :P

Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc
  Init
  For_ ct=1 To 100
        xor ebx, ebx ; flag Fizz or Buzz
        mov eax, ct
        cdq
        mov ecx, 3
        div ecx
        test edx, edx
        sete bl
        mov eax, ct
        mov ecx, 5
        div ecx
        test edx, edx
        sete dl
        lea ebx, [ebx+2*edx]
        Print Choose(ebx, Str$("%i ", ct), "Fizz ", "Buzz ", "FizzBuzz ")
  Next
  Inkey "ok?"
EndOfCode
Title: Re: Miscellaneous snippets
Post by: AW on May 09, 2019, 03:57:50 AM
 :( itoa  :biggrin: _itoa  :lol: purest Assembly
Title: Re: Miscellaneous snippets
Post by: jj2007 on May 09, 2019, 11:51:40 AM
Certain similarities should be accepted 8)

Code: [Select]
printf("%s\n", !(i % 3) && !(i % 5) ? "FizzBuff": (!(i % 5) ? "Buzz": (!(i % 3) ? "Fizz": itoa(i,buff,10))));
Print Choose(ebx, Str$("%i ", ct), "Fizz ", "Buzz ", "FizzBuzz ")

Full version:

include Modulo.inc
  Init
  For_ ecx=1 To 30
        lea ebx, [2*IsModulo(ecx, 5)]
        add ebx, IsModulo(ecx, 3)
       PrintLine Choose(ebx, Str$("%i ", ecx), "Fizz ", "Buzz ", "FizzBuzz ")
  Next
  Inkey
EndOfCode


I wonder if it should be called ModZero(src, imm)?

Output:
Code: [Select]
1
2
Fizz
4
Buzz
Fizz
7
8
Fizz
Buzz
11
Fizz
13
14
FizzBuzz
16
17
Fizz
19
Buzz
Fizz
22
23
Fizz
Buzz
26
Fizz
28
29
FizzBuzz
;)
Title: Plotting data
Post by: jj2007 on May 16, 2019, 01:33:12 PM
include \masm32\MasmBasic\Res\MbGui.asm
  ArraySet current() As double=120, 125, 122, 119, 134, 138, 141, 159, 162, 178
  ArraySet voltage() As double=250, 210, 180, 155, 140, 125, 110, 100, 90, 80
  SetAxisX "Электроток", s 0, d 1/5, grid 1   ; s=start value, d=difference between gridlines
  SetAxisY "Voltage", s 0, d 5/5, grid 1
Event Paint
  ArrayPlotValues "%i V", 8, -12        ; format$, dx & dy positions
  ArrayPlot current():voltage(), RgbCol(0, 0, 255), lines=3
  ArrayPlot exit, "繪製科學數據非常容易!"
EndOfCode


(http://www.jj2007.eu/images/PlotVoltageOverCurrent.png)
Title: Re: Miscellaneous snippets
Post by: daydreamer on May 18, 2019, 03:54:37 AM
Impressive Jochen :t
how fast is arrayplot compared to GDI?
is it masmbasic functions used in Lord Adef's game,scrolling and sprite functions included already in masmbasic?
strange if not,because its included GET and PUT in qbasic
Title: Re: Miscellaneous snippets
Post by: jj2007 on May 18, 2019, 10:29:03 AM
Thanks, Daydreamer. Arrayplot is Gdi, actually. Speedwise, check the Sinus plot template (attached). Re GET & PUT: There are ways to do something similar in MasmBasic, but I doubt that LordAdef is using them.
Title: Re: Plotting data
Post by: LiaoMi on May 18, 2019, 06:22:21 PM
include \masm32\MasmBasic\Res\MbGui.asm
  ArraySet current() As double=120, 125, 122, 119, 134, 138, 141, 159, 162, 178
  ArraySet voltage() As double=250, 210, 180, 155, 140, 125, 110, 100, 90, 80
  SetAxisX "Электроток", s 0, d 1/5, grid 1   ; s=start value, d=difference between gridlines
  SetAxisY "Voltage", s 0, d 5/5, grid 1
Event Paint
  ArrayPlotValues "%i V", 8, -12        ; format$, dx & dy positions
  ArrayPlot current():voltage(), RgbCol(0, 0, 255), lines=3
  ArrayPlot exit, "繪製科學數據非常容易!"
EndOfCode


(http://www.jj2007.eu/images/PlotVoltageOverCurrent.png)

Hi jj2007,

is it possible to make smoothing lines? the soul requires aesthetics)
Smoothing a curve in VB.Net https://www.codeproject.com/Questions/358853/Smoothing-a-curve-in-VB-Net (https://www.codeproject.com/Questions/358853/Smoothing-a-curve-in-VB-Net)
Title: Re: Plotting data
Post by: jj2007 on May 18, 2019, 07:06:10 PM
is it possible to make smoothing lines?

Probably, but the CodeProject guy is on the wrong track. For scientific data visualisation, you can't use "shortcuts" of that sort, they must be exact. What you can do, though, is smoothing a ragged line by anti-aliasing:
(https://joeycamson.files.wordpress.com/2011/11/aliasing.png)

If I find the time, I'll find a way to let GdiPlus draw these lines 8)
Title: Re: Miscellaneous snippets
Post by: daydreamer on May 19, 2019, 12:19:26 AM
Thanks, Daydreamer. Arrayplot is Gdi, actually. Speedwise, check the Sinus plot template (attached). Re GET & PUT: There are ways to do something similar in MasmBasic, but I doubt that LordAdef is using them.
if its gdi draw chinese characters,please check in my thread if you can show a smoother solution to this problem Jochen
http://masm32.com/board/index.php?topic=7834.0 (http://masm32.com/board/index.php?topic=7834.0)
Title: Re: Miscellaneous snippets
Post by: jj2007 on May 19, 2019, 05:16:09 AM
The text is not the problem, Gdi draws fonts OK. It is the ragged line. Below an excerpt from the plot where I added a line drawn with Gdi+, using high quality anti-aliasing. It does make a difference, but the extra quality is not overwhelming.

You must zoom in quite a lot to see a difference. On Chrome/SlimJet it's holding Control and pushing the mousewheel forward.

Btw this is line width 3; for finer lines, the difference between plain Gdi and high quality anti-aliased Gdi+ is almost negligible. On the right side of the graph, I added a comparison between 5px and 1px lines. If you zoom to 200 or 250%, the difference becomes evident. Note also how neat the Chinese text looks - it's really fine.
Title: Re: Miscellaneous snippets
Post by: daydreamer on May 19, 2019, 06:01:06 AM
The text is not the problem, Gdi draws fonts OK. It is the ragged line. Below an excerpt from the plot where I added a line drawn with Gdi+, using high quality anti-aliasing. It does make a difference, but the extra quality is not overwhelming.

You must zoom in quite a lot to see a difference. On Chrome/SlimJet it's holding Control and pushing the mousewheel forward.

Btw this is line width 3; for finer lines, the difference between plain Gdi and high quality anti-aliased Gdi+ is almost negligible. On the right side of the graph, I added a comparison between 5px and 1px lines. If you zoom to 200 or 250%, the difference becomes evident. Note also how neat the Chinese text looks - it's really fine.
maybe d3d can antialias better and faster with full antialias settings
Title: Re: Miscellaneous snippets
Post by: jj2007 on May 19, 2019, 06:18:16 AM
maybe - post a demo ;-)
Title: Re: Miscellaneous snippets
Post by: LiaoMi on May 19, 2019, 07:08:31 PM
Hi,

I take my words back  :biggrin: It looks like its just impossible to make normal smoothing with GDI, other technologies have to deal with it.

https://software.intel.com/en-us/articles/mlaa-efficiently-moving-antialiasing-from-the-gpu-to-the-cpu (https://software.intel.com/en-us/articles/mlaa-efficiently-moving-antialiasing-from-the-gpu-to-the-cpu)
SMAA: Subpixel Morphological Antialiasing https://github.com/iryoku/smaa (https://github.com/iryoku/smaa)
Demo - https://web.archive.org/web/20121023110459/http://www.iryoku.com/mlaa/downloads/Jimenez-MLAA-DX10-v1.5.exe (https://web.archive.org/web/20121023110459/http://www.iryoku.com/mlaa/downloads/Jimenez-MLAA-DX10-v1.5.exe)

Below, I gave examples showing the difference between display technologies.
Title: Re: Miscellaneous snippets
Post by: jj2007 on May 19, 2019, 08:03:31 PM
Project upgrade failed (your source is 2007, I tried with Visual Crap 2010) 8)
Title: Re: Miscellaneous snippets
Post by: daydreamer on May 20, 2019, 09:01:26 PM
maybe - post a demo ;-)
docs says it doesnt antialias lines,only polys in fullscene antialias
Title: Re: Miscellaneous snippets
Post by: LiaoMi on May 20, 2019, 10:46:18 PM
Project upgrade failed (your source is 2007, I tried with Visual Crap 2010) 8)

Hi jj2007,

I also have no success in the visual studio 2019, I will try on another machine. The first example shows that in GDI it is not reachable, and the second example shows how ideally it should be, taking into account that another mechanism is used. The speed and processing of both techniques are completely different. I do not think it's worth puzzling over this problem  :rolleyes:
Title: Re: Miscellaneous snippets
Post by: daydreamer on May 25, 2019, 10:34:45 PM
Thanks, Daydreamer. Arrayplot is Gdi, actually. Speedwise, check the Sinus plot template (attached). Re GET & PUT: There are ways to do something similar in MasmBasic, but I doubt that LordAdef is using them.
you use GDI background color=bitmap? or use background color=null?
for example want to have a moving object,just redraw it together with erase few pixels behind it?

I found this direct2d vs GDI,look below at the images direct2d is smoother curves
https://docs.microsoft.com/sv-se/windows/desktop/direct2d/direct2d-overview (https://docs.microsoft.com/sv-se/windows/desktop/direct2d/direct2d-overview)
Title: Re: Miscellaneous snippets
Post by: jj2007 on May 25, 2019, 11:26:11 PM
I found this direct2d vs GDI,look below at the images direct2d is smoother curves

The curves are Gdi vs D2D, not Gdi+. They write "When rendering in software, applications that use Direct2D experience substantially better rendering performance than with GDI+ and with similar visual quality." - and I bet they mean "almost the same quality".
Title: WM_DROPFILES
Post by: jj2007 on June 20, 2019, 06:15:26 PM
GuiParas equ "Event Dropfiles demo", x1000, y20, w350, h700, cblack, b00FFFFD0h
include \masm32\MasmBasic\Res\MbGui.asm

Event DropFiles
  GfNoPaths=1                           ; optional: don't include the paths
  For_ ecx=0 To eax-1                   ; #files was returned in eax
        wPrintLine wRec$(Files$(ecx))   ; show the files in the console window
  Next
  GuiRefresh                            ; GuiText needs a WM_PAINT handler

Event Paint
  For_ ecx=0 To Files$(?)-1
        GuiText 3, ecx*20, Files$(ecx)
  Next
GuiEnd
Title: InternetCrackUrl
Post by: jj2007 on July 03, 2019, 08:13:59 AM
Little problems, it works only partially:

Code: [Select]
include \masm32\MasmBasic\MasmBasic.inc ; download
uselib WinInet

if 0
 URL_COMPONENTSA STRUCT
 dwStructSize DWORD ?
 lpszScheme LPSTR ?
 dwSchemeLength DWORD ?
 nScheme DWORD ?
 lpszHostName LPSTR ?
 dwHostNameLength DWORD ?
 nPort      INTERNET_PORT <>
 lpszUserName LPSTR ?
 dwUserNameLength DWORD ?
 lpszPassword LPSTR ?
 dwPasswordLength DWORD ?
 lpszUrlPath LPSTR ?
 dwUrlPathLength DWORD ?
 lpszExtraInfo LPSTR ?
 dwExtraInfoLength DWORD ?
 URL_COMPONENTSA ENDS
endif
.data?
UrlComp URL_COMPONENTS <>
HostName db 100 dup(?)
UserName db 100 dup(?)
UrlPath db 1000 dup(?)
ExtraInfo db 100 dup(?)

  Init
  add UrlComp.dwStructSize, URL_COMPONENTS
  mov UrlComp.lpszScheme, Chr$("Whatever suits you")
  add UrlComp.dwSchemeLength, c$Len
  mov UrlComp.lpszHostName, offset HostName
  add UrlComp.dwHostNameLength, 100
  add UrlComp.nScheme, INTERNET_SCHEME_UNKNOWN ; INTERNET_SCHEME_DEFAULT
  mov UrlComp.lpszUserName, offset UserName
  add UrlComp.dwUserNameLength, 100
  mov UrlComp.lpszUrlPath, offset UrlPath
  add UrlComp.dwUrlPathLength, 1000
  mov UrlComp.lpszExtraInfo, offset ExtraInfo
  add UrlComp.dwExtraInfoLength, 100

  invoke InternetCrackUrl, Chr$("https://docs.microsoft.com/en-us/windows/win32/api/wininet/nf-wininet-internetcrackurla"), 0, ICU_DECODE, addr UrlComp
  deb 4, "res", eax, $Err$(), $UrlComp.lpszScheme, $offset HostName, $offset UserName, $UrlPath, $ExtraInfo, UrlComp.nPort
  invoke InternetCrackUrl, Chr$("http://www.google.com/test.html"), 0, ICU_DECODE, addr UrlComp
  deb 4, "res", eax, $Err$(), $UrlComp.lpszScheme, $offset HostName, $offset UserName, $UrlPath, $ExtraInfo, UrlComp.nPort
 
EndOfCode

Code: [Select]
res
eax             1
$Err$()         Operazione completata.__
$UrlComp.lpszScheme     https
$offset HostName        docs.microsoft.com
$offset UserName
$UrlPath        470     <not a pointer>
$ExtraInfo      00      <not a pointer>
UrlComp.nPort   443

res
eax             0
$Err$()         Area dati passata ad una chiamata al sistema troppo piccola.__
$UrlComp.lpszScheme     http
$offset HostName        www.google.com
$offset UserName
$UrlPath        470     <not a pointer>
$ExtraInfo      00      <not a pointer>
UrlComp.nPort   80
Title: Re: Miscellaneous snippets
Post by: TimoVJL on July 03, 2019, 04:55:34 PM
Init buffer sizes between calls
Title: Re: Miscellaneous snippets
Post by: jj2007 on July 03, 2019, 05:59:18 PM
Thanks, Timo. Right, even a mov UrlComp.dwUserNameLength, 1 is sufficient. It seems that if you pass a pointer to a buffer, the length must be at least one even if you don't get a text back.