forum.boolean.name

forum.boolean.name (http://forum.boolean.name/index.php)
-   Blitz3D (http://forum.boolean.name/forumdisplay.php?f=45)
-   -   Непостоянная ошибка (http://forum.boolean.name/showthread.php?t=18718)

Devilox 15.11.2013 19:47

Непостоянная ошибка
 
Я не знаю, куда конкретно закралась ошибка, поэтому пишу оба кода. Blitz-евский код с подключённой библиотекой работает непостоянно: иногда запускается, иногда выдаёт MAV. Знает кто, что это за фигня?

Код:

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

cam = CreateCamera()
PositionEntity cam,0,0,-10

plane = CreatePlane()
EntityColor plane,0,100,100
PositionEntity plane,0,-1,0

sphere1 = CreateSphere()
EntityColor sphere1,150,0,0

sphere2 = CreateSphere()
EntityColor sphere2,0,0,150

sphere3 = CreateSphere()
EntityColor sphere3,0,150,0

r1 = dpCreateArea(1,1)
r2 = dpCreateArea(1,1)
r3 = dpCreateArea(1,1)

While Not KeyHit(1)

dpAttachEntity(sphere1,r1)
dpAttachEntity(sphere2,r2)
dpAttachEntity(sphere3,r3)

dpPropelArea(r1,1,0,1)
dpPropelArea(r2,-1,0,1)
dpPropelArea(r3,0,0,1)

dpUpdateAreas()

UpdateWorld()
RenderWorld()

Flip

Wend

End

Код:

Structure Object
  num.i
  type.i
  mass.f
  xPos.f
  yPos.f
  zPos.f
  xSc.f
  ySc.f
  zSc.f
  xRot.f
  yRot.f
  zRot.f
  xSp.f
  ySp.f
  zSp.f
EndStructure
 
Global NewMap Objects.Object()

Global num.i = 0

;==========Procedures==========;

ProcedureDLL.f dpCreateArea(type.i,mass.f)
 
  AddMapElement(Objects(),Str(num))
 
  Objects()\num = num
  Objects()\type = type
  Objects()\mass = mass
  Objects()\xPos = 0
  Objects()\yPos = 0
  Objects()\zPos = 0
  Objects()\xSc = 1
  Objects()\ySc = 1
  Objects()\zSc = 1
  Objects()\xRot = 0
  Objects()\yRot = 0
  Objects()\zRot = 0
  Objects()\xSp = 0
  Objects()\ySp = 0
  Objects()\zSp = 0
 
  Protected *area = AllocateMemory(56)
 
  PokeI(*area,Objects()\num)
  PokeI(*area + 4,Objects()\type)
  PokeF(*area + 8,Objects()\mass)
  PokeF(*area + 12,Objects()\xPos)
  PokeF(*area + 16,Objects()\yPos)
  PokeF(*area + 20,Objects()\zPos)
  PokeF(*area + 24,Objects()\xSc)
  PokeF(*area + 28,Objects()\ySc)
  PokeF(*area + 32,Objects()\zSc)
  PokeF(*area + 36,Objects()\xRot)
  PokeF(*area + 40,Objects()\yRot)
  PokeF(*area + 44,Objects()\zRot)
  PokeF(*area + 48,Objects()\xSp)
  PokeF(*area + 52,Objects()\ySp)
  PokeF(*area + 56,Objects()\zSp)
   
  num = num + 1
   
  ProcedureReturn *area
EndProcedure

ProcedureDLL.f dpAttachEntity(*entity,*area)
  FindMapElement(Objects(),Str(PeekI(*area)))
 
  PokeF(*area + 12,Objects()\xPos)
  PokeF(*area + 16,Objects()\yPos)
  PokeF(*area + 20,Objects()\zPos)
 
  PokeI(*entity + 44,-1)
 
  PokeF(*entity + 64,PeekF(*area + 12))
  PokeF(*entity + 68,PeekF(*area + 16))
  PokeF(*entity + 72,PeekF(*area + 20))
EndProcedure

ProcedureDLL.f dpUpdateAreas()
  ForEach Objects()
    Objects()\xPos = Objects()\xPos + Objects()\xSp
    Objects()\yPos = Objects()\yPos + Objects()\ySp
    Objects()\zPos = Objects()\zPos + Objects()\zSp
  Next
EndProcedure

ProcedureDLL.f dpMoveArea(*area,x.f,y.f,z.f)
  FindMapElement(Objects(),Str(PeekI(*area)))
 
  Objects()\xPos = Objects()\xPos + x
  Objects()\yPos = Objects()\yPos + y
  Objects()\zPos = Objects()\zPos + z
EndProcedure

ProcedureDLL.f dpPropelArea(*area,fx.f,fy.f,fz.f)
  FindMapElement(Objects(),Str(PeekI(*area)))
  Protected m.f = Objects()\mass * 1000
 
  Objects()\xSp = Objects()\xSp + fx / m
  Objects()\ySp = Objects()\ySp + fy / m
  Objects()\zSp = Objects()\zSp + fz / m
EndProcedure


Devilox 15.11.2013 20:52

Ответ: Непостоянная ошибка
 
Как мне кажется, Blitz как-то неправильно понимает команду dpCreateArea(type.i,mass.f), если функция была применена единожды, то всё нормально работает, если больше, то глючит MAV-ом. Ошибка от заданных параметров не зависит: проверял.

UPD. Похоже, что Blitz запускает новую функцию, не дожидаясь окончания старой. Есть способы это решить?

RBK 15.11.2013 21:33

Ответ: Непостоянная ошибка
 
Первое что бросается в глаза - ты не обрабатываешь возможные ошибки в AddMapElement и FindMapElement.
Код:

if FindMapElement(Map(), Key$)
 элемент есть - работаем
else
 элемента нет - с этим надо что-то делать
endif

чтобы сказать что-то подробней нужно гонять программу в дебагере и смотреть что там происходит.

Devilox 15.11.2013 21:44

Ответ: Непостоянная ошибка
 
Спасибо! Поработать с дебаггером было хорошим советом. Проблема была в недостаточном выделении памяти для параметров объектов(надо было не 56 байт, как я выделял, а 60). Обработку ошибок учту. :)

Devilox 16.11.2013 14:10

Ответ: Непостоянная ошибка
 
Чтобы раздел не захламлять, напишу сюда. Возникла ещё проблема: я создал команду dpPositionArea, аналогичную Blitz-евской PositionEntity, если её использовать не более, чем дважды, вне цикла, то всё работает, если больше, то Blitz зависает на чёрном экране(помогает задержка, но чем чаще команду используешь, тем продолжительней она нужна(например, для 3-й - 400мс)). Интересно, что в цикле никаких проблем не возникает. С чем это может быть связано?

P.S. Дебаггер Барсика ошибок не выявил.

Код:

ProcedureDLL.f dpPositionArea(*area,xPos.f,yPos.f,zPos.f)
  If FindMapElement(Objects(),Str(PeekI(*area)))
    Objects()\xPos = xPos
    Objects()\yPos = yPos
    Objects()\zPos = zPos
  Else
    error = 1 
  EndIf
EndProcedure

Код:

Graphics3D 800,600,32,2
SetBuffer BackBuffer()

arial = LoadFont("arial",20,True)
SetFont arial

cam = CreateCamera()
PositionEntity cam,0,0,-10

plane = CreatePlane()
EntityColor plane,0,100,100
PositionEntity plane,0,-1,0

sphere1 = CreateSphere()
EntityColor sphere1,150,0,0

sphere2 = CreateSphere()
EntityColor sphere2,0,0,150

sphere3 = CreateSphere()
EntityColor sphere3,0,150,0

sphere4 = CreateSphere()
EntityColor sphere4,150,0,0

r1 = dpCreateArea(0,10)
r2 = dpCreateArea(0,2)
r3 = dpCreateArea(0,3)

dpPositionArea(r1,0,0,0)
dpPositionArea(r2,0,0,0)
dpPositionArea(r3,0,0,0)


While Not dpControlErrors() <> 0 Or KeyHit(1)

If KeyDown(17)
        dpPropelArea(r1,1,0,0)
EndIf

dpAttachEntity(sphere1,r1)
dpAttachEntity(sphere2,r2)
dpAttachEntity(sphere3,r3)

dpUpdateAreas()

UpdateWorld()
RenderWorld()

Flip

Wend

If dpControlErrors() <> 0
        Print dpControlErrors()
EndIf

WaitKey()

End

UPD. Решается с помощью задержки в Blitz-е, а не в Барсике: для 9 команд подходит Delay(40)


Часовой пояс GMT +4, время: 12:11.

vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot