Memory coping with assembler.

New to FreeBASIC? Post your questions here.
podvornyak
Posts: 148
Joined: Nov 12, 2007 11:46
Location: Russia

Memory coping with assembler.

Postby podvornyak » Jun 14, 2013 9:34

Stoled this code here. My Assembler skills is below ZERO point. What is wrong and is this code safe?

Code: Select all

sub frame_copy (source as uinteger, target as uinteger, size as uinteger)
    screenlock
    asm
        MOV     ESI,[source]
        MOV     EDI,[target]
        MOV     ECX,[size]
        CLD
        REP     MOVSD
    end asm
    screenunlock
end sub

dim as single ptr a = new single[16], b = new single[16]
for i as integer = 0 to 15: a[i]=rnd*2-1: next i

frame_copy(a, b, 16) '!?

for i as integer = 0 to 15: print @a[i];" = ";a[i];" ";@b[i];" = ";b[i]: next i

УМВР. ЧЯДНТ?
D.J.Peters
Posts: 8038
Joined: May 28, 2005 3:28
Contact:

Re: Memory coping with assembler.

Postby D.J.Peters » Jun 14, 2013 18:16

copy target,source,nbytes

Code: Select all

sub frame_copy (pTarget as any ptr ,pSource as any ptr, nBytes as uinteger)
  asm
  MOV     EDI,[pTarget]
  MOV     ESI,[pSource]
  MOV     ECX,[nBytes]
  shr     ecx,2 ' bytes to DWORDS'
  CLD
  REP     MOVSD
  end asm
end sub

dim as single ptr a = new single[16], b = new single[16]
for i as integer = 0 to 15:
  a[i]=rnd*2-1:
next

frame_copy(b, a, 16*sizeof(single)) '!?

for i as integer = 0 to 15
  print "a 0x" & hex(@a[i],8) & " = " & a[i] & " b 0x" & hex(@b[i],8) & " = " & b[i]
next
sleep
podvornyak
Posts: 148
Joined: Nov 12, 2007 11:46
Location: Russia

Re: Memory coping with assembler.

Postby podvornyak » Jun 14, 2013 20:30

D.J.Peters wrote:

Code: Select all

  shr     ecx,2 ' bytes to DWORDS'
Great! Thank you a lot.
MichaelW
Posts: 3500
Joined: May 16, 2006 22:34
Location: USA

Re: Memory coping with assembler.

Postby MichaelW » Jun 14, 2013 21:07

REP MOVSD is generally fast, but for moving a small number of DWORDs moving them individually is faster. The definition of “small” depends on the processor, for example on my P3 processor REP MOVSD is faster for DWORD counts > ~4, but on my P4 processor REP MOVSD is faster for DWORD counts > ~32.

Running under Windows CLD is very slow on some processors, and it is not normally necessary because the direction flag is normally cleared.

Code: Select all

''=============================================================================
#include "counter.bas"
''=============================================================================
'' Counter.bas is available here:
''
''  http://www.freebasic.net/forum/viewtopic.php?f=7&t=20003
''
''=============================================================================

dim as DWORD_PTR processAffinityMask, systemAffinityMask
dim as integer processPriority, threadPriority
dim as any ptr p1, p2

p1 = allocate(1000000)
p2 = allocate(1000000)

GetProcessAffinityMask( GetCurrentProcess(), _
                        @processAffinityMask, _
                        @systemAffinityMask )

''------------------------------------------------------------
'' Select maximum priority levels for multicore systems only.
''------------------------------------------------------------

if systemAffinityMask > 1 then
    processPriority = REALTIME_PRIORITY_CLASS
    threadPriority = THREAD_PRIORITY_TIME_CRITICAL
else
    processPriority = HIGH_PRIORITY_CLASS
    threadPriority = THREAD_PRIORITY_NORMAL
end if

''------------------------------------
'' Restrict process to a single core.
''------------------------------------

SetProcessAffinityMask( GetCurrentProcess(), 1)

sleep 10000

#define DWORD_COUNT 16

for i as integer = 1 to 3

    counter_begin( 1000000, processPriority, threadPriority )
        asm
            mov esi, [p1]
            mov edi, [p2]
            mov ecx, DWORD_COUNT-1
          0:
            mov eax, [esi+ecx*4]
            mov [edi+ecx*4], eax
            sub ecx, 1
            jns 0b
        end asm
    counter_end()
    print counter_cycles;" cycles"

    counter_begin( 1000000, processPriority, threadPriority )
        asm
            mov esi, [p1]
            mov edi, [p2]
            mov ecx, DWORD_COUNT
            rep movsd
        end asm
    counter_end()
    print counter_cycles;" cycles"

    counter_begin( 1000000, processPriority, threadPriority )
        asm
            mov esi, [p1]
            mov edi, [p2]
            mov ecx, DWORD_COUNT
            cld
            rep movsd
        end asm
    counter_end()
    print counter_cycles;" cycles"
    print

next

deallocate(p1)
deallocate(p2)

sleep

Running on my P3:

Code: Select all

 53 cycles
 38 cycles
 48 cycles

 53 cycles
 38 cycles
 48 cycles

 54 cycles
 38 cycles
 48 cycles

Running on my P4 (Northwood):

Code: Select all

 75 cycles
 103 cycles
 112 cycles

 74 cycles
 97 cycles
 112 cycles

 68 cycles
 100 cycles
 112 cycles
podvornyak
Posts: 148
Joined: Nov 12, 2007 11:46
Location: Russia

Re: Memory coping with assembler.

Postby podvornyak » Feb 13, 2017 11:07

MichaelW wrote:...
Hey Man. I'm back. Can you help me once more? I just need point to direct mouse events... probably assembler approach. I got big delay with getmouse function. Maby i'v just coded it wrong... Anyway - i'm looking for advice. No more. Here is my long started project code. OBJ file is require.

Code: Select all

'                     
'    nblJIG 2017     
'               
'               
'    Вектора     
'               
'               

'               
'  определения   
'               

' vec2 
type CLASS_VECTOR2
   as single ptr data

   declare constructor
   declare constructor(as single, as single)
   declare constructor(byref as CLASS_VECTOR2)
   declare destructor
   declare operator let(byref as CLASS_VECTOR2)
end type
   constructor CLASS_VECTOR2
      this.data = new single[2]
      this.data[1] = 1
   end constructor
   constructor CLASS_VECTOR2(a as single, b as single)
      this.data = new single[2]
      this.data[0] = a
      this.data[1] = b
   end constructor
   constructor CLASS_VECTOR2(byref _rhs as CLASS_VECTOR2)
      this.data = new single[2]
      this = _rhs
   end constructor
   destructor CLASS_VECTOR2
      delete this.data
   end destructor
   operator CLASS_VECTOR2.let(byref _rhs as CLASS_VECTOR2)
      this.data[0] = _rhs.data[0]
      this.data[1] = _rhs.data[1]
   end operator

