Jose's Read Only Forum 2023

IT-Consultant: James C. Fuller => Discussion => Topic started by: James C. Fuller on March 08, 2017, 12:04:58 PM

Title: TCLib update for Patrice
Post by: James C. Fuller on March 08, 2017, 12:04:58 PM
Patrice,
  I added sin,cos,acos,asin,atan,atan2,sqrt,time,rand,srand,fmod,fmodf to TCLib.
If there are other ones you need for testing let me know.
I am going to add most all the math functions but I want to install the new Visual Studio 2017 community today.

James
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 08, 2017, 07:25:22 PM
James

That doesn't work by me, from inside the IDE, no DllMain external symbol.
and a bunch of unresolved external

Did you try to compile the DLL project that was in my zip?

Thanks anyway ;)


Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 08, 2017, 08:45:23 PM
Patrice,
  You have to be careful with your #includes and not #include files that in turn #include the standard <c lib headers>.
This appears to be the case with mfapi.h amd shlwapi.h
Probably just not worth the effort with the type of apps/dlls you write.

James
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 08, 2017, 09:55:11 PM
Patrice,
  There are no issues with the GL.h and GLU.h.
Maybe if you prototyped just the calls from mfapi.h and shlwapi.h you use I could figure it out.
I am close I think ?? :)

James

 
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 09, 2017, 10:41:31 AM
i shall make another try later this day, after adding the missing DllMain entry point.

thanks
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 09, 2017, 11:00:50 AM
Patrice,
  Try to make another standard Visual studio project like the one you posted without including  mfapi.h and shlwapi.h, instead add the prototypes of the functions used in the source. I forgot to add tan (DUH) to TCLib so that will fail until I update and post a new TCLib.
Also there are a couple of calls in IsFileImage that are not supported (yet):
_wsplitpath_s
wcsncat_s
wcsstr

James


Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 09, 2017, 01:42:31 PM
rand, and srand are causing me havoc
--> redefinition, previous definition was 'function'.
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 09, 2017, 05:17:33 PM
Patrice,
  Yeah that is one of the issues you have to be aware of. One of your includes is also including the sdk <stdlib.h>
It's going to take a bit more planning on your part on managing #include files and prototypes.
What I would suggest if/when you decide to continue is to create tour own versions of includes you need and put them in the TCLib folder.
I have a mixed version (bc9/c++) of your dll compiled but don't quite know what to do with it to test?
It comes in at 12k.

James

Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 09, 2017, 05:20:09 PM
I don't know how to resolve these 3 link errors (see the attached screen shot)

...
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 09, 2017, 05:44:16 PM
Patrice,
  I updated the library and it should help.
Attached is the new library and includes along with my version of your dll.
To compile: TBLIBDLL.BAT LB01

James
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 09, 2017, 05:56:31 PM
I just noticed I hadn't finished up work in IsFileImage so it will not work as is.

James
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 09, 2017, 06:23:50 PM
I could remove the IsFileImage function, because in that specific case, a texture should be always a valid image file name.

I have written my own replacement for PathCombine, based on direct use of the RtlMoveMemory

void Path_Combine(OUT WCHAR* zResource, IN WCHAR* path, IN WCHAR* combine) {
    long offset = (long) wcslen(path) * sizeof(WCHAR);
    ZeroMemory(zResource, MAX_PATH);
    MoveMemory(zResource, path, offset);
    MoveMemory(&zResource[offset / 2], &combine[0], (long) wcslen(combine) * sizeof(WCHAR));
}



Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 09, 2017, 07:04:05 PM
Patrice,
  It's just the header files that are giving the problems.

Make your own for shlwapi.h in case you need something in the future and use #pragma comment(lib,"shlwapi.lib")

