Author Topic: Object-oriented programming (OOP) in Asmc  (Read 7756 times)

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #30 on: June 08, 2020, 04:14:13 AM »
Test case for the Effect class.

https://docs.microsoft.com/en-us/windows/win32/api/gdipluseffects/nl-gdipluseffects-effect

The Effect class serves as a base class for eleven classes that you can use to apply effects and adjustments to bitmaps. The following classes descend from Effect.

    Blur
    Sharpen
    Tint
    RedEyeCorrection
    ColorMatrixEffect
    ColorLUT
    BrightnessContrast
    HueSaturationLightness
    ColorBalance
    Levels
    ColorCurve

Code: [Select]
    .case WM_PAINT

        BeginPaint(rcx, &ps)

       .new g:Graphics(rax)
       .new i:Image(L"Photograph.jpg")
       .new r:RectF
       .new m:Matrix(1.0, 0.0, 0.0, 1.0, 20.0, 280.0)
       .new P:ColorBalanceParams
       .new E:ColorBalance()

        mov r.X,0.0
        mov r.Y,0.0
        i.GetWidth()
        cvtsi2ss xmm0,eax
        movss r.Width,xmm0
        i.GetHeight()
        cvtsi2ss xmm0,eax
        movss r.Height,xmm0

        ;; Integer in the range -100 through 100 that specifies a change in the
        ;; amount of red in the image. If the value is 0, there is no change.
        mov P.cyanRed,-60
        ;; Integer in the range -100 through 100 that specifies a change in the
        ;; amount of green in the image. If the value is 0, there is no change.
        mov P.magentaGreen,40
        ;; Integer in the range -100 through 100 that specifies a change in the
        ;; amount of blue in the image. If the value is 0, there is no change.
        mov P.yellowBlue,-50

        E.SetParameters(&P)

        ;; Draw the image with no change.
        g.DrawImage(&i, 20.0, 20.0, r.Width, r.Height)

        ;; Draw the image with applied Effect
        g.DrawImage(&i, &r, &m, &E, NULL, UnitPixel)

        i.Release()
        g.Release()
        EndPaint(hWnd, &ps)
        .endc

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #31 on: June 10, 2020, 04:49:05 AM »
The ImageAttributes class.

https://docs.microsoft.com/en-us/windows/win32/api/gdiplusimageattributes/nl-gdiplusimageattributes-imageattributes

An ImageAttributes object contains information about how bitmap and metafile colors are manipulated during rendering. An ImageAttributes object maintains several color-adjustment settings, including color-adjustment matrices, grayscale-adjustment matrices, gamma-correction values, color-map tables, and color-threshold values.

Code: [Select]

include windows.inc
include gdiplus.inc
include tchar.inc

    .code

WndProc proc uses rsi hWnd:HWND, message:UINT, wParam:WPARAM, lParam:LPARAM

  local ps:PAINTSTRUCT

    .switch edx

    .case WM_PAINT

        BeginPaint(rcx, &ps)

       .new g:Graphics(rax)

       ;; Create a palette that has four entries.

       .new p:ptr ColorPalette(4)
        mov rcx,rax
        [rcx].ColorPalette.SetPalette(0, Aqua)
        [rcx].ColorPalette.SetPalette(1, White)
        [rcx].ColorPalette.SetPalette(2, Red)
        [rcx].ColorPalette.SetPalette(3, Green)

        ;; Display the four palette colors with no adjustment.

       .new b:SolidBrush(Black)

        .for (esi = 0: esi < 4: ++esi)

            p.GetPalette(rsi)
            b.SetColor(eax)

            imul r8d,esi,30
            add  r8d,20

            g.FillRectangle(&b, r8d, 20, 20, 20)
        .endf

        ;; Create a remap table that converts green to blue.

       .new map:ColorMap
        mov map.oldColor,Green
        mov map.newColor,Blue

        ;; Create an ImageAttributes object, and set its bitmap remap table.

       .new imAtt:ImageAttributes()

        imAtt.SetRemapTable(1, &map, ColorAdjustTypeBitmap)

        ;; Adjust the palette.

        imAtt.GetAdjustedPalette(p, ColorAdjustTypeBitmap)

        ;; Display the four palette colors after the adjustment.

        .for (esi = 0: esi < 4: ++esi)

            p.GetPalette(rsi)
            b.SetColor(eax)

            imul r8d,esi,30
            add  r8d,20

            g.FillRectangle(&b, r8d, 50, 20, 20)
        .endf

        p.Release()
        g.Release()
        EndPaint(hWnd, &ps)
        .endc

    .case WM_DESTROY
        PostQuitMessage(0)
        .endc
    .case WM_CHAR
        .gotosw(WM_DESTROY) .if r8d == VK_ESCAPE
        .endc
    .default
        .return DefWindowProc(rcx, edx, r8, r9)
    .endsw
    xor eax,eax
    ret

