/* GdiPlus Librarys for OxygenBasic by P. Wirbelauer 28.o6.2o12 */

'updated 15:18 02/05/2019 cp
'updated 11:27 19/04/2023 cp

uses corewin

indexbase 0

Type DEVMODE
   zstring dmDeviceName[32]    
   dmSpecVersion   as word    
   dmDriverVersion as word    
   dmSize          as word    
   dmDriverExtra   as word    
   dmFields        as long    
   dmOrientation   as word   
   dmPaperSize     as word   
   dmPaperLength   as word   
   dmPaperWidth    as word   
   dmScale         as word   
   dmCopies        as word   
   dmDefaultSource as word   
   dmPrintQuality  as word   
   dmColor         as word   
   dmDuplex        as word   
   dmYResolution   as word   
   dmTTOption      as word   
   dmCollate       as word   
   zstring dmFormName[32]    
   dmUnusedPadding as word   
   dmBitsPerPel    as long   
   dmPelsWidth     as long   
   dmPelsHeight    as long   
   dmDisplayFlags  as long   
   dmDisplayFrequency   as long  
   dmDisplayOrientation as long
End Type                     

Type RECTF
   x as Single
   y as Single
   w as Single
   h as Single
End Type

Type POINTF
   x as Single
   y as Single
End Type

Type GdiPlusStartupInput
   GdiPlusVersion           as Long
   DebugEventCallback       as Long
   SuppressBackgroundThread as Long
   SuppressExternalCodecs   as Long
End Type

% FontStyleRegular    = 0
% FontStyleBold       = 1
% FontStyleItalic     = 2
% FontStyleBoldItalic = 3
% FontStyleUnderline  = 4
% FontStyleStrikeout  = 8

% QualityModeInvalid = -1
% QualityModeDefault =  0
% QualityModeLow     =  1
% QualityModeHigh    =  2

% SmoothingModeInvalid       = QualityModeInvalid
% SmoothingModeDefault       = QualityModeDefault
% SmoothingModeHighSpeed     = QualityModeLow
% SmoothingModeHighQuality   = QualityModeHigh
% SmoothingModeNone          = QualityModeHigh + 1
% SmoothingModeAntiAlias8x4  = QualityModeHigh + 2
% SmoothingModeAntiAlias     = SmoothingModeAntiAlias8x4
% SmoothingModeAntiAlias8x8  = SmoothingModeAntiAlias8x4 + 1

% PixelOffsetModeInvalid     = QualityModeInvalid
% PixelOffsetModeDefault     = QualityModeDefault
% PixelOffsetModeHighSpeed   = QualityModeLow
% PixelOffsetModeHighQuality = QualityModeHigh
% PixelOffsetModeNone        = QualityModeHigh + 1
% PixelOffsetModeHalf        = QualityModeHigh + 2 

% BrushTypeSolidColor     = 0
% BrushTypeHatchFill      = 1
% BrushTypeTextureFill    = 2
% BrushTypePathGradient   = 3
% BrushTypeLinearGradient = 4 

% WarpModePerspective = 0
% WarpModeBilinear    = 1 
% WrapModeTile        = 0
% WrapModeTileFlipX   = 1
% WrapModeTileFlipY   = 2
% WrapModeTileFlipXY  = 3
% WrapModeClamp       = 4
% MatrixOrderPrepend  = 0
% MatrixOrderAppend   = 1 

% SW_SHOW        = 5
% CS_VREDRAW     = 1
% CS_HREDRAW     = 2
% IDI_WINLOGO    = 32517
% IDC_ARROW      = 32512
% WS_MINIMIZEBOX = 0x20000
% PM_REMOVE      = 1
% WHITE_BRUSH    = 0
% BLACK_BRUSH    = 4
% DM_PELSWIDTH   = 0x80000
% DM_PELSHEIGHT  = 0x100000
% DM_BITSPERPEL  = 0x40000
% DI_NORMAL      = 3 
% GENERIC_WRITE  = 0x40000000
% GENERIC_READ   = 0x80000000
% FILE_SHARE_READ  = 1
% FILE_SHARE_WRITE = 2
% OPEN_ALWAYS      = 4

Dim wm  as MSG
Dim wc  as WNDCLASS 
Dim rc  as RECT
Dim dvm as DEVMODE
Dim Reso(3) as sys 
Dim tRect as RECTF