EXTERN_C LPWSTR  PathCombineA(_Out_writes_(MAX_PATH) LPWSTR pszDest, _In_opt_ LPCTSTR pszDir, _In_opt_ LPCTSTR pszFile);
EXTERN_C LPWSTR  PathCombineW(_Out_writes_(MAX_PATH) LPWSTR pszDest, _In_opt_ LPCWSTR pszDir, _In_opt_ LPCWSTR pszFile);
#ifdef UNICODE
#define PathCombine  PathCombineW
#else
#define PathCombine  PathCombineA
#endif
#define _MAX_DRIVE 3
#define _MAX_DIR 256
#define _MAX_FNAME 256
#define _MAX_EXT 256

James



Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 09, 2017, 07:30:09 PM
James--

From 108 Kb down to 13 Kb, that's amazing!!!

However in Math.h,  i still couldn't use
extern int (__cdecl* rand)(void);
extern void (__cdecl* srand)(unsigned int);

because of error C2365:  previous definition was function

Title: Re: TCLib update for Patrice
Post by: Frederick J. Harris on March 09, 2017, 07:33:37 PM
Does this help...


#ifdef TCLib
   int rand(void)
   {
    static unsigned int next = 1;
    next = next * 1103515245 + 12345;
    return (unsigned int)(next>>16) & RAND_MAX;
   }
#endif


size_t Rnd(int iMin, int iMax)
{
double dblRange=iMax-iMin;
double dblMaxFactor=dblRange/RAND_MAX;
double dblRandomNumber=(double)rand();

return iMin+dblMaxFactor*dblRandomNumber;
}


I was working with that some time ago.  I forget the details, and I forget where RAND_MAX is defined.  Possibly in stdlib.h.  My Rnd() function above is a quick and dirty interpretation of PowerBASIC's Rnd(), where one can specify a min and max value.  It just scales stuff about using stdlib's rand.  It worked OK for the use I made of it.  Random number generation can get to be a tricky subject if you let it!
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 09, 2017, 07:45:16 PM
Patrice,
  You must have an include file somewhere including <stdlib.h> .
I'll try renaming them to see if that helps.
James
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 09, 2017, 07:53:14 PM
Patrice,
  This is the test code I used for the math functions.

James


// *********************************************************************
//  Created with bc9Basic - BASIC To C/C++ Translator (V) 9.2.6.0 (2017/02/05)
//       The bc9Basic translator (bc9.exe) was compiled with
//                           g++ (tdm64-1) 5.1.0
// ----------------------------------------------------------------------
//                 BCX (c) 1999 - 2009 by Kevin Diggins
// *********************************************************************
//              Translated for compiling with the
//           Microsoft (R) C/C++ Optimizing Compiler
//                           On MS Windows
//                    Using TCLib by Fred Harris
// *********************************************************************
#ifndef UNICODE
#define UNICODE
#endif
#ifndef _UNICODE
#define _UNICODE
#endif
#define _X(y) y
#include <windows.h>
#define   x64
#include "TCLib\stdio.h"
#include "TCLib\string.h"
#include "TCLib\stdlib.h"
#include "TCLib\memory.h"
#include "TCLib\malloc.h"
#include "TCLib\math.h"
#include "TCLib\tchar.h"
#include "TCLib\Strings.cpp"
typedef String fstring;
FILE* stdin;
FILE* stdout;
FILE* stderr;
//<---UNICODE AWARE
#define SFMT (const char*)"%s\r\n"
//>---UNICODE AWARE

// NO HEADERS START
#ifndef _WINDOWS_
//<---UNICODE AWARE
typedef _TCHAR *PCHAR, *LPCH, *PCH, *NPSTR, *LPSTR, *PSTR;
typedef unsigned long DWORD, *PDWORD, *LPDWORD;
typedef unsigned int UINT;
//>---UNICODE AWARE
#endif
// NO HEADERS END

// ***************************************************
// Compiler Defines
// ***************************************************

// C++
#if defined( __cplusplus )
#define overloaded
#define C_EXPORT EXTERN_C __declspec(dllexport)
#define C_IMPORT EXTERN_C __declspec(dllimport)
#define BEGIN_EXTERN_C extern _T("C") {
#define END_EXTERN_C }
#else
#define C_EXPORT __declspec(dllexport)
#define C_IMPORT __declspec(dllimport)
#endif


// Microsoft VC++
#ifndef DECLSPEC_UUID
#if (_MSC_VER >= 1100) && defined ( __cplusplus )
#define DECLSPEC_UUID(x)    __declspec(uuid(x))
#else
#define DECLSPEC_UUID(x)
#endif
#endif

// ***************************************************
// Compiler Defines
// ***************************************************
#ifndef __cplusplus
#error A C++ compiler is required
#endif

// *************************************************
//        User's GLOBAL ENUM blocks
// *************************************************

// *************************************************
//            System Defined Constants
// *************************************************

typedef const _TCHAR* ccptr;
#define CCPTR const _TCHAR*
#define cfree free
//<---UNICODE AWARE
typedef char _char;
#define _strlen strlen
//>---UNICODE AWARE
#define EQU ==
#define NOT_USED(x) if(x);
#define CTLHNDL(id) GetDlgItem(hWnd,id)
#define cSizeOfDefaultString 2048

// *************************************************
//            User Defined Constants
// *************************************************

#define PI 3.141592653589753
#define TR 57.2957795130831

// *************************************************
//               Standard Prototypes
// *************************************************

_TCHAR*   BCX_TmpStr(size_t, size_t = 0, int = 1);
void    Pause (void);

// *************************************************
//                System Variables
// *************************************************

#define LDOUBLE long double
// *************************************************
//          User Defined Types, Unions and Classes
// *************************************************


// *************************************************
//            User Global Variables
// *************************************************



// *************************************************
//               User Prototypes
// *************************************************

int     _tmain (void);

// *************************************************
//            User Global Initialized Arrays
// *************************************************



// *************************************************
//                 Runtime Functions
// *************************************************

#ifndef BCXTmpStrSize
#define BCXTmpStrSize  2048
#endif
_TCHAR *BCX_TmpStr (size_t Bites, size_t  iPad, int iAlloc)
{
    static int   StrCnt;
    static _TCHAR *StrFunc[BCXTmpStrSize];
    StrCnt = (StrCnt + 1) & (BCXTmpStrSize - 1);
    if(StrFunc[StrCnt]) {
        free (StrFunc[StrCnt]);
        StrFunc[StrCnt] = NULL;
    }
#if defined BCX_MAX_VAR_SIZE
    if(Bites * sizeof(_TCHAR) > BCX_MAX_VAR_SIZE)
    {
        _tprintf(_T("Buffer Overflow caught in BCX_TmpStr - requested space of %d EXCEEDS %d\n"), (int)(Bites * sizeof(_TCHAR)), BCX_MAX_VAR_SIZE);
        abort();
    }
#endif
    if(iAlloc) StrFunc[StrCnt] = (_TCHAR*)calloc(Bites + iPad + 1, sizeof(_TCHAR));
    return StrFunc[StrCnt];
}


void Pause(void)
{
    _tprintf(_T("\n%ls\n"), _T("Press any key to continue..."));
    _getwch();
}



// *************************************************
//       User Subs, Functions and Class Methods
// *************************************************

