The MASM Forum

General => The Workshop => Topic started by: K_F on August 29, 2017, 05:11:11 AM

Title: Converting a C/C++ class to Masm Structure
Post by: K_F on August 29, 2017, 05:11:11 AM
Maybe someone with C/C++ to Masm knowledge might be able to help here.

I'm tinkering with a mod for a game/simulation in Masm and am a bit rusty on the C++ to Masm conversion thing.
The class is defined ..
// ======================================================================
// class ExternalCameraControl
// interface to externally provided camera position data

class OAPIFUNC ExternalCameraControl {
public:
ExternalCameraControl (DWORD dmode, DWORD cmode);

void SetDataMode (DWORD mode);
DWORD GetDataMode () const;

void SetCameraMode (DWORD mode);
DWORD GetCameraMode () const;

struct CamData { // position data
double x, y, z;
double yaw, pitch, roll;
};

struct VCMode { // defines the VC behaviour
bool trackrotation;   // apply rotation data
bool trackposition;   // apply translation data
bool freezeonmouse;   // freeze camera after mouse move
double rotationrange; // default rotation range [rad]
double positionrange; // default translation range [m]
double freeze_t;      // freeze time [s]
};

struct TrackMode { // defines external track view behaviour
bool trackrotation;   // allow camera orbiting target
bool trackzoom;       // allow camera advancing on/retreating from target
enum {BYROTATION,BYPOSITION} rotationdata; // use rotation/position data for rotation
double deadzone;      // tracking deadzone (0-1)
double speed;         // movement speed
};

inline const VCMode *GetVCMode () const { return &vcmode; }
inline const TrackMode *GetTrackMode () const { return &trkmode; }

virtual bool clbkPoll (CamData *data) = 0;
// callback function for providing absolute position data
// must be provided by implementations

protected:
DWORD datamode;
DWORD cameramode;
VCMode vcmode;
TrackMode trkmode;
};


The obvious structures are no problem, but it's the function definitions and their 'correct' places in the structure that bother me.
The above class definition is a mess of a mix, and I'd imagine one has to follow this mess or risk a crash.

Anyones thoughts of a masm equivalent or links to such documentation ?
Thanks
Title: Re: Converting a C/C++ class to Masm Structure
Post by: aw27 on August 29, 2017, 12:35:52 PM
Quote from: K_F on August 29, 2017, 05:11:11 AM
Maybe someone with C/C++ to Masm knowledge might be able to help here.

I'm tinkering with a mod for a game/simulation in Masm and am a bit rusty on the C++ to Masm conversion thing.
The class is defined ..
// ======================================================================
// class ExternalCameraControl
// interface to externally provided camera position data

class OAPIFUNC ExternalCameraControl {
public:
ExternalCameraControl (DWORD dmode, DWORD cmode);

void SetDataMode (DWORD mode);
DWORD GetDataMode () const;

void SetCameraMode (DWORD mode);
DWORD GetCameraMode () const;

struct CamData { // position data
double x, y, z;
double yaw, pitch, roll;
};

struct VCMode { // defines the VC behaviour
bool trackrotation;   // apply rotation data
bool trackposition;   // apply translation data
bool freezeonmouse;   // freeze camera after mouse move
double rotationrange; // default rotation range [rad]
double positionrange; // default translation range [m]
double freeze_t;      // freeze time [s]
};

struct TrackMode { // defines external track view behaviour
bool trackrotation;   // allow camera orbiting target
bool trackzoom;       // allow camera advancing on/retreating from target
enum {BYROTATION,BYPOSITION} rotationdata; // use rotation/position data for rotation
double deadzone;      // tracking deadzone (0-1)
double speed;         // movement speed
};

inline const VCMode *GetVCMode () const { return &vcmode; }
inline const TrackMode *GetTrackMode () const { return &trkmode; }

virtual bool clbkPoll (CamData *data) = 0;
// callback function for providing absolute position data
// must be provided by implementations

protected:
DWORD datamode;
DWORD cameramode;
VCMode vcmode;
TrackMode trkmode;
};


The obvious structures are no problem, but it's the function definitions and their 'correct' places in the structure that bother me.
The above class definition is a mess of a mix, and I'd imagine one has to follow this mess or risk a crash.

Anyones thoughts of a masm equivalent or links to such documentation ?
Thanks

You need to pull out the methods from inside the class, making them regular procedures with one parameter being a pointer to the object.


Title: Re: Converting a C/C++ class to Masm Structure
Post by: habran on August 29, 2017, 01:49:54 PM
Hi K_F :biggrin:
UASM is able to deal with objects 8)
Here is an example that Johnsa wrote, see if you can use that info.



; Demonstration of HJWasm 2.25 OO and additional features:

; Build with:
;..\hjwasm64 -win64 -c -Zp8 -Zi -Zd -Zf oo1.asm
;d:\vs2015\vc\bin\link /subsystem:console /machine:x64 /debug /Libpath:"%WINSDK%\v7.1\Lib\x64" oo1.obj

.X64
OPTION CASEMAP:NONE
OPTION WIN64:7 ; 11/15 for RSP and 1-7 for RBP.
OPTION STACKBASE:RBP ; RSP or RBP are supported options for the stackbase.

  .nolist
    .nocref
WIN32_LEAN_AND_MEAN equ 1
_WIN64 equ 1
    include ..\wininc\Include\windows.inc
    .list
    .cref

    includelib <kernel32.lib>
    includelib <user32.lib>

;=====================================================================================================================================================
;
; CLASS Definition inclusion guard.
;
;=====================================================================================================================================================
IFNDEF _CLASS_PERSON_
_CLASS_PERSON_ EQU 1

OINTERFACE Entity
CVIRTUAL PrintName
CVIRTUAL SetName
ENDOINTERFACE

;---------------------------------------------------------------------------------------------------------------
; Define our Person class with 2 instance methods, 1 static method and 3 member fields.
;---------------------------------------------------------------------------------------------------------------
CLASS Person
CMETHOD PrintName
CMETHOD SetName
CSTATIC IsHuman
pName   dq 0
age     db 0
human   db 0
handle  dq 0
ENDCLASS

; A Pointer to Object type.
pPerson TYPEDEF PTR Person

;---------------------------------------------------------------------------------------------------------------
; Constructor
; Can take optional arguments.
;---------------------------------------------------------------------------------------------------------------
METHOD Person, Init, <USES rbx r10>, age:BYTE, consoleHandle:QWORD, ptrName:QWORD

LOCAL isAlive:DWORD
; Internally the METHOD forms a traditional procedure, so anything that you can do in a PROC you can do in a method.

; Store console output handle.
mov rax,consoleHandle
mov [rcx].handle,rax

; Store pointer to passed in name. (r9 can be used directly)
; -> The proc arguments conform to calling convention: rcx=thisPtr, dl=age, r8=consoleHandle, r9=ptrName
mov [rcx].pName,r9

; On entry into any method RCX is a pointer to the instance
; and the correct reference type is assumed.
mov [rcx].human, 1 ; Hence this is possible.
mov (Person PTR [rcx]).human, 1 ; Alternative forms of reference.
mov [rcx].Person.human, 1 ; " "

mov isAlive,0
mov al,age
mov [rcx].age,al

.if( age < 100 )
mov isAlive,1
.endif

; The constructor MUST return it's this pointer in RAX.
mov rax,thisPtr

ret
ENDMETHOD

;---------------------------------------------------------------------------------------------------------------
; Destructor
; Takes no arguments.
;---------------------------------------------------------------------------------------------------------------
METHOD Person, Destroy, <>
mov [rcx].age,0
ret
ENDMETHOD

;---------------------------------------------------------------------------------------------------------------
; Print the persons name to the console.
;---------------------------------------------------------------------------------------------------------------
METHOD Person, PrintName, <USES rbx>

LOCAL bWritten:DWORD

invoke lstrlen,[rcx].pName
mov r10d,eax

mov rcx,thisPtr
mov rax,[rcx].handle
mov rbx,[rcx].pName

invoke WriteConsole, rax, rbx, r10d, ADDR bWritten, NULL

ret
ENDMETHOD

;---------------------------------------------------------------------------------------------------------------
; Set person name.
;---------------------------------------------------------------------------------------------------------------
METHOD Person, SetName, <USES rbx>, pNameStr:QWORD

mov rax,pNameStr
mov [rcx].pName,rax

ret
ENDMETHOD

;---------------------------------------------------------------------------------------------------------------
; Static method to check if a person is a human.
;---------------------------------------------------------------------------------------------------------------
STATICMETHOD Person, IsHuman, <USES rbx>, somebody:PTR Person