WndProc endp

_tWinMain proc hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPTSTR, nShowCmd:SINT

  local wc:WNDCLASSEX, msg:MSG, hwnd:HANDLE

    xor eax,eax
    mov wc.cbSize,          WNDCLASSEX
    mov wc.style,           CS_HREDRAW or CS_VREDRAW
    mov wc.cbClsExtra,      eax
    mov wc.cbWndExtra,      eax
    mov wc.hbrBackground,   COLOR_ACTIVEBORDER
    mov wc.lpszMenuName,    rax
    mov wc.hIcon,           rax
    mov wc.hIconSm,         rax
    mov wc.hInstance,       rcx
    mov wc.lpfnWndProc,     &WndProc
    mov wc.lpszClassName,   &@CStr("GetAdjustedPalette")
    mov wc.hCursor,         LoadCursor(0, IDC_ARROW)

    .ifd RegisterClassEx(&wc)

        .if CreateWindowEx(0, "GetAdjustedPalette", "GetAdjustedPalette", WS_OVERLAPPEDWINDOW,
                100, 80, 400, 160, NULL, NULL, hInstance, 0)

            mov hwnd,rax

           ;; Initialize GDI+.
           .new gdiplus:GdiPlus()

            ShowWindow(hwnd, SW_SHOWNORMAL)
            UpdateWindow(hwnd)
            .while GetMessage(&msg, 0, 0, 0)
                TranslateMessage(&msg)
                DispatchMessage(&msg)
            .endw
            gdiplus.Release()
            mov rax,msg.wParam
        .endif
    .endif
    ret

_tWinMain endp

    end _tstart

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #32 on: June 14, 2020, 11:58:40 AM »
New sample
WIC Viewer GDI+

This code sample shows a Windows application using WIC to decode an image file and GDI+ to render the image to the screen. 

Files
WICViewerGDIPlus.inc: Header file that declares application class DemoApp interface
WICViewerGDIPlus.asm: Implementation of the application class interface

Building the Sample
To build the sample using the command prompt:
asmc64 -pe -ws -gui WICViewerGDIPlus.asm

Running the Sample
After the application is launched, load an image file through file open menu. Window resizing is supported.

Changes
The @CStr() macro now handles zero terminated strings. It also accept additional L"" on split strings but only the first one is valid.
Code: [Select]
DemoApp::LocateImageFile proc hWnd:HWND, pszFileName:LPWSTR, cchFileName:DWORD

    local ofn:OPENFILENAME

    mov word ptr [r8],0
    ZeroMemory(&ofn, sizeof(ofn))

    mov ofn.lStructSize,  sizeof(ofn)
    mov ofn.hwndOwner,    hWnd
    mov ofn.lpstrFilter,  &@CStr(
        L"All Image Files\0"               L"*.bmp;*.dib;*.wdp;*.mdp;*.hdp;*.gif;*.png;*.jpg;*.jpeg;*.tif;*.ico\0"
        L"Windows Bitmap\0"                L"*.bmp;*.dib\0"
        L"High Definition Photo\0"         L"*.wdp;*.mdp;*.hdp\0"
        L"Graphics Interchange Format\0"   L"*.gif\0"
        L"Portable Network Graphics\0"     L"*.png\0"
        L"JPEG File Interchange Format\0"  L"*.jpg;*.jpeg\0"
        L"Tiff File\0"                     L"*.tif\0"
        L"Icon\0"                          L"*.ico\0"
        L"All Files\0"                     L"*.*\0" )
    mov ofn.lpstrFile,    pszFileName
    mov ofn.nMaxFile,     cchFileName
    mov ofn.lpstrTitle,   &@CStr(L"Open Image")
    mov ofn.Flags,        OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST

    ;; Display the Open dialog box.
    GetOpenFileName(&ofn)
    ret