int _tmain ()
{
    LDOUBLE  ld = {0};
    double   d1 = {0};
    float    f1 = {0};
    int      I = {0};
    ld = sin( 45 / TR);
    _tprintf(_T("%.19LG\n"), (LDOUBLE)ld);
    I = sin( 45 / TR);
    d1 = sin( 45 / TR);
    f1 = sin( 45 / TR);
    _tprintf(_T("%d\n"), (int)I);
    _tprintf(_T("%.15G\n"), (double)d1);
    _tprintf(_T("%.7G\n"), (float)f1);
    ld = cos( 45 / TR);
    _tprintf(_T("%.19LG\n"), (LDOUBLE)ld);
    ld = acos( 45 / TR);
    d1 = sqrt( 144);
    _tprintf(_T("%.15G\n"), (double)d1);
    I = time( NULL);
    _tprintf(_T("%ls%d\n"), _T("I = "), (int)I);
    _tprintf(_T("%ls\n"), _T("Hello There"));
    I = rand();
    _tprintf(_T("%ls%d\n"), _T("I = "), (int)I);
    srand((DWORD)time(NULL));
    d1 = fmod( 5.3, 2);
    _tprintf(_T("%ls%.15G\n"), _T("d1 = "), (double)d1);
    f1 = fmodf( 5.3, 2);
    _tprintf(_T("%ls%.7G\n"), _T("f1 = "), (float)f1);
    Pause();
}




Title: Re: TCLib update for Patrice
Post by: Mike Lobanovsky on March 09, 2017, 08:40:35 PM
#define RAND_MAX 0x7fff belongs to stdlib.h so it should be defined explicitly elsewhere since stdlib.h is eliminated altogether.
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 09, 2017, 10:02:30 PM
James

The main difference between you and me is that you don't use the IDE.

I have attached the full VS 2015 community project to create the 64-bit OpenGL bbp_Laserbeam.dll (13312 bytes) to be used with the latest MBox64.exe player.

I shall try to convert the other plugins, once the rand() and srand() problem will be sorted out ;)

Thank you for helping me to produce this tiny visual plugin.
As a matter of comparison the size of the PowerBASIC 32-bit LaserBeam.dll plugin is 35328 bytes, that means 2.65 bigger, i am very happy!
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 09, 2017, 11:44:50 PM
Patrice,
  Try this one.
James
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 10, 2017, 12:21:09 PM
Fred

Thanks for the rand and rnd functions, i didn't see your post until today.
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 10, 2017, 02:24:54 PM
Fred

What do you use to replace the srand function to seed the pseudorandom-number ?
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 10, 2017, 06:03:18 PM
Amazing

i have been able to reduce the size of most of my plugins by a factor ranging between 4 and 7 !!!
Title: Re: TCLib update for Patrice
Post by: Frederick J. Harris on March 10, 2017, 06:08:40 PM
Patrice, I don't think I have any implementation for srand().  I had only run into the problem of coming up with a replacement for PowerBASIC's Rnd() function in converting a multi-threaded example I posted here some time ago...

http://www.jose.it-berater.org/smfforum/index.php?topic=5058.0

...from PowerBASIC to C++.  As you are probably aware, C's rand produces a rather limited range of integers.  I forget the exact range, but its rather limited.  For my example I needed numbers like PowerBASIC's Rnd() would generate, so I scaled them into an acceptable range.

Later, when I attempted to get that example working with my TCLib, I ran into the same problem you did, that is, I hadn't included in TCLib an implementation of rand() or srand().  So I hunted around on the internet a bit and found what I did for rand() and that by itself met my simple needs at the time.  The implementation seems to use integer overflow to get crazy numbers. 

Just off the top of my head, I think there are two solutions possible if you need rand() or srand().  First, you could hunt around the internet for an implementation of srand().  My guess is it wouldn't be too hard to come up with something.

The other possibility would be to simply include it within TCLib itself in the manner Jim seems to have done with the trig and other Math functions.  Its a fairly straightforward process.  As I've said before, the C Runtime is loaded into every GUI process.  All the C Runtime functions are there, including, I'm assuming, rand() and srand().  Its just a matter of calling LoadLibrary() to get the dll HINSTANCE, and calling GetProcAddress() to get a pointer to the function.  In many cases the function pointer can be named exactly the same as the function itself, and the usage is the same. 
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 10, 2017, 06:21:55 PM
Patrice,
  I noticed in your bbp_Laserbeam.cpp source you are not including TCLib\tchar.h.
