News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

plotting in masm 32 bit

Started by markallyn, March 06, 2018, 07:19:16 AM

Previous topic - Next topic

dedndave


jj2007

@DednDave: Very cute :t Can you post the source?

Quote from: markallyn on March 14, 2018, 09:07:30 AMHow to put labeled axes and tick marks on the plot.  Can it be done?

Everything can be done in assembler :P

But not everything is already implemented as a "SetLegends" macro (except for pie charts, see attachment). By hand, this is possible:

include \masm32\MasmBasic\Res\MbGui.asm
.data?
hPen    dd ?
.code
  MakeFont hHorzFont, Height:18, Weight:FW_SEMIBOLD
  MakeFont hVertFont, Height:18, Weight:FW_SEMIBOLD, Escapement:900
  Dim rk() As REAL4             ; define a REAL4 array
  Dim range(4) As REAL4         ; create another array
  ArraySet range()=-0.1, 1.0, 1.05, 0.0         ; set a plotting range
  StringToArray 99, rk()        ; fill it; 99 is the resource ID for rk4.txt
  mov hPen, rv(CreatePen, PS_SOLID, 3, RgbCol(0, 0, 80))

Event Paint
  ArrayPlot RgbCol(192, 255, 255)       ; init & set background
  ArrayPlot range(XY),,,, setrange     ; use a fake array to set the ranges
  ArrayPlot rk(XY), RgbCol(222, 0, 0), lines=2         ; draw the array with 2px red lines (try bars=40)
  ArrayPlot exit, "Data read from a resource"  ; finish with a title

  invoke SetBkColor, PtDC, RgbCol(192, 255, 255)
  GuiText 25, 400, "Hello, I am the Y axis", font hVertFont
  GuiLine 50, 50, 50, 600, hPen
  GuiText 420, 610, "And I am the X axis", font hHorzFont
  GuiLine 50, 600, 1100, 600, hPen
EndOfCode


GuiLine and GuiText are MasmBasic macros. However, you can roll your own legend using PtDC after the ArrayPlot exit line, for example:

invoke TextOut, PtDC, 300, 330, Chr$("Hello"), 5

dedndave

Quote from: jj2007 on March 14, 2018, 04:49:56 PM
@DednDave: Very cute :t Can you post the source?

sorry Jochen - it may become proprietary source code
i may post a portion of it at some point, though
it has been my intention to make the custom button code available

attached is SimpleBezier (the png is just an image)
enter your own set of data points and assemble
re-size the window, and it re-scales the graph

raymond

QuoteWhat I am trying to accomplish is to write in assembly (masm, uasm, Jwasm, goasm, poasm,nasm,  etc.) a numerical integrator that can call a plotter written also in assembly.  Why?  I could write a c/c++ program, write results to a file, and then call a plotter.  It would be much easier, but not nearly as much fun or as instructive.

You are absolutely right with that last sentence.

If you want to use the FPU, a good library is available with the MASM32 SDK or you can download it from http://www.ray.masmcode.com/fpu.html#fpulib
Each of its functions has a lot of overhead to cater to the allowed types of input and output. With time, you may want to speed it up by writing your own code specifically designed for your own use. (The above download also includes the source code of each function.) An FPU tutorial is also available on the same site.

While you are at it, you may realize that you don't need all the precision available from the FPU. You might also want to experiment with fixed point math. Here again, a library is available for numerous functions (including all source code) at http://www.ray.masmcode.com/fixmath.html

I'm also attaching a small program (complete with source code) which I wrote some 20 years ago to display biorythms using fixed point math to draw the sinusoidal curves.

Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

dedndave

always good to see you, Raymond  :t

Ray makes a good point about resolution or precision
the nicer display systems these days might have 12 bits of resolution
printers, maybe 8 bits
so, 32 bit integers are overkill, really
the FPU is nice to handle values over a wide range
or, if exponential or trigonometric functions are needed (of course)
otherwise, integer math is fast and easy

jj2007

Quote from: raymond on March 16, 2018, 01:03:37 PMI'm also attaching a small program (complete with source code) which I wrote some 20 years ago to display biorythms using fixed point math to draw the sinusoidal curves.

Very nice indeed :t

I tried to build it but: Cannot open file: "\masm32\include\mix.inc"

markallyn

Good morning/afternoon/evening, Raymond, Dave, and Jochen:

Wow, you folks have really risen to the challenge.  Very impressive indeed.  I have saved all your zip files and will play with them this afternoon USA EDT time.  My guess is that I will encounter same problem with mix.inc that JJ did so I'm hoping Raymond will share this .inc or a workaround, if possible. 