mov rax,somebody
mov al,(Person PTR [rax]).human

ret
ENDMETHOD

ENDIF

;=====================================================================================================================================================
; END OF PERSON CLASS
;=====================================================================================================================================================

.DATA

hOutput dq 0
person1 pPerson 0 ; A global variable to hold a reference to a Person type.

avgAge REAL4 0 ; Integer to real type promotion. (You can use an integer initializer instead of N.n format).

.CODE

; All default procedures are now FRAME based (so there is no need to specify FRAME).
; -> Using a FRAME PROC as the entry point for both Console and Windows applications is advised to ensure correct stack startup.
MainCRTStartup PROC
LOCAL person2:PTR Person ; A local variable to hold a reference to a Person type. (Note you can also use _DECLARE if the Object name includes <>).

invoke GetStdHandle,STD_OUTPUT_HANDLE
    mov hOutput,rax
   
    ; Create two Person instances.
    mov person1, _NEW(Person, 30, hOutput, CSTR("Jane Doe "))
    mov person2, _NEW(Person, 40, hOutput, CSTR("Peter Smith "))
   
    _INVOKE Person, PrintName, person1 ; Direct call (Type, Method, arguments)
    _VINVOKE person2, Person, PrintName ; Vtable call (instance, Type, Method)   
    _INVOKE Person, SetName, person1, CSTR("Michael Smith ")
    _INVOKE Person, PrintName, person1
   
    mov rax, _STATIC(Person, IsHuman, person1) ; Default return type from $STATIC is 64bit integer.
   
    ; Delete the objects.
    _DELETE(person1)
    _DELETE(person2)


ret
MainCRTStartup ENDP

END MainCRTStartup
Title: Re: Converting a C/C++ class to Masm Structure
Post by: K_F on September 01, 2017, 02:12:59 AM
Thanks.. I'll try that
:t
Title: Re: Converting a C/C++ class to Masm Structure
Post by: habran on September 01, 2017, 01:19:50 PM
If you don't succeed, or need some more info you can PM Johnsa, he'll be happy to give you a hand and if necessary add some stuff to UASM to make it work. :biggrin:
Title: Re: Converting a C/C++ class to Masm Structure
Post by: JR.VOY on October 04, 2017, 02:34:24 PM
Quote from: K_F on August 29, 2017, 05:11:11 AM
Maybe someone with C/C++ to Masm knowledge might be able to help here.

I'm tinkering with a mod for a game/simulation in Masm and am a bit rusty on the C++ to Masm conversion thing.
The class is defined ..
// ======================================================================
// class ExternalCameraControl
// interface to externally provided camera position data

class OAPIFUNC ExternalCameraControl {
public:
ExternalCameraControl (DWORD dmode, DWORD cmode);

void SetDataMode (DWORD mode);
DWORD GetDataMode () const;

void SetCameraMode (DWORD mode);
DWORD GetCameraMode () const;

struct CamData { // position data
double x, y, z;
double yaw, pitch, roll;
};

struct VCMode { // defines the VC behaviour
bool trackrotation;   // apply rotation data
bool trackposition;   // apply translation data
bool freezeonmouse;   // freeze camera after mouse move
double rotationrange; // default rotation range [rad]
double positionrange; // default translation range [m]
double freeze_t;      // freeze time [s]
};

struct TrackMode { // defines external track view behaviour
bool trackrotation;   // allow camera orbiting target
bool trackzoom;       // allow camera advancing on/retreating from target
enum {BYROTATION,BYPOSITION} rotationdata; // use rotation/position data for rotation
double deadzone;      // tracking deadzone (0-1)
double speed;         // movement speed
};

inline const VCMode *GetVCMode () const { return &vcmode; }
inline const TrackMode *GetTrackMode () const { return &trkmode; }

virtual bool clbkPoll (CamData *data) = 0;
// callback function for providing absolute position data
// must be provided by implementations

protected:
DWORD datamode;
DWORD cameramode;
VCMode vcmode;
TrackMode trkmode;
};


The obvious structures are no problem, but it's the function definitions and their 'correct' places in the structure that bother me.
The above class definition is a mess of a mix, and I'd imagine one has to follow this mess or risk a crash.

Anyones thoughts of a masm equivalent or links to such documentation ?
Thanks
The structure is interesting.