DemoApp::LocateImageFile endp

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #33 on: June 15, 2020, 02:13:32 PM »
WIC Animated Gif

WIC added support for reading/writing GIF metadata which is essential for rendering Animated GIFs.

This code sample is a simple Windows application that demonstrates decoding various frames in an GIF file, reading appropriate metadata for each frame, composing frames, and rendering the animation with Direct2D.

Files
sample.gif: sample gif file
WICAnimatedGif.inc: Header file that declares application class DemoApp interface
WICAnimatedGif.asm: Implementation of the application class interface

LiaoMi

  • Member
  • ****
  • Posts: 711
Re: Object-oriented programming (OOP) in Asmc
« Reply #34 on: June 15, 2020, 08:34:23 PM »
Hi nidud,

very cool examples, thanks for the work!  :thumbsup:

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #35 on: June 20, 2020, 03:33:39 AM »
IAmsiStream interface sample

Demonstrates how to use the Antimalware Scan Interface to scan a stream.

The sample implements the
IAmsiStream interface so that an antimalware provider can use it to scan the contents of a stream.

The sample demonstrates a stream where the data comes from a file
and a stream where the data comes from an in-memory buffer.

Files
AmsiStream.inc: Header file
AmsiStream.asm: Implementation

Note: this needs Windows 10

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #36 on: June 20, 2020, 03:53:28 AM »
printf versus cout

Files
https://github.com/nidud/asmc/tree/master/source/test/class/cout

Using cout:
Code: [Select]
    cout << "Ascii string"        << endl
    cout << ( L"Unicode string" ) << endl
    cout << endl

    cout << "signed char    (-1): " << signed_char  << endl
    cout << "signed short   (-1): " << signed_short << endl
    cout << "signed int     (-1): " << signed_int   << endl
    cout << "signed int64   (-1): " << signed_int64 << endl
    cout << "unsigned char  (-1): " << bl           << endl
    cout << "unsigned short (-1): " << bx           << endl
    cout << "unsigned int   (-1): " << ebx          << endl
    cout << "unsigned int64 (-1): " << rbx          << endl
    cout << endl

Using printf:
Code: [Select]
    printf( "Ascii string\n" )
    wprintf( L"Unicode string\n\n" )

    printf( "signed char    (-1): %d\n", signed_char )
    printf( "signed short   (-1): %d\n", signed_short )
    printf( "signed int     (-1): %d\n", signed_int )
    printf( "signed int64   (-1): %d\n", signed_int64 )
    printf( "unsigned char  (-1): %u\n", bl )
    printf( "unsigned short (-1): %u\n", bx )
    printf( "unsigned int   (-1): %u\n", ebx )
    printf( "unsigned int64 (-1): %llu\n\n", rbx )


cout.exe   7680 byte
stdio.exe 26624 byte

Note that this only apply to static linking using the Asmc LIBC-64.

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #37 on: June 20, 2020, 06:34:11 AM »
Added assignment of struct members. This apply to structs with default constructors (templates) and works with the .new directive.

Examples using the RECT structure. This also allow direct assignment.

    RECT()
    RECT(1, 2, 3)
    RECT() : left   (100),
             top    (200),
             right  (640),
             bottom (480)

    foo( RECT(100, 200, 640, 480) )

   .new RECT()        : right(1)
   .new rc:RECT()     : right(2)
   .new rp:ptr RECT() : right(3)

    rp.Clear()
    rp.Init(1, 2)

Note that the way a new RECT is constructed here there will only be one instance created (named __rc) except from rc.

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #38 on: June 21, 2020, 01:07:23 AM »
Added a small bug-fix to the MacroLocals counter. This is now reset between passes so the local label may now be used as a stable id.

Example

.class T

    x dd ?
    y dd ?

    .operator T :abs=<0>, :abs=<0>, :vararg {
      local n
       .new n:T
        mov n.x,_1
        mov n.y,_2
        lea rax,n
        }
    .ends

main proc

    T()
    T(1, 2)
    ret

main endp

Label names:

  ??0000 T rbp - 0010
  ??0001 T rbp - 0020


Code produced:

        push    rbp
        mov     rbp, rsp
        sub     rsp, 64
        mov     dword ptr [rbp-8H], 0
        mov     dword ptr [rbp-4H], 0
        lea     rax, [rbp-10H]
        mov     dword ptr [rbp-18H], 1
        mov     dword ptr [rbp-14H], 2
        lea     rax, [rbp-20H]
        leave
        ret


nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #39 on: July 03, 2020, 08:55:33 AM »
Assignment of members based on input.

The main reason for these constructs is to optimize code based on type. The typeid operator is in C++ part of the standard library header typeinfo.

The Asmc implementation is similar and used as type identification for macro arguments. It's a text macro and may be used for direct branching in a class or a regular macro. This simplify and also gives a more accurate type definition than TYPE and OPATTR that is often used for the same purpose.

The preprocessor also handles real math so this opens up more possibilities for doing the same as more advanced compilers do. This also means that more code is moved to the header files but less needed on the user end.

As an example the ARGB color constants are defined as a DWORD and expanded to a D3DCOLORVALUE struct of 4 float values. The input will then in most cases be immediate values:

    .new color:D3DCOLORVALUE(Black, 0.0)

The code for each float:

    mov      eax,_1
    and      eax,sc_redMask
    shr      eax,sc_redShift
    cvtsi2ss xmm0,eax
    divss    xmm0,255.0
    movss    [rcx].D3DCOLORVALUE.r,xmm0

Or the simplified version:

    %mov [rcx].D3DCOLORVALUE.r, @CatStr(%((_1 and sc_redMask) shr sc_redShift), <.0>) / 255.0

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #40 on: July 08, 2020, 01:52:35 AM »
Inheritance of objects has been limited to data members and functions. The inline functions in the base was therefor not expanded in derived classes.

This is now added by simple equations of the function names if defined.

Code: [Select]

include iostream

;; Base class

.class Shape

  width   int_t ?
  height  int_t ?

    .operator setWidth :int_t {
        mov [this].Shape.width,_1
        }
    .operator setHeight :int_t {
        mov [this].Shape.height,_1
        }
    .ends

;; Derived class

.class Rectangle : public Shape

    .operator getArea {
        mov eax,[this].Shape.width
        mul [this].Shape.height
        }
    .ends

    .code

main proc

  local Rect:Rectangle

    Rect.setWidth(5)
    Rect.setHeight(7)

    ;; Print the area of the object.

    cout << "Total area: " << ( Rect.getArea() ) << endl

    exit(0)

main endp

    end main

Derived classes are added as anonymous structures for class and classVtbl.

*   RectangleVtbl struct
*   ShapeVtbl <>

*   Rectangle_setWidth  equ <Shape_setWidth>
*   Rectangle_setHeight equ <Shape_setHeight>

...

guga

  • Member
  • *****
  • Posts: 1377
  • Assembly is a state of art.
    • RosAsm
Re: Object-oriented programming (OOP) in Asmc
« Reply #41 on: August 08, 2020, 12:43:01 PM »
New sample
WIC Viewer GDI+

This code sample shows a Windows application using WIC to decode an image file and GDI+ to render the image to the screen. 

Files
WICViewerGDIPlus.inc: Header file that declares application class DemoApp interface
WICViewerGDIPlus.asm: Implementation of the application class interface

Building the Sample
To build the sample using the command prompt:
asmc64 -pe -ws -gui WICViewerGDIPlus.asm

Running the Sample
After the application is launched, load an image file through file open menu. Window resizing is supported.

Changes
The @CStr() macro now handles zero terminated strings. It also accept additional L"" on split strings but only the first one is valid.
Code: [Select]
DemoApp::LocateImageFile proc hWnd:HWND, pszFileName:LPWSTR, cchFileName:DWORD

    local ofn:OPENFILENAME

    mov word ptr [r8],0
    ZeroMemory(&ofn, sizeof(ofn))

    mov ofn.lStructSize,  sizeof(ofn)
    mov ofn.hwndOwner,    hWnd
    mov ofn.lpstrFilter,  &@CStr(
        L"All Image Files\0"               L"*.bmp;*.dib;*.wdp;*.mdp;*.hdp;*.gif;*.png;*.jpg;*.jpeg;*.tif;*.ico\0"
        L"Windows Bitmap\0"                L"*.bmp;*.dib\0"
        L"High Definition Photo\0"         L"*.wdp;*.mdp;*.hdp\0"
        L"Graphics Interchange Format\0"   L"*.gif\0"
        L"Portable Network Graphics\0"     L"*.png\0"
        L"JPEG File Interchange Format\0"  L"*.jpg;*.jpeg\0"
        L"Tiff File\0"                     L"*.tif\0"
        L"Icon\0"                          L"*.ico\0"
        L"All Files\0"                     L"*.*\0" )
    mov ofn.lpstrFile,    pszFileName
    mov ofn.nMaxFile,     cchFileName
    mov ofn.lpstrTitle,   &@CStr(L"Open Image")
    mov ofn.Flags,        OFN_FILEMUSTEXIST or OFN_PATHMUSTEXIST

    ;; Display the Open dialog box.
    GetOpenFileName(&ofn)
    ret

