Hello,
Is someone have written macros to solve this form of operations: v1
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 :biggrin:). 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>
endm
Regards, HSE.
Yves
I expected the kind of matrice masm macro you use, when cpu don't support dotproduct
D3d matrices library
I search Macro to do it.My prefered method is to let it done by the c compiler (mixed langage c asm).
Perhap's smplmath is abble to do it but i need a demo.
After stay to write macro to do that.
Quote from: TouEnMasm on July 30, 2021, 05:27:02 PM
I search Macro to do it
Only macros in Mtx.inc
Quote from: TouEnMasm on July 30, 2021, 05:27:02 PM
Perhap's smplmath is abble to do it but i need a demo.
It's not SmplMath and, because macro expansion, only work with SmplMath in limited cases. Of course, is very interesting when can work together, how you can see in some Hydrograph lines.
Don't need SmplMath:
fild v2
fmul varD
fsub descargaunidad(v1ant, 0)
fld descargaunidad(v1, 0)
fsub descargaunidad(v1ant, 0)
fdiv
fld descargaunidad(v1, 1)
fsub descargaunidad(v1ant, 1)
fmul
fadd descargaunidad(v1ant, 1)
fstp tablero2(v2, 0)
In this case I'm using real8, but you can use any type or structure.
··············································································
If you have no mind for this advanced matrix :dazzled: (or you are using ML), you still can use the 20 years old method :thumbsup::
matrix macro p1 , p2 , p3, regaux, no1
mov eax , p3
imul p1
add eax , p2
ifb <no1>
ifnb <regaux>
mov ®aux , eax
else
mov ebx , eax
endif
endif
endm
.data
mat_ET1 dd 100 dup (0)
mat_ATL_max equ 3
mat_ATL real4 3*100 dup (0.0)
mat_UTL_max equ 4
mat_UTL real4 4*100 dup (0.0)
.code
···
fild mat_ET1[ecx*4]
matrix nn, 0, mat_ATL_max
fst real4 ptr mat_ATL[ebx*4]
fstp real4 ptr mat_UAT[ebx*4]
···
This is used in now corrected http://masm32.com/board/index.php?topic=9439.msg103363#new
Regards, HSE