sys FontHnd    [64]
sys ImageHnd   [512]
sys ImageWidth [512]
sys ImageHeight[512]
sys TileHnd    [512]
sys TileWidth  [512]
sys TileHeight [512]
sys MouseButton,xMouse,yMouse,wExit,seed,AscKey,sys_fjs,sys_Frames
sys hwnd,hdc,bHdc,sWidth,sHeight,hBitmap,GdipToken,GdipStartUp,pPen,pGraphics
Quad sys_ct1,sys_ct2,sys_freq,sys_qc1,sys_qc2,sys_qf                                                               
Double sys_interval               

extern lib "winmm.dll"
======================
! PlaySoundA

extern lib "gdiplus.dll"
========================
! GdiplusStartup
! GdiplusShutdown 
! GdipDrawLineI
! GdipDrawEllipseI
! GdipFillEllipseI
! GdipFillRectangleI
! GdipDrawRectangleI
! GdipFillPolygonI
! GdipDrawPolygonI
! GdipBitmapGetPixel
! GdipBitmapSetPixel
! GdipCreateFromHDC
! GdipDeleteGraphics
! GdipGraphicsClear
! GdipCreatePen1
! GdipDeletePen
! GdipDeleteBrush
! GdipCreateSolidFill
! GdipSetSmoothingMode
! GdipDisposeImage
! GdipLoadImageFromFile
! GdipDrawImageI
! GdipGetImageHeight
! GdipGetImageWidth
! GdipDrawImageRectI
! GdipImageRotateFlip
! GdipSetPixelOffsetMode
! GdipCreateTexture2I
! GdipCreateTexture
! GdipCreateFont
! GdipDeleteFont
! GdipDeleteFontFamily
! GdipDrawString
! GdipScaleTextureTransform
! GdipRotateTextureTransform
! GdipSetTextRenderingHint
! GdipCreateFontFamilyFromName
! GdipDrawImagePointRectI
! GdipGetImageGraphicsContext
! GdipCreateBitmapFromGraphics
end extern

Function HiWord (sys hi) as sys
shr hi,16
Return hi
End Function

Function LoWord (sys lo) as sys
and lo,0xFFFF 
Return lo
End Function

Function SetDisplay(sys width, height, bpp) as sys
sys i,dev 
Do
dev = EnumDisplaySettings 0,i,@dvm   
iF dev =0 Then Exit Do
i +=1
End Do
Reso(0) = dvm.dmPelsWidth
Reso(1) = dvm.dmPelsHeight  
Reso(2) = dvm.dmBitsPerPel
dvm.dmFields = DM_PELSWIDTH Or DM_PELSHEIGHT Or DM_BITSPERPEL
dvm.dmPelsWidth  = width
dvm.dmPelsHeight = height
dvm.dmBitsPerPel = bpp
ChangeDisplaySettings @dvm,4
Return eax
End Function

Sub RestoreDisplay()
dvm.dmPelsWidth  = Reso(0)
dvm.dmPelsHeight = Reso(1)
dvm.dmBitsPerPel = Reso(2)
ChangeDisplaySettings 0,0   
End Sub

Sub StartUp()
Dim GdipStartupInput as GdiPlusStartupInput
GdipStartupInput.GdiPlusVersion =1 
GdiPlusStartUp &GdipToken, &GdipStartupInput, ByVal 0
GdipCreateFromHDC Hdc, &pGraphics
GdipCreateBitmapFromGraphics sWidth, sHeight, pGraphics, &hBitmap 
GdipGetImageGraphicsContext hBitmap, &bHdc
End Sub

Sub Ends()
sys ix
iF Reso(0) >0 and Reso(1) >0 Then RestoreDisplay
For ix=1 To 512
iF ImageHnd[ix] >0  
   GdipDisposeImage ImageHnd[ix] 
End iF    
Next
For ix=1 To 512
iF TileHnd[ix] >0  
   GdipDisposeImage TileHnd[ix] 
End iF    
Next
For ix=0 to 32
iF FontHnd[ix] >0
   GdipDeleteFont FontHnd[ix]
End iF
Next
GdipDisposeImage hBitmap
GdipDeleteGraphics pGraphics 
GdiplusShutdown GdipToken 
ReleaseDC hwnd,hdc
End Sub 

Sub PlayWav(string snd)
    PlaysoundA snd,0,1
End Sub

Function LoadFont(wString FontName,single FontSize) as sys
    static sys id: iF id<32 Then id +=1
    sys FontFamily,pFont
    GdipCreateFontFamilyFromName StrPtr(FontName), 0, @FontFamily
    GdipCreateFont FontFamily, FontSize, FontStyleRegular, 2, @pFont
    GdipDeleteFontFamily FontFamily
    FontHnd[id] = pFont
    Return id
