max2d.bmx 51 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817
  1. SuperStrict
  2. Rem
  3. bbdoc: Graphics/Max2D
  4. End Rem
  5. Module BRL.Max2D
  6. ModuleInfo "Version: 1.23"
  7. ModuleInfo "Author: Mark Sibly, Simon Armstrong"
  8. ModuleInfo "License: zlib/libpng"
  9. ModuleInfo "Copyright: Blitz Research Ltd"
  10. ModuleInfo "Modserver: BRL"
  11. ModuleInfo "History: 1.23"
  12. ModuleInfo "History: Changed to SuperStrict"
  13. ModuleInfo "History: Extended flags to Long"
  14. ModuleInfo "History: 1.22 Release"
  15. ModuleInfo "History: fixed ResetCollision not resetting recycled collision quads"
  16. ModuleInfo "History: 1.21 Release"
  17. ModuleInfo "History: makecurrent now does validate before initial cls"
  18. ModuleInfo "History: 1.20 Release"
  19. ModuleInfo "History: Fixed TImageFont.Draw so it uses float translation"
  20. ModuleInfo "History: 1.19 Release"
  21. ModuleInfo "History: Fixed collision bug with non alpha/masked images"
  22. ModuleInfo "History: 1.18 Release"
  23. ModuleInfo "History: Add Flip Hook and polledinput"
  24. ModuleInfo "History: 1.17 Release"
  25. ModuleInfo "History: Added MIPMAPPEDIMAGE to smooth fonts"
  26. ModuleInfo "History: Fixed ImageFont TImage.Load parameters in wrong order!"
  27. ModuleInfo "History: 1.16 Release"
  28. ModuleInfo "History: Improved ImageFont unicode support"
  29. ModuleInfo "History: 1.15 Release"
  30. ModuleInfo "History: Added OnEnd EndGraphics"
  31. ModuleInfo "History: 1.14 Release"
  32. ModuleInfo "History: CreateImage/LockImage now always returns RGBA8888 pixmap"
  33. ModuleInfo "History: Fixed multiple Graphics calls crashing due to using Flip before DetectSync"
  34. ModuleInfo "History: 1.13 Release"
  35. ModuleInfo "History: LoadImageFont generates filteredimage images only for smoothfont fonts"
  36. ModuleInfo "History: 1.12 Release"
  37. ModuleInfo "History: Added MIPMAPPEDIMAGE flag"
  38. ModuleInfo "History: 1.11 Release"
  39. ModuleInfo "History: Fixed Garbage at graphics startup"
  40. ModuleInfo "History: 1.10 Release"
  41. ModuleInfo "History: Fixed LockImage bug"
  42. ModuleInfo "History: 1.09 Release"
  43. ModuleInfo "History: Integrated with new graphics system"
  44. ModuleInfo "History: ImageFrames now lazily evaluated"
  45. ModuleInfo "History: Fixed GetMaskColor"
  46. ModuleInfo "History: 1.08 Release"
  47. ModuleInfo "History: Collision system optimized"
  48. ModuleInfo "History: Graphics now does an EndGraphics first"
  49. ModuleInfo "History: 1.07 Release"
  50. ModuleInfo "History: 1.06 Release"
  51. ModuleInfo "History: Added GetLineWidth:Float()"
  52. ModuleInfo "History: Added GetClsColor( red Var,green Var,blue Var )"
  53. ModuleInfo "History: Fixed Object reference bug in Collision system"
  54. ModuleInfo "History: 1.05 Release"
  55. ModuleInfo "History: Fixed AnimImage collisions"
  56. ModuleInfo "History: Fixed ImagesCollide/ImagesCollide2 parameter types"
  57. Import BRL.PolledInput
  58. Import BRL.LinkedList
  59. Import BRL.Hook
  60. Import "image.bmx"
  61. Import "renderimage.bmx"
  62. Import "driver.bmx"
  63. Import "imagefont.bmx"
  64. Private
  65. Global gc:TMax2DGraphics
  66. Function UpdateTransform()
  67. Local s:Float=Sin(gc.tform_rot)
  68. Local c:Float=Cos(gc.tform_rot)
  69. gc.tform_ix= c*gc.tform_scale_x
  70. gc.tform_iy=-s*gc.tform_scale_y
  71. gc.tform_jx= s*gc.tform_scale_x
  72. gc.tform_jy= c*gc.tform_scale_y
  73. _max2dDriver.SetTransform gc.tform_ix,gc.tform_iy,gc.tform_jx,gc.tform_jy
  74. SetCollisions2DTransform gc.tform_ix,gc.tform_iy,gc.tform_jx,gc.tform_jy
  75. End Function
  76. Public
  77. Type TMax2DGraphics Extends TGraphics
  78. 'Field color_red,color_green,color_blue
  79. Field color:SColor8
  80. Field color_alpha:Float
  81. 'Field clscolor_red,clscolor_green,clscolor_blue
  82. Field clscolor:SColor8
  83. Field line_width:Float
  84. Field tform_rot:Float,tform_scale_x:Float,tform_scale_y:Float
  85. Field tform_ix:Float,tform_iy:Float,tform_jx:Float,tform_jy:Float
  86. Field viewport_x:Int,viewport_y:Int,viewport_w:Int,viewport_h:Int
  87. Field origin_x:Float,origin_y:Float
  88. Field handle_x:Float,handle_y:Float
  89. Field image_font:TImageFont
  90. Field blend_mode:Int
  91. Field vres_width:Float,vres_height:Float
  92. Field vres_mousexscale:Float,vres_mouseyscale:Float
  93. Field g_width:Int,g_height:Int
  94. Global default_font:TImageFont
  95. Global mask_red:Int,mask_green:Int,mask_blue:Int
  96. Global auto_midhandle:Int
  97. Global auto_imageflags:Int=MASKEDIMAGE|FILTEREDIMAGE
  98. Field _graphics:TGraphics,_driver:TMax2DDriver,_setup:Int
  99. Field _ric:TRenderImageContext
  100. Method Driver:TMax2DDriver() Override
  101. Return _driver
  102. End Method
  103. Method GetSettings( width:Int Var,height:Int Var,depth:Int Var,hertz:Int Var,flags:Long Var, x:Int Var, y:Int Var ) Override
  104. Local w:Int,h:Int,d:Int,r:Int,f:Long,xp:Int,yp:Int
  105. _graphics.GetSettings w,h,d,r,f,xp,yp
  106. width=w
  107. height=h
  108. depth=d
  109. hertz=r
  110. flags=f
  111. x=-1
  112. y=-1
  113. End Method
  114. Method Close() Override
  115. If Not _graphics Return
  116. _graphics.Close
  117. _graphics=Null
  118. _driver=Null
  119. End Method
  120. Method Validate()
  121. Local w:Int,h:Int,d:Int,r:Int,f:Long,xp:Int,yp:Int
  122. _graphics.GetSettings w,h,d,r,f,xp,yp
  123. If w<>g_width Or h<>g_height
  124. g_width=w
  125. g_height=h
  126. vres_width=w
  127. vres_height=h
  128. vres_mousexscale=1
  129. vres_mouseyscale=1
  130. EndIf
  131. SetVirtualResolution vres_width,vres_height
  132. SetBlend blend_mode
  133. SetColor color
  134. SetAlpha color_alpha
  135. SetClsColor clscolor
  136. SetLineWidth line_width
  137. SetRotation tform_rot
  138. SetScale tform_scale_x,tform_scale_y
  139. SetViewport viewport_x,viewport_y,viewport_w,viewport_h
  140. SetOrigin origin_x,origin_y
  141. SetHandle -handle_x,-handle_y
  142. SetImageFont image_font
  143. End Method
  144. Method MakeCurrent()
  145. gc=Self
  146. _max2dDriver=TMax2DDriver( Driver() )
  147. Assert _max2dDriver
  148. Validate
  149. If _setup Return
  150. Cls
  151. Flip 0
  152. Cls
  153. Flip 0
  154. _setup=True
  155. End Method
  156. Function ClearCurrent()
  157. gc=Null
  158. _max2dDriver=Null
  159. End Function
  160. Function Current:TMax2DGraphics()
  161. Return gc
  162. End Function
  163. Function Create:TMax2DGraphics( g:TGraphics,d:TMax2DDriver )
  164. Local gw:Int,gh:Int,gd:Int,gr:Int,gf:Long,gx:Int,gy:Int
  165. g.GetSettings gw,gh,gd,gr,gf,gx,gy
  166. If Not default_font default_font=TImageFont.CreateDefault()
  167. Local t:TMax2DGraphics=New TMax2DGraphics
  168. t.g_width=gw
  169. t.g_height=gh
  170. t.blend_mode=MASKBLEND
  171. t.color = New SColor8(255, 255, 255)
  172. t.color_alpha=1
  173. t.clscolor = New SColor8(0, 0, 0)
  174. t.line_width=1
  175. t.tform_rot=0
  176. t.tform_scale_x=1
  177. t.tform_scale_y=1
  178. t.tform_ix=1
  179. t.tform_iy=0
  180. t.tform_jx=1
  181. t.tform_jy=0
  182. t.viewport_x=0
  183. t.viewport_y=0
  184. t.viewport_w=gw
  185. t.viewport_h=gh
  186. t.origin_x=0
  187. t.origin_y=0
  188. t.handle_x=0
  189. t.handle_y=0
  190. t.image_font=default_font
  191. t.vres_width=gw
  192. t.vres_height=gh
  193. t.vres_mousexscale=1
  194. t.vres_mouseyscale=1
  195. t._graphics=g
  196. t._driver=d
  197. t._setup=False
  198. Return t
  199. End Function
  200. Method Resize(width:Int, height:Int) Override
  201. _graphics.Resize(width, height)
  202. End Method
  203. Method Position(x:Int, y:Int) Override
  204. _graphics.Position(x, y)
  205. End Method
  206. Method CreateRenderImage:TRenderImage(width:Int, height:Int, UseLinearFlitering:Int = True, max2DGraphics:TGraphics = Null)
  207. If Not max2DGraphics Then max2DGraphics = self
  208. Local max2D:TMax2DGraphics = TMax2DGraphics(max2DGraphics)
  209. If Not max2D Then Return Null 'only supporting Max2D graphics
  210. If _ric And _ric.GraphicsContext() <> max2D._graphics
  211. _ric.Destroy()
  212. _ric = Null
  213. EndIf
  214. If Not _ric
  215. _ric = TRenderImageContext(max2D._driver.CreateRenderImageContext(max2D._graphics))
  216. EndIf
  217. 'sanity check
  218. ?debug
  219. Assert _ric <> Null, "The code for the current TGraphics instance doesn't exist yet for rendering to a texture, feel free to write one."
  220. ?
  221. Return _ric.CreateRenderImage(width, height, UseLinearFlitering)
  222. End Method
  223. Method DestroyRenderImage(renderImage:TRenderImage)
  224. ' sanity check
  225. ?debug
  226. Assert _ric <> Null, "No TRenderImage instances have been created"
  227. ?
  228. _ric.DestroyRenderImage(renderImage)
  229. End Method
  230. Method SetRenderImage(renderimage:TRenderImage)
  231. ' sanity check
  232. ?debug
  233. Assert _ric <> Null, "No TRenderImage instances have been created"
  234. ?
  235. _ric.SetRenderImage(renderimage)
  236. End Method
  237. Method CreatePixmapFromRenderImage:TPixmap(renderimage:TRenderImage)
  238. ' sanity check
  239. ?debug
  240. Assert _ric <> Null, "No TRenderImage instances have been created"
  241. ?
  242. Return _ric.CreatePixmapFromRenderImage(renderimage)
  243. End Method
  244. Method SetRenderImageViewport(renderimage:TRenderimage, x:Int, y:Int, width:Int, height:Int)
  245. ' sanity check
  246. ?debug
  247. Assert _ric <> Null, "No TRenderImage instances have been created"
  248. ?
  249. renderimage.SetViewport(x, y, width, height)
  250. End Method
  251. Method ClearRenderImage(renderimage:TRenderimage, r:Int=0, g:Int=0, b:Int=0, a:Float=0.0)
  252. ' sanity check
  253. ?debug
  254. Assert _ric <> Null, "No TRenderImage instances have been created"
  255. ?
  256. renderimage.Clear(r,g,b,a)
  257. End Method
  258. Method CreateRenderImageFromPixmap:TRenderImage(Pixmap:TPixmap, UseLinearFlitering:Int = True, max2DGraphics:TGraphics = Null)
  259. If Not max2DGraphics then max2DGraphics = self
  260. Local max2d:TMax2DGraphics = TMax2DGraphics(max2DGraphics)
  261. If Not max2d Then Return Null ' only supports Max2D
  262. If _ric And _ric.GraphicsContext() <> max2d._graphics
  263. _ric.Destroy()
  264. _ric = Null
  265. EndIf
  266. If Not _ric
  267. _ric = TRenderImageContext(max2D._driver.CreateRenderImageContext(max2D._graphics))
  268. EndIf
  269. 'sanity check
  270. ?debug
  271. Assert _ric <> Null, "The code for the current TGraphics instance doesn't exist yet for rendering to a texture, feel free to write one."
  272. Assert Pixmap <> Null, "Invalid pixmap"
  273. Assert Pixmap.Width <> 0 And Pixmap.Height <> 0, "Invalid pixmap"
  274. ?
  275. Return _ric.CreateRenderImageFromPixmap(Pixmap, UseLinearFlitering)
  276. End Method
  277. End Type
  278. Rem
  279. bbdoc: Clear graphics buffer
  280. about:
  281. Clears the graphics buffer to the current cls color as determined by #SetClsColor.
  282. End Rem
  283. Function Cls()
  284. _max2dDriver.Cls
  285. End Function
  286. Rem
  287. bbdoc: Set current #Cls color
  288. about:
  289. The @red, @green and @blue parameters should be in the range of 0 to 255.
  290. The default cls color is black.
  291. End Rem
  292. Function SetClsColor( red:Int,green:Int,blue:Int )
  293. gc.clscolor = New SColor8(red, green, blue)
  294. _max2dDriver.SetClsColor red,green,blue
  295. End Function
  296. Function SetClsColor( color:SColor8 )
  297. gc.clscolor = color
  298. _max2dDriver.SetClsColor color
  299. End Function
  300. Rem
  301. bbdoc: Get red, green and blue component of current cls color.
  302. returns: Red, green and blue values in the range 0..255 in the variables supplied.
  303. End Rem
  304. Function GetClsColor( red:Int Var,green:Int Var,blue:Int Var )
  305. red=gc.clscolor.r
  306. green=gc.clscolor.g
  307. blue=gc.clscolor.b
  308. End Function
  309. Rem
  310. bbdoc: Plot a pixel
  311. about:
  312. Sets the color of a single pixel on the back buffer to the current drawing color
  313. defined with the #SetColor command. Other commands that affect the operation of
  314. #Plot include #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
  315. End Rem
  316. Function Plot( x:Float,y:Float )
  317. _max2dDriver.Plot x+gc.origin_x,y+gc.origin_y
  318. End Function
  319. Rem
  320. bbdoc: Draw a rectangle
  321. about:
  322. Sets the color of a rectangular area of pixels using the current drawing color
  323. defined with the #SetColor command.
  324. Other commands that affect the operation of #DrawRect include #SetHandle, #SetScale,
  325. #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
  326. End Rem
  327. Function DrawRect( x:Float,y:Float,width:Float,height:Float )
  328. _max2dDriver.DrawRect..
  329. gc.handle_x,gc.handle_y,..
  330. gc.handle_x+width,gc.handle_y+height,..
  331. x+gc.origin_x,y+gc.origin_y
  332. End Function
  333. Rem
  334. bbdoc: Draw a line
  335. about:
  336. #DrawLine draws a line from @x, @y to @x2, @y2 with the current drawing color.
  337. BlitzMax commands that affect the drawing of lines include #SetLineWidth, #SetColor, #SetHandle,
  338. #SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
  339. The optional @draw_last_pixel parameter can be used to control whether the last pixel of the line is drawn or not.
  340. Not drawing the last pixel can be useful if you are using certain blending modes.
  341. End Rem
  342. Function DrawLine( x:Float,y:Float,x2:Float,y2:Float,draw_last_pixel:Int=True )
  343. _max2dDriver.DrawLine..
  344. gc.handle_x,gc.handle_y,..
  345. gc.handle_x+x2-x,gc.handle_y+y2-y,..
  346. x+gc.origin_x,y+gc.origin_y
  347. If Not draw_last_pixel Return
  348. Local px:Float=gc.handle_x+x2-x,py:Float=gc.handle_y+y2-y
  349. _max2dDriver.Plot..
  350. px*gc.tform_ix+py*gc.tform_iy+x+gc.origin_x,px*gc.tform_jx+py*gc.tform_jy+y+gc.origin_y
  351. End Function
  352. Rem
  353. bbdoc: Draw an oval
  354. about:
  355. #DrawOval draws an oval that fits in the rectangular area defined by @x, @y, @width
  356. and @height parameters.
  357. BlitzMax commands that affect the drawing of ovals include #SetColor, #SetHandle,
  358. #SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
  359. End Rem
  360. Function DrawOval( x:Float,y:Float,width:Float,height:Float )
  361. _max2dDriver.DrawOval..
  362. gc.handle_x,gc.handle_y,..
  363. gc.handle_x+width,gc.handle_y+height,..
  364. x+gc.origin_x,y+gc.origin_y
  365. End Function
  366. Rem
  367. bbdoc: Draw a polygon
  368. about:
  369. #DrawPoly draws a polygon with corners defined by an array of x#,y# coordinate pairs.
  370. BlitzMax commands that affect the drawing of polygons include #SetColor, #SetHandle,
  371. #SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
  372. End Rem
  373. Function DrawPoly( xy:Float[], indices:Int[] = Null )
  374. _max2dDriver.DrawPoly xy,..
  375. gc.handle_x,gc.handle_y,..
  376. gc.origin_x,gc.origin_y, indices
  377. End Function
  378. Rem
  379. bbdoc: Draw text
  380. about:
  381. #DrawText prints strings at position @x,@y of the graphics display using
  382. the current image font specified by the #SetImageFont command.
  383. Other commands that affect #DrawText include #SetColor, #SetHandle,
  384. #SetScale, #SetRotation, #SetOrigin, #SetViewPort, #SetBlend and #SetAlpha.
  385. It is recomended that the blend mode be set to ALPHABLEND using the #SetBlend
  386. command for non jagged antialiased text. Text that will be drawn at a smaller
  387. size using the #SetScale command should use fonts loaded with the SMOOTHFONT
  388. style to benefit from mip-mapped filtering, see #LoadImageFont for more information.
  389. End Rem
  390. Function DrawText( t:String,x:Float,y:Float )
  391. gc.image_font.Draw t,..
  392. x+gc.origin_x+gc.handle_x*gc.tform_ix+gc.handle_y*gc.tform_iy,..
  393. y+gc.origin_y+gc.handle_x*gc.tform_jx+gc.handle_y*gc.tform_jy,..
  394. gc.tform_ix,gc.tform_iy,gc.tform_jx,gc.tform_jy
  395. End Function
  396. Rem
  397. bbdoc: Draw an image to the back buffer
  398. about:
  399. Drawing is affected by the current blend mode, color, scale and rotation.
  400. If the blend mode is ALPHABLEND the image is affected by the current alpha value
  401. and images with alpha channels are blended correctly with the background.
  402. End Rem
  403. Function DrawImage( image:TImage,x:Float,y:Float,frame:Int=0 )
  404. Local x0:Float=-image.handle_x,x1:Float=x0+image.width
  405. Local y0:Float=-image.handle_y,y1:Float=y0+image.height
  406. Local iframe:TImageFrame=image.Frame(frame)
  407. If iframe iframe.Draw x0,y0,x1,y1,x+gc.origin_x,y+gc.origin_y,0,0,image.width,image.height
  408. End Function
  409. Rem
  410. bbdoc: Draw an image to a rectangular area of the back buffer
  411. about:
  412. @x, @y, @w and @h specify the destination rectangle to draw to.
  413. @frame is the image frame to draw.
  414. Drawing is affected by the current blend mode, color, scale and rotation.
  415. If the blend mode is ALPHABLEND, then the image is also affected by the current alpha value.
  416. End Rem
  417. Function DrawImageRect( image:TImage,x:Float,y:Float,w:Float,h:Float,frame:Int=0 )
  418. Local x0:Float=-image.handle_x,x1:Float=x0+w
  419. Local y0:Float=-image.handle_y,y1:Float=y0+h
  420. Local iframe:TImageFrame=image.Frame(frame)
  421. If iframe iframe.Draw x0,y0,x1,y1,x+gc.origin_x,y+gc.origin_y,0,0,image.width,image.height
  422. End Function
  423. Rem
  424. bbdoc: Draw a sub rectangle of an image to a rectangular area of the back buffer
  425. about:
  426. @x, @y, @w and @h specify the destination rectangle to draw to.
  427. @sx, @sy, @sw and @sh specify the source rectangle within the image to draw from.
  428. @hx and @hy specify a handle offset within the source rectangle.
  429. @frame is the image frame to draw.
  430. Drawing is affected by the current blend mode, color, scale and rotation.
  431. If the blend mode is ALPHABLEND, then the image is also affected by the current alpha value.
  432. End Rem
  433. Function DrawSubImageRect( image:TImage,x:Float,y:Float,w:Float,h:Float,sx:Float,sy:Float,sw:Float,sh:Float,hx:Float=0,hy:Float=0,frame:Int=0 )
  434. Local x0:Float=-hx*w/sw,x1:Float=x0+w
  435. Local y0:Float=-hy*h/sh,y1:Float=y0+h
  436. Local iframe:TImageFrame=image.Frame(frame)
  437. If iframe iframe.Draw x0,y0,x1,y1,x+gc.origin_x,y+gc.origin_y,sx,sy,sw,sh
  438. End Function
  439. Rem
  440. bbdoc: Draw an image in a tiled pattern
  441. about:
  442. #TileImage draws an image in a repeating, tiled pattern, filling the current viewport.
  443. End Rem
  444. Function TileImage( image:TImage,x:Float=0:Float,y:Float=0:Float,frame:Int=0 )
  445. Local iframe:TImageFrame=image.Frame(frame)
  446. If Not iframe Return
  447. _max2dDriver.SetTransform 1,0,0,1
  448. Local w:Int=image.width
  449. Local h:Int=image.height
  450. Local ox:Int=gc.viewport_x-w+1
  451. Local oy:Int=gc.viewport_y-h+1
  452. Local px:Float=x+gc.origin_x-image.handle_x
  453. Local py:Float=y+gc.origin_y-image.handle_y
  454. Local fx:Float=px-Floor(px)
  455. Local fy:Float=py-Floor(py)
  456. Local tx:Int=Floor(px)-ox
  457. Local ty:Int=Floor(py)-oy
  458. If tx>=0 tx=tx Mod w + ox Else tx=w - -tx Mod w + ox
  459. If ty>=0 ty=ty Mod h + oy Else ty=h - -ty Mod h + oy
  460. Local vr:Int=gc.viewport_x+gc.viewport_w,vb:Int=gc.viewport_y+gc.viewport_h
  461. Local iy:Int=ty
  462. While iy<vb
  463. Local ix:Int=tx
  464. While ix<vr
  465. iframe.Draw 0,0,w,h,ix+fx,iy+fy,0,0,w,h
  466. ix=ix+w
  467. Wend
  468. iy=iy+h
  469. Wend
  470. UpdateTransform
  471. End Function
  472. Rem
  473. bbdoc: Set current color
  474. about:
  475. The #SetColor command affects the color of #Plot, #DrawRect, #DrawLine, #DrawText,
  476. #DrawImage and #DrawPoly.
  477. The @red, @green and @blue parameters should be in the range of 0 to 255.
  478. End Rem
  479. Function SetColor( red:Int,green:Int,blue:Int )
  480. gc.color = New SColor8(red, green, blue)
  481. _max2dDriver.SetColor red,green,blue
  482. End Function
  483. Function SetColor( color:SColor8 )
  484. gc.color = color
  485. _max2dDriver.SetColor color
  486. End Function
  487. Rem
  488. bbdoc: Get red, green and blue component of current color.
  489. returns: Red, green and blue values in the range 0..255 in the variables supplied.
  490. End Rem
  491. Function GetColor( red:Int Var,green:Int Var,blue:Int Var )
  492. red=gc.color.r
  493. green=gc.color.g
  494. blue=gc.color.b
  495. End Function
  496. Function GetColor( color:SColor8 Var )
  497. color = gc.color
  498. End Function
  499. Rem
  500. bbdoc: Set current blend mode
  501. about:
  502. SetBlend controls how pixels are combined with existing pixels in the back buffer when drawing
  503. commands are used in BlitzMax.
  504. @blend should be one of:
  505. [ @{Blend mode} | @Effect
  506. * MASKBLEND | Pixels are drawn only if their alpha component is greater than .5
  507. * SOLIDBLEND | Pixels overwrite existing backbuffer pixels
  508. * ALPHABLEND | Pixels are alpha blended with existing backbuffer pixels
  509. * LIGHTBLEND | Pixel colors are added to backbuffer pixel colors, giving a 'lighting' effect
  510. * SHADEBLEND | Pixel colors are multiplied with backbuffer pixel colors, giving a 'shading' effect
  511. ]
  512. End Rem
  513. Function SetBlend( blend:Int )
  514. gc.blend_mode=blend
  515. _max2dDriver.SetBlend blend
  516. End Function
  517. Rem
  518. bbdoc: Get current blend mode
  519. returns: The current blend mode.
  520. About:
  521. See #SetBlend for possible return values.
  522. End Rem
  523. Function GetBlend:Int()
  524. Return gc.blend_mode
  525. End Function
  526. Rem
  527. bbdoc: Set current alpha level
  528. about:
  529. @alpha should be in the range 0 to 1.
  530. @alpha controls the transparancy level when the ALPHABLEND blend mode is in effect.
  531. The range from 0.0 to 1.0 allows a range of transparancy from completely transparent
  532. to completely solid.
  533. End Rem
  534. Function SetAlpha( alpha:Float )
  535. gc.color_alpha=alpha
  536. _max2dDriver.SetAlpha alpha
  537. End Function
  538. Rem
  539. bbdoc: Get current alpha setting.
  540. returns: the current alpha value in the range 0..1.0
  541. End Rem
  542. Function GetAlpha:Float()
  543. Return gc.color_alpha
  544. End Function
  545. Rem
  546. bbdoc: Sets pixel width of lines drawn with the #DrawLine command
  547. End Rem
  548. Function SetLineWidth( width:Float )
  549. gc.line_width=width
  550. _max2dDriver.SetLineWidth width
  551. End Function
  552. Rem
  553. bbdoc: Get line width
  554. returns: Current line width, in pixels
  555. End Rem
  556. Function GetLineWidth:Float()
  557. Return gc.line_width
  558. End Function
  559. Rem
  560. bbdoc: Set current mask color
  561. about:
  562. The current mask color is used to build an alpha mask when images are loaded or modified.
  563. The @red, @green and @blue parameters should be in the range of 0 to 255.
  564. End Rem
  565. Function SetMaskColor( red:Int,green:Int,blue:Int )
  566. gc.mask_red=red
  567. gc.mask_green=green
  568. gc.mask_blue=blue
  569. End Function
  570. Rem
  571. bbdoc: Get red, green and blue component of current mask color
  572. returns: Red, green and blue values in the range 0..255
  573. End Rem
  574. Function GetMaskColor( red:Int Var,green:Int Var,blue:Int Var )
  575. red=gc.mask_red
  576. green=gc.mask_green
  577. blue=gc.mask_blue
  578. End Function
  579. Rem
  580. bbdoc: Set virtual graphics resolution
  581. about:
  582. SetResolution allows you to set a 'virtual' resolution independent of the graphics resolution.
  583. This allows you to design an application to work at a fixed resolution, say 640 by 480, and run it
  584. at any graphics resolution.
  585. End Rem
  586. Function SetVirtualResolution( width:Float,height:Float )
  587. gc.vres_width=width
  588. gc.vres_height=height
  589. gc.vres_mousexscale=width/GraphicsWidth()
  590. gc.vres_mouseyscale=height/GraphicsHeight()
  591. _max2dDriver.SetResolution width,height
  592. End Function
  593. Rem
  594. bbdoc: Get virtual graphics resolution width
  595. End Rem
  596. Function VirtualResolutionWidth:Float()
  597. Return gc.vres_width
  598. End Function
  599. Rem
  600. bbdoc: Get virtual graphics resolution height
  601. End Rem
  602. Function VirtualResolutionHeight:Float()
  603. Return gc.vres_height
  604. End Function
  605. Rem
  606. bbdoc: Get virtual mouse X coordinate
  607. End Rem
  608. Function VirtualMouseX:Float()
  609. Return MouseX() * gc.vres_mousexscale
  610. End Function
  611. Rem
  612. bbdoc: Get virtual mouse Y coordinate
  613. End Rem
  614. Function VirtualMouseY:Float()
  615. Return MouseY() * gc.vres_mouseyscale
  616. End Function
  617. Rem
  618. bbdoc: Get virtual mouse X speed
  619. End Rem
  620. Function VirtualMouseXSpeed:Float()
  621. Return MouseXSpeed() * gc.vres_mousexscale
  622. End Function
  623. Rem
  624. bbdoc: Get virtual mouse Y speed
  625. End Rem
  626. Function VirtualMouseYSpeed:Float()
  627. Return MouseYSpeed() * gc.vres_mouseyscale
  628. End Function
  629. Rem
  630. bbdoc: Move virtual mouse
  631. End Rem
  632. Function MoveVirtualMouse( x:Float,y:Float )
  633. MoveMouse Int(x/gc.vres_mousexscale),Int(y/gc.vres_mouseyscale)
  634. End Function
  635. Rem
  636. bbdoc: Set drawing viewport
  637. about:
  638. The current ViewPort defines an area within the back buffer that all drawing is clipped to. Any
  639. regions of a DrawCommand that fall outside the current ViewPort are not drawn.
  640. End Rem
  641. Function SetViewport( x:Int,y:Int,width:Int,height:Int )
  642. gc.viewport_x=x
  643. gc.viewport_y=y
  644. gc.viewport_w=width
  645. gc.viewport_h=height
  646. Local x0:Int=Floor( x / gc.vres_mousexscale )
  647. Local y0:Int=Floor( y / gc.vres_mouseyscale )
  648. Local x1:Int=Floor( (x+width) / gc.vres_mousexscale )
  649. Local y1:Int=Floor( (y+height) / gc.vres_mouseyscale )
  650. _max2dDriver.SetViewport x0,y0,(x1-x0),(y1-y0)
  651. End Function
  652. Rem
  653. bbdoc: Get dimensions of current Viewport.
  654. returns: The horizontal, vertical, width and height values of the current Viewport in the variables supplied.
  655. End Rem
  656. Function GetViewport( x:Int Var,y:Int Var,width:Int Var,height:Int Var )
  657. x=gc.viewport_x
  658. y=gc.viewport_y
  659. width=gc.viewport_w
  660. height=gc.viewport_h
  661. End Function
  662. Rem
  663. bbdoc: Set drawing origin
  664. about:
  665. The current Origin is an x,y coordinate added to all drawing x,y coordinates after any rotation or scaling.
  666. End Rem
  667. Function SetOrigin( x:Float,y:Float )
  668. gc.origin_x=x
  669. gc.origin_y=y
  670. End Function
  671. Rem
  672. bbdoc: Get current origin position.
  673. returns: The horizontal and vertical position of the current origin.
  674. End Rem
  675. Function GetOrigin( x:Float Var,y:Float Var )
  676. x=gc.origin_x
  677. y=gc.origin_y
  678. End Function
  679. Rem
  680. bbdoc: Set drawing handle
  681. about:
  682. The drawing handle is a 2D offset subtracted from the x,y location of all
  683. drawing commands except #DrawImage as Images have their own unique handles.
  684. Unlike #SetOrigin the drawing handle is subtracted before rotation and scale
  685. are applied providing a 'local' origin.
  686. End Rem
  687. Function SetHandle( x:Float,y:Float )
  688. gc.handle_x=-x
  689. gc.handle_y=-y
  690. End Function
  691. Rem
  692. bbdoc: Get current drawing handle.
  693. returns: The horizontal and vertical position of the current drawing handle.
  694. End Rem
  695. Function GetHandle( x:Float Var,y:Float Var )
  696. x=-gc.handle_x
  697. y=-gc.handle_y
  698. End Function
  699. Rem
  700. bbdoc: Set current rotation
  701. about:
  702. @rotation is given in degrees and should be in the range 0 to 360.
  703. End Rem
  704. Function SetRotation( Rotation:Float )
  705. gc.tform_rot=Rotation
  706. UpdateTransform
  707. End Function
  708. Rem
  709. bbdoc: Get current Max2D rotation setting.
  710. returns: The rotation in degrees.
  711. End Rem
  712. Function GetRotation:Float()
  713. Return gc.tform_rot
  714. End Function
  715. Rem
  716. bbdoc: Set current scale
  717. about:
  718. @scale_x and @scale_y multiply the width and height of drawing
  719. commands where 0.5 will half the size of the drawing and 2.0 is equivalent
  720. to doubling the size.
  721. End Rem
  722. Function SetScale( scale_x:Float,scale_y:Float )
  723. gc.tform_scale_x=scale_x
  724. gc.tform_scale_y=scale_y
  725. UpdateTransform
  726. End Function
  727. Rem
  728. bbdoc: Get current Max2D scale settings.
  729. returns: The current x and y scale values in the variables supplied.
  730. End Rem
  731. Function GetScale( scale_x:Float Var,scale_y:Float Var )
  732. scale_x=gc.tform_scale_x
  733. scale_y=gc.tform_scale_y
  734. End Function
  735. Rem
  736. bbdoc: Set current rotation and scale
  737. about:
  738. SetTransform is a shortcut for setting both the rotation and
  739. scale parameters in Max2D with a single function call.
  740. End Rem
  741. Function SetTransform( Rotation:Float=0,scale_x:Float=1,scale_y:Float=1 )
  742. gc.tform_rot=Rotation
  743. gc.tform_scale_x=scale_x
  744. gc.tform_scale_y=scale_y
  745. UpdateTransform
  746. End Function
  747. Rem
  748. bbdoc: Make the mouse pointer visible
  749. End Rem
  750. Rem
  751. Function ShowMouse()
  752. _max2dDriver.SetMouseVisible True
  753. End Function
  754. End Rem
  755. Rem
  756. bbdoc: Make the mouse pointer invisible
  757. End Rem
  758. Rem
  759. Function HideMouse()
  760. _max2dDriver.SetMouseVisible False
  761. End Function
  762. End Rem
  763. Rem
  764. bbdoc: Load an image font
  765. returns: An image font object
  766. about:
  767. @style can be a combination of BOLDFONT, ITALICFONT and SMOOTHFONT
  768. flags. Use the SMOOTHFONT flag for improved filtering if the font is to be rotated or
  769. scaled.
  770. End Rem
  771. Function LoadImageFont:TImageFont( url:Object,size:Int,style:Int=SMOOTHFONT )
  772. Return TImageFont.Load( url,size,style )
  773. End Function
  774. Rem
  775. bbdoc: Set current image font
  776. about:
  777. In order to #DrawText in fonts other than the default system font use the #SetImageFont
  778. command with a font handle returned by the #LoadImageFont command.
  779. Use &{SetImageFont Null} to select the default, built-in font.
  780. End Rem
  781. Function SetImageFont( font:TImageFont )
  782. If Not font font=gc.default_font
  783. gc.image_font=font
  784. End Function
  785. Rem
  786. bbdoc: Get current image font.
  787. returns: The current image font.
  788. End Rem
  789. Function GetImageFont:TImageFont()
  790. Return gc.image_font
  791. End Function
  792. Rem
  793. bbdoc: Get width of text
  794. returns: the width, in pixels, of @text based on the current image font.
  795. about:
  796. This command is useful for calculating horizontal alignment of text when using
  797. the #DrawText command.
  798. End Rem
  799. Function TextWidth:Int( Text:String )
  800. Local width:Int=0
  801. For Local n:Int=0 Until Text.length
  802. Local i:Int=gc.image_font.CharToGlyph( Text[n] )
  803. If i<0 Continue
  804. width:+gc.image_font.LoadGlyph(i).Advance()
  805. Next
  806. Return width
  807. End Function
  808. Rem
  809. bbdoc: Get height of text
  810. returns: the height, in pixels, of @text based on the current image font.
  811. about:
  812. This command is useful for calculating vertical alignment of text when using
  813. the #DrawText command.
  814. End Rem
  815. Function TextHeight:Int( Text:String )
  816. Return gc.image_font.Height()
  817. Rem
  818. Local height=0
  819. For Local n=0 Until text.length
  820. Local c=text[n]-image_font.BaseChar()
  821. If c<0 Or c>=image_font.CountGlyphs() Continue
  822. Local x,y,w,h
  823. image_font.Glyph(c).GetRect( x,y,w,h )
  824. height=Max(height,h)
  825. Next
  826. Return height
  827. End Rem
  828. End Function
  829. Rem
  830. bbdoc: Load an image
  831. returns: A new image object
  832. about:
  833. @url can be either a string or an existing pixmap.
  834. @flags can be 0, -1 or any combination of:
  835. [ @{Flags value} | @{Effect}
  836. * MASKEDIMAGE | The image is masked with the current mask color.
  837. * FILTEREDIMAGE | The image is smoothed when scaled up to greater than its original
  838. size, when rotated, or when drawn at fractional pixel coordinates.
  839. * MIPMAPPEDIMAGE | The image is smoothed when scaled down to less than its original size.
  840. * DYNAMICIMAGE | The image can be modified using #LockImage or #GrabImage.
  841. ]
  842. Note MIPMAPPEDIMAGE images consume extra video memory, so this flag should only be used
  843. when really necessary.
  844. If flags is -1, the auto image flags are used: See #AutoImageFlags.
  845. To combine flags, use the | (boolean OR) operator.
  846. End Rem
  847. Function LoadImage:TImage( url:Object,flags:Int=-1 )
  848. If flags=-1 flags=gc.auto_imageflags
  849. Local image:TImage=TImage.Load( url,flags,gc.mask_red,gc.mask_green,gc.mask_blue )
  850. If Not image Return null
  851. If gc.auto_midhandle MidHandleImage image
  852. Return image
  853. End Function
  854. Rem
  855. bbdoc: Load a multi-frame image
  856. returns: An image object
  857. about:
  858. #LoadAnimImage extracts multiple image frames from a single, larger image. @url can be either a string or an
  859. existing pixmap.
  860. See #LoadImage for valid @flags values.
  861. End Rem
  862. Function LoadAnimImage:TImage( url:Object,cell_width:Int,cell_height:Int,first_cell:Int,cell_count:Int,flags:Int=-1 )
  863. If flags=-1 flags=gc.auto_imageflags
  864. Local image:TImage=TImage.LoadAnim( url,cell_width,cell_height,first_cell,cell_count,flags,gc.mask_red,gc.mask_green,gc.mask_blue )
  865. If Not image Return null
  866. If gc.auto_midhandle MidHandleImage image
  867. Return image
  868. End Function
  869. Rem
  870. bbdoc: Set an image's handle to an arbitrary point
  871. about:
  872. An image's handle is subtracted from the coordinates of #DrawImage before
  873. rotation and scale are applied.
  874. End Rem
  875. Function SetImageHandle( image:TImage,x:Float,y:Float )
  876. image.handle_x=x
  877. image.handle_y=y
  878. End Function
  879. Rem
  880. bbdoc: Enable or disable auto midhandle mode
  881. about:
  882. When auto midhandle mode is enabled, all images are automatically 'midhandled' (see #MidHandleImage)
  883. when they are created. If auto midhandle mode is disabled, images are handled by their top left corner.
  884. AutoMidHandle defaults to False after calling #Graphics.
  885. End Rem
  886. Function AutoMidHandle( enable:Int )
  887. gc.auto_midhandle=enable
  888. End Function
  889. Rem
  890. bbdoc: Set auto image flags
  891. about:
  892. The auto image flags are used by #LoadImage and #CreateImage when no image
  893. flags are specified. See #LoadImage for a full list of valid image flags.
  894. AutoImageFlags defaults to MASKEDIMAGE | FILTEREDIMAGE.
  895. End Rem
  896. Function AutoImageFlags( flags:Int )
  897. If flags=-1 Return
  898. gc.auto_imageflags=flags
  899. End Function
  900. Function GetAutoImageFlags:Int()
  901. Return gc.auto_imageflags
  902. End Function
  903. Rem
  904. bbdoc: Set an image's handle to its center
  905. End Rem
  906. Function MidHandleImage( image:TImage )
  907. image.handle_x=image.width*.5
  908. image.handle_y=image.height*.5
  909. End Function
  910. Rem
  911. bbdoc: Get width of an image
  912. returns: The width, in pixels, of @image
  913. End Rem
  914. Function ImageWidth:Int( image:TImage )
  915. Return image.width
  916. End Function
  917. Rem
  918. bbdoc: Get height of an image
  919. returns: The height, in pixels, of @image
  920. End Rem
  921. Function ImageHeight:Int( image:TImage )
  922. Return image.height
  923. End Function
  924. Rem
  925. bbdoc: Create an empty image
  926. returns: A new image object
  927. about:
  928. #CreateImage creates an 'empty' image, which should be initialized using either #GrabImage or #LockImage
  929. before being drawn.
  930. Please refer to #LoadImage for valid @flags values. The @flags value is always combined with DYNAMICIMAGE.
  931. End Rem
  932. Function CreateImage:TImage( width:Int,height:Int,frames:Int=1,flags:Int=-1 )
  933. If flags=-1 flags=gc.auto_imageflags
  934. Local image:TImage=TImage.Create( width,height,frames,flags|DYNAMICIMAGE,gc.mask_red,gc.mask_green,gc.mask_blue )
  935. If gc.auto_midhandle MidHandleImage image
  936. Return image
  937. End Function
  938. Rem
  939. bbdoc: Lock an image for direct access
  940. returns: A pixmap representing the image contents
  941. about:
  942. Locking an image allows you to directly access an image's pixels.
  943. Only images created with the DYNAMICIMAGE flag can be locked.
  944. Locked images must eventually be unlocked with #UnlockImage before they can be drawn.
  945. End Rem
  946. Function LockImage:TPixmap( image:TImage,frame:Int=0,read_lock:Int=True,write_lock:Int=True )
  947. Return image.Lock( frame,read_lock,write_lock )
  948. End Function
  949. Rem
  950. bbdoc: Unlock an image
  951. about:
  952. Unlocks an image previously locked with #LockImage.
  953. end rem
  954. Function UnlockImage( image:TImage,frame:Int=0 )
  955. End Function
  956. Rem
  957. bbdoc: Grab an image from the back buffer
  958. about:
  959. Copies pixels from the back buffer to an image frame.
  960. Only images created with the DYNAMICIMAGE flag can be grabbed.
  961. End Rem
  962. Function GrabImage( image:TImage,x:Int,y:Int,frame:Int=0 )
  963. Local pixmap:TPixmap=_max2dDriver.GrabPixmap( x,y,image.width,image.height )
  964. If image.flags&MASKEDIMAGE
  965. pixmap=MaskPixmap( pixmap,gc.mask_red,gc.mask_green,gc.mask_blue )
  966. EndIf
  967. image.SetPixmap frame,pixmap
  968. End Function
  969. Rem
  970. bbdoc: Draw pixmap
  971. end rem
  972. Function DrawPixmap( pixmap:TPixmap,x:Int,y:Int )
  973. _max2dDriver.DrawPixmap pixmap,x,y
  974. End Function
  975. Rem
  976. bbdoc: Grab pixmap
  977. end rem
  978. Function GrabPixmap:TPixmap( x:Int,y:Int,width:Int,height:Int )
  979. Return _max2dDriver.GrabPixmap( x,y,width,height )
  980. End Function
  981. Rem
  982. bbdoc: Create a new render image
  983. about:
  984. @width, @height specify the dimensions of the render image.
  985. @useLinearFlitering defines the image flag to filter images when scaling.
  986. @max2DGraphics is an optional parameter to pass a custom Max2DGraphics context.
  987. returns: #TRenderImage with the given dimension
  988. End Rem
  989. Function CreateRenderImage:TRenderImage(width:Int, height:Int, useLinearFlitering:Int = True, max2DGraphics:TMax2DGraphics = Null)
  990. Return gc.CreateRenderImage(width, height, useLinearFlitering, max2DGraphics)
  991. End Function
  992. Rem
  993. bbdoc: Create a render image from a given #TPixmap
  994. about:
  995. @pixmap defines the #TPixmap to create a new #TRenderImage from.
  996. @useLinearFlitering defines the image flag to filter images when scaling.
  997. @max2DGraphics is an optional parameter to pass a custom Max2DGraphics context.
  998. returns: #TRenderImage with the content of the passed #TPixmap
  999. End Rem
  1000. Function CreateRenderImageFromPixmap:TRenderImage(pixmap:TPixmap, useLinearFlitering:Int = True, max2DGraphics:TMax2DGraphics = Null)
  1001. Return gc.CreateRenderImageFromPixmap(pixmap, useLinearFlitering, max2DGraphics)
  1002. EndFunction
  1003. Rem
  1004. bbdoc: Destroy a no longer needed render image
  1005. End Rem
  1006. Function DestroyRenderImage(renderImage:TRenderImage)
  1007. gc.DestroyRenderImage(renderImage)
  1008. End Function
  1009. Rem
  1010. bbdoc: Set a render image as currently active render target
  1011. about:
  1012. @renderImage defines the render image to use as target. Set to Null to render on the default graphics buffer again.
  1013. End Rem
  1014. Function SetRenderImage(renderImage:TRenderImage)
  1015. gc.SetRenderImage(renderImage)
  1016. End Function
  1017. Rem
  1018. bbdoc: Clear content of the passed render image
  1019. about:
  1020. @renderImage defines the render image to clear.
  1021. @r, @g, @b define the red, green and blue components of the clear color. Range is 0 - 255.
  1022. @a defines the alpha value and is ranged 0.0 to 1.0.
  1023. End Rem
  1024. Function ClearRenderImage(renderImage:TRenderImage, r:Int=0, g:Int=0, b:Int=0, a:Float=0.0)
  1025. gc.ClearRenderImage(renderImage, r,g,b,a)
  1026. End Function
  1027. Rem
  1028. bbdoc: Create a #TPixmap from a render image
  1029. about:
  1030. @renderImage defines the render image from where the #TPixmap is to generate
  1031. returns: #TPixmap of the render image
  1032. End Rem
  1033. Function CreatePixmapFromRenderImage:TPixmap(renderImage:TRenderImage)
  1034. Return gc.CreatePixmapFromRenderImage(renderImage)
  1035. End Function
  1036. Rem
  1037. bbdoc: Set the viewport of the given render image
  1038. about:
  1039. @renderImage defines the render image to set the viewport for
  1040. @x, @y, @width, @height define the dimension of the viewport
  1041. End Rem
  1042. Function SetRenderImageViewport(renderImage:TRenderImage, x:Int, y:Int, width:Int, height:Int)
  1043. gc.SetRenderImageViewport(renderImage, x, y, width, height)
  1044. End Function
  1045. Rem
  1046. bbdoc: Backup the render image (from GPU to RAM)
  1047. about:
  1048. When a running application is suspended (eg user logs out from the OS or hibernation)
  1049. then Direct3D-graphics loose their context ("D3DERR_DEVICELOST").
  1050. To enable restoration an render image needs to "persist" as else after resume the texture
  1051. will be blank.
  1052. Use this for dynamically created render image content which you do not re-draw each frame.
  1053. Also use #RenderImageValid() to check if content needs to be recreated.
  1054. @renderImage defines the render image to backup
  1055. End Rem
  1056. Function PersistRenderImage:Int(renderImage:TRenderImage)
  1057. If renderImage Then Return renderImage.Persist()
  1058. Return False
  1059. End Function
  1060. Rem
  1061. bbdoc: Check if render image content is still valid
  1062. about:
  1063. When a running application is suspended (eg user logs out from the OS or hibernation)
  1064. then Direct3D-graphics loose their context ("D3DERR_DEVICELOST") and so the textures.
  1065. If that happens, the render image is flagged to no longer be valid.
  1066. @renderImage defines the render image to backup
  1067. returns: False if content the render image needs to be recreated
  1068. End Rem
  1069. Function RenderImageValid:Int(renderImage:TRenderImage)
  1070. If renderImage Then Return renderImage.Valid()
  1071. Return False
  1072. End Function
  1073. Rem
  1074. bbdoc: Mark a render image (in-)valid
  1075. about:
  1076. When a running application is suspended (eg user logs out from the OS or hibernation)
  1077. then Direct3D-graphics loose their context ("D3DERR_DEVICELOST") and so the textures.
  1078. Once you restored/recreated the content of your render image you can set it
  1079. to be valid again.
  1080. @renderImage defines the render image to backup
  1081. @bool defines the new state of the valid flag (True or False)
  1082. End Rem
  1083. Function SetRenderImageValid(renderImage:TRenderImage, bool:Int = True)
  1084. If renderImage Then renderImage.SetValid(bool)
  1085. End Function
  1086. Const COLLISION_LAYER_ALL:Int=0
  1087. Const COLLISION_LAYER_1:Int=$0001
  1088. Const COLLISION_LAYER_2:Int=$0002
  1089. Const COLLISION_LAYER_3:Int=$0004
  1090. Const COLLISION_LAYER_4:Int=$0008
  1091. Const COLLISION_LAYER_5:Int=$0010
  1092. Const COLLISION_LAYER_6:Int=$0020
  1093. Const COLLISION_LAYER_7:Int=$0040
  1094. Const COLLISION_LAYER_8:Int=$0080
  1095. Const COLLISION_LAYER_9:Int=$0100
  1096. Const COLLISION_LAYER_10:Int=$0200
  1097. Const COLLISION_LAYER_11:Int=$0400
  1098. Const COLLISION_LAYER_12:Int=$0800
  1099. Const COLLISION_LAYER_13:Int=$1000
  1100. Const COLLISION_LAYER_14:Int=$2000
  1101. Const COLLISION_LAYER_15:Int=$4000
  1102. Const COLLISION_LAYER_16:Int=$8000
  1103. Const COLLISION_LAYER_17:Int=$00010000
  1104. Const COLLISION_LAYER_18:Int=$00020000
  1105. Const COLLISION_LAYER_19:Int=$00040000
  1106. Const COLLISION_LAYER_20:Int=$00080000
  1107. Const COLLISION_LAYER_21:Int=$00100000
  1108. Const COLLISION_LAYER_22:Int=$00200000
  1109. Const COLLISION_LAYER_23:Int=$00400000
  1110. Const COLLISION_LAYER_24:Int=$00800000
  1111. Const COLLISION_LAYER_25:Int=$01000000
  1112. Const COLLISION_LAYER_26:Int=$02000000
  1113. Const COLLISION_LAYER_27:Int=$04000000
  1114. Const COLLISION_LAYER_28:Int=$08000000
  1115. Const COLLISION_LAYER_29:Int=$10000000
  1116. Const COLLISION_LAYER_30:Int=$20000000
  1117. Const COLLISION_LAYER_31:Int=$40000000
  1118. Const COLLISION_LAYER_32:Int=$80000000
  1119. Rem
  1120. bbdoc: Tests if two images collide
  1121. returns: True if any pixels of the two images specified at the given location overlap.
  1122. about:
  1123. #ImagesCollide uses the current Rotation and Scale factors from the most previous
  1124. call to #SetScale and #SetRotation to calculate at a pixel level if the two images collide.
  1125. End Rem
  1126. Function ImagesCollide:Int(image1:TImage,x1:Int,y1:Int,frame1:Int,image2:TImage,x2:Int,y2:Int,frame2:Int)
  1127. ResetCollisions COLLISION_LAYER_32
  1128. CollideImage image1,x1,y1,frame1,0,COLLISION_LAYER_32
  1129. If CollideImage(image2,x2,y2,frame2,COLLISION_LAYER_32,0) Return True
  1130. End Function
  1131. Rem
  1132. bbdoc: Tests if two images with arbitrary Rotation and Scales collide
  1133. returns: True if any pixels of the two images specified at the given location overlap.
  1134. about:
  1135. #ImagesCollide2 uses the specified Rotation and Scale paramteters
  1136. to calculate at a pixel level if the two images collide (overlap).
  1137. End Rem
  1138. Function ImagesCollide2:Int(image1:TImage,x1:Int,y1:Int,frame1:Int,rot1:Float,scalex1:Float,scaley1:Float,image2:TImage,x2:Int,y2:Int,frame2:Int,rot2:Float,scalex2:Float,scaley2:Float)
  1139. Local _scalex:Float,_scaley:Float,_rot:Float,res:Int
  1140. _rot=GetRotation()
  1141. GetScale _scalex,_scaley
  1142. ResetCollisions COLLISION_LAYER_32
  1143. SetRotation rot1
  1144. SetScale scalex1,scaley1
  1145. CollideImage image1,x1,y1,frame1,0,COLLISION_LAYER_32
  1146. SetRotation rot2
  1147. SetScale scalex2,scaley2
  1148. If CollideImage(image2,x2,y2,frame2,COLLISION_LAYER_32,0) res=True
  1149. SetRotation _rot
  1150. SetScale _scalex,_scaley
  1151. Return res
  1152. End Function
  1153. Rem
  1154. bbdoc: Clears collision layers specified by the value of @mask, mask=0 for all layers.
  1155. about:
  1156. The BlitzMax 2D collision system manages 32 layers, the @mask parameter can
  1157. be a combination of the following values or the special value COLLISION_LAYER_ALL in order
  1158. to perform collision operations on multiple layers.
  1159. Note: COLLISION_LAYER_32 is used by the #ImagesCollide and #ImagesCollide2 commands.
  1160. [ @Layer | @{Mask value}
  1161. * COLLISION_LAYER_ALL | 0
  1162. * COLLISION_LAYER_1 | $0001
  1163. * COLLISION_LAYER_2 | $0002
  1164. * COLLISION_LAYER_3 | $0004
  1165. * COLLISION_LAYER_4 | $0008
  1166. * COLLISION_LAYER_5 | $0010
  1167. * COLLISION_LAYER_6 | $0020
  1168. * COLLISION_LAYER_7 | $0040
  1169. * COLLISION_LAYER_8 | $0080
  1170. * COLLISION_LAYER_9 | $0100
  1171. * COLLISION_LAYER_10 | $0200
  1172. * COLLISION_LAYER_11 | $0400
  1173. * COLLISION_LAYER_12 | $0800
  1174. * COLLISION_LAYER_13 | $1000
  1175. * COLLISION_LAYER_14 | $2000
  1176. * COLLISION_LAYER_15 | $4000
  1177. * COLLISION_LAYER_16 | $8000
  1178. ]
  1179. EndRem
  1180. Function ResetCollisions(mask:Int=0)
  1181. Local i:Int,q:TQuad
  1182. For i=0 To 31
  1183. If mask=0 Or mask&(1 Shl i)
  1184. q=quadlayer[i]
  1185. If q
  1186. q.mask=Null
  1187. q.id=Null
  1188. While q.link
  1189. q=q.link
  1190. q.mask=Null
  1191. q.id=Null
  1192. Wend
  1193. q.link=freequads
  1194. q=quadlayer[i]
  1195. freequads=q
  1196. quadlayer[i]=Null
  1197. EndIf
  1198. EndIf
  1199. Next
  1200. End Function
  1201. Rem
  1202. bbdoc: Pixel accurate collision testing between transformed Images.
  1203. about:
  1204. The @collidemask specifies any layers to test for collision with.
  1205. The @writemask specifies which if any collision layers the @image is added to in it's currently transformed state.
  1206. The id specifies an object to be returned to future #CollideImage calls when collisions occur.
  1207. EndRem
  1208. Function CollideImage:Object[](image:TImage,x:Int,y:Int,frame:Int,collidemask:Int,writemask:Int,id:Object=Null)
  1209. Local q:TQuad
  1210. q=CreateQuad(image,frame,x,y,image.width,image.height,id)
  1211. Return CollideQuad(q,collidemask,writemask)
  1212. End Function
  1213. Rem
  1214. bbdoc: Pixel accurate collision testing between image layers
  1215. about:
  1216. The @collidemask specifies any layers to test for collision with.
  1217. The @writemask specifies which if any collision layers the @image is added to in it's currently transformed state.
  1218. The @id specifies an object to be returned to future #CollideImage calls when collisions occur.
  1219. EndRem
  1220. Function CollideRect:Object[](x:Int,y:Int,w:Int,h:Int,collidemask:Int,writemask:Int,id:Object=Null)
  1221. Local q:TQuad
  1222. q=CreateQuad(Null,0,x,y,w,h,id)
  1223. Return CollideQuad(q,collidemask,writemask)
  1224. End Function
  1225. Private
  1226. Global cix:Float,ciy:Float,cjx:Float,cjy:Float
  1227. Function SetCollisions2DTransform(ix:Float,iy:Float,jx:Float,jy:Float) 'callback from module Blitz2D
  1228. cix=ix
  1229. ciy=iy
  1230. cjx=jx
  1231. cjy=jy
  1232. End Function
  1233. Global TextureMaps:TPixmap[]
  1234. Global LineBuffer:Int[]
  1235. Global quadlayer:TQuad[32]
  1236. Global freequads:TQuad
  1237. Const POLYX:Int=0
  1238. Const POLYY:Int=1
  1239. Const POLYU:Int=2
  1240. Const POLYV:Int=3
  1241. Function DotProduct:Int(x0:Float,y0:Float,x1:Float,y1:Float,x2:Float,y2:Float)
  1242. Return (((x2-x1)*(y1-y0))-((x1-x0)*(y2-y1)))
  1243. End Function
  1244. Function ClockwisePoly(data:Float[],channels:Int) 'flips order if anticlockwise
  1245. Local count:Int,clk:Int,i:Int,j:Int
  1246. Local r0:Int,r1:Int,r2:Int
  1247. Local t:Float
  1248. count=Len(data)/channels
  1249. ' clock wise test
  1250. r0=0
  1251. r1=channels
  1252. clk=2
  1253. For i=2 To count-1
  1254. r2=r1+channels
  1255. If DotProduct(data[r0+POLYX],data[r0+POLYY],data[r1+POLYX],data[r1+POLYY],data[r2+POLYX],data[r2+POLYY])>=0 clk:+1
  1256. r1=r2
  1257. Next
  1258. If clk<count Return
  1259. ' flip order for anticockwise
  1260. r0=0
  1261. r1=(count-1)*channels
  1262. While r0<r1
  1263. For j=0 To channels-1
  1264. t=data[r0+j]
  1265. data[r0+j]=data[r1+j]
  1266. data[r1+j]=t
  1267. Next
  1268. r0:+channels
  1269. r1:-channels
  1270. Wend
  1271. End Function
  1272. Type rpoly
  1273. Field texture:TPixmap
  1274. Field data:Float[]
  1275. Field channels:Int,count:Int,size:Int
  1276. Field ldat:Float[],ladd:Float[]
  1277. Field rdat:Float[],radd:Float[]
  1278. Field Left:Int,Right:Int,top:Int
  1279. Field state:Int
  1280. End Type
  1281. Function RenderPolys:Int(vdata:Float[][],channels:Int[],textures:TPixmap[],renderspans:Int(polys:TList,count:Int,ypos:Int))
  1282. Local polys:rpoly[],p:rpoly,pcount:Int
  1283. Local active:TList
  1284. Local top:Int,bot:Int
  1285. Local n:Int,y:Int,h:Int,i:Int,j:Int,res:Int
  1286. Local data:Float[]
  1287. bot=$80000000
  1288. top=$7fffffff
  1289. n=Len(vdata)
  1290. ' create polys an array of poly renderers
  1291. polys=New rpoly[n]
  1292. For i=0 Until n
  1293. p=New rpoly
  1294. polys[i]=p
  1295. p.texture=textures[i]
  1296. p.data=vdata[i]
  1297. p.channels=channels[i]
  1298. p.count=Len(p.data)/p.channels
  1299. p.size=p.count*p.channels
  1300. ClockwisePoly(p.data,p.channels) 'flips order if anticlockwise
  1301. ' find top verticies
  1302. p.Left=0
  1303. j=0
  1304. p.top=$7fffffff
  1305. While j<p.size
  1306. y=p.data[j+POLYY] 'float to int conversion
  1307. If y<p.top p.top=y;p.Left=j
  1308. If y<top top=y
  1309. If y>bot bot=y
  1310. j:+p.channels
  1311. Wend
  1312. p.Right=p.Left
  1313. Next
  1314. active=New TList
  1315. pcount=0
  1316. ' draw top to bottom
  1317. For y=top To bot-1
  1318. ' get left gradient
  1319. For p=EachIn polys
  1320. If p.state=2 Continue
  1321. If p.state=0 And y<p.top Continue
  1322. data=p.data
  1323. If y>=Int(data[p.Left+POLYY])
  1324. j=p.Left
  1325. i=(p.Left-p.channels)
  1326. If i<0 i:+p.size
  1327. While i<>p.Left
  1328. If Int(data[i+POLYY])>y Exit
  1329. j=i
  1330. i=(i-p.channels)
  1331. If i<0 i:+p.size
  1332. Wend
  1333. h=Int(data[i+POLYY])-Int(data[j+POLYY])
  1334. If i=p.Left Or h<=0
  1335. active.remove p
  1336. ' p.remove
  1337. pcount:-1
  1338. p.state=2
  1339. Continue
  1340. EndIf
  1341. p.ldat=data[j..j+p.channels]
  1342. p.ladd=data[i..i+p.channels]
  1343. For j=0 To p.channels-1
  1344. p.ladd[j]=(p.ladd[j]-p.ldat[j])/h
  1345. p.ldat[j]:+p.ladd[j]*0.5
  1346. Next
  1347. p.Left=i
  1348. If p.state=0
  1349. p.state=1
  1350. active.AddLast p
  1351. pcount:+1
  1352. EndIf
  1353. EndIf
  1354. ' get right gradient
  1355. If y>=Int(data[p.Right+POLYY])
  1356. i=(p.Right+p.channels) Mod p.size
  1357. j=p.Right
  1358. While i<>p.Right
  1359. If Int(data[i+POLYY])>y Exit
  1360. j=i
  1361. i=(i+p.channels)Mod p.size
  1362. Wend
  1363. h=Int(data[i+POLYY])-Int(data[j+POLYY])
  1364. If i=p.Right Or h<=0
  1365. active.remove p
  1366. pcount:-1
  1367. p.state=2
  1368. Continue
  1369. EndIf
  1370. p.rdat=data[j..j+p.channels]
  1371. p.radd=data[i..i+p.channels]
  1372. For j=0 To p.channels-1
  1373. p.radd[j]=(p.radd[j]-p.rdat[j])/h
  1374. p.rdat[j]:+p.radd[j]*0.5
  1375. Next
  1376. p.Right=i
  1377. If p.state=0
  1378. p.state=1
  1379. active.AddLast p
  1380. pcount:+1
  1381. EndIf
  1382. EndIf
  1383. Next
  1384. ' call renderer
  1385. If pcount
  1386. res=renderspans(active,pcount,y)
  1387. If res<0 Return res
  1388. EndIf
  1389. ' increment spans
  1390. For p=EachIn active
  1391. For j=0 To p.channels-1
  1392. p.ldat[j]:+p.ladd[j]
  1393. p.rdat[j]:+p.radd[j]
  1394. Next
  1395. Next
  1396. Next
  1397. Return res
  1398. End Function
  1399. Function CollideSpans:Int(polys:TList,count:Int,y:Int)
  1400. Local p:rpoly
  1401. Local startx:Int,endx:Int
  1402. Local x0:Int,x1:Int,w:Int,x:Int
  1403. Local u:Float,v:Float,ui:Float,vi:Float
  1404. Local pix:Int Ptr
  1405. Local src:TPixmap
  1406. Local tw:Int,th:Int,tp:Int,argb:Int
  1407. Local width:Int,skip:Float
  1408. startx=$7fffffff
  1409. endx=$80000000
  1410. If count<2 Return 0
  1411. p=rpoly(polys.ValueAtIndex(0))
  1412. startx=p.ldat[POLYX]
  1413. endx=p.rdat[POLYX]
  1414. p=rpoly(polys.ValueAtIndex(1))
  1415. x0=p.ldat[POLYX]
  1416. x1=p.rdat[POLYX]
  1417. If x0>=endx Return 0
  1418. If x1<=startx Return 0
  1419. If x0>startx startx=x0
  1420. If x1<endx endx=x1
  1421. width=endx-startx
  1422. If width<=0 Return 0
  1423. If width>Len(LineBuffer) LineBuffer=New Int[width]
  1424. MemClear LineBuffer,Size_T(width*4)
  1425. For p=EachIn polys
  1426. src=p.texture
  1427. If src
  1428. x0=p.ldat[POLYX]
  1429. x1=p.rdat[POLYX]
  1430. w=x1-x0
  1431. If w<=0 Continue
  1432. u=p.ldat[POLYU]
  1433. v=p.ldat[POLYV]
  1434. ui=(p.rdat[POLYU]-u)/w
  1435. vi=(p.rdat[POLYV]-v)/w
  1436. skip=(startx-x0)+0.5
  1437. u=u+ui*skip
  1438. v=v+vi*skip
  1439. pix=Int Ptr(src.pixels)
  1440. tw=src.width
  1441. th=src.height
  1442. tp=src.pitch/4
  1443. For x=0 Until width
  1444. If u<0.0 u=0.0
  1445. If v<0.0 v=0.0
  1446. If u>1.0 u=1.0
  1447. If v>1.0 v=1.0
  1448. ?BigEndian
  1449. argb=$00000080 & pix[(Int(v*th))*tp+(Int(u*tw))]
  1450. ?LittleEndian
  1451. argb=$80000000 & pix[(Int(v*th))*tp+(Int(u*tw))]
  1452. ?
  1453. If (argb)
  1454. If LineBuffer[x] Return -1
  1455. LineBuffer[x]=argb
  1456. EndIf
  1457. u:+ui
  1458. v:+vi
  1459. Next
  1460. Else
  1461. For x=0 Until width
  1462. If LineBuffer[x] Return -1
  1463. LineBuffer[x]=-1
  1464. Next
  1465. EndIf
  1466. Next
  1467. Return 0
  1468. End Function
  1469. Type TQuad
  1470. Field link:TQuad
  1471. Field id:Object
  1472. Field mask:TPixmap
  1473. Field frame:Int
  1474. Field minx:Float,miny:Float,maxx:Float,maxy:Float
  1475. Field xyuv:Float[16]
  1476. Method SetCoords(tx0:Float,ty0:Float,tx1:Float,ty1:Float,tx2:Float,ty2:Float,tx3:Float,ty3:Float)
  1477. xyuv[0]=tx0
  1478. xyuv[1]=ty0
  1479. xyuv[2]=0.0
  1480. xyuv[3]=0.0
  1481. xyuv[4]=tx1
  1482. xyuv[5]=ty1
  1483. xyuv[6]=1.0
  1484. xyuv[7]=0.0
  1485. xyuv[8]=tx2
  1486. xyuv[9]=ty2
  1487. xyuv[10]=1.0
  1488. xyuv[11]=1.0
  1489. xyuv[12]=tx3
  1490. xyuv[13]=ty3
  1491. xyuv[14]=0.0
  1492. xyuv[15]=1.0
  1493. minx=Min(Min(Min(tx0,tx1),tx2),tx3)
  1494. miny=Min(Min(Min(ty0,ty1),ty2),ty3)
  1495. maxx=Max(Max(Max(tx0,tx1),tx2),tx3)
  1496. maxy=Max(Max(Max(ty0,ty1),ty2),ty3)
  1497. End Method
  1498. End Type
  1499. Function QuadsCollide:Int(p:TQuad,q:TQuad)
  1500. If p.maxx<q.minx Or p.maxy<q.miny Or p.minx>q.maxx Or p.miny>q.maxy Return False
  1501. Local vertlist:Float[][2]
  1502. Local textures:TPixmap[2]
  1503. Local channels:Int[2]
  1504. vertlist[0]=p.xyuv
  1505. vertlist[1]=q.xyuv
  1506. textures[0]=p.mask
  1507. textures[1]=q.mask
  1508. channels[0]=4
  1509. channels[1]=4
  1510. Return RenderPolys(vertlist,channels,textures,CollideSpans)
  1511. End Function
  1512. Function CreateQuad:TQuad(image:TImage,frame:Int,x:Float,y:Float,w:Float,h:Float,id:Object)
  1513. Local x0:Float,y0:Float,x1:Float,y1:Float,tx:Float,ty:Float
  1514. Local tx0:Float,ty0:Float,tx1:Float,ty1:Float,tx2:Float,ty2:Float,tx3:Float,ty3:Float
  1515. Local minx:Float,miny:Float,maxx:Float,maxy:Float
  1516. Local q:TQuad
  1517. Local pix:TPixmap
  1518. If image
  1519. x0=-image.handle_x
  1520. y0=-image.handle_y
  1521. EndIf
  1522. x1=x0+w
  1523. y1=y0+h
  1524. tx=x+gc.origin_x
  1525. ty=y+gc.origin_y
  1526. tx0=x0*cix+y0*ciy+tx
  1527. ty0=x0*cjx+y0*cjy+ty
  1528. tx1=x1*cix+y0*ciy+tx
  1529. ty1=x1*cjx+y0*cjy+ty
  1530. tx2=x1*cix+y1*ciy+tx
  1531. ty2=x1*cjx+y1*cjy+ty
  1532. tx3=x0*cix+y1*ciy+tx
  1533. ty3=x0*cjx+y1*cjy+ty
  1534. If freequads
  1535. q=freequads
  1536. freequads=q.link
  1537. q.link=Null
  1538. Else
  1539. q=New TQuad
  1540. EndIf
  1541. q.id=id
  1542. If image
  1543. pix=image.Lock( frame,True,False )
  1544. If AlphaBitsPerPixel[pix.format] q.mask=pix
  1545. EndIf
  1546. q.setcoords(tx0,ty0,tx1,ty1,tx2,ty2,tx3,ty3)
  1547. Return q
  1548. End Function
  1549. Function CollideQuad:Object[](pquad:TQuad,collidemask:Int,writemask:Int)
  1550. Local result:Object[]
  1551. Local p:TQuad,q:TQuad
  1552. Local i:Int,j:Int,count:Int
  1553. p=pquad 'CreateImageQuad(image,frame,x,y)
  1554. ' check for collisions
  1555. For i=0 To 31
  1556. If collidemask & (1 Shl i)
  1557. q=quadlayer[i]
  1558. While q
  1559. If QuadsCollide(p,q)
  1560. If count=Len(result) result=result[..((count+4)*1.2)]
  1561. result[count]=q.id
  1562. count:+1
  1563. EndIf
  1564. q=q.link
  1565. Wend
  1566. EndIf
  1567. Next
  1568. ' write to layers
  1569. For i=0 To 31
  1570. If writemask & (1 Shl i)
  1571. If freequads
  1572. q=freequads
  1573. freequads=q.link
  1574. Else
  1575. q=New TQuad
  1576. EndIf
  1577. q.id=p.id; 'TODO:optimize with memcpy?
  1578. q.mask=p.mask;
  1579. q.frame=p.frame
  1580. MemCopy q.xyuv,p.xyuv,64
  1581. q.minx=p.minx;q.miny=p.miny;q.maxx=p.maxx;q.maxy=p.maxy;
  1582. q.link=quadlayer[i]
  1583. quadlayer[i]=q
  1584. EndIf
  1585. Next
  1586. ' return result
  1587. If count Return result[..count]
  1588. End Function