NO

Author Topic: Squeezing some cool from Windows GDI  (Read 20756 times)

Offline MrBcx

  • Global Moderator
  • Member
  • *****
  • Posts: 189
    • Bcx Basic to C/C++ Translator
Squeezing some cool from Windows GDI
« on: August 16, 2023, 03:47:52 AM »
Here's a neat graphics demo that I recently converted to BCX BASIC.

I copied BCX's translation into main.c inside a new Pelles C project.

There are a lot of non-Pelles C directives that I left in. The demo compiles with
all the other popular c\c++ compilers too.

The demo is named CARDIOID.  It uses the Windows plain old Gdi for its
graphics, and a bit of geometry and trig.  I also added double buffering (bitblit)
to improve the visual appearance.

It will run to 99.99 iterations and then end or you can end it any time.  There
is no user control - its a simple graphics demo with some pretty colorful effects.

To rebuild, update the Pelles C path in the project options.

Bcx Basic to C/C++ Translator
https://www.BcxBasicCoders.com

Offline Vortex

  • Member
  • *
  • Posts: 864
    • http://www.vortex.masmcode.com
Re: Squeezing some cool from Windows GDI
« Reply #1 on: August 16, 2023, 11:17:37 AM »
Hi MrBcx,

Very nice work.
Code it... That's all...

Offline frankie

  • Global Moderator
  • Member
  • *****
  • Posts: 2113
Re: Squeezing some cool from Windows GDI
« Reply #2 on: August 16, 2023, 12:32:57 PM »
Nice.  :)
"It is better to be hated for what you are than to be loved for what you are not." - Andre Gide

Offline Vortex

  • Member
  • *
  • Posts: 864
    • http://www.vortex.masmcode.com
Re: Squeezing some cool from Windows GDI
« Reply #3 on: August 16, 2023, 08:34:39 PM »
Hello MrBcx,

The demo compiles with all the other popular c\c++ compilers too.

Trying to compile main.c with VS 2019 commandline tools, I receive a lot of error messages.

Code: [Select]
cl -c main.c

main.c(238): error C2143: syntax error: missing ')' before '='
main.c(238): error C2072: 'BCX_Form': initialization of a function
main.c(238): error C2059: syntax error: 'type'
main.c(238): error C2059: syntax error: ')'
main.c(239): error C2143: syntax error: missing ')' before '='
main.c(239): error C2072: 'BCX_Printex': initialization of a function
main.c(239): error C2059: syntax error: ')'
main.c(241): error C2143: syntax error: missing ')' before '='
main.c(241): error C2072: 'BCX_Line': initialization of a function
main.c(241): error C2040: 'HDC': 'int' differs in levels of indirection from 'HDC__ *'
main.c(241): error C2059: syntax error: ')'
main.c(242): error C2143: syntax error: missing ')' before '='
main.c(242): error C2072: 'BCX_Circle': initialization of a function
main.c(242): error C2059: syntax error: 'type'
main.c(242): error C2059: syntax error: ')'
main.c(243): error C2143: syntax error: missing ')' before '='
main.c(243): error C2072: 'Center': initialization of a function
main.c(243): error C2040: 'HWND': 'int' differs in levels of indirection from 'HWND__ *'
main.c(243): error C2059: syntax error: ')'
main.c(249): error C2143: syntax error: missing ')' before '='
main.c(249): error C2072: 'instr': initialization of a function
main.c(249): error C2059: syntax error: 'type'
main.c(249): error C2059: syntax error: ')'
main.c(252): error C2143: syntax error: missing ')' before '='
main.c(252): error C2072: 'ModStyle': initialization of a function
main.c(252): warning C4142: 'DWORD': benign redefinition of type
C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared\minwindef.h(156): note: see declaration of 'DWORD'
main.c(252): error C2370: 'DWORD': redefinition; different storage class
C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared\minwindef.h(156): note: see declaration of 'DWORD'
main.c(252): error C2370: 'BOOL': redefinition; different storage class
C:\Program Files (x86)\Windows Kits\10\include\10.0.19041.0\shared\minwindef.h(157): note: see declaration of 'BOOL'
main.c(252): error C2059: syntax error: ')'
main.c(409): error C2198: 'instr': too few arguments for call
main.c(413): error C2198: 'instr': too few arguments for call
main.c(417): error C2198: 'instr': too few arguments for call
main.c(474): warning C4029: declared formal parameter list different from definition
main.c(528): error C2371: 'Center': redefinition; different basic types
main.c(243): note: see declaration of 'Center'
main.c(596): error C2371: 'BCX_Printex': redefinition; different basic types
main.c(239): note: see declaration of 'BCX_Printex'
main.c(628): error C2040: 'BCX_Form': 'HWND (LPCTSTR,int,int,int,int,int,int)' differs in levels of indirection from 'int (LPCTSTR,int)'
main.c(643): warning C4029: declared formal parameter list different from definition
main.c(662): warning C4029: declared formal parameter list different from definition
main.c(677): warning C4029: declared formal parameter list different from definition
main.c(791): warning C4020: 'BCX_Form': too many actual parameters
main.c(791): warning C4047: '=': 'HWND' differs in levels of indirection from 'int'
main.c(794): error C2198: 'Center': too few arguments for call
Code it... That's all...

