Memory coping with assembler.

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

Memory coping with assembler.

Post by podvornyak »

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: 8586
Joined: May 28, 2005 3:28
Contact:

Re: Memory coping with assembler.

Post by D.J.Peters »

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.

Post by podvornyak »

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.

Post by MichaelW »

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.

Post by podvornyak »

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: 1626
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Memory coping with assembler.

Post by St_W »

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.

Post by podvornyak »

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: 2157
Joined: Feb 26, 2007 5:32

Re: Memory coping with assembler.

Post by caseih »

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.

Post by greenink »

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.

Post by podvornyak »

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: 2157
Joined: Feb 26, 2007 5:32

Re: Memory coping with assembler.

Post by caseih »

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.

Post by podvornyak »

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?
Post Reply