JJ:  As you know I'm having problems running RichMasm on my 64 bit machine.  So, I can't try out your code on the 64 bit box until I've resolved the problem with masm32rt.inc and friends.  But, I can try it on my 32 bit box and it should run there.

Dave:  OK, you did the exponential curve (solution to dy/dt=1.0 - 2.0*y on [0,1]).  Very nice.  But, if I understand your response to JJ the source code is for the moment anyway proprietary.  How about creating a .dll that users can load and call with some nice interface that specifies the plot coordinates, axes, labels, ticks, and legend.  I for one would find this very cool.  I would award you the Alexander Nevsky prize.

Regards,
Mark

raymond

Quote from: jj2007 on March 16, 2018, 02:51:01 PM
Quote from: raymond on March 16, 2018, 01:03:37 PMI'm also attaching a small program (complete with source code) which I wrote some 20 years ago to display biorythms using fixed point math to draw the sinusoidal curves.

Very nice indeed :t

I tried to build it but: Cannot open file: "\masm32\include\mix.inc"

It is part of the package available at http://www.ray.masmcode.com/fixmath.html (indicated previously). Apart from that, you may have to modify the code to indicate where you effectively copy the required files if you don't have/want the used "masm32" folder tree.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html

jj2007

Quote from: raymond on March 17, 2018, 03:04:37 AMIt is part of the package available at http://www.ray.masmcode.com/fixmath.html