Offline MrBcx

  • Global Moderator
  • Member
  • *****
  • Posts: 189
    • Bcx Basic to C/C++ Translator
Re: Squeezing some cool from Windows GDI
« Reply #4 on: August 16, 2023, 09:12:29 PM »
Hi Vortex ... It compiles and runs just fine using MS Visual Studio 2022.

BCX BASIC to C/C++ Translator (c) 1999-2023 by Kevin Diggins
Version 8.0.2 (08/16/2023) Compiled using MS Visual C++ for 64-bit Windows Systems
[Lines In: 123] [Lines Out: 875] [Statements: 92] [Time: 0.03 Sec's]
BCX translated [Cardioid.Bas] to [Cardioid.C] for a C Compiler

**********************************************************************
** Visual Studio 2022 Developer Command Prompt v17.0
** Copyright (c) 2022 Microsoft Corporation
**********************************************************************
[vcvarsall.bat] Environment initialized for: 'x64'
**************************************************************************
MSVC is compiling [ "C:\Bc\Demos\_Other\Cardioid\cardioid" ] as a 64-bit GUI application.

Microsoft (R) C/C++ Optimizing Compiler Version 19.32.31332 for x64
Copyright (C) Microsoft Corporation.  All rights reserved.

Linking "C:\Bc\Demos\_Other\Cardioid\cardioid"

Microsoft (R) Incremental Linker Version 14.32.31332.0
Copyright (C) Microsoft Corporation.  All rights reserved.

**************************************************************************
MSVC built [ "C:\Bc\Demos\_Other\Cardioid\cardioid".exe ]
**************************************************************************


Below are my MSVC  cl.exe and link.exe command lines that might help you troubleshoot:

cl.exe
/std:c++20 /permissive /c /O2 /Gd /W2 /MT -D NTDDI_VERSION=0x0A000000 -D_WIN32_WINNT=0x0A000000 /EHsc /Tp  %1.c

link.exe /RELEASE /MACHINE:X64 /SUBSYSTEM:WINDOWS %1.obj  /OUT:%1.exe
Bcx Basic to C/C++ Translator
https://www.BcxBasicCoders.com

Offline Vortex

  • Member
  • *
  • Posts: 864
    • http://www.vortex.masmcode.com
Re: Squeezing some cool from Windows GDI
« Reply #5 on: August 16, 2023, 09:23:32 PM »
Hi MrBcx,

Many thanks, your parameters worked fine :

Code: [Select]
cl.exe /std:c++20 /permissive /c /O2 /Gd /W2 /MT -D NTDDI_VERSION=0x0A000000 -D_WIN32_WINNT=0x0A000000 /EHsc /Tp  %1.c
This is why I like the assemlers, no need to struggle with those constantly changing standards and complicated commandline options. Everything in the life is coming with a price.  :)

Edit : MS Link works as expected but Polink complains a lot but it manages to create the executable :
Code: [Select]
E:\pellesc\bin\polink /SUBSYSTEM:WINDOWS main.obj
POLINK: warning: Unrecognized option '/FAILIFMISMATCH:_CRT_STDIO_ISO_WIDE_SPECIFIERS=0'; ignored.
POLINK: warning: Realigned section '.idata$2' in object 'kernel32.Lib(KERNEL32.dll)' (from 4 to 1 byte(s)).
POLINK: warning: Realigned section '.idata$3' in object 'kernel32.Lib(KERNEL32.dll)' (from 4 to 1 byte(s)).
POLINK: warning: Realigned section '.idata$2' in object 'User32.Lib(USER32.dll)' (from 4 to 1 byte(s)).
POLINK: warning: Realigned section '.idata$2' in object 'Gdi32.Lib(GDI32.dll)' (from 4 to 1 byte(s)).
POLINK: warning: Realigned section '.idata$2' in object 'ComCtl32.Lib(COMCTL32.dll)' (from 4 to 1 byte(s)).
POLINK: warning: Realigned section '.idata$2' in object 'Ole32.Lib(ole32.dll)' (from 4 to 1 byte(s)).
POLINK: warning: Section '.gfids$y' is not supported; ignored.
POLINK: warning: Unrecognized option '/disallowlib:msvcrt.lib'; ignored.
POLINK: warning: Unrecognized option '/disallowlib:msvcrtd.lib'; ignored.
POLINK: warning: Unrecognized option '/disallowlib:libcmtd.lib'; ignored.
POLINK: warning: Unrecognized option '/disallowlib:vcruntime.lib'; ignored.
POLINK: warning: Unrecognized option '/disallowlib:vcruntimed.lib'; ignored.
POLINK: warning: Unrecognized option '/disallowlib:libvcruntimed.lib'; ignored.
POLINK: warning: Unrecognized option '/disallowlib:ucrtd.lib'; ignored.
POLINK: warning: Unrecognized option '/disallowlib:libucrtd.lib'; ignored.
POLINK: warning: Unrecognized option '/GUARDSYM:__C_specific_handler,S'; ignored.
POLINK: warning: Unrecognized option '/GUARDSYM:__CxxFrameHandler3,S'; ignored.
POLINK: warning: Unrecognized option '/GUARDSYM:__CxxFrameHandler4,S'; ignored.
POLINK: warning: Unrecognized option '/GUARDSYM:__CxxFrameHandler2,S'; ignored.
POLINK: warning: Unrecognized option '/GUARDSYM:__CxxFrameHandler,S'; ignored.
POLINK: warning: COMDAT symbol '??$__crt_interlocked_read_pointer@UHINSTANCE__@@@@YAPEAUHINSTANCE__@@PEDSEAU0@@Z' is multiply defined: 'libvcruntime.lib(winapi_downlevel.obj)' and 'libucrt.lib(winapi_thunks.obj)'.
POLINK: warning: COMDAT symbol '??$__crt_interlocked_read_pointer@X@@YAPEAXPEDSEAX@Z' is multiply defined: 'libvcruntime.lib(winapi_downlevel.obj)' and 'libucrt.lib(winapi_thunks.obj)'.
POLINK: warning: COMDAT symbol '?__crt_interlocked_read_64@@YA_JPED_J@Z' is multiply defined: 'libvcruntime.lib(std_type_info.obj)' and 'libucrt.lib(winapi_thunks.obj)'.
« Last Edit: August 16, 2023, 10:14:45 PM by Vortex »
Code it... That's all...

Offline MrBcx

  • Global Moderator
  • Member
  • *****
  • Posts: 189
    • Bcx Basic to C/C++ Translator
Re: Squeezing some cool from Windows GDI
« Reply #6 on: August 16, 2023, 09:44:47 PM »
These are what I routinely use to compile 64-bit GUI apps using Pelles:


SET  PoccOPTS= /Go /Gn /W1 /Gd /Ze /Zx /Tx64-coff /D NTDDI_VERSION=0x0A000007 /std:c17 /fp:precise

SET  PolinkOPTS= -release -machine:x64 /subsystem:windows,5.02 /STACK:10485760   

and below for 32-bit:


SET  PoccOPTS=/Go /Gn /W1 /Gd /Ze /Zx /Tx86-coff  /D NTDDI_VERSION=0x0A000007 /std:c17 /fp:precise

SET  PolinkOPTS= -release -machine:x86 /subsystem:windows,5.01 /STACK:10485760
Bcx Basic to C/C++ Translator
https://www.BcxBasicCoders.com

Offline John Z

  • Member
  • *
  • Posts: 860
Re: Squeezing some cool from Windows GDI
« Reply #7 on: August 17, 2023, 05:13:03 PM »
MrBCX - nice mesmerizing display.  Good demo for BCX too, amazed at the code it generated...

John Z

Offline MrBcx

  • Global Moderator
  • Member
  • *****
  • Posts: 189
    • Bcx Basic to C/C++ Translator
Re: Squeezing some cool from Windows GDI
« Reply #8 on: August 17, 2023, 07:45:12 PM »
Quote
MrBCX - nice mesmerizing display.  Good demo for BCX too, amazed at the code it generated...

John Z

Thanks John !

Below is the BCX BASIC code ( before it is translated to C)

Approx 100 lines of BCX BASIC produced approx 900 lines of C.

Even if folks prefer C\C++ over BASIC, BCX will save us a lot of time
when beginning a project.  It's useful for prototyping ideas and for learning
about Windows API programming.

Coincidentally, I actually have another BCX graphics demo named
 "Mesmerize" here:
https://bcxbasiccoders.com/smf/index.php?topic=889.0


Code: [Select]
GUI "Cardioid and Beyond", PIXELS

CONST xmax    = 700
CONST ymax    = 700
CONST npoints = 200

GLOBAL Form1    AS HWND
GLOBAL BufferDC AS HDC


SUB FORMLOAD
    Form1 = BCX_FORM ("Cardiod",  0, 0, xmax + 10, ymax + 30)
    MODSTYLE(Form1, 0, WS_MAXIMIZEBOX | WS_MINIMIZEBOX, FALSE)
    BCX_SET_FORM_COLOR (Form1, RGB(0, 0, 0))
    CENTER Form1
    SHOW   Form1
    '==============================
    ' Create the off-screen buffer
    '==============================
    DIM hDC AS HDC
    hDC = GetDC(Form1)
    BufferDC = CreateCompatibleDC(hDC)
    ReleaseDC(Form1, hDC)
    '==============================
    CALL Drawit
END SUB


BEGIN EVENTS
    SELECT CASE CBMSG
        CASE WM_QUIT, WM_CLOSE, WM_DESTROY
        END
    END SELECT
END EVENTS