End Function

Sub Text(sys id, single x,y, wString txt,sys col)
    sys brush
    tRect.x=x:tRect.y=y:tRect.w=sWidth:tRect.h=sHeight
    GdipCreateSolidFill col, @brush
    GdipDrawString bHdc, StrPtr(txt), -1, FontHnd[id], @tRect, 0, brush
    GdipDeleteBrush brush
End Sub    

Function LoadImage(wString iName, sys fx) as sys
    sys image,width,height
    iF fx <=0 Then fx=1 
    static sys id: iF id <512 Then id +=1 
    GdipLoadImageFromFile StrPtr(iName), &image
    GdipGetImageWidth  image,@width
    GdipGetImageHeight image,@height
    ImageHnd   [id]= image
    ImageWidth [id]= width/fx
    ImageHeight[id]= height
    Return id
End Function

Sub ZoomImage(sys id,x,y,zx,zy)
    GdipDrawImageRectI bHdc,ImageHnd[id],x,y,zx,zy
End Sub

Sub DrawImage(sys id,x,y,fx)
    GdipDrawImagePointRectI bHdc,ImageHnd[id],x,y,ImageWidth[id]*fx,0,ImageWidth[id],ImageHeight[id],2
End Sub    

Function LoadTiles(wString iName, sys fx,fy) as sys
    sys image,width,height
    iF fx <=0 Then fx=1: iF fy <=0 Then fy=1  
    static sys id: iF id <512 Then id +=1 
    GdipLoadImageFromFile StrPtr(iName), &image
    GdipGetImageWidth  image,&width
    GdipGetImageHeight image,&height
    TileHnd   [id]= image
    TileWidth [id]= width /fx
    TileHeight[id]= height/fy
    Return id
End Function

Sub DrawTiles(sys id,x,y,fx,fy)
    GdipDrawImagePointRectI bHdc,TileHnd[id],x,y,TileWidth[id]*fx,TileHeight[id]*fy,TileWidth[id],TileHeight[id],2
End Sub    

Sub iText(sys id,tx,ty, string txt) 
sys sx, rx
For sx=1 To Len(txt)
rx = Asc(txt, sx)
iF rx >=32 and rx <=127 
   rx = rx -32
   DrawImage id,tx,ty,rx
   iF rx=0 Then
      tx = tx + 12
   Else
      tx = tx + ImageWidth[id]
   End iF
End iF
Next 
End Sub

Sub SetPixelMode(sys pMode)
    GdipSetPixelOffsetMode bHdc, pMode    '0-5
End Sub 

Sub SetSmoothMode(sys smoothing)
    GdipSetSmoothingMode bHdc,smoothing   '0-5
End Sub    

Function ARGB(sys a,r,g,b) as sys 
    Return r << 0x10 | g << 8 | b | a << 0x18 & 0xFFFFFFFF
End Function

Sub ClsColor(byte a,r,g,b)
    GdipGraphicsClear bHdc,ARGB(a,r,g,b)
End Sub    

Sub Oval(sys x,y,ra,rb,single thick,sys col)
    sys pen
    GdipCreatePen1 col,thick, 2, &Pen
    GdipDrawEllipseI bHdc,pen,x,y,ra,rb
    GdipDeletePen Pen
End Sub

Sub FillOval(sys x,y,ra,rb,col)
    sys brush
    GdipCreateSolidFill col,@brush
    GdipFillEllipseI bHdc,brush,x,y,ra,rb
    GdipDeleteBrush brush
End Sub

Sub Box(sys x,y,w,h,single thick,sys col)
    sys pen
    GdipCreatePen1 col,thick, 2, &Pen
    GdipDrawRectangleI bHdc,pen,x,y,w,h
    GdipDeletePen Pen
End Sub    

Sub FillBox(sys x,y,w,h,col)
    sys brush
    GdipCreateSolidFill col,&brush
    GdipFillRectangleI bHdc,brush,x,y,w,h
    GdipDeleteBrush brush
End Sub    

Sub Poly(int *poly,n,single thick,int col)
    sys pen
    GdipCreatePen1 col,thick, 2, &Pen
    GdipDrawPolygonI bHdc,Pen,&poly,n
    GdipDeletePen Pen
End Sub    

Sub FillPoly(int *poly,n,col)
    sys brush
    'SetDCBrushColor bhdc,col
    GdipCreateSolidFill col,&brush
    GdipFillPolygonI bHdc,brush,&poly,n,0
    GdipDeleteBrush brush