' vec3 
type CLASS_VECTOR3
   as single ptr data

   declare constructor
   declare constructor(as single, as single, as single)
   declare constructor(byref as CLASS_VECTOR2, as single)
   declare constructor(as single, byref as CLASS_VECTOR2)
   declare constructor(byref as CLASS_VECTOR3)
   declare destructor
   declare operator let(byref as CLASS_VECTOR3)
end type
   constructor CLASS_VECTOR3
      this.data = new single[3]
      this.data[2] = 1
   end constructor
   constructor CLASS_VECTOR3(_a as single, _b as single, _c as single)
      this.data = new single[3]
      this.data[0] = _a
      this.data[1] = _b
      this.data[2] = _c
   end constructor
   constructor CLASS_VECTOR3(byref _a as CLASS_VECTOR2, _b as single)
      this.data = new single[3]
      this.data[0] = _a.data[0]
      this.data[1] = _a.data[1]
      this.data[2] = _b
   end constructor
   constructor CLASS_VECTOR3(_a as single, byref _b as CLASS_VECTOR2)
      this.data = new single[3]
      this.data[0] = _a
      this.data[1] = _b.data[0]
      this.data[2] = _b.data[1]
   end constructor
   constructor CLASS_VECTOR3(byref _rhs as CLASS_VECTOR3)
      this.data = new single[3]
      this = _rhs
   end constructor
   destructor CLASS_VECTOR3
      delete this.data
   end destructor
   operator CLASS_VECTOR3.let(byref _rhs as CLASS_VECTOR3)
      this.data[0] = _rhs.data[0]
      this.data[1] = _rhs.data[1]
      this.data[2] = _rhs.data[2]
   end operator

' vec4 
type CLASS_VECTOR4
   as single ptr data

   declare constructor
   declare constructor(as single, as single, as single, as single)
   declare constructor(byref as CLASS_VECTOR2, as single, as single)
   declare constructor(as single, byref as CLASS_VECTOR2, as single)
   declare constructor(as single, as single, byref as CLASS_VECTOR2)
   declare constructor(byref as CLASS_VECTOR2, byref as CLASS_VECTOR2)
   declare constructor(byref as CLASS_VECTOR3, as single)
   declare constructor(as single, byref as CLASS_VECTOR3)

   declare constructor(byref as CLASS_VECTOR4)
   declare destructor
   declare operator let(byref as CLASS_VECTOR4)
end type
   constructor CLASS_VECTOR4
      this.data = allocate(16) '4 * size of single
      this.data[3]=1
   end constructor
   constructor CLASS_VECTOR4(_a as single, _b as single, _c as single, _d as single)
      this.data = allocate(16)
      this.data[0] = _a
      this.data[1] = _b
      this.data[2] = _c
      this.data[3] = _d
   end constructor
   constructor CLASS_VECTOR4(byref _a as CLASS_VECTOR2, _b as single, _c as single)
      this.data = new single[4]
      this.data[0] = _a.data[0]
      this.data[1] = _a.data[1]
      this.data[2] = _b
      this.data[3] = _c
   end constructor
   constructor CLASS_VECTOR4(_a as single, byref _b as CLASS_VECTOR2, _c as single)
      this.data = new single[4]
      this.data[0] = _a
      this.data[1] = _b.data[0]
      this.data[2] = _b.data[1]
      this.data[3] = _c
   end constructor
   constructor CLASS_VECTOR4(_a as single, _b as single, byref _c as CLASS_VECTOR2)
      this.data = new single[4]
      this.data[0] = _a
      this.data[1] = _b
      this.data[2] = _c.data[0]
      this.data[3] = _c.data[1]
   end constructor
   constructor CLASS_VECTOR4(byref _a as CLASS_VECTOR2, byref _b as CLASS_VECTOR2)
      this.data = new single[4]
      this.data[0] = _a.data[0]
      this.data[1] = _a.data[1]
      this.data[2] = _b.data[0]
      this.data[3] = _b.data[1]
   end constructor
   constructor CLASS_VECTOR4(byref _a as CLASS_VECTOR3, _b as single)
      this.data = new single[4]
      this.data[0] = _a.data[0]
      this.data[1] = _a.data[1]
      this.data[2] = _a.data[2]
      this.data[3] = _b
   end constructor
   constructor CLASS_VECTOR4(_a as single, byref _b as CLASS_VECTOR3)
      this.data = new single[4]
      this.data[0] = _a
      this.data[1] = _b.data[0]
      this.data[2] = _b.data[1]
      this.data[3] = _b.data[2]
   end constructor
   constructor CLASS_VECTOR4(byref _a as CLASS_VECTOR4)
      this.data = new single[4]
      this = _a
   end constructor
   destructor CLASS_VECTOR4
      delete this.data
   end destructor
   operator CLASS_VECTOR4.let(byref _rhs as CLASS_VECTOR4)
      this.data[0] = _rhs.data[0]
      this.data[1] = _rhs.data[1]
      this.data[2] = _rhs.data[2]
      this.data[3] = _rhs.data[3]
   end operator

'           
'  функции   
'           

' скалярное произведение 
' vec2 
operator * overload(byref _lhs as CLASS_VECTOR2, _rhs as single) as CLASS_VECTOR2
   dim as CLASS_VECTOR2 result
   result.data[0] = _lhs.data[0] * _rhs
   result.data[1] = _lhs.data[1] * _rhs
   operator = result
end operator
' vec3 
operator * overload(byref _lhs as CLASS_VECTOR3, _rhs as single) as CLASS_VECTOR3
   dim as CLASS_VECTOR3 result
   result.data[0] = _lhs.data[0] * _rhs
   result.data[1] = _lhs.data[1] * _rhs
   result.data[2] = _lhs.data[2] * _rhs
   operator = result
end operator
' vec4 
operator * overload(byref _lhs as CLASS_VECTOR4, _rhs as single) as CLASS_VECTOR4
   dim as CLASS_VECTOR4 result
   result.data[0] = _lhs.data[0] * _rhs
   result.data[1] = _lhs.data[1] * _rhs
   result.data[2] = _lhs.data[2] * _rhs
'   result.data[3] = _lhs.data[3] * _rhs
   operator = result
end operator

'  сложение и вычитание векторов 
' vec2 
operator + overload(byref _lhs as CLASS_VECTOR2, byref _rhs as CLASS_VECTOR2) as CLASS_VECTOR2
   dim as CLASS_VECTOR2 result
   result.data[0] = _lhs.data[0] + _rhs.data[0]
   result.data[1] = _lhs.data[1] + _rhs.data[1]
   operator = result