SUB Drawit
    DIM AS DOUBLE Mult, DA, R
    DIM AS LONG xx1, xx2, yy1, yy2, cx, cy

    cx = xmax/2
    cy = ymax/2
    DA = 0.0314159
    R = cx - 10

    FOR Mult = 0 TO 100 STEP 0.01
        DOEVENTS
        SLEEP(1)
        '=========================================
        ' Create our off-screen bitmap for drawing
        '=========================================
        DIM AS HBITMAP hOldBitmap
        DIM AS INTEGER bmWidth, bmHeight
        DIM RAW bm AS BITMAPINFO
        bmWidth = xmax
        bmHeight = ymax
        bm.bmiHeader.biSize = SIZEOF(BITMAPINFOHEADER)
        bm.bmiHeader.biWidth = bmWidth
        bm.bmiHeader.biHeight = -bmHeight
        bm.bmiHeader.biPlanes = 1
        bm.bmiHeader.biBitCount = 32
        bm.bmiHeader.biCompression = BI_RGB
        hOldBitmap = (HBITMAP)SelectObject(BufferDC, CreateDIBSection(0, &bm, DIB_RGB_COLORS, 0, 0, 0))
        '==========================================
        BCX_PRINTEX (0, 10, 10, "Multiple: " + USING$("###.##", Mult),  RGB(128, 162, 225), RGB(0, 0, 0), "Verdana", 26, BufferDC)

        IF Mult = INT(Mult) THEN CALL ResetPlasma

        BCX_CIRCLE(0, cx, cy, R, Kolor, 0, BufferDC)

        FOR INT i = 1 TO npoints
            DOEVENTS
            xx1 = cx + R * COS(i * DA)
            yy1 = cy + R * SIN(i * DA)
            xx2 = cx + R * COS(Mult * i * DA)
            yy2 = cy + R * SIN(Mult * i * DA)
            CALL ChangePlasma
            BCX_LINE(0, xx1, yy1, xx2, yy2, Kolor, BufferDC )
        NEXT
        '==================================================
        ' Copy the off-screen buffer to the visible window
        '==================================================
        DIM RAW hDC AS HDC
        hDC = GetDC(Form1)
        BitBlt(hDC, 0, 0, bmWidth, bmHeight, BufferDC, 0, 0, SRCCOPY)
        ReleaseDC(Form1, hDC)
        DeleteObject(SelectObject(BufferDC, hOldBitmap)) ' Clean up
    NEXT
    MSGBOX "Press Okay to close the window", "Completed!"
    END
END SUB


SUB ChangePlasma
    GLOBAL AS ULONG Kolor
    GLOBAL AS ULONG cN
    GLOBAL AS DOUBLE pR, pG, pB
    cN = cN + 1
    Kolor = RGB(127 + 127 * SIN(pR * cN), 127 + 127 * SIN(pG * cN), 127 + 127 * SIN(pB * cN))
END SUB


SUB ResetPlasma
    pR = RND ^ 2
    pG = RND ^ 2
    pB = RND ^ 2
END SUB
« Last Edit: August 17, 2023, 08:26:11 PM by MrBcx »
Bcx Basic to C/C++ Translator
https://www.BcxBasicCoders.com

Offline Vortex

  • Member
  • *
  • Posts: 864
    • http://www.vortex.masmcode.com
Re: Squeezing some cool from Windows GDI
« Reply #9 on: August 17, 2023, 09:42:28 PM »
Hi  MrBcx,

Compiling your code with Msys2, the equivalent of the MS VC option /Tp ( compile as c++ ) is -x c++ :

Quote
-x <language>            Specify the language of the following input files.
                           Permissible languages include: c c++ assembler none
                           'none' means revert to the default behavior of
                           guessing the language based on the file's extension.

Code: [Select]
# gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
Code: [Select]
gcc -x c++ main.c -o main.exe -luser32 -lgdi32 -lole32 -loleaut32 -lcomctl32 -mwindows
Code it... That's all...

Offline MrBcx

  • Global Moderator
  • Member
  • *****
  • Posts: 189
    • Bcx Basic to C/C++ Translator
Re: Squeezing some cool from Windows GDI
« Reply #10 on: August 18, 2023, 12:34:47 AM »
Hi  MrBcx,

Compiling your code with Msys2, the equivalent of the MS VC option /Tp ( compile as c++ ) is -x c++ :

Quote
-x <language>            Specify the language of the following input files.
                           Permissible languages include: c c++ assembler none
                           'none' means revert to the default behavior of
                           guessing the language based on the file's extension.

Code: [Select]
# gcc --version
gcc.exe (Rev2, Built by MSYS2 project) 13.2.0
Copyright (C) 2023 Free Software Foundation, Inc.
Code: [Select]
gcc -x c++ main.c -o main.exe -luser32 -lgdi32 -lole32 -loleaut32 -lcomctl32 -mwindows

Thanks -- That's a good  tip.