DemoApp::LocateImageFile endp

That´s really really good. It can open webp files as well. Can you try making it to 32 bits, nidud ? And also making it open heic files too ?
Coding in Assembly requires a mix of:
80% of brain, passion, intuition, creativity
10% of programming skills
10% of alcoholic levels in your blood.

My Code Sites:
http://rosasm.freeforums.org
http://winasm.tripod.com

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #42 on: August 11, 2020, 05:44:48 AM »
Can you try making it to 32 bits, nidud ?

The samples here are primarily written to test inline functions and this is not fully supported in 32 bit yet.

It is however a Windows classic sample so it should be possible to build a 32 bit version from the original source:
https://github.com/microsoft/Windows-classic-samples/tree/master/Samples/Win7Samples/multimedia/wic/wicviewergdiplus

Quote
And also making it open heic files too ?

I assume you may have to download some support for that? In any case it should be possible to add this to the list and see what happens.

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #43 on: October 02, 2020, 08:25:47 AM »
Added two Direct2D samples from the Windows-classic samples.

  GDI/Direct2D Interoperability Sample
  Direct2D Hello World Sample

These are similar to the WIC Animated Gif sample which also use Direct2D but they use the dwrite.inc header file as well. The interface in these headers are pure C++ so the translation may not always be correct for all methods, especially value returned by reference like the ID2D1RenderTarget::GetSize method:

  D2D1_SIZE_F GetSize();

The struct will be passed in RDX here (the class in RCX) so the C version and the COMDEF entry should be something like this:

  D2D1_SIZE_F *GetSize(D2D1_SIZE_F*);
  GetSize proc :ptr D2D1_SIZE_F

Note that the data used here is not static but rather allocated by the class which is passed in the lpParam to CreateWindowEx(). The module handle (hInstance) however is a static global label created by the ORG directive. This has to be the first entry in the code segment to work:
Code: [Select]
    .code

    org -0x1000
    __ImageBase label IMAGE_DOS_HEADER
    org 0

mainCRTStartup proc

The class pointer is picked up in WndProc:

Code: [Select]
    .if edx == WM_CREATE

        mov r8,[r9].CREATESTRUCT.lpCreateParams
        SetWindowLongPtrW(rcx, GWLP_USERDATA, PtrToUlong(r8))
        mov result,1

    .else

        mov pDemoApp,GetWindowLongPtrW(rcx, GWLP_USERDATA)

The class itself is allocated on the stack in WinMain().

Code: [Select]
wWinMain proc hInstance:HINSTANCE, hPrevInstance:HINSTANCE, lpCmdLine:LPWSTR, nCmdShow:SINT

  local vtable:DemoAppVtbl

    ;; Ignore the return value because we want to run the program even in the
    ;; unlikely event that HeapSetInformation fails.

    HeapSetInformation(NULL, HeapEnableTerminationOnCorruption, NULL, 0)

    CoInitialize(NULL)
    .if (SUCCEEDED(eax))

       .new app:DemoApp(&vtable)

        app.Initialize()

        .if (SUCCEEDED(eax))

            app.RunMessageLoop()
        .endif
        CoUninitialize()
    .endif

    .return 0

wWinMain endp

Files
Direct2DHelloWorld.inc
Direct2DHelloWorld.asm
GdiInteropSample.inc
GdiInteropSample.asm

nidud

  • Member
  • *****
  • Posts: 2013
    • https://github.com/nidud/asmc
Re: Object-oriented programming (OOP) in Asmc
« Reply #44 on: October 04, 2020, 07:12:40 PM »
Some movement.

  Direct2D Simple Path Animation Sample

  Demonstrates how to create a simple path animation with Direct2D.

Files
Animation.inc - Defines animation helpers.
SimplePathAnimationSample.inc - The header file for the DemoApp class.
SimplePathAnimationSample.asm - Contains the application entry point and the implementation of the DemoApp class.