end operator
operator - overload(byref _lhs as CLASS_VECTOR2, byref _rhs as CLASS_VECTOR2) as CLASS_VECTOR2
   dim as CLASS_VECTOR2 result
   result.data[0] = _lhs.data[0] - _rhs.data[0]
   result.data[1] = _lhs.data[1] - _rhs.data[1]
   operator = result
end operator
' vec3 
operator + overload(byref _lhs as CLASS_VECTOR3, byref _rhs as CLASS_VECTOR3) as CLASS_VECTOR3
   dim as CLASS_VECTOR3 result
   result.data[0] = _lhs.data[0] + _rhs.data[0]
   result.data[1] = _lhs.data[1] + _rhs.data[1]
   result.data[2] = _lhs.data[2] + _rhs.data[2]
   operator = result
end operator
operator - overload(byref _lhs as CLASS_VECTOR3, byref _rhs as CLASS_VECTOR3) as CLASS_VECTOR3
   dim as CLASS_VECTOR3 result
   result.data[0] = _lhs.data[0] - _rhs.data[0]
   result.data[1] = _lhs.data[1] - _rhs.data[1]
   result.data[2] = _lhs.data[2] - _rhs.data[2]
   operator = result
end operator
' vec4 
operator + overload(byref _lhs as CLASS_VECTOR4, byref _rhs as CLASS_VECTOR4) as CLASS_VECTOR4
   dim as CLASS_VECTOR4 result
   result.data[0] = _lhs.data[0] + _rhs.data[0]
   result.data[1] = _lhs.data[1] + _rhs.data[1]
   result.data[2] = _lhs.data[2] + _rhs.data[2]
'   result.data[3] = _lhs.data[3] + _rhs.data[3]
   operator = result
end operator
operator - overload(byref _lhs as CLASS_VECTOR4, byref _rhs as CLASS_VECTOR4) as CLASS_VECTOR4
   dim as CLASS_VECTOR4 result
   result.data[0] = _lhs.data[0] - _rhs.data[0]
   result.data[1] = _lhs.data[1] - _rhs.data[1]
   result.data[2] = _lhs.data[2] - _rhs.data[2]
'   result.data[3] = _lhs.data[3] - _rhs.data[3]
   operator = result
end operator

' dot произведение
' vec2 
function dot overload(byref _a as CLASS_VECTOR2, byref _b as CLASS_VECTOR2) as single
   return _a.data[0] * _b.data[0] + _a.data[1] * _b.data[1]
end function
' vec3 
function dot overload(byref _a as CLASS_VECTOR3, byref  _b as CLASS_VECTOR3) as single
   return _a.data[0] * _b.data[0] + _a.data[1] * _b.data[1] + _a.data[2] * _b.data[2]
end function
' vec4 
function dot overload(byref _a as CLASS_VECTOR4, byref _b as CLASS_VECTOR4) as single
   return _a.data[0] * _b.data[0] + _a.data[1] * _b.data[1] + _a.data[2] * _b.data[2] ' + _a->data[3] * _b->data[3]
end function

'  длина вектора 
' vec2 
function veclen overload(byref _a as CLASS_VECTOR2) as single
   return sqr(_a.data[0] * _a.data[0] + _a.data[1] * _a.data[1])
end function
' vec3 
function veclen overload(byref _a as CLASS_VECTOR3) as single
   return sqr(_a.data[0] * _a.data[0] + _a.data[1] * _a.data[1] + _a.data[2] * _a.data[2])
end function
' vec4 
function veclen overload(byref _a as CLASS_VECTOR4) as single
   return sqr(_a.data[0] * _a.data[0] + _a.data[1] * _a.data[1] + _a.data[2] * _a.data[2]) '_a.data[3] * _a.data[3]
end function

'   нормализация вектора   
' vec2 
function normalize overload(byref _a as CLASS_VECTOR2) as CLASS_VECTOR2
   dim as CLASS_VECTOR2 result
   dim as single temp = veclen(_a)
   result.data[0]=_a.data[0] / temp
   result.data[1]=_a.data[1] / temp
   function = result
end function
' vec3 
function normalize overload(byref _a as CLASS_VECTOR3) as CLASS_VECTOR3
   dim as CLASS_VECTOR3 result
   dim as single temp = veclen(_a)
   result.data[0]=_a.data[0] / temp
   result.data[1]=_a.data[1] / temp
   result.data[2]=_a.data[2] / temp
   function = result
end function
' vec4 
function normalize overload(byref _a as CLASS_VECTOR4) as CLASS_VECTOR4
   dim as CLASS_VECTOR4 result
   dim as single temp = veclen(_a)
   result.data[0]=_a.data[0] / temp
   result.data[1]=_a.data[1] / temp
   result.data[2]=_a.data[2] / temp
'   result.data[3]=_a.data[3] / temp
   function = result
end function

'  векторное произведение   
' vec3 
function cross overload(byref _a as CLASS_VECTOR3, byref _b as CLASS_VECTOR3) as CLASS_VECTOR3
    dim as CLASS_VECTOR3 result
    result.data[0] = _a.data[1] * _b.data[2] - _a.data[2] * _b.data[1]
    result.data[1] = _a.data[2] * _b.data[0] - _a.data[0] * _b.data[2]
    result.data[2] = _a.data[0] * _b.data[1] - _a.data[1] * _b.data[0]
    return result
end function
' vec4 
function cross overload(byref _a as CLASS_VECTOR4, byref _b as CLASS_VECTOR4) as CLASS_VECTOR4
    dim as CLASS_VECTOR4 result
    result.data[0] = _a.data[1] * _b.data[2] - _a.data[2] * _b.data[1]
    result.data[1] = _a.data[2] * _b.data[0] - _a.data[0] * _b.data[2]
    result.data[2] = _a.data[0] * _b.data[1] - _a.data[1] * _b.data[0]
'    result.data[3] =
    return result
end function

'   нормаль треугольника   
function get_face_normal(byref _a as CLASS_VECTOR3, byref _b as CLASS_VECTOR3, byref _c as CLASS_VECTOR3) as CLASS_VECTOR3
    dim as CLASS_VECTOR3 edge1 = _b - _a
    dim as CLASS_VECTOR3 edge2 = _c - _a
    dim as CLASS_VECTOR3 result = cross(edge1,edge2)
    return result
end function

'                 
'                 
'     Матрицы     
'                 
'                 

'                 
'   определения   
'                 

' mat2           

type CLASS_MATRIX2X2
   as single ptr data

   declare operator let(byref as CLASS_MATRIX2X2)
   declare constructor
   declare constructor(byref as CLASS_MATRIX2X2)
   declare destructor