I never use gcc, I always use g++ which will compile c and c++g++ will bark a warning
about deprecated behavior when compiling C but the warning can be disabled easily enough.
Whenever possible, I test my codes using Pelles C, msvc, Mingw, AND Lcc-Win32. 
It's a good way to catch issues before they become problems.
« Last Edit: August 18, 2023, 12:37:22 AM by MrBcx »
Bcx Basic to C/C++ Translator
https://www.BcxBasicCoders.com

Offline Vortex

  • Member
  • *
  • Posts: 864
    • http://www.vortex.masmcode.com
Re: Squeezing some cool from Windows GDI
« Reply #11 on: August 20, 2023, 09:28:09 PM »
Hi MrBcx,

I managed to build the project with Embarcadero’s free C++ Compiler. Some minor modifications in the source code are required for the compilation, main.cpp ( main.c ) and main.rc are modified.

https://www.embarcadero.com/free-tools/ccompiler

Code: [Select]
rc /iD:\BCC102\include\windows\sdk main.rc
bcc32c.exe -c main.cpp
ilink32 -LD:\BCC102\lib\win32c\release -LD:\BCC102\lib\win32c\release\psdk -aa main.obj c0w32.obj,main.exe,,import32.lib cw32.lib,,main.res

c0w32.obj : GUI EXE startup module
Code it... That's all...

Offline MrBcx

  • Global Moderator
  • Member
  • *****
  • Posts: 189
    • Bcx Basic to C/C++ Translator
Re: Squeezing some cool from Windows GDI
« Reply #12 on: August 21, 2023, 06:21:33 AM »
Hi MrBcx,

I managed to build the project with Embarcadero’s free C++ Compiler. Some minor modifications in the source code are required for the compilation, main.cpp ( main.c ) and main.rc are modified.



Here's a trick that works for compiling with Embarcadero at the commandline. 

The only file you need is main.cpp


1) add the following to the end of main.cpp (right after WinMain)
 
int main() {
  WinMain(0,0,0,0);
  return 0;
}

2) c:\embarcadero\bin\bcc32 main.cpp         

or

2) c:\embarcadero\bin\bcc64 main.cpp     


The 32-bit compiler will throw a few warnings but main.exe will run just fine.

The 64-bit compiler throws no warnings or errors.

« Last Edit: August 21, 2023, 03:26:09 PM by MrBcx »
Bcx Basic to C/C++ Translator
https://www.BcxBasicCoders.com

Offline Vortex

  • Member
  • *
  • Posts: 864
    • http://www.vortex.masmcode.com
Re: Squeezing some cool from Windows GDI
« Reply #13 on: August 21, 2023, 07:38:41 PM »
Hi MrBcx,

Thanks for the tip. The free command-line tools of Embarcadero does not provide the 64-bit C\C++ compiler, how did you manage to obtain this compiler?

https://www.embarcadero.com/free-tools/ccompiler
Code it... That's all...

Offline MrBcx

  • Global Moderator
  • Member
  • *****
  • Posts: 189
    • Bcx Basic to C/C++ Translator
Re: Squeezing some cool from Windows GDI
« Reply #14 on: August 21, 2023, 11:43:35 PM »
Hi MrBcx,

Thanks for the tip. The free command-line tools of Embarcadero does not provide the 64-bit C\C++ compiler, how did you manage to obtain this compiler?

https://www.embarcadero.com/free-tools/ccompiler

I first signed up for Embarcadero RAD Studio ( free annual renewal ) in 2020.  I stopped renewing
because they made it such a hassle.  Despite not renewing it for over a year, the command line tools
obviously still work just fine for the rare occasions I want them.  RAD Studio was never my preferred
IDE, but I did learn a little about using its command line tools. 

I was even compiling BCX with it for a while but eventually went back to Microsoft Visual C++ for all
my release versions.  I test a lot of my projects using multiple compilers.  That's a great way to strengthen
ones code.

« Last Edit: August 21, 2023, 11:48:31 PM by MrBcx »
Bcx Basic to C/C++ Translator
https://www.BcxBasicCoders.com