This is a vital component that eliminates the duplicate definitions for rand srand.

James

Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 10, 2017, 06:27:34 PM
LoadLibrary() to get the dll HINSTANCE, and calling GetProcAddress()

OF COURSE, that could be the easiest solution!
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 10, 2017, 06:34:15 PM
Fred,
  I have found that renaming the functions in the TCLib and then using tchar.h for the translation seems to work fine.
For rand and srand I just prefaced with an underscore but I am going to go back and preface everything with tcl_.

I found I needed fflush so :

tcl_fflush = (int (__cdecl*)(FILE* fp)) GetProcAddress(hLib,"fflush");

Then in tchar.h:
#define fflush tcl_fflush

James

Title: Re: TCLib update for Patrice
Post by: Mike Lobanovsky on March 10, 2017, 08:43:36 PM
Quote from: Frederick J. Harris on March 10, 2017, 06:08:40 PM... C's rand produces a rather limited range of integers.  I forget the exact range, but its rather limited.

The ISO standard declares a compatible C rand() function's exact range to be entirely compiler implementation dependent but states that it be at least 0 thru 32767 inclusive. As it happens, both VC and GCC define their RAND_MAX value as 0x7FFF, which is exactly 32767 decimal.
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 10, 2017, 08:55:38 PM
Here is what i came with to simulate the PowerBASIC:
RANDOMIZE TIMER
typedef void (*FuncWithParams)(DWORD seed);
void RandoMize(IN DWORD seed) {
    HMODULE hModule = LoadLibrary(L"MSVCRT");
    if (hModule) {
        FuncWithParams hProc;
        hProc = (FuncWithParams) GetProcAddress(hModule, "srand");
        if (hProc) { hProc(seed); }
    }
}

void RandomizeTimer() {
//    //static long done;
//    //if (!done) { srand((DWORD) time(NULL)); done = !done; }
    //srand((DWORD) time(NULL));
    RandoMize((DWORD) time(NULL));
}

i shall post the source code of all the new TCLib plugins on www.objreader.com to render in Mbox64.exe

...
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 10, 2017, 10:02:02 PM
i was missing the log2 function.
here is what i came with


#define M_LOG2E 1.44269504088896340736
#define double_proc typedef double (__stdcall *zProc)

HMODULE MSVCRT() {
    static HMODULE hModule;
    if (hModule == 0) { hModule = LoadLibrary(L"MSVCRT"); }
    return hModule;
}

double log2(IN double X) {
    double l2 = 0;
    HMODULE hModule = MSVCRT();
    if (hModule) {
        double_proc (double);
        zProc hProc = (zProc) GetProcAddress(hModule, "log");
        if (hProc) { l2 = hProc(X) * M_LOG2E; }
    }
    return l2;
}
Title: Re: TCLib update for Patrice
Post by: Frederick J. Harris on March 10, 2017, 10:22:07 PM
Quote
The ISO standard declares a compatible C rand() function's exact range to be entirely compiler implementation dependent but states that it be at least 0 thru 32767 inclusive. As it happens, both VC and GCC define their RAND_MAX value as 0x7FFF, which is exactly 32767 decimal.

That's the number I thought RAND_MAX was equal to for VC and GCC Mike, but I didn't want to state it without checking.  At the time I needed it (rand()), I needed numbers from about a million to 50,000,000, so I had to devise something to produce them.  I'm not really sure what's in the C++ Standard Library (if anything), relating to a C++ version of rand().
Title: Re: TCLib update for Patrice
Post by: Charles Pegge on March 11, 2017, 01:58:55 AM
This is a satisfactory, though home-made 32-bit pseudo-randomizer. It churns integers but scales them to return floats -1.0 to +1.0. To return 32bit integer ranges, omit the float scaler and return the raw integer value in eax instead.


  int seed=0x12345678
  '
  function Rnd() as float
  =======================
  Static As float f, d=1/0x7fffffff
  mov eax,seed
  inc eax
  rol eax,13
  xor eax,0xdab5ca3a
  mov seed,eax
  push eax
  fild dword [esp]
  pop eax
  fmul dword d
  fstp dword f
  return f
  end function