end type
operator CLASS_MATRIX2X2.let (byref _rhs as CLASS_MATRIX2X2)
   this.data[0] = _rhs.data[0]: this.data[1] = _rhs.data[1]
   this.data[2] = _rhs.data[2]: this.data[3] = _rhs.data[3]
end operator
constructor CLASS_MATRIX2X2
   this.data = new single[4]
   this.data[0] = 1:  this.data[1] = 0
   this.data[2] = 0:  this.data[3] = 1
end constructor
constructor CLASS_MATRIX2X2(_rhs as CLASS_MATRIX2X2)
   this.data = new single[4]
   this = _rhs ''!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end constructor
destructor CLASS_MATRIX2X2
   delete this.data
end destructor

' mat3           

type CLASS_MATRIX3X3
   as single ptr data

   declare operator let(byref as CLASS_MATRIX3X3)
   declare constructor
   declare constructor(byref as CLASS_MATRIX3X3)
   declare destructor
end type
operator CLASS_MATRIX3X3.let (byref _rhs as CLASS_MATRIX3X3)
   this.data[0] = _rhs.data[0]: this.data[1] = _rhs.data[1]: this.data[2] = _rhs.data[2]
   this.data[3] = _rhs.data[3]: this.data[4] = _rhs.data[4]: this.data[5] = _rhs.data[5]
   this.data[6] = _rhs.data[6]: this.data[7] = _rhs.data[7]: this.data[8] = _rhs.data[8]
end operator
constructor CLASS_MATRIX3X3
   this.data= new single[9]
   this.data[0]=1:  this.data[1]=0:  this.data[2]=0
   this.data[3]=0:  this.data[4]=1:  this.data[5]=0
   this.data[6]=0:  this.data[7]=0:  this.data[8]=1
end constructor
constructor CLASS_MATRIX3X3(byref _rhs as CLASS_MATRIX3X3)
   this.data=new single[9]
   this = _rhs ''!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end constructor
destructor CLASS_MATRIX3X3
   delete this.data
end destructor


' mat4 
type CLASS_MATRIX4X4
   as single ptr data

   declare operator let(byref as CLASS_MATRIX4X4)
   declare constructor
   declare constructor(byref as CLASS_MATRIX4X4)
   declare destructor
end type
operator CLASS_MATRIX4X4.let (byref _rhs as CLASS_MATRIX4X4)
   this.data[0]  = _rhs.data[0]: this.data[1]   = _rhs.data[1]: this.data[2]   = _rhs.data[2]: this.data[3]   = _rhs.data[3]
   this.data[4]  = _rhs.data[4]: this.data[5]   = _rhs.data[5]: this.data[6]   = _rhs.data[6]: this.data[7]   = _rhs.data[7]
   this.data[8]  = _rhs.data[8]: this.data[9]   = _rhs.data[9]: this.data[10]  = _rhs.data[10]: this.data[11] = _rhs.data[11]
   this.data[12] = _rhs.data[12]: this.data[13] = _rhs.data[13]: this.data[14] = _rhs.data[14]: this.data[15] = _rhs.data[15]
end operator
constructor CLASS_MATRIX4X4
   this.data = new single[16]
   this.data[0]=1:  this.data[1]=0:  this.data[2]=0:  this.data[3]=0
   this.data[4]=0:  this.data[5]=1:  this.data[6]=0:  this.data[7]=0
   this.data[8]=0:  this.data[9]=0:  this.data[10]=1: this.data[11]=0
   this.data[12]=0: this.data[13]=0: this.data[14]=0: this.data[15]=1
end constructor
constructor CLASS_MATRIX4X4(_rhs as CLASS_MATRIX4X4)
   this.data = new single[16]
   this = _rhs ''!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
end constructor
destructor CLASS_MATRIX4X4
   delete this.data
end destructor

'             
'   функции   
'             

' умножение вектора на матрицу

' vec2 x mat2 
operator * overload(byref _lhs as CLASS_VECTOR2, byref _rhs as CLASS_MATRIX2X2) as CLASS_VECTOR2
   dim as CLASS_VECTOR2 result
   result.data[0] = _lhs.data[0] * _rhs.data[0] + _lhs.data[1] * _rhs.data[1]
   result.data[1] = _lhs.data[0] * _rhs.data[2] + _lhs.data[1] * _rhs.data[3]
   operator = result
end operator

' vec3 x mat3 
operator * overload(byref _lhs as CLASS_VECTOR3, byref _rhs as CLASS_MATRIX3X3) as CLASS_VECTOR3
   dim as CLASS_VECTOR3 result
   result.data[0] = _lhs.data[0] * _rhs.data[0] + _lhs.data[1] * _rhs.data[1]  + _lhs.data[2] * _rhs.data[2]
   result.data[1] = _lhs.data[0] * _rhs.data[3] + _lhs.data[1] * _rhs.data[4]  + _lhs.data[2] * _rhs.data[5]
   result.data[2] = _lhs.data[0] * _rhs.data[6] + _lhs.data[1] * _rhs.data[6]  + _lhs.data[2] * _rhs.data[7]
   operator = result
end operator

' vec4 x mat4 
operator * overload(byref _lhs as CLASS_VECTOR4, byref _rhs as CLASS_MATRIX4X4) as CLASS_VECTOR4
   dim as CLASS_VECTOR4 result
   result.data[0] = _lhs.data[0] * _rhs.data[0]  + _lhs.data[1] * _rhs.data[1]  + _lhs.data[2] * _rhs.data[2]  + _lhs.data[3] * _rhs.data[3]
   result.data[1] = _lhs.data[0] * _rhs.data[4]  + _lhs.data[1] * _rhs.data[5]  + _lhs.data[2] * _rhs.data[6]  + _lhs.data[3] * _rhs.data[7]
   result.data[2] = _lhs.data[0] * _rhs.data[8]  + _lhs.data[1] * _rhs.data[9]  + _lhs.data[2] * _rhs.data[10] + _lhs.data[3] * _rhs.data[11]
   result.data[3] = _lhs.data[0] * _rhs.data[12] + _lhs.data[1] * _rhs.data[13] + _lhs.data[2] * _rhs.data[14] + _lhs.data[3] * _rhs.data[15]
   operator = result
end operator

' умножение матрицы на матрицу
operator * overload(byref _lhs as CLASS_MATRIX2X2, byref _rhs as CLASS_MATRIX2X2) as CLASS_MATRIX2X2
   dim as CLASS_MATRIX2X2 result
   result.data[0] = _lhs.data[0] * _rhs.data[0] + _lhs.data[1] * _rhs.data[2]
   result.data[1] = _lhs.data[0] * _rhs.data[1] + _lhs.data[1] * _rhs.data[3]

   result.data[2] = _lhs.data[2] * _rhs.data[0] + _lhs.data[3] * _rhs.data[2]
   result.data[3] = _lhs.data[2] * _rhs.data[1] + _lhs.data[3] * _rhs.data[3]
   operator = result
end operator

operator * overload(byref _lhs as CLASS_MATRIX3X3, byref _rhs as CLASS_MATRIX3X3) as CLASS_MATRIX3X3
   dim as CLASS_MATRIX3X3 result
   result.data[0] = _lhs.data[0] * _rhs.data[0] + _lhs.data[1] * _rhs.data[3] + _lhs.data[2] * _rhs.data[6]
   result.data[1] = _lhs.data[0] * _rhs.data[1] + _lhs.data[1] * _rhs.data[4] + _lhs.data[2] * _rhs.data[7]
   result.data[2] = _lhs.data[0] * _rhs.data[2] + _lhs.data[1] * _rhs.data[5] + _lhs.data[2] * _rhs.data[8]

   result.data[3] = _lhs.data[3] * _rhs.data[0] + _lhs.data[4] * _rhs.data[3] + _lhs.data[5] * _rhs.data[6]
   result.data[4] = _lhs.data[3] * _rhs.data[1] + _lhs.data[4] * _rhs.data[4] + _lhs.data[5] * _rhs.data[7]
   result.data[5] = _lhs.data[3] * _rhs.data[2] + _lhs.data[4] * _rhs.data[5] + _lhs.data[5] * _rhs.data[8]

   result.data[5] = _lhs.data[6] * _rhs.data[0] + _lhs.data[7] * _rhs.data[3] + _lhs.data[8] * _rhs.data[6]
   result.data[7] = _lhs.data[6] * _rhs.data[1] + _lhs.data[7] * _rhs.data[4] + _lhs.data[8] * _rhs.data[7]
   result.data[8] = _lhs.data[6] * _rhs.data[2] + _lhs.data[7] * _rhs.data[5] + _lhs.data[8] * _rhs.data[8]
   operator = result
end operator

operator * overload(byref _lhs as CLASS_MATRIX4X4, byref _rhs as CLASS_MATRIX4X4) as CLASS_MATRIX4X4
   dim as CLASS_MATRIX4X4 result
   result.data[0]  = _lhs.data[0]  * _rhs.data[0] + _lhs.data[1]  * _rhs.data[4] + _lhs.data[2]  * _rhs.data[8]  + _lhs.data[3]  * _rhs.data[12]
   result.data[1]  = _lhs.data[0]  * _rhs.data[1] + _lhs.data[1]  * _rhs.data[5] + _lhs.data[2]  * _rhs.data[9]  + _lhs.data[3]  * _rhs.data[13]
   result.data[2]  = _lhs.data[0]  * _rhs.data[2] + _lhs.data[1]  * _rhs.data[6] + _lhs.data[2]  * _rhs.data[10] + _lhs.data[3]  * _rhs.data[14]
   result.data[3]  = _lhs.data[0]  * _rhs.data[3] + _lhs.data[1]  * _rhs.data[7] + _lhs.data[2]  * _rhs.data[11] + _lhs.data[3]  * _rhs.data[15]

   result.data[4]  = _lhs.data[4]  * _rhs.data[0] + _lhs.data[5]  * _rhs.data[4] + _lhs.data[6]  * _rhs.data[8]  + _lhs.data[7]  * _rhs.data[12]
   result.data[5]  = _lhs.data[4]  * _rhs.data[1] + _lhs.data[5]  * _rhs.data[5] + _lhs.data[6]  * _rhs.data[9]  + _lhs.data[7]  * _rhs.data[13]
   result.data[6]  = _lhs.data[4]  * _rhs.data[2] + _lhs.data[5]  * _rhs.data[6] + _lhs.data[6]  * _rhs.data[10] + _lhs.data[7]  * _rhs.data[14]
   result.data[7]  = _lhs.data[4]  * _rhs.data[3] + _lhs.data[5]  * _rhs.data[7] + _lhs.data[6]  * _rhs.data[11] + _lhs.data[7]  * _rhs.data[15]

   result.data[8]  = _lhs.data[8]  * _rhs.data[0] + _lhs.data[9]  * _rhs.data[4] + _lhs.data[10] * _rhs.data[8]  + _lhs.data[11] * _rhs.data[12]
   result.data[9]  = _lhs.data[8]  * _rhs.data[1] + _lhs.data[9]  * _rhs.data[5] + _lhs.data[10] * _rhs.data[9]  + _lhs.data[11] * _rhs.data[13]
   result.data[10] = _lhs.data[8]  * _rhs.data[2] + _lhs.data[9]  * _rhs.data[6] + _lhs.data[10] * _rhs.data[10] + _lhs.data[11] * _rhs.data[14]
   result.data[11] = _lhs.data[8]  * _rhs.data[3] + _lhs.data[9]  * _rhs.data[7] + _lhs.data[10] * _rhs.data[11] + _lhs.data[11] * _rhs.data[15]

   result.data[12] = _lhs.data[12] * _rhs.data[0] + _lhs.data[13] * _rhs.data[4] + _lhs.data[14] * _rhs.data[8]  + _lhs.data[15] * _rhs.data[12]
   result.data[13] = _lhs.data[12] * _rhs.data[1] + _lhs.data[13] * _rhs.data[5] + _lhs.data[14] * _rhs.data[9]  + _lhs.data[15] * _rhs.data[13]
   result.data[14] = _lhs.data[12] * _rhs.data[2] + _lhs.data[13] * _rhs.data[6] + _lhs.data[14] * _rhs.data[10] + _lhs.data[15] * _rhs.data[14]
   result.data[15] = _lhs.data[12] * _rhs.data[3] + _lhs.data[13] * _rhs.data[7] + _lhs.data[14] * _rhs.data[11] + _lhs.data[15] * _rhs.data[15]
   operator = result
end operator

' еденичная матрица 
function identity() as CLASS_MATRIX4X4
   dim as CLASS_MATRIX4X4 result
   result.data[0]=1:  result.data[1]=0:  result.data[2]=0:  result.data[3]=0
   result.data[4]=0:  result.data[5]=1:  result.data[6]=0:  result.data[7]=0
   result.data[8]=0:  result.data[9]=0:  result.data[10]=1: result.data[11]=0
   result.data[12]=0: result.data[13]=0: result.data[14]=0: result.data[15]=1
   function = result
end function