End Sub    

Sub Line(sys x1,y1,x2,y2,single thick,sys col)
    sys pen
    GdipCreatePen1 col,thick, 2, &Pen
    GdipDrawLineI bHdc,pen,x1,y1,x2,y2
    GdipDeletePen Pen
End Sub         

Function GetImagePixel(sys id,x,y) as sys
    sys col
    GdipBitmapGetPixel ImageHnd[id],x,y,@col
    Return col    
End Function

Sub SetImagePixel(sys id,x,y,col)
    GdipBitmapSetPixel ImageHnd[id],x,y,col
End Sub    

Function GetColorA(sys kol) as byte
    Return (kol >> 24) & 0xFF
End Function

Function GetColorR(sys kol) as byte
    Return (kol >> 16) & 0xFF
End Function

Function GetColorG(sys kol) as byte
    Return (kol >> 8) & 0xFF
End Function

Function GetColorB(sys kol) as byte
    Return kol & 0xFF
End Function

Sub Events()
sys vRes
vRes = PeekMessage &wm,0,0,0,Pm_Remove 
iF vRes >0
   iF wm.message = Wm_Quit Then wExit=1
   TranslateMessage &wm
   DispatchMessage  &wm
End iF
End Sub

Sub Flip()
    Events
    call GdipDrawImagePointRectI pGraphics,hBitmap,0,0,0,0,sWidth,sHeight,2
End Sub

Sub SetCaption(string txt)
    SetWindowText hwnd,txt
End Sub    

Sub ShowMouse(sys mouse)   
    ShowCursor mouse
End Sub                

Function Key(sys cKey) As short
    iF wExit=1 Then Return 1
    Return GetAsyncKeyState cKey 
End Function

Sub WaitKey(sys iKey)
    sys xKey
    While xKey=0  
    iF wExit=1 Then Return 1
    xKey = GetAsyncKeyState iKey
    Flip
    Sleep 10
    Wend
End Sub

Sub WaitMouse()
    While (1)
    iF MouseButton >=1 and MouseButton <=4
       Return MouseButton
    End iF
    iF wExit=1 Then Return 1
    Flip
    Sleep 10
    Wend
End Sub

#ifndef CustomWndProc
'
Function WndProc(byval hWnd as sys,byval wMsg as sys, byval wParam as sys,byval lparam as sys) as sys callback
select wMsg
'case WM_CREATE
  '
case WM_MOVE 
  Flip
  ValidateRect hwnd,0
case WM_MOUSEMOVE
  xMouse = LoWord(lParam)
  yMouse = HiWord(lParam)
  InValidateRect hwnd,0,0
case WM_LBUTTONDOWN
  MouseButton =1
  InvalidateRect hWnd,0,0 
case WM_LBUTTONUP
  MouseButton =0  
  InvalidateRect hWnd,0,0 
case WM_RBUTTONDOWN
  MouseButton =2
  InvalidateRect hWnd,0,0 
case WM_RBUTTONUP
  MouseButton =0
  InvalidateRect hWnd,0,0
case WM_MBUTTONDOWN
  MouseButton =4
  InvalidateRect hWnd,0,0 
case WM_MBUTTONUP
  MouseButton =0
  InvalidateRect hWnd,0,0
case WM_CHAR
  AscKey = wParam
  InvalidateRect hWnd,0,0
case WM_KEYUP
  AscKey =0
  InvalidateRect hWnd,0,0
case WM_DESTROY
  PostQuitMessage 0
case Else
  Return DefWindowProc hWnd,wMsg,wParam,lParam
End select
End Function'
#endif

Function Screen(sys width, height, s) as sys
sys hInst, mode, w, h
/*
iF s =1 then s = 0xCF0000
iF s =2 then s = 0x80000 
iF s =3 then s = 0x80000000
iF s =4 then s = 0x400000
*/
iF s>=1 Then s= WS_OVERLAPPED | WS_MINIMIZEBOX
iF s<=0 
   mode = SetDisplay(width,height,32)
   iF mode =-2  
      s= WS_OVERLAPPED | WS_MINIMIZEBOX 
   Else   
      s= WS_POPUP
   End iF
