Hi Yves!
Using macros in mtx.inc :
http://masm32.com/board/index.php?topic=8398.0. Requiere JWasm family because there are macros creating macros.
Using Matrix.inc in ObjAsm:
http://masm32.com/board/index.php?topic=8583.0. Examples of use are in ObjAsm32. This Matrix.inc is a modification in progress of that.
A litle more specific and in development, perhaps using a more advanced mtx.inc (I have to see

). Also in ObjAsm I'm translating some C++ code:
;/*!
; * \file
; * Scanline edge-flag algorithm for antialiasing <br>
; * Copyright (c) 2005-2007 Kiia Kallio
; *
; * http://mlab.uiah.fi/~kkallio/antialiasing/
; *
; * This code is distributed under the three-clause BSD license.
; * Read the LICENSE file or visit the URL above for details.
; *
; * \brief A simple 2d matrix class.
; *
; *
; * $Id: $
; * $Date: $
; * $Revision: $
; */
MATRIX2D textequ <POINTER>
defMATRIX2D macro var1
DefineVariable &var1, MATRIX2D, 0
endm
;//! A simple 2d matrix class.
Object Matrix2D,, Primer
; Makes a rotation matrix.
;void makeRotation(RATIONAL aAngle);
VirtualMethod makeRotation, RATIONAL
; Makes a translation matrix.
;void makeTranslation(const Vector2d &aTranslation);
VirtualMethod makeTranslation, POINTER
; Makes a scaling matrix.
;void makeScaling(const Vector2d &aScale);
VirtualMethod makeScaling, POINTER
; Makes an identity matrix.
;void makeIdentity();
VirtualMethod makeIdentity
; Rotates the matrix by an angle
;void rotate(RATIONAL rotate);
VirtualMethod rotate, RATIONAL
; Translates the matrix with a vector.
;void translate(const Vector2d &aTranslation);
VirtualMethod translate, POINTER
; Scales the matrix with a vector.
;void scale(const Vector2d &aScale);
VirtualMethod scale, POINTER
; Multiplies the matrix with another matrix.
;void multiply(const Matrix2d &aMatrix);
VirtualMethod multiply, POINTER
; Transforms a point with the matrix.
;void transform(const Vector2d &aSource, Vector2d &aTarget) const;
VirtualMethod transform, POINTER, POINTER
DIMOA mMatrix, RATIONAL, 3, 2
ObjectEnd
;#define MATRIX2D_MAKEROTATION(aMatrix,aAngle) aMatrix.makeRotation(aAngle)
;#define MATRIX2D_MAKETRANSLATION(aMatrix,aTranslation) aMatrix.makeTranslation(aTranslation)
MATRIX2D_MAKESCALING macro aMatrix, aScale
OCall &aMatrix::Matrix2D.makeScaling, &aScale
endm
MATRIX2D_MAKEIDENTITY macro aMatrix
OCall &aMatrix::Matrix2D.makeIdentity
endm
;#define MATRIX2D_ROTATE(aMatrix,aAngle) aMatrix.rotate(aAngle)
MATRIX2D_TRANSLATE macro aMatrix, aTranslation
OCall &aMatrix::Matrix2D.translate, &aTranslation
endm
;#define MATRIX2D_SCALE(aMatrix,aScale) aMatrix.scale(aScale)
MATRIX2D_MULTIPLY macro aMatrix, aMultiplier
OCall &aMatrix::Matrix2D.multiply, &aMultiplier
endm
MATRIX2D_TRANSFORM macro aMatrix,aSource,aResult
OCall &aMatrix::Matrix2D.transform, &aSource, &aResult
endm
;#define MATRIX2D_GET_M11(aMatrix) aMatrix.mMatrix[0][0]
;#define MATRIX2D_GET_M12(aMatrix) aMatrix.mMatrix[0][1]
;#define MATRIX2D_GET_M21(aMatrix) aMatrix.mMatrix[1][0]
;#define MATRIX2D_GET_M22(aMatrix) aMatrix.mMatrix[1][1]
;#define MATRIX2D_GET_DX(aMatrix) aMatrix.mMatrix[2][0]
;#define MATRIX2D_GET_DY(aMatrix) aMatrix.mMatrix[2][1]
; * Scanline edge-flag algorithm for antialiasing <br>
; * Copyright (c) 2005-2007 Kiia Kallio
; *
; * http:;mlab.uiah.fi/~kkallio/antialiasing/
; *
; * This code is distributed under the three-clause BSD license.
; * Read the LICENSE file or visit the URL above for details.
; *
; * \brief A simple 2d matrix class.
; Makes a rotation matrix.
Method Matrix2D.makeRotation, uses xsi, aAngle : RATIONAL
local sinRot : RATIONAL
local cosRot : RATIONAL
SetObject xsi
fSlv8 sinRot = sin(aAngle)
fSlv8 cosRot = cos(aAngle)
fSlv8 mMatrix(0,0) = cosRot
fSlv8 mMatrix(0,1) = sinRot
fSlv8 mMatrix(1,0) = -sinRot
fSlv8 mMatrix(1,1) = cosRot
fSlv8 mMatrix(2,0) = 0
fSlv8 mMatrix(2,1) = 0
MethodEnd
; Makes a translation matrix.
Method Matrix2D.makeTranslation, uses xsi, aTranslation : POINTER
SetObject xsi
SetObject xdx, Vector2D, aTranslation
fSlv8 mMatrix(0,0) = 1
fSlv8 mMatrix(0,1) = 0
fSlv8 mMatrix(1,0) = 0
fSlv8 mMatrix(1,1) = 1
fSlv8 mMatrix(2,0) = [xdx].mX
fSlv8 mMatrix(2,1) = [xdx].mY
MethodEnd
; Makes a scaling matrix.
Method Matrix2D.makeScaling, uses xsi, aScale :POINTER
SetObject xsi
SetObject xdx, Vector2D, aScale
fSlv8 mMatrix(0,0) = [xdx].mX;
fSlv8 mMatrix(0,1) = 0
fSlv8 mMatrix(1,0) = 0
fSlv8 mMatrix(1,1) = [xdx].mY;
fSlv8 mMatrix(2,0) = 0
fSlv8 mMatrix(2,1) = 0
MethodEnd
; Makes an identity matrix.
Method Matrix2D.makeIdentity, uses xsi
SetObject xsi
fSlv8 mMatrix(0,0) = 1
fSlv8 mMatrix(0,1) = 0
fSlv8 mMatrix(1,0) = 0
fSlv8 mMatrix(1,1) = 1
fSlv8 mMatrix(2,0) = 0
fSlv8 mMatrix(2,1) = 0
MethodEnd
; Rotates the matrix by an angle
Method Matrix2D.rotate, uses xsi, rotate : RATIONAL
local tmp : POINTER
SetObject xsi
New Matrix2D
mov tmp, xax
OCall tmp::Matrix2D.makeRotation, rotate
OCall xsi.multiply, tmp
Destroy tmp
MethodEnd
; Translates the matrix with a vector.
Method Matrix2D.translate, uses xsi, aTranslation : POINTER
local tmp : POINTER
SetObject xsi
;SetObject xdx, Vector2D, aTranslation ;pointer to Vector2d
New Matrix2D
mov tmp, xax
OCall tmp::Matrix2D.makeTranslation, aTranslation
OCall xsi.multiply, tmp
Destroy tmp
MethodEnd
; Scales the matrix with a vector.
Method Matrix2D.scale, uses xsi, aScale : POINTER
local tmp : POINTER
SetObject xsi
;Vector2d
New Matrix2D; tmp;
mov tmp, xax
OCall tmp::Matrix2D.makeScaling, aScale
OCall xsi.multiply, tmp
Destroy tmp
MethodEnd
; Multiplies the matrix with another matrix.
Method Matrix2D.multiply, uses xsi xdi, aMatrix : POINTER
local tmp : POINTER
SetObject xsi
New Matrix2D
mov tmp, eax
CopiaObjeto OA_Matrix2D, tmp
SetObject xdi, Matrix2D, aMatrix
SetObject xdx, Matrix2D, tmp
fSlv8 mMatrix(0,0) = mMatrixP(xdx,0,0) * mMatrixP(xdi,0,0) +\
mMatrixP(xdx,0,1) * mMatrixP(xdi,1,0);
fSlv8 mMatrix(0,1) = mMatrixP(xdx,0,0) * mMatrixP(xdi,0,1) +\
mMatrixP(xdx,0,1) * mMatrixP(xdi,1,1);
fSlv8 mMatrix(1,0) = mMatrixP(xdx,1,0) * mMatrixP(xdi,0,0) +\
mMatrixP(xdx,1,1) * mMatrixP(xdi,1,0);
fSlv8 mMatrix(1,1) = mMatrixP(xdx,1,0) * mMatrixP(xdi,0,1) +\
mMatrixP(xdx,1,1) * mMatrixP(xdi,1,1);
fSlv8 mMatrix(2,0) = mMatrixP(xdx,2,0) * mMatrixP(xdi,0,0) +\
mMatrixP(xdx,2,1) * mMatrixP(xdi,1,0) +\
mMatrixP(xdi,2,0);
fSlv8 mMatrix(2,1) = mMatrixP(xdx,2,0) * mMatrixP(xdi,0,1) +\
mMatrixP(xdx,2,1) * mMatrixP(xdi,1,1) +\
mMatrixP(xdi,2,1);
DbgFloat mMatrix(0,0)
DbgFloat mMatrix(0,1)
DbgFloat mMatrix(1,0)
DbgFloat mMatrix(1,1)
DbgFloat mMatrix(2,0)
DbgFloat mMatrix(2,1)
;Ç
Destroy tmp
MethodEnd
; Transforms a point with the matrix.
Method Matrix2D.transform, uses xsi xdi, aSource : POINTER, aTarget :POINTER
local vector2D : $Obj(Vector2D)
DbgMtit
SetObject xsi
SetObject xdi, Vector2D, aSource
DbgHex xdi
DbgHex aTarget
.if xdi == aTarget
lea xax, vector2D
SetObject xdx, Vector2D, xax
.else
SetObject xdx, Vector2D, aTarget
.endif
DbgHex xdx
fSlv8 [xdx].mX = mMatrix(0,0) * [xdi].mX + mMatrix(1,0) * [xdi].mY + mMatrix(2,0)
fSlv8 [xdx].mY = mMatrix(0,1) * [xdi].mX + mMatrix(1,1) * [xdi].mY + mMatrix(2,1)
.if xdi == aTarget
lea xax, vector2D
SetObject xdi, Vector2D, xax
SetObject xdx, Vector2D, aTarget
fSlv8 [xdx].mX = [xdi].mX
fSlv8 [xdx].mY = [xdi].mY
.endif
DbgMsal
MethodEnd
Yes. To include matrix in objects requiere this:
;* @ArgI - Macro function returns an argument specified by number
;* from a VARARG list.
;*
;* Params: index - one-based number of the argument to be returned
;* arglist - argument list
@ArgI MACRO index:REQ, arglist:VARARG
LOCAL count,retstr
count = 0
FOR arg,<arglist>
count = count + 1
IF count EQ index
retstr TEXTEQU <arg>
ENDIF
ENDM
EXITM retstr
ENDM
;mtx_tls_warning_line = -1
;@mtxTLS_warning macro
; IF mtx_tls_warning_line NE @Line
; %echo @FileCur: WARNING: code not thread save: line @CatStr(%@Line)
; ENDIF
; mtx_tls_warning_line = @Line
;endm
mtxTLS_curr_line = -1
mtxTLS_curr_file textequ <>
; mod1 0 = variable, 1 = structure
; mod2 0 = standard, 1 = SmplMath
; mod3 0 = plain, 1 = ObjAsm
DIM_MASTER macro isStruct, isSmpMth, isOA, nombre, tipo, dimensions:VARARG
local value1
value1 textequ <1>
count = 0
FOR dimension, <&dimensions>
value1 CATSTR value1 , <*>, %dimension
ENDM
if isOA eq 0
if isStruct eq 0
nombre&_mtx &tipo value1 dup (?)
else
nombre&_mtx &tipo value1 dup (<?>)
endif
else
nombre&_mtx_type textequ <&tipo>
if isStruct eq 0
DefineVariable nombre&_mtx, &tipo, value1 dup (?)
else
DefineVariable nombre&_mtx, &tipo, value1 dup (<?>)
endif
endif
&nombre MACRO dimensionsn:VARARG
LOCAL count, dwidth, dist, hayc, hayv, dewidth2, nombrestore
count = 0
dwidth = 1
dist = 0
hayc = 0
hayv = 0
if 0
if &isSmpMth eq 1
IF mtxTLS_curr_line NE @Line
mtxTLS_curr_line = @Line
mtxTLS_usados = 0
ENDIF
endif
endif
FOR arg,<&dimensionsn>
oa = OPATTR arg
if oa and 0100b
hayc = 1
else
hayv = 1
endif
ENDM
if hayv
mov eax, 0
endif
FOR arg,<&dimensionsn>
count = count + 1
oa = OPATTR arg
if oa and 0100b
if isOA eq 0
dwidth2 = dwidth * TYPE nombre&_mtx
else
dwidth2 = dwidth * TYPE nombre&_mtx_type
endif
dist = dist + (arg * dwidth2)
else
push eax
mov eax, arg
mov ecx, dwidth
mul ecx
pop ecx
add eax, ecx
endif
dwidth = dwidth * @ArgI(%count, <dimensions>)
ENDM
if hayv
if isStruct eq 1
if isOA eq 0
mov ecx, TYPE nombre&_mtx
else
mov ecx, TYPE nombre&_mtx_type
endif
mul ecx
endif
if isSmpMth eq 1
% add eax, offset @CatStr(&nombre,<_mtx>)
mtxTLS_usados = mtxTLS_usados + 1
;; % echo @CatStr(%mtxTLS_usados)
% if mtxTLS_usados gt mtxTLS_reservados
.err incrementar reserva mtxTLS() en @FileCur
endif
if hayc
% add eax, dist
endif
% mov dword ptr SS:[ebp - mtxTLS_usados*@WordSize ], eax
endif
endif
if hayv and hayc
if isStruct eq 0
if isSmpMth eq 0
if isOA eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx+ %dist ,<]>)
else
EXITM @CatStr(<[esi].>,&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx_type+ %dist ,<]>)
endif
else
% echo @CatStr(<add dword ptr [ebp - >,%mtxTLS_usados*@WordSize,< ],>, %dist)
% @CatStr(<add dword ptr SS:[ebp - >,%mtxTLS_usados*@WordSize,< ],>, %dist)
% echo EXITM <@CatStr(tipo,< ptr [ebp->,%mtxTLS_usados*@WordSize,<]>)>
EXITM <@CatStr(tipo,< ptr [ebp->,%mtxTLS_usados*@WordSize,<]>)>
endif
else
if isSmpMth eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>,eax + %dist ,<]>)
else
add dword ptr SS:[ebp - mtxTLS_usados*@WordSize ], %dist
EXITM <@CatStr(<[ebp->,mtxTLS_usados*@WordSize,<].>,&tipo)>
endif
endif
elseif hayv
if isStruct eq 0
if isSmpMth eq 0
if isOA eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx ,<]>)
else
EXITM @CatStr(<[esi].>,&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx_type ,<]>)
endif
else
EXITM <@CatStr(&nombre,<_mtx>,<[ebp->,mtxTLS_usados*@WordSize,<]>)>
endif
else
if isSmpMth eq 0
if isOA eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>,eax,<]>)
else
EXITM @CatStr(<[esi].>,&nombre,<_mtx>,<[>,eax,<]>)
endif
else
EXITM <@CatStr(<[ebp->,mtxTLS_usados*@WordSize,<].>,&tipo)>
endif
endif
elseif hayc
if isOA eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>, %dist ,<]>)
else
EXITM @CatStr(<[esi].>,&nombre,<_mtx>,<[>, %dist ,<]>)
endif
endif
ENDM
;-------------------------------------------------------------------------------
&nombre&P MACRO PuntReg:=<esi>, dimensionsn:VARARG
LOCAL count, dwidth, dist, hayc, hayv, dewidth2, nombrestore
count = 0
dwidth = 1
dist = 0
hayc = 0
hayv = 0
if 0
if &isSmpMth eq 1
IF mtxTLS_curr_line NE @Line
mtxTLS_curr_line = @Line
mtxTLS_usados = 0
ENDIF
endif
endif
FOR arg,<&dimensionsn>
oa = OPATTR arg
if oa and 0100b
hayc = 1
else
hayv = 1
endif
ENDM
if hayv
mov eax, 0
endif
FOR arg,<&dimensionsn>
count = count + 1
oa = OPATTR arg
if oa and 0100b
if isOA eq 0
dwidth2 = dwidth * TYPE nombre&_mtx
else
dwidth2 = dwidth * TYPE nombre&_mtx_type
endif
dist = dist + (arg * dwidth2)
else
push eax
mov eax, arg
mov ecx, dwidth
mul ecx
pop ecx
add eax, ecx
endif
dwidth = dwidth * @ArgI(%count, <dimensions>)
ENDM
if hayv
if isStruct eq 1
if isOA eq 0
mov ecx, TYPE nombre&_mtx
else
mov ecx, TYPE nombre&_mtx_type
endif
mul ecx
endif
if isSmpMth eq 1
% add eax, offset @CatStr(&nombre,<_mtx>)
mtxTLS_usados = mtxTLS_usados + 1
;; % echo @CatStr(%mtxTLS_usados)
% if mtxTLS_usados gt mtxTLS_reservados
.err incrementar reserva mtxTLS() en @FileCur
endif
if hayc
% add eax, dist
endif
% mov dword ptr SS:[ebp - mtxTLS_usados*@WordSize ], eax
endif
endif
if hayv and hayc
if isStruct eq 0
if isSmpMth eq 0
if isOA eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx+ %dist ,<]>)
else
EXITM @CatStr(<[>,&PuntReg,<].>,&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx_type+ %dist ,<]>)
endif
else
% echo @CatStr(<add dword ptr [ebp - >,%mtxTLS_usados*@WordSize,< ],>, %dist)
% @CatStr(<add dword ptr SS:[ebp - >,%mtxTLS_usados*@WordSize,< ],>, %dist)
% echo EXITM <@CatStr(tipo,< ptr [ebp->,%mtxTLS_usados*@WordSize,<]>)>
EXITM <@CatStr(tipo,< ptr [ebp->,%mtxTLS_usados*@WordSize,<]>)>
endif
else
if isSmpMth eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>,eax + %dist ,<]>)
else
add dword ptr SS:[ebp - mtxTLS_usados*@WordSize ], %dist
EXITM <@CatStr(<[ebp->,mtxTLS_usados*@WordSize,<].>,&tipo)>
endif
endif
elseif hayv
if isStruct eq 0
if isSmpMth eq 0
if isOA eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx ,<]>)
else
EXITM @CatStr(<[>,&PuntReg,<].>,&nombre,<_mtx>,<[>,eax * TYPE nombre&_mtx_type ,<]>)
endif
else
EXITM <@CatStr(&nombre,<_mtx>,<[ebp->,mtxTLS_usados*@WordSize,<]>)>
endif
else
if isSmpMth eq 0
if isOA eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>,eax,<]>)
else
EXITM @CatStr(<[>,&PuntReg,<].>,&nombre,<_mtx>,<[>,eax,<]>)
endif
else
EXITM <@CatStr(<[ebp->,mtxTLS_usados*@WordSize,<].>,&tipo)>
endif
endif
elseif hayc
if isOA eq 0
EXITM @CatStr(&nombre,<_mtx>,<[>, %dist ,<]>)
else
EXITM @CatStr(<[>,&PuntReg,<].>,&nombre,<_mtx>,<[>, %dist ,<]>)
endif
endif
ENDM
endm
DIM macro nombre, tipo, dimensions:VARARG
% DIM_MASTER 0, 0, 0, nombre, tipo, <dimensions>
ENDM
DIMS macro nombre, tipo, dimensions:VARARG
% DIM_MASTER 1, 0, 0, nombre, tipo, <dimensions>
ENDM
DIMOA macro nombre, tipo, dimensions:VARARG
% DIM_MASTER 0, 0, 1, nombre, tipo, <dimensions>
ENDM
DIMSOA macro nombre, tipo, dimensions:VARARG
% DIM_MASTER 0, 0, 1, nombre, tipo, <dimensions>
ENDM
mtxTLS macro punteros
ifb <punteros>
% mtxTLS_reservados = 4*@WordSize
else
% mtxTLS_reservados = &punteros*@WordSize
endif
mtxTLS_usados = 0
%EXITM <mtxTLS_puntero[mtxTLS_reservados]:byte>
endmRegards, HSE.