declare function CreateDetour(ORGPTR as any ptr,DETOURPTR as any ptr=0,TRAMPOLINEPTR as any ptr=0) as integer
declare function CreateSimpleDetour(ORGPTRPTR as any ptr ptr,DETOURPTR as any ptr=0,TRAMPOLINEPTR as any ptr=0) as integer

#macro UndefAll()
#undef P1
#undef P2
#undef P3
#undef P4
#undef P5
#undef P6
#undef P7
#undef P8
#undef P9
#undef P10
#undef P11
#undef P12
#undef P13
#undef P14
#undef P15
#undef P16
#endmacro
#macro SimpleTrampoline(MYFUNC)
asm
  MYFUNC##_SKIP:
  mov esp,ebp
  pop ebp
  mov edx,0
  MYFUNC##Trampoline:
  jmp edx
end asm
#endmacro
#macro SimpleTrampolineFunction(MYFUNC)
asm
  mov eax,[ebp+4]
  mov [ORGRET],eax
  mov [MYESP],esp
  mov [MYEBP],ebp
  mov dword ptr [ebp+4], offset MYFUNC##Trampoline_Result
  mov esp,ebp
  pop ebp
  mov edx,0
  MYFUNC##Trampoline:
  jmp edx
  MYFUNC##Trampoline_Result:  
  mov [FUNCRESULT],eax
  mov [RESP],esp
  mov [REBP],ebp
  mov esp,[MYESP]
  mov ebp,[MYEBP]
end asm
#endmacro
#macro TrampolineReturn()
asm
  mov eax,[FUNCRESULT]
  mov esp,[RESP]
  mov ebp,[REBP]
  mov edx,[ORGRET]    
  jmp edx
end asm
#endmacro

#macro Trampoline(MYFUNC)
asm
  MYFUNC##_SKIP:
  mov esp, ebp
  pop ebp
  MYFUNC##Trampoline:
  .skip 16, 0x90
end asm
#endMacro

#macro TrampolineN_BEGIN(MYFUNC)
asm
  pusha
  push dword ptr [MYFUNC##_MUTEX_]
  call _fb_MutexLock@4
  mov esi, offset MYFUNC##_ORGCODE_
  mov edi, [MYFUNC##_ORGPTR_]
  mov ecx, [MYFUNC##_ORGSIZE_]
  rep movsb
  push 0
  push 0
  push -1
  call FlushInstructionCache
  mov eax, [MYFUNC##_ORGFUNC_]
  mov [MYFUNC##_ORG],eax
  popa
end asm
#endmacro
#macro TrampolineN_END(MYFUNC)
asm
  pusha
  mov esi, offset MYFUNC##_FUNCJUMP_
  mov edi, [MYFUNC##_ORGPTR_]
  mov ecx, 5
  rep movsb
  push 0
  push 0
  push -1
  call FlushInstructionCache
  push dword ptr [MYFUNC##_MUTEX_]
  call _fb_MutexUnlock@4
  popa
  jmp MYFUNC##_SKIP_DATA_
  MYFUNC##Trampoline:
  MYFUNC##_ORGPTR_: .skip 4
  MYFUNC##_ORGSIZE_: .skip 4
  MYFUNC##_ORGFUNC_: .skip 4
  MYFUNC##_FUNCJUMP_: .skip 5,0x90
  MYFUNC##_ORGCODE_: .skip 16,0x90
  MYFUNC##_TMPVAR_: .skip 4
  MYFUNC##_SKIP_DATA_:
end asm
#endmacro

#macro TrampolineN(MYFUNC)
asm
  MYFUNC##_SKIP_:
  mov esp, ebp
  pop ebp  
  pusha
  push dword ptr [MYFUNC##_MUTEX_]
	call _fb_MutexLock@4
  mov esi, offset MYFUNC##_ORGCODE_
  mov edi, [MYFUNC##_ORGPTR_]
  mov ecx, [MYFUNC##_ORGSIZE_]
  rep movsb
  push 0
  push 0
  push -1
  call FlushInstructionCache
  popa
  pop eax
  mov [MYFUNC##_TMPVAR_],eax
  mov eax,[MYFUNC##_ORGFUNC_]
  call eax
  pusha
  mov esi, offset MYFUNC##_FUNCJUMP_
  mov edi, [MYFUNC##_ORGPTR_]
  mov ecx, 5
  rep movsb
  push 0
  push 0
  push -1
  call FlushInstructionCache
  push dword ptr [MYFUNC##_MUTEX_]
	call _fb_MutexUnlock@4
  popa  
  push dword ptr [MYFUNC##_TMPVAR_]
  ret
  MYFUNC##Trampoline:
  MYFUNC##_ORGPTR_: .skip 4
  MYFUNC##_ORGSIZE_: .skip 4
  MYFUNC##_ORGFUNC_: .skip 4
  MYFUNC##_FUNCJUMP_: .skip 5,0x90
  MYFUNC##_ORGCODE_: .skip 16,0x90
  MYFUNC##_TMPVAR_: .skip 4
end asm
#endmacro