End iF
'
hInst = GetModuleHandle 0
wc.style = CS_HREDRAW or CS_VREDRAW   
wc.lpfnWndProc = &WndProc
wc.cbClsExtra =0
wc.cbWndExtra =0
wc.hInstance  = hInst
wc.hIcon  = LoadIcon 0,IDI_WINLOGO            
wc.hCursor= LoadCursor 0,IDC_ARROW       
wc.hbrBackground = GetStockObject WHITE_BRUSH 
wc.lpszMenuName  = 0
wc.lpszClassName = StrPtr "window"
RegisterClass &wc
hwnd = CreateWindowEx 0,wc.lpszClassName,"",s,CW_USEDEFAULT,CW_USEDEFAULT,width,height,0,0,hInst,0
ShowWindow hwnd, SW_SHOW
hdc = GetDC hwnd
GetClientRect hwnd,&rc   
w = width - rc.right
h = height- rc.bottom
GetWindowRect hwnd,&rc
MoveWindow hwnd,rc.left,rc.top,width+w,height+h,1
sWidth = width
sHeight= height
QueryPerformanceFrequency @sys_qf   
QueryPerformanceCounter   @sys_qc1
seed = GetTickCount
StartUp
Return hwnd
End Function

Sub SetFps(sys frame)    
QueryPerformanceFrequency @sys_freq                                                                                          
sys_Interval = sys_freq/frame  
While (1)                                                                       
  QueryPerformanceCounter @sys_ct2                                                 
  iF sys_ct2 >= sys_ct1 + sys_interval                                             
    QueryPerformanceCounter @sys_ct1                                              
    Exit Sub            
  End iF
  sleep 1
Wend                                                                             
End Sub

Function ShowFps() as sys 
QueryPerformanceCounter @sys_qc2
iF sys_qc2 - sys_qc1 > sys_qf             
sys_fjs = sys_Frames
sys_Frames =0
sys_qc1 += sys_qf                         
End iF
sys_Frames +=1
Return sys_fjs
End Function

Sub Randomize()
    seed = GetTickCount
End Sub

Function Rand(sys z1,z2) as sys
sys  rnd 
mov  eax,z2
sub  eax,z1
inc  eax
imul edx,seed,0x8088405
inc  edx
mov  seed,edx
mul  edx
add  edx,z1
mov  rnd,edx
Return rnd
End Function 

sub translate(int *p,*q,n,ox,oy)
int i,j,k
for i=0 to n-1
   j=i+i
   k=j+1
   q[j]=p[j]+ox
   q[k]=p[k]+oy
next
end sub

sub scale(int *p,*q,n,float sx,sy,ox=0,oy=0)
int i,j,k
for i=0 to n-1
   j=i+i
   k=j+1
   q[j]=sx*p[j]+ox
   q[k]=sy*p[k]+oy
next
end sub

sub rotate(int *p,*q,n,float ang,ox=0,oy=0)
int i,j,k
float ra,qa
for i=0 to n-1
   j=i+i
   k=j+1
   q[j]=p[j]
   q[k]=p[k]
   ra=hypot(q[j],q[k])
   qa=ang+atan(q[k],q[j])
   q[j]=ra*cos(qa)+ox
   q[k]=ra*sin(qa)+oy
next
end sub

sub transform(int *p,*q,n,float ang=0.0,sx=1.0,sy=1.0,ox=0.0,oy=0.0)
'ang xy rotation degrees
'sx,sy  scale
'ox,oy  translation
'
'order: scale then rotate then translate
int i,j,k
float an,ra,qa
an=rad(ang)
for i=0 to n-1
  j=i+i
  k=j+1
  q[j]=p[j]*sx
  q[k]=p[k]*sy
  if ang
    ra=hypot(q[j],q[k])
    qa=an+atan(q[k],q[j])
    q[j]=ra*cos(qa)
    q[k]=ra*sin(qa)
  endif
  q[j]+=ox
  q[k]+=oy
next
end sub

macro polypoints(p,q,n,r,x,y)
redim int p(n*2)
redim int q(n*2)
scope
#ifndef r
  def r 10
#endif
#ifndef x
  def x 0
#endif
#ifndef y
  def y 0
#endif
float a=pi()*2/n
int i,j,k
for i=0 to n-1
  j=i+i
  k=j+1
  p[j]=r*cos(i*a)+x
  p[k]=r*sin(i*a)+y
next
end scope
end macro

==============
class points2D
==============
int *p
int *q
int n
'
function poly(int nn,r=10,x=0,y=0)
n=nn
int m=nn*2*sizeof p
if @p
  freememory @p
  freememory @q
endif
@p=getmemory m
@q=getmemory m
float a=pi()*2/n
int i,j,k
for i=0 to n-1
  j=i+i
  k=j+1
  p[j]=r*cos(i*a)+x
  p[k]=r*sin(i*a)+y