You are probably familiar with this one from the web, based on mul overflows into edx.
The 2 inputs are the lower and upper range limits:


  function irnd(int z1, z2) as int
  ================================
  mov    eax,z2
  sub    eax,z1
  inc    eax
  imul   edx,Seed,0x8088405
  inc    edx
  mov    Seed,edx 'store new seed
  mul    edx 'multiply eax by edx
  return edx+z1
  end Function
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 11, 2017, 10:46:59 AM
The TCLib version of the Visual Studio community 2015 has been attached to this post
http://www.jose.it-berater.org/smfforum/index.php?topic=5176.msg22444#msg22444

Thank you all, for having helped me to produce these amazing small 64-bit DLL(s), without using any compressor !
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 21, 2017, 11:03:06 AM
So far i have been able to create my smallest OpenGL 64-bit plugin, only 13 Kb.

And i was able to reduce the size of my PNGanim project from 140 Kb down to 60 Kb, using GetprocAdress to access directly to MSVCRT, the only thing that is causing me havoc, is when there are multiple optional parameters like for swprintf, and i don't know the syntax to use to create the prototype to use the "...".

Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 21, 2017, 11:11:18 AM
Patrice,
  Take a look at the TCLib\stdio.h file.

James
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 21, 2017, 02:21:47 PM
James--

I have seen it already, but what i am looking for is a replacement for the PowerBASIC statement "AS ANY"
without using va_list


Currently i am doing this to use swprintf with long, and i must have another function for float, double, etc.

#define long_proc_c typedef long (__cdecl *zProc)

HMODULE MSVCRT() {
    static HMODULE hModule;
    if (hModule == 0) { hModule = LoadLibrary(L"MSVCRT"); }
    return hModule;
}

long long_swprintf(OUT WCHAR* buffer, IN WCHAR* format, IN long N) {
    long nRet = -1; // Error
    HMODULE hModule = MSVCRT();
    if (hModule) {
        long_proc_c (WCHAR*, WCHAR*, long);
        zProc hProc = (zProc)GetProcAddress(hModule, "swprintf");
        if (hProc) { nRet = hProc(buffer, format, N); }
    }
    return nRet;
}
Title: Re: TCLib update for Patrice
Post by: Patrice Terrier on March 25, 2017, 05:13:40 PM
James, Fred,

I have attached the latest Visual Studio 2015/2017 TCLIB version of my 64-bit OpenGL plugins
to this post (http://www.objreader.com/index.php?topic=80.0)
C++bbp_plugins64.zip

The smallest dll is only 13 Kb.
Title: Re: TCLib update for Patrice
Post by: James C. Fuller on March 26, 2017, 07:32:59 PM
Thanks Patrice,
  I realize now why you were having problems with rand and srand as I found issues with my own work.
I assume one of your included files:
  #include <gl/GL.h>
  #include <gl/GLU.h>
is pulling in <stdlib.h> or one of the other msvcrt include files.

I had done a lot of successful testing originally with my port of José's CWindow and Afx framework but when I tried with my latest version of TCLib I had a number of redefinition errors.
I was including:
   #include <psapi.h>
   #include <Shlobj.h>
   #include <KnownFolders.h>
   #include <shlwapi.h>
   #include <commctrl.h>
   #include <uxtheme.h>
and at least one of them is pulling in msvcrt include files.

I write all my bc9Basic code as ansi. I then parse the c++ translated code with the ULEX utility which does all the transformations. I can name the library function tcl_rand and translate the source "rand" call to tcl_rand on the fly.
I am scratching my head though as only a few are a causing problems.

James