' транспортная матрица 
function translate(_x as single = 0, _y as single = 0, _z as single = 0) as CLASS_MATRIX4X4
   dim as CLASS_MATRIX4X4 result
   result.data[0]=1:  result.data[1]=0:  result.data[2]=0:  result.data[3]=  _x
   result.data[4]=0:  result.data[5]=1:  result.data[6]=0:  result.data[7]=  _y
   result.data[8]=0:  result.data[9]=0:  result.data[10]=1: result.data[11]= _z
   result.data[12]=0: result.data[13]=0: result.data[14]=0: result.data[15]=1
   function = result
end function

' матрица вращения 

' матрица вращения по оси x 
function rotate_x(_x as single) as CLASS_MATRIX4X4
   dim as single cos_x=cos(_x), sin_x=sin(_x)
   dim as CLASS_MATRIX4X4 result
   
   result.data[0] = 1:  result.data[1] = 0:     result.data[2] = 0:      result.data[3] = 0
   result.data[4] = 0:  result.data[5] = cos_x: result.data[6] = -sin_x: result.data[7] = 0
   result.data[8] = 0:  result.data[9] = sin_x: result.data[10] = cos_x: result.data[11] = 0
   result.data[12] = 0: result.data[13] = 0:    result.data[14] = 0:     result.data[15] = 1
   function = result
end function

' матрица вращения по оси y 
function rotate_y(_y as single) as CLASS_MATRIX4X4
   dim as single cos_y=cos(_y), sin_y=sin(_y)
   dim as CLASS_MATRIX4X4 result
   
   result.data[0] = cos_y:  result.data[1] = 0:  result.data[2] = sin_y:  result.data[3] = 0
   result.data[4] = 0:      result.data[5] = 1:  result.data[6] = 0:      result.data[7] = 0
   result.data[8] = -sin_y: result.data[9] = 0:  result.data[10] = cos_y: result.data[11] = 0
   result.data[12] = 0:     result.data[13] = 0: result.data[14] = 0:     result.data[15] = 1
   function = result
end function

'  матрица вращения по оси z 
function rotate_z(_z as single) as CLASS_MATRIX4X4
   dim as single cos_z=cos(_z), sin_z=sin(_z)
   dim as CLASS_MATRIX4X4 result

   result.data[0] = cos_z: result.data[1] = -sin_z: result.data[2] = 0:  result.data[3] = 0
   result.data[4] = sin_z: result.data[5] = cos_z:  result.data[6] = 0:  result.data[7] = 0
   result.data[8] = 0:     result.data[9] = 0:      result.data[10] = 1: result.data[11] = 0
   result.data[12] = 0:    result.data[13] = 0:     result.data[14] = 0: result.data[15] = 1
   function = result
end function

' матрица масштабирования
function scale(_x as single, _y as single, _z as single) as CLASS_MATRIX4X4
   dim as CLASS_MATRIX4X4 result
   result.data[0]=_x: result.data[1]=0:  result.data[2]=0:   result.data[3]=0
   result.data[4]=0:  result.data[5]=_y: result.data[6]=0:   result.data[7]=0
   result.data[8]=0:  result.data[9]=0:  result.data[10]=_z: result.data[11]=0
   result.data[12]=0: result.data[13]=0: result.data[14]=0:  result.data[15]=1
   function = result
end function

' матрица перспективной проэкции 

function frustum(_left as single, _right as single, _bottom as single, _top as single, _near as single, _far as single) as CLASS_MATRIX4X4
   dim as CLASS_MATRIX4X4 result
   result.data[0]= 2 * _near / (_right - _left)
   result.data[1]=0
   result.data[2]=0
   result.data[3]=0
   result.data[4]=0
   result.data[5]= 2 * _near / (_top - _bottom)
   result.data[6]=0
   result.data[7]=0
   result.data[8]=(_right + _left) / (_right - _left)
   result.data[9]=(_top + _bottom) / (_top - _bottom)
   result.data[10]= -((_far + _near) / (_far - _near))
   result.data[11]= -1
   result.data[12]=0
   result.data[13]=0
   result.data[14]=-((2 * _far * _near) / (_far - _near))
   result.data[15]=0
   function = result
end function

' матрица перспективной проэкции со значением угла обзора 

const as single _radians = ( atn(1) * 4)/180
function perspective(_fov as single, _rate as single, _near as single, _far as single) as CLASS_MATRIX4X4
   dim as CLASS_MATRIX4X4 result
   dim as single tan_half_fov = tan(_fov/2*_radians)
   result.data[0]= 1/(tan_half_fov*_rate)
   result.data[1]=0
   result.data[2]=0
   result.data[3]=0
   result.data[4]=0
   result.data[5]= 1/tan_half_fov
   result.data[6]=0
   result.data[7]=0
   result.data[8]=0
   result.data[9]=0
   result.data[10]= (_near+_far)/(_near-_far)
   result.data[11]= (2*_far*_near)/(_near-_far)
   result.data[12]=0
   result.data[13]=0
   result.data[14]=-1
   result.data[15]=0
   function = result
end function

' матрица ортогональной проэкции 
function orthogonal(_left as single, _right as single, _bottom as single, _top as single, _near as single, _far as single) as CLASS_MATRIX4X4
   dim as CLASS_MATRIX4X4 result
   result.data[0]= 2 / (_right - _left)
   result.data[1]=0
   result.data[2]=0
   result.data[3]=-(_right + _left) / (_right - _left)
   result.data[4]=0
   result.data[5]= 2 / (_top - _bottom)
   result.data[6]=0
   result.data[7]= -(_top + _bottom) / (_top - _bottom)
   result.data[8]=0
   result.data[9]=0
   result.data[10]=-2 / (_far - _near)
   result.data[11]=-(_far + _near) / (_far - _near)
   result.data[12]=0
   result.data[13]=0
   result.data[14]=0
   result.data[15]=1
   function = result
end function

' умножение вектора на матрицу с прямым обращением к объектам минуя копии.
sub multiply_vector(result as single ptr, vector as single ptr, matrix as single ptr)
   result[0] = vector[0] * matrix[0]  + vector[1] * matrix[1]  + vector[2] * matrix[2]  + vector[3] * matrix[3]
   result[1] = vector[0] * matrix[4]  + vector[1] * matrix[5]  + vector[2] * matrix[6]  + vector[3] * matrix[7]
   result[2] = vector[0] * matrix[8]  + vector[1] * matrix[9]  + vector[2] * matrix[10] + vector[3] * matrix[11]
   result[3] = vector[0] * matrix[12] + vector[1] * matrix[13] + vector[2] * matrix[14] + vector[3] * matrix[15]
end sub

type as CLASS_VECTOR2 vec2
type as CLASS_VECTOR3 vec3
type as CLASS_VECTOR4 vec4
type as CLASS_MATRIX2X2 mat2
type as CLASS_MATRIX3X3 mat3
type as CLASS_MATRIX4X4 mat4

