Page4_En.html 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305
  1. <html>
  2. <head>
  3. <title>
  4. Bind a Dll to LuaEdit (Tutorial) - Controling and binding the Game
  5. </title>
  6. <link rel="stylesheet" href="..\Tutorial.css" type="text/css">
  7. </head>
  8. <body bgcolor="#FFFFFF" vlink="silver" alink="navy" link="navy">
  9. <table width="100%" border="0" cellpadding="0" cellspacing="0" summary="">
  10. <tr>
  11. <td valign="bottom">
  12. <div align="left">
  13. <b><font face="Tahoma" size="3" color="navy">Controling and binding the Game</font></b>
  14. </div>
  15. </td>
  16. <td>
  17. <font face="Tahoma" size="1" color="silver">
  18. <div align="right" valign="top">
  19. <a href="http://www.lua.org">Lua homepage</a>
  20. </div>
  21. </font>
  22. </td>
  23. </tr>
  24. <tr valign="top">
  25. <td colspan="2">
  26. <hr size="1" color="#000000">
  27. <br>
  28. <br>
  29. <font face="Tahoma" size="2">
  30. <p style="text-align:justify">
  31. Now that we have something to start with, it's time to actually control
  32. the game through that main loop.
  33. </p>
  34. <br>
  35. </font>
  36. </td>
  37. </tr>
  38. <tr>
  39. <td colspan="2">
  40. <font face="Tahoma" size="2">
  41. <p style="text-align:justify">
  42. Before the simon.Create() function call previously added, we will add a new call
  43. to the simon.SetMediaPath() function. This will specify the game's engine to look
  44. in the specified directory to find its multimedia files (*.wav). Here is how the whole
  45. chunk should looks like:
  46. </p>
  47. <br>
  48. </td>
  49. </tr>
  50. <tr>
  51. <td class="code" colspan="2">
  52. <br>
  53. <blockquote>
  54. -- Show Simon game main form<br>
  55. simon.SetMediaPath("C:\\Prog\\Delphi\\MNet\\Bin\\Medias")<br>
  56. simon.Create()<br><br>
  57. -- Main processing loop<br>
  58. while simon.GetPowerStatus() == 1 do<br>
  59. &nbsp;&nbsp;&nbsp;&nbsp;if simon.GetPlayStatus() == 1 then<br>
  60. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;simon:Initialize()<br><br>
  61. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;-- Game processing loop<br>
  62. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;while GameState do<br>
  63. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;UserSequenceCount = 0<br>
  64. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;simon:AddSequence()<br>
  65. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;simon:DisplayMessage("Simon's Turn!", "clRed", 750)<br>
  66. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;simon:PlaySequence(MainSequence)<br><br>
  67. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;simon:DisplayMessage("Your Turn!", "clLime", 1000)<br>
  68. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GameState = simon.GetUserSequence(SequenceCount, 2000)<br><br>
  69. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if simon:GetScore() > 1000 then<br>
  70. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;simon:DisplayMessage("You Win!", "clAqua", -1)<br>
  71. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;GameState = false<br>
  72. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br>
  73. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;end<br>
  74. &nbsp;&nbsp;&nbsp;&nbsp;end<br><br>
  75. &nbsp;&nbsp;&nbsp;&nbsp;-- Make sure the processor doesn't runs for no reason<br>
  76. &nbsp;&nbsp;&nbsp;&nbsp;Sleep(10)<br>
  77. end<br><br>
  78. simon.Destroy()<br>
  79. </blockquote>
  80. </td>
  81. </tr>
  82. <tr>
  83. <td colspan="2">
  84. <font face="Tahoma" size="2">
  85. <br>
  86. <br>
  87. <p style="text-align:justify">
  88. The function simon.GetPowerStatus() is used to determine if the "power" (in our
  89. case virtual) is still on. If this function returns 1, this means the "power" is still
  90. on. The simon.GetPlayerStatus() function returns 1 if the user pushed the "play" button.
  91. Calling simon.DisplayMessage() will display the specified string using the specified
  92. color (for color codes, look at the "Delphi/C++ Builder" column of
  93. <a href="http://www.iocomp.com/support/helpvcl/ioc01592.htm">this website</a>)
  94. and the specified length in miliseconds. In our case, this will be used to display whose turn it is.
  95. The function simon.GetUserSequence() will prompt the user to enter its sequence. The first
  96. argument specifies the length of the sequence to retrieve and the second one specifies
  97. the timeout value in miliseconds to use before considering the turn as wrong. In terms of
  98. execution in the Lua script, this call should hang the code while waiting for user's response
  99. but will eventually trigger automated calls to the simon:OnButtonClick() function everytime
  100. the user pushes a button from the game. This function also return the state of the game
  101. (false == game over). Now, the following should briefly explain how to configure the dll
  102. in C++/Delphi to actually allow LuaEdit to bind to your code, in this case: simon.dll. (The full
  103. code is available in the tutorial's sources but for a reason of time and complexity, it won't be explained in
  104. details like the simon.lua script. Only the "initializer" part will be.)
  105. </p>
  106. <p style="text-align:justify">
  107. As discussed in the <a href=".\Page1_En.html">part 1</a> of the tutorial, your dll MUST export the
  108. specific function LuaDebug_Initializer(). This function will be called by LuaEdit right before starting
  109. a debugging session. We will then use this "hook"/"callback" to register all of the game's engine
  110. functions previously described. This will map the functions in Lua and prevent LuaEdit from yelding
  111. errors because it can't find any reference to the function from the script. This way, runtime debugging
  112. will be available through LuaEdit.
  113. </p>
  114. <br>
  115. <b>Delphi:</b> (This function must be added in the "exports" instruction area of your code just like all the registred functions referenced in it)
  116. <br>
  117. <br>
  118. </td>
  119. </tr>
  120. <tr>
  121. <td class="code" colspan="2">
  122. <br>
  123. <blockquote>
  124. // Register a c function in a specified table<br>
  125. procedure LuaRegisterCustom(L: PLua_State; ndx: Integer; funcname: String; func: lua_CFunction);<br>
  126. begin<br>
  127. &nbsp;&nbsp;&nbsp;&nbsp;lua_pushstring(L, funcname);<br>
  128. &nbsp;&nbsp;&nbsp;&nbsp;lua_pushcfunction(L, func);<br>
  129. &nbsp;&nbsp;&nbsp;&nbsp;lua_rawset(L, ndx - 2);<br>
  130. end;<br><br>
  131. // Register a c function using the globalsindex constant<br>
  132. procedure LuaRegister(L: PLua_State; funcname: String; func: lua_CFunction);<br>
  133. begin<br>
  134. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, LUA_GLOBALSINDEX, funcname, func);<br>
  135. end;<br><br>
  136. // LuaEdit is calling this function everytime a script with a project<br>
  137. // specifying this dll as the initializer when debugging<br>
  138. function LuaDebug_Initializer(L: PLua_State): Integer;<br>
  139. begin<br>
  140. &nbsp;&nbsp;&nbsp;&nbsp;// Create new table on the lua stack<br>
  141. &nbsp;&nbsp;&nbsp;&nbsp;lua_newtable(L);<br><br>
  142. &nbsp;&nbsp;&nbsp;&nbsp;// Register delphi functions in that new table<br>
  143. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'SetMediaPath', SetMediaPath);<br>
  144. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'SetLight', SetLight);<br>
  145. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'Create', Create);<br>
  146. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'Destroy', Destroy);<br>
  147. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'GetUserSequence', GetUserSequence);<br>
  148. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'GetPowerStatus', GetPowerStatus);<br>
  149. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'GetPlayStatus', GetPlayStatus);<br>
  150. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'SetScore', SetScore);<br>
  151. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'GetScore', GetScore);<br>
  152. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'LockControls', LockControls);<br>
  153. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'UnlockControls', UnlockControls);<br>
  154. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, 'DisplayMessage', DisplayMessage);<br><br>
  155. &nbsp;&nbsp;&nbsp;&nbsp;// Register other miscalleneous functions<br>
  156. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegister(L, 'Sleep', LuaSleep);<br><br>
  157. &nbsp;&nbsp;&nbsp;&nbsp;// Assing "simon" lua global variable to the new table<br>
  158. &nbsp;&nbsp;&nbsp;&nbsp;lua_setglobal(L, 'simon');<br>
  159. end;<br>
  160. </blockquote>
  161. </td>
  162. </tr>
  163. <tr>
  164. <td colspan="2">
  165. <font face="Tahoma" size="2">
  166. <br>
  167. <br>
  168. <b>C/C++:</b> (This function must be added in the "EXPORTS" instruction area of your *.def file just like all the registred functions referenced in it)
  169. <br>
  170. <br>
  171. </td>
  172. </tr>
  173. <tr>
  174. <td class="code" colspan="2">
  175. <br>
  176. <blockquote>
  177. // Register a c function in a specified table<br>
  178. void LuaRegisterCustom(lua_State *L, long ndx, const char* funcname, lua_CFunction func)<br>
  179. {<br>
  180. &nbsp;&nbsp;&nbsp;&nbsp;lua_pushstring(L, funcname);<br>
  181. &nbsp;&nbsp;&nbsp;&nbsp;lua_pushcfunction(L, func);<br>
  182. &nbsp;&nbsp;&nbsp;&nbsp;lua_rawset(L, ndx - 2);<br>
  183. }<br><br>
  184. // Register a c function using the globalsindex constant<br>
  185. void LuaRegister(lua_State *L, const char* funcname, lua_CFunction func)<br>
  186. {<br>
  187. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, LUA_GLOBALSINDEX, funcname, func);<br>
  188. }<br><br>
  189. // LuaEdit is calling this function everytime a script with a project<br>
  190. // specifying this dll as the initializer when debugging<br>
  191. int LuaDebug_Initializer(lua_State *L)<br>
  192. {<br>
  193. &nbsp;&nbsp;&nbsp;&nbsp;// Create new table on the lua stack<br>
  194. &nbsp;&nbsp;&nbsp;&nbsp;lua_newtable(L);<br><br>
  195. &nbsp;&nbsp;&nbsp;&nbsp;// Register delphi functions in that new table<br>
  196. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "SetMediaPath", SetMediaPath);<br>
  197. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "SetLight", SetLight);<br>
  198. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "Create", Create);<br>
  199. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "Destroy", Destroy);<br>
  200. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "GetUserSequence", GetUserSequence);<br>
  201. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "GetPowerStatus", GetPowerStatus);<br>
  202. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "GetPlayStatus", GetPlayStatus);<br>
  203. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "SetScore", SetScore);<br>
  204. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "GetScore", GetScore);<br>
  205. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "LockControls", LockControls);<br>
  206. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "UnlockControls", UnlockControls);<br>
  207. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegisterCustom(L, -1, "DisplayMessage", DisplayMessage);<br><br>
  208. &nbsp;&nbsp;&nbsp;&nbsp;// Register other miscalleneous functions<br>
  209. &nbsp;&nbsp;&nbsp;&nbsp;LuaRegister(L, "Sleep", LuaSleep);<br><br>
  210. &nbsp;&nbsp;&nbsp;&nbsp;// Assing "simon" lua global variable to the new table<br>
  211. &nbsp;&nbsp;&nbsp;&nbsp;lua_setglobal(L, "simon");<br>
  212. }<br>
  213. </blockquote>
  214. </td>
  215. </tr>
  216. <tr>
  217. <td colspan="2">
  218. <font face="Tahoma" size="2">
  219. <br>
  220. <br>
  221. <p style="text-align:justify">
  222. The LuaRegisterCustom() and LuaRegister() functions will simplify the code's complexity
  223. since we would have had to repeat those 3 lines of code for every function that
  224. we needed to register in the Lua environment. Now, to complete this project/turotial,
  225. all you need to do is inspired yourself from the supplied code and finish the dll. As mentioned
  226. higher, this part will not be explained in detail.
  227. </p>
  228. <br>
  229. <p style="text-align:justify">
  230. Now you've seen enough to know how Lua works in interaction with LuaEdit to eventually
  231. build your own project that way so that Lua code can finally be an easy thing to debug.
  232. I hope this tutorial helped you in many ways. If you still have questions you can always
  233. post a new thread in the <a href="">"Tutorial" section</a> of our forum or feel free to
  234. contact me at the following address: <a href="mailto:[email protected]?subject=About Bind a Dll to LuaEdit (Tutorial)...">
  235. [email protected]</a>. Thank you very much for using this tutorial and good luck in your future projects!
  236. </p>
  237. </td>
  238. </tr>
  239. <tr>
  240. <td colspan="2">
  241. <font face="Tahoma" size="2">
  242. <br>
  243. <br>
  244. <b>Hints:</b>
  245. <ul type="square">
  246. <li>Try live debugging with the script you just finished using the compiled simon.dll
  247. and lua.dll located in the bin folder. Copy/paste the project and Lua script you
  248. created in that same folder, launch LuaEdit, set a breakpoint somewhere and press
  249. play.</li>
  250. <li>Try adding some "Level" logic in the Lua code by modifying the game's variants
  251. such as the sequence display speed, the player's timeout, the number of
  252. items added to the main sequence per turn, etc...</li>
  253. <li>Challenge your firends with some "impossible to win" scripts! :P</li>
  254. <li>For more advanced users, try adding a multiplayer engine to play over LAN.</li>
  255. <li>Implement an *.exe application that will launch the dll the same way LuaEdit
  256. does by calling at first the LuaDebug_Initializer() function and then loading
  257. the Lua script using the luaL_loadbuffer() API. See Delphi code of the SimonExec
  258. project.</li>
  259. </ul>
  260. </p>
  261. </td>
  262. </tr>
  263. <tr>
  264. <td valign="bottom">
  265. <font face="Tahoma" size="2">
  266. <div align="left" valign="bottom">
  267. <a href=".\Page3_En.html">&lt;&lt; Previous</a>
  268. </div>
  269. </td>
  270. </tr>
  271. <tr>
  272. <td colspan="2">
  273. <font face="Tahoma" size="1" color="silver">
  274. <hr size="1" color="#000000">
  275. <div align="right">
  276. <a href="http://www.luaedit.org">www.luaedit.org</a>
  277. <br>
  278. © Copyright 2004-2005 LuaEdit
  279. <br>
  280. Bind a Dll to LuaEdit (Tutorial)
  281. </div>
  282. </font>
  283. </td>
  284. </tr>
  285. </table>
  286. </body>
  287. </html>