next
end function
'
function clear
  if @p
    freememory @p
    freememory @q
  endif
  @p=0
  @q=0
  n=0
end function
'
function constructor
end function
'
function destructor
clear
end function
'
end class
'#recordof points2d

=============
class polygon
=============
has points2d
'
function ring(int nn=0,r1=10,r2=0,x=0,y=0)
n=nn
int m=nn*8*sizeof p
freememory @p : @p=getmemory m
freememory @q : @q=getmemory m
float a=pi()*2/n
int i,j,k,b
'series of 4 sided polys
for i=0 to n-1
  b=i+1
  j=i*8
  k=j+1
  p[j]=r1*cos(i*a)+x
  p[k]=r1*sin(i*a)+y
  j+=2 : k+=2
  p[j]=r1*cos(b*a)+x
  p[k]=r1*sin(b*a)+y
  j+=2 : k+=2
  p[j]=r2*cos(b*a)
  p[k]=r2*sin(b*a)
  j+=2 : k+=2
  p[j]=r2*cos(i*a)
  p[k]=r2*sin(i*a)
next
end function
'
function constructor(int n=0,r=0,x=0,y=0)
  poly n,r,x,y
end function
'
end class


==================
class transforms2D
==================
float mat[0x400]
float mtt[9]
float mtu[9]
int mi
'
function pushmatrix
int i,j
j=mi+9
if j>=0x400
  exit function
endif
for i=mi to mi+8
  mat[j]=mat[i]
  j++
next
mi+=9
end function
'
function popmatrix
int i,j
j=mi-9
if j<0
  exit function
endif
mi=j
end function
'
'
'x  0  3  6
'y  1  4  7
'.  2  5  8
'
function mulm(float *r,*m1,*m2)
r[0]  =  m1[0] * m2[0]  +  m1[3] * m2[1]  +  m1[6] * m2[2]
r[1]  =  m1[1] * m2[0]  +  m1[4] * m2[1]  +  m1[7] * m2[2]
r[2]  =  m1[2] * m2[0]  +  m1[5] * m2[1]  +  m1[8] * m2[2]
r[3]  =  m1[0] * m2[3]  +  m1[3] * m2[4]  +  m1[6] * m2[5]
r[4]  =  m1[1] * m2[3]  +  m1[4] * m2[4]  +  m1[7] * m2[5]
r[5]  =  m1[2] * m2[3]  +  m1[5] * m2[4]  +  m1[8] * m2[5]
r[6]  =  m1[0] * m2[6]  +  m1[3] * m2[7]  +  m1[6] * m2[8]
r[7]  =  m1[1] * m2[6]  +  m1[4] * m2[7]  +  m1[7] * m2[8]
r[8]  =  m1[2] * m2[6]  +  m1[5] * m2[7]  +  m1[8] * m2[8]
end function
'
function copym(float *r,*s, int n=1)
copy @r,@s,n*36
end function
'
function clearmtt
float n,u
u=1.0
mtt={u,n,n,n,u,n,n,n,u}
end function
'
function mulmatrix(float *m)
mulm mtu,mat[mi],m
copym mat[mi],mtu
end function
'
function loadmatrix(float *m)
copym mat[mi],m
end function
'
function newmatrix
clearmtt
loadmatrix mtt
end function
'
function translate(float x,y)
clearmtt
mtt[6]=x
mtt[7]=y
mulm mtu,mat[mi],mtt
copym mat[mi],mtu
end function
'
function scale(float x,y)
clearmtt
mtt[0]=x
mtt[4]=y
mulm mtu,mat[mi],mtt
copym mat[mi],mtu
end function
'
function rotate(float a)
'
' cos -sin  0.0
' sin  cos  0.0
' 0.0  0.0  1.0
'
float b=rad(a)
clearmtt
mtt[0]=cos(b)
mtt[4]=mtt[0]
mtt[1]=sin(b)
mtt[3]=-mtt[1]
mulm mtu,mat[mi],mtt
copym mat[mi],mtu
end function
'
function transform(int *v,*r, sys n=1)
'using vec2 and mat3x3
int i
float m at @mat[mi]
for i=1 to n
  r[0]  = m[0] * v[0]  +  m[3] * v[1]  +  m[6]
  r[1]  = m[1] * v[0]  +  m[4] * v[1]  +  m[7]
  @v+=8
  @r+=8
next
end function
'
function constructor
end function
'
function destructor
end function
'
end class