'--------------------------------------------------------------------------------------------------------------------------------------------
'                                                                         main code
'--------------------------------------------------------------------------------------------------------------------------------------------

   '                     
    '    nblJIG 2013     
   '                     

   '                     
    ' Esc - exit.         
    ' W - move forward.   
    ' S - move backward   
    ' A - strafe left     
    ' D - strafe right   
    ' C - strafe down     
    ' SPACE - strafe up   
    ' Q - tilt left       
    ' E - tilt right     
   '                     
union UNION_BGRA
   as ulong bgra
   type
      as ubyte b,g,r,a
   end type
end union

redim shared as vec4 vertex(0)

type CLASS_CAMERA
   as single x, y, z, w
   as single p, h, b
   as mat4 data
end type

dim as CLASS_CAMERA camera

sub load_obj_file(filename as string)

   dim as integer file, dimension, lenght, i
   dim as string buffer, value, symbol

   file = freefile
   if not open(exepath + "\" + filename for binary access read as #file) then
      while not eof(file)
         line input #file, buffer
         lenght = len(buffer)
         select case mid(buffer, 1, 2)
            case "v "
               dimension = 2
               for i = lenght to 2 step -1
                  symbol = mid(buffer, i, 1)
                  if symbol <> " " then
                     value = symbol + value
                  else
                     vertex(ubound(vertex)).data[dimension] = val(value)
                     dimension -= 1
                     value = ""
                  end if
               next i
               vertex(ubound(vertex)).data[3] = 1
               redim preserve as vec4 vertex(lbound(vertex) to ubound(vertex)+1)
         end select
      wend
   end if
   close #file
end sub

load_obj_file "data/geometry/female.obj"
''load_obj_file "data/geometry/file.obj"

dim as long screen_width=1600, screen_height=900, bit_depth = 32,full_screen = 0, _ 'screen mode'
            screen_size=screen_width*screen_height, _
            screen_width_half = screen_width/2-1, _
            screen_height_half = screen_height/2-1, _
            frame_x, frame_y, _ 'pixel position on screen
            mouse_x, mouse_y, mouse_focus, mouse_focus_last, _ 'mouse
            fps_count, fps_value, _ ' frame per second
            flag_refresh
dim as single screen_ratio = screen_width/screen_height
dim as double time_last, time_current ' timer

'dim as single angle_x, angle_y, angle_z

screenres screen_width, screen_height, bit_depth, 0, full_screen
windowtitle "matrix-projection"
dim as UNION_BGRA ptr frame_cursor, frame_buffer = screenptr

setmouse screen_width_half, screen_height_half, 0   
time_last = timer

dim as mat4 matrix_result
dim as vec4 cursor



while not multikey(&h01)

'                                                                 
'                              Матрицы                             
'                                                                 

   camera.data = translate(camera.x, camera.y, camera.z) _
            * rotate_z(camera.b) _
            * rotate_y(camera.h) _
            * rotate_x(camera.p) _
            * camera.data

   camera.b = 0
   camera.h = 0
   camera.p = 0
   camera.x = 0
   camera.y = 0
   camera.z = 0

   matrix_result = perspective(45, screen_ratio, 0.1, 1000) * camera.data
   
   flag_refresh = 0

'                                                                 
'                           Визуализация                           
'                                                                 

   screenlock
   cls

'                            Геометрия                             

   for i as integer = 0 to ubound(vertex)

      multiply_vector(cursor.data, vertex(i).data, matrix_result.data)

      if (cursor.data[0] > -cursor.data[3] and cursor.data[0] < cursor.data[3]) and _
         (cursor.data[1] > -cursor.data[3] and cursor.data[1] < cursor.data[3]) and _
         cursor.data[2] > 0 then

         frame_x = (cursor.data[0]/cursor.data[3]+1)*(screen_width_half)
         frame_y = (cursor.data[1]/cursor.data[3]+1)*(screen_height_half)

         frame_cursor = frame_buffer + frame_y * screen_width + frame_x

         if frame_cursor->r < 230 then frame_cursor->r +=25
         if frame_cursor->g < 245 then frame_cursor->g +=10
         if frame_cursor->b < 245 then frame_cursor->b +=10

      end if
   next i

'                            Вывод информации                           

   draw string (0,10), "fps: "+ str(fps_value)
   draw string (0,20), "vertexes: "+ str(ubound(vertex))
   draw string (0,30), "mouse: "+ str(mouse_focus)
   screenunlock
   sleep 1

'                                                                 
'                            События                               
'                                                                 

'                             Время                               

   time_current=timer
   fps_count += 1
   if time_current > time_last + 1 then
      time_last = time_current
      fps_value = fps_count
      fps_count = 0
   end if

'                             Мышка                               

   mouse_focus_last = mouse_focus
   mouse_focus = getmouse (mouse_x, mouse_y)
   if mouse_focus=0 then
      if mouse_focus_last<>mouse_focus then
         setmouse(screen_width_half, screen_height_half)
      elseif mouse_x<>screen_width_half or mouse_y<>screen_height_half then
         camera.h += (mouse_x - screen_width_half)*0.0005
         camera.p += (screen_height_half - mouse_y)*0.0005
         setmouse(screen_width_half, screen_height_half)
         flag_refresh = 1
      end if

'                           Клавиатура                             

      if multikey(&h1e) then camera.x += 0.1 ' a
      if multikey(&h20) then camera.x -= 0.1 ' d
      if multikey(&h2c) then end if ' z
      if multikey(&h2d) then end if ' x
      if multikey(&h39) then camera.y += 0.1 ' space
      if multikey(&h2e) then camera.y -= 0.1 ' c
      if multikey(&h11) then camera.z += 0.1 ' w
      if multikey(&h1f) then camera.z -= 0.1 ' s
      if multikey(&h10) then camera.b += 0.03 ' q
      if multikey(&h12) then camera.b -= 0.03 ' e

   end if

wend
end
Last edited by podvornyak on Feb 13, 2017 13:28, edited 2 times in total.
St_W
Posts: 1494
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Memory coping with assembler.

Postby St_W » Feb 13, 2017 12:49

I could not reproduce your performance issue with getmouse() - are you sure that getmouse is the cause? Anyway there's probably not much you can to to improve the performance of getmouse as all it does it basically reading the status values from variables that gfxlib is tracking internally anyway. The most expensive part is probably the involved locking. You may try to use screenevent and track the movements yourself, but I doubt whether that would be faster. Assembler won't help you in this case as you rely on information from the operating system in any way. I'd suggest using a profiler (and compile with "-profile") to identify and analyse the performance issue.

Some additional tips:

instead of your own #define for 64-bit (#define _x_64) use __FB_64BIT__
See also http://freebasic.net/wiki/wikka.php?wak ... gDdfb64bit

instead of writing a custom assembly version for standard features like copying memory use the implementations of the C runtime (which is used by FB anyway). It is usually faster and more portable. The functions is called "memcpy" and you've to #include "crt.bi" for the declaration.
podvornyak
Posts: 148
Joined: Nov 12, 2007 11:46
Location: Russia

Re: Memory coping with assembler.

Postby podvornyak » Feb 13, 2017 13:13

St_W wrote:I could not reproduce your performance issue with getmouse() - are you sure that getmouse is the cause?

Yep. Cause keyboard events move geometry smoothly. Try to load OBJ file with, approximately, one million vertexes. For my i3 2-nd generation it is an edge of performance.
St_W wrote:Some additional tips:

Thanks for the tips. I'll keep them in mind. Anyway i am trying to evade any OS dependencies, such as include side library. It makes code portable as much as possible. Compiling is painless. Look around. There is not much clean and portable code at all. Everyone use windows headers. Even for context initialization. I think it is wrong, and leads to nowhere. Useless and unreadable bunch of code.
Those asm inlines in code, actually, do nothing. I will remove them to evade misunderstanding.
PS: I've just thinked about process priority. I'm using Linux, with equal privileges for system processes... Gone to checkout.
PPS: Nope. Problem is in the code.
caseih
Posts: 1505
Joined: Feb 26, 2007 5:32

Re: Memory coping with assembler.

Postby caseih » Feb 13, 2017 13:46

podvornyak wrote:Anyway i am trying to evade any OS dependencies, such as include side library. It makes code portable as much as possible. Compiling is painless.
If portability is your goal, then using assembler is certainly not appropriate, unless you plan to include platform-specific versions that can be selected by the compiler.

Once you've formally profiled your code's runtime and identified a section of code that is consuming all your time, and you cannot optimize it in any other way, then and only then is assembly appropriate in my opinion. Premature optimization is the root of all evil.

I suspect your performance issues are not coming from getmouse itself but your use of getmouse. Perhaps you need to compress mouse events. Remember that mouse events can happen many times faster than keyboard events, maybe dozens of times per second during movement. So likely what's happening is your response to the mouse events is happening too slow. So maybe you just need to throw out redundant mouse events.
Look around. There is not much clean and portable code at all. Everyone use windows headers. Even for context initialization. I think it is wrong, and leads to nowhere. Useless and unreadable bunch of code.

Actually portable code is extremely common these days (the FB runtime is a good example). It's certainly readable to those who are familiar with the code.

Your adversion to windows headers is a bit strange. Every single program on Windows requires at least windows.h. At some point every app on any OS has to depend on the OS.
greenink
Posts: 200
Joined: Jan 28, 2016 15:45

Re: Memory coping with assembler.

Postby greenink » Feb 13, 2017 14:16

That reminds me that capturing mouse events in Java is very unreliable. Sometimes you get them, sometimes you don't!
podvornyak
Posts: 148
Joined: Nov 12, 2007 11:46
Location: Russia

Re: Memory coping with assembler.

Postby podvornyak » Feb 13, 2017 14:37

caseih wrote:I suspect your performance issues are not coming from getmouse itself but your use of getmouse. Perhaps you need to compress mouse events. Remember that mouse events can happen many times faster than keyboard events, maybe dozens of times per second during movement.
Hmm... Maby you are right. But it means that mouse event may be caught more than once per iteration, despite that only one call of getmouse() function? In fact, im just getting current mouse position and return cursor back in center of window, till next iteration...

caseih wrote: Every single program on Windows requires at least windows.h
Not in my case, man... not in my case. WinAPI is awful. Even more - any developer can replace .net libs with fake and redirect procedure calls, what leads to completely unpredictable behavior of code. Checkout "Black Desert Online". When it is running - no keyboard and mouse events allowed in whole system.
PS: Hm... I've set mouse clipping to window and gaps, in movement, disappear... Seems it is kind a solution. Looking forward for better solving, cause mouse loose clipping. I can't just set clipping mode outside main cycle and forget about it, like with visibility.
caseih
Posts: 1505
Joined: Feb 26, 2007 5:32

Re: Memory coping with assembler.

Postby caseih » Feb 13, 2017 16:11

podvornyak wrote:Hmm... Maby you are right. But it means that mouse event may be caught more than once per iteration, despite that only one call of getmouse() function? In fact, im just getting current mouse position and return cursor back in center of window, till next iteration...
Hmm, I'm not sure. Sounds like mouse clipping solved your problem. So I was probably barking up the wrong tree with the mouse events stuff.
caseih wrote: Every single program on Windows requires at least windows.h
Not in my case, man... not in my case. WinAPI is awful. Even more - any developer can replace .net libs with fake and redirect procedure calls, what leads to completely unpredictable behavior of code. Checkout "Black Desert Online". When it is running - no keyboard and mouse events allowed in whole system.

I don't love the Win32 API either, but I disagree that it leads to unpredictable code. In fact I'm not sure I understand any of what you wrote. "Redirection" as you put it is possible with any system that uses dynamically-linked libraries. The Black Desert Online game runs as a full-screen app. So of course it's going to block mouse and keyboard events from going to other windows. What else would you expect?

Anyway, all Win32 exes use the Win32 API. Maybe you're using an abstraction layer that hides it, but it's still there. Even with FB apps.
PS: Hm... I've set mouse clipping to window and gaps, in movement, disappear... Seems it is kind a solution. Looking forward for better solving, cause mouse loose clipping. I can't just set clipping mode outside main cycle and forget about it, like with visibility.

Glad you found a solution.
podvornyak
Posts: 148
Joined: Nov 12, 2007 11:46
Location: Russia

Re: Memory coping with assembler.

Postby podvornyak » Feb 13, 2017 16:58

caseih wrote:The Black Desert Online game runs as a full-screen app. So of course it's going to block mouse and keyboard events from going to other windows. What else would you expect?
Nope. It runs both - windowed and fullscreen. Even - collapse to system tray for working in background. I was wondering - why, some of application and my code, sometimes, won't work properly. I've drag out all my hairs, until, once, i've decided to code simple bot for this game. Immediately i realize - whom should i blame for my lost nerves. Yep. Black Desert Online. While it working - no WinAPI events allowed in usual way. You can check by yourself, if you don't believe me. You, even, don't need to run the game. Just go inside game folder and look at the name of some files, and those size. Completely cutout functionality, fake libraries to replace MAJOR SYSTEM LIBS. Is it legal at all?

Return to “Beginners”

Who is online

Users browsing this forum: No registered users and 5 guests