Works perfectly if
- mix.inc goes to \Masm32\include\Mix.inc
- mix.lib goes to \Masm32\lib\Mix.lib
- line 40 of Mix.inc is modified as MixError EQU 80000000h (ERROR is already defined elsewhere; and it's not used in this source)
:t

dedndave

Quote from: markallyn on March 17, 2018, 01:53:11 AM
But, if I understand your response to JJ the source code is for the moment anyway proprietary.  How about creating a .dll that users can load and call with some nice interface that specifies the plot coordinates, axes, labels, ticks, and legend.  I for one would find this very cool.  I would award you the Alexander Nevsky prize.

well - that program may be sold, at some point

as for making lines and hash-marks, it is easy-peazy

just use MoveToEx and LineTo

https://msdn.microsoft.com/en-us/library/dd145069(v=vs.85).aspx

https://msdn.microsoft.com/en-us/library/dd145029(v=vs.85).aspx

text is not as easy....
for the numbers, i used a 6x8 terminal font

;8 x 12  Terminal
;4 x 6   Terminal
;5 x 12  Terminal
;6 x 8   Terminal
;7 x 12  Terminal

;lfn           LOGFONT <8,6,,,,,,,OEM_CHARSET,,,,FIXED_PITCH,"Terminal">
; lfHeight          DWORD ?
; lfWidth           DWORD ?
; lfEscapement      DWORD ?
; lfOrientation     DWORD ?
; lfWeight          DWORD ?
; lfItalic          BYTE  ?
; lfUnderline       BYTE  ?
; lfStrikeOut       BYTE  ?
; lfCharSet         BYTE  ?
; lfOutPrecision    BYTE  ?
; lfClipPrecision   BYTE  ?
; lfQuality         BYTE  ?
; lfPitchAndFamily  BYTE  ?
; lfFaceName        BYTE  LF_FACESIZE dup(?)

    mov     edx,offset lfn
    mov dword ptr [edx].LOGFONT.lfFaceName,'mreT'
    mov dword ptr [edx].LOGFONT.lfFaceName+4,'lani'
    mov byte ptr [edx.LOGFONT.lfFaceName+8,0
    INVOKE  CreateFontIndirect,edx
    mov     hNumFont,eax


and, the following functions...

SetTextColor
https://msdn.microsoft.com/en-us/library/dd145093(v=vs.85).aspx

SetBkColor (actually, i used opaque mode, so didn't need this one)
https://msdn.microsoft.com/en-us/library/dd162964(v=vs.85).aspx

SetBkMode
https://msdn.microsoft.com/en-us/library/dd162965(v=vs.85).aspx

there are a few functions to display text, i use this one because it is relatively fast
ExtTextOut
https://msdn.microsoft.com/en-us/library/dd162713(v=vs.85).aspx

to make vertical text, i use the same font
at program initialization, i create a bitmap with the entire ASCII set
i rotate it 90 degrees, and use that to make vertical text   :P

dedndave

i could show you more, but i hate to suck all the fun out of it  :lol:

;***********************************************************************************************

VtxtInit PROC USES EBX ESI EDI

;hNumFont must be initialized prior to call (6x8 terminal font)

;-----------------------------------------

    LOCAL   bmis        :BITMAPINFO256
    LOCAL   pvBits1     :LPVOID
    LOCAL   pvBits2     :LPVOID
    LOCAL   hbmpDib1    ;HBITMAP
    LOCAL   hbmpDib2    ;HBITMAP
    LOCAL   hbmpMem1    ;HBITMAP
    LOCAL   hbmpMem2    ;HBITMAP
    LOCAL   hdcMem1     :HDC
    LOCAL   hdcMem2     :HDC

;-----------------------------------------

;initialize 256-color BITMAPINFO structure

;BITMAPINFO256   STRUCT
;  bmiHeader       BITMAPINFOHEADER <>
;    biSize          dd ?               ;BITMAPINFOHEADER structure size
;    biWidth         dd ?               ;image width in pixels
;    biHeight        dd ?               ;signed image height in pixels
;    biPlanes        dw ?               ;= 1
;    biBitCount      dw ?               ;= 8
;    biCompression   dd ?               ;= BI_RGB = 0
;    biSizeImage     dd ?               ;image data bytes
;    biXPelsPerMeter dd ?               ;= 0
;    biYPelsPerMeter dd ?               ;= 0
;    biClrUsed       dd ?               ;= 0
;    biClrImportant  dd ?               ;= 0
;  bmiColors       RGBQUAD 256 dup(<>)

;initialize the BMP header structure, 1536x8 pixels, 256 colors

    xor     eax,eax
    mov     bmis.bmiHeader.biSize,sizeof BITMAPINFOHEADER
    mov     bmis.bmiHeader.biWidth,1536
    mov     bmis.bmiHeader.biHeight,8
    mov     bmis.bmiHeader.biPlanes,1
    mov     bmis.bmiHeader.biBitCount,8
    mov     bmis.bmiHeader.biCompression,eax     ;BI_RGB = 0
    mov     bmis.bmiHeader.biSizeImage,8*1536
    mov     bmis.bmiHeader.biXPelsPerMeter,eax
    mov     bmis.bmiHeader.biYPelsPerMeter,eax
    mov     bmis.bmiHeader.biClrUsed,eax
    mov     bmis.bmiHeader.biClrImportant,eax

;fill the palette with 256 colors, all plot bg color

;rgbbg = rrggbb
;crefbg = bbggrr

    mov     eax,RGB_PLOTBG
    lea     edi,bmis.bmiColors
    mov     ecx,256
    .repeat
        mov     [edi],eax
        dec     ecx
        lea     edi,[edi+4]
    .until ZERO?

;old standard: first color = text background, second color = text foreground

    mov dword ptr bmis.bmiColors+4,ecx

;get the desktop DC

    INVOKE  GetDC,HWND_DESKTOP
    xchg    eax,ebx                                                             ;EBX = hdcDesktop

;create DIB section 1, and select it into DC 1

    xor     ecx,ecx
    INVOKE  CreateDIBSection,ebx,addr bmis,DIB_RGB_COLORS,addr pvBits1,ecx,ecx
    xchg    eax,esi
    mov     hbmpDib1,esi
    INVOKE  CreateCompatibleDC,ebx
    xchg    eax,esi                                                             ;ESI = hdcMem1
    mov     hdcMem1,esi
    INVOKE  SelectObject,esi,eax
    mov     hbmpMem1,eax

;create DIB section 2, and select it into DC 2

    xor     ecx,ecx
    mov     bmis.bmiHeader.biWidth,8
    mov     bmis.bmiHeader.biHeight,1536
    INVOKE  CreateDIBSection,ebx,addr bmis,DIB_RGB_COLORS,addr pvBits2,ecx,ecx
    mov     hbmpDib2,eax
    INVOKE  CreateCompatibleDC,ebx
    mov     hdcMem2,eax
    INVOKE  SelectObject,eax,hbmpDib2
    mov     hbmpMem2,eax

;release the desktop DC

    INVOKE  ReleaseDC,HWND_DESKTOP,ebx

;draw the horizontal text into DC 1

    INVOKE  SelectObject,esi,hNumFont
    push    eax
    INVOKE  SetBkColor,esi,CREF_PLOTBG
    push    eax
    INVOKE  SetTextColor,esi,0
    push    eax
    INVOKE  SetBkMode,esi,OPAQUE
    mov     edi,3020100h
    push    eax
    xor     ebx,ebx
    .repeat
        push    edi
        xor     ecx,ecx
        mov     edx,esp
        INVOKE  ExtTextOut,esi,ebx,ecx,ecx,ecx,edx,4,ecx
        add     edi,4040404h
        pop     edx
        lea     ebx,[ebx+24]
    .until CARRY?
    push    esi
    CALL    SetBkMode
    push    esi
    CALL    SetTextColor
    push    esi
    CALL    SetBkColor
    push    esi
    CALL    SelectObject

;flip and rotate the text pixels from DIB 1 into DIB 2

    push    ebp
    mov     edi,pvBits2
    mov     esi,pvBits1
    mov     ebp,8
    add     edi,8*1535
    .repeat
        push    ebp
        mov     ebp,192
        .repeat
            mov     ax,[esi]
            mov     cx,[esi+2]
            mov     dx,[esi+4]
            mov     bx,[esi+6]
            mov     [edi],al
            mov     [edi-8],ah
            mov     [edi-16],cl
            mov     [edi-24],ch
            mov     [edi-32],dl
            mov     [edi-40],dh
            mov     [edi-48],bl
            mov     [edi-56],bh
            dec     ebp
            lea     esi,[esi+8]
            lea     edi,[edi-64]
        .until ZERO?
        pop     ebp
        add     edi,12289
        dec     ebp
    .until ZERO?
    pop     ebp

;switch the palette in DIB 1 for horizontal XOR text

    lea     edi,bmis.bmiColors
    mov     ecx,256
    xor     eax,eax
    mov     edx,edi
    rep     stosw
    mov dword ptr [edx+4],0FFFFFFh
    INVOKE  SetDIBColorTable,hdcMem1,eax,256,edx

;cleanup and exit with hbmpDib1, hbmpDib2, and pvBits2

    INVOKE  SelectObject,hdcMem1,hbmpMem1
    INVOKE  DeleteDC,hdcMem1
    INVOKE  SelectObject,hdcMem2,hbmpMem2
    INVOKE  DeleteDC,hdcMem2
    mov     ecx,hbmpDib1
    mov     eax,hbmpDib2
    mov     edx,pvBits2
    ret

VtxtInit ENDP

;***********************************************************************************************

avcaballero

Is it top secret? :lol:
A sign program

jj2007

Reminds me a bit of my old PolyLine demo ;)

daydreamer

Quote from: raymond on March 16, 2018, 01:03:37 PM

While you are at it, you may realize that you don't need all the precision available from the FPU. You might also want to experiment with fixed point math. Here again, a library is available for numerous functions (including all source code) at http://www.ray.masmcode.com/fixmath.html

nice program Raymond
actually dont you get little more precision with 32bit integer hold more digits than 23 bit float?,your function stored as 31bit decimal data MUL gives you 64bit results

in my youth some friends coded kinda multiplayer monopoly style game, but it was 1930's gangsta style and money was treated as integers with opposite offset as your description of fixed point,each output of player wealth the money integer was  ended with "000", and input divided money by 1000
before subtracting for example how much money player bought drugs,bodyguards etc for
counts as fixed point?

8bit Sine LUT which only hold decimals+conditional code for byte=255:sine=1.0 branch over MUL,if byte=0,store zero as result and branch over MUL
old 8bit cpu code performed a 16bit MUL PROC
counts as fixed point?
maybe should have done a reverse approach with load 8bit precalculated circle value in High byte and just a bitshift it to smaller value like old sprites just resized x1,x2,x4 in star raiders,when circle is small, load 8bit precalculated in low byte and bitshift to bigger
my none asm creations
https://masm32.com/board/index.php?topic=6937.msg74303#msg74303
I am an Invoker
"An Invoker is a mage who specializes in the manipulation of raw and elemental energies."
Like SIMD coding

raymond

Quotedon't you get little more precision with 32bit integer hold more digits than 23 bit float?

Actually, the "23-bit float" really gives you 24 bits of precision; the initial bit is assumed. Another bit being used for the sign, this would leave only 7 bits in a 32-bit dword for the integer portion, leaving you a range of +/- 127. That would definitely not be sufficient to cover the usual screen size range for plotting with the same 'precision' as floats. Using dwords, every additional bit of precision would reduce that range by half.

The 32-bit integer will be more precise than the 23-bit float only when the integer portion exceeds 24 bits, i.e. 16,777,215. But then you don't have many bits left, if any, for the fractional portion.

The mix.lib library mentioned previously uses the lower 16 bits for the fraction, leaving 16 bits for the integer portion and sign for a range of +/- 32767.
Whenever you assume something, you risk being wrong half the time.
https://masm32.com/masmcode/rayfil/index.html