Автор Тема: CarRec  (Прочитано 11774 раз)

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
CarRec
« : Май 28, 2017, 01:34:43 am »
Решил я сделать "визуальный эквалайзер" для Dubstep-пушки(да простит меня Prographer за то что я влез и изнасиловал его идею), для чего понадобилось записать огромное кол-во значений в файл, который позднее был бы загружен скриптом. ini для этого не подходил(пустой расход ресурсов) - понадобилось создать бинарник средствами CLEO. Опыта у меня в этом не было, однако DK мне всё разъяснил и показал на конкретных примерах(за что ему еще раз огромнейшее спасибо!).
Однако пока я ковырял эту тему, на ум мне пришла ооочень старая идея, реализацию которой я несколько лет откладывал на "потом", а сейчас возникла реальная возможность её воплотить.
Подробная запись движения автомобиля.
Без лишних слов - вот 2 видоса:
! No longer available

! No longer available


Думаю, нет нужды объяснять, для чего такая запись может понадобиться(все помнят подобные сцены из SA, либо записи трюков в школе вождения), вопрос лишь в том, как лучше её произвести.

Я сделал так: взял(для начала) 19 переменных:
1)время
2-13)матрица позиции и поворота транспорта
14-16)скорость движения(movement speed) транспорта
17-19)сила вращения(turn speed) транспорта
20)переменная про запас(сейчас уже понял, что "докинуть" придется гораздо больше переменных)

На каждую переменную по 4 байта(знаю, что в SA версии всё гораздо экономнее, но за идеями оптимизации я сюда и пишу), 20x4=80 байт за такт x30 тактов в секунду при записи с ограничителем кадров = 2400 байт в секунду. Я сделал для теста лимит 4 млн байт(около получаса времени записи), однако если записывать без ограничителя кадров - может уходить до миллиона(!) байт в минуту, а то и больше. Скрипт написан так, что фреймрейт записи никак не влияет на скорость воспроизведения, так что никаких проблем с синхронизацией не возникнет.
Запись происходит в CLEO/carrec.cr
Активация/деактивация скрипта: C+R
Далее R - начать/закончить запись(можно писать поверх старого файла)
P - начать/закончить воспроизведение имеющейся записи.
При отсутствии carrec.cr файла воспроизведение не начнется.
Воспроизведение автоматически повторяется после завершения, пока не будет нажата P.

Код скрипта:
Код: Text
  1. {$CLEO .cs}
  2.  
  3. //-------------MAIN---------------
  4. thread 'CARREC'
  5.  
  6. :CARRECORD_01
  7. wait 0
  8. if and
  9.    Player.Defined($PLAYER_CHAR)
  10. 00E0:   player $PLAYER_CHAR driving
  11. jf @CARRECORD_01
  12. if and
  13. 0AB0: key_pressed 67 // C
  14. 0AB0: key_pressed 82 // R
  15. jf @CARRECORD_01
  16.  
  17. :CARRECORD_02
  18. wait 0
  19. if and
  20.    Player.Defined($PLAYER_CHAR)
  21. 00E0:   player $PLAYER_CHAR driving
  22. jf @CARRECORD_01
  23. if or
  24. 8AB0: NOT key_pressed 67 // C
  25. 8AB0: NOT key_pressed 82 // R
  26. jf @CARRECORD_02
  27. 03C1: 0@ = player $PLAYER_CHAR car_no_save
  28. 018C: play_sound 14 at 0.0 0.0 0.0
  29.  
  30. :CARRECORD_03
  31. wait 0
  32. 0AD1: show_formatted_text_highpriority "Car Recording Script is ~t~ready. ~h~Press ~o~R ~h~to start recording. ~h~Press ~p~P ~h~to play record." time 100
  33. if and
  34.    Player.Defined($PLAYER_CHAR)
  35. 00E0:   player $PLAYER_CHAR driving
  36. 8039:   NOT 0@ == -1
  37. 00DC:   player $PLAYER_CHAR driving 0@
  38. jf @CARRECORD_CANCEL
  39. if
  40. 0AB0: key_pressed 82 // R
  41. jf @CARRECORD_PLAY
  42. if
  43. 8AB0: NOT key_pressed 67 // C
  44. jf @CARRECORD_CANCEL
  45.  
  46. :CARRECORD_04
  47. wait 0
  48. if and
  49.    Player.Defined($PLAYER_CHAR)
  50. 00E0:   player $PLAYER_CHAR driving
  51. 8039:   NOT 0@ == -1
  52. 00DC:   player $PLAYER_CHAR driving 0@
  53. jf @CARRECORD_CANCEL
  54. if
  55. 8AB0: NOT key_pressed 82 // R
  56. jf @CARRECORD_04
  57. 0006: 1@ = 4000000 // memory limit
  58. 0AC8: 2@ = allocate_memory_size 1@
  59. 0006: 3@ = 0x00 // allocated memory offset
  60. 018C: play_sound 16 at 0.0 0.0 0.0
  61. 0006: 16@ = 0
  62.  
  63. :CARRECORD_05
  64. 0AD1: show_formatted_text_highpriority "~o~RECORDING: %d ms ~h~Press ~x~R ~h~to finish recording." time 100 16@
  65. if and
  66.    Player.Defined($PLAYER_CHAR)
  67. 00E0:   player $PLAYER_CHAR driving
  68. 8039:   NOT 0@ == -1
  69. jf @CARRECORD_END
  70. if and
  71. 00DC:   player $PLAYER_CHAR driving 0@
  72. 8AB0: NOT key_pressed 82 // R
  73. jf @CARRECORD_END
  74. 0AB1: call_scm_func @CARRECORD_RECORDING 4 0@ 2@ 3@ 16@ 3@
  75. wait 0
  76. 0085: 15@ = 1@
  77. 0062: 15@ -= 3@
  78. 000E: 15@ -= 0x50 // 80 bytes
  79. 001B:   0 > 15@ // if memory full
  80. jf @CARRECORD_05
  81. //jump @CARRECORD_END
  82.  
  83. :CARRECORD_END
  84. 0AB1: call_scm_func @CARRECORD_RECORDTOCR 2 2@ 3@
  85. 0AC9: free_allocated_memory 2@
  86. 018C: play_sound 10 at 0.0 0.0 0.0
  87. 0AD1: show_formatted_text_highpriority "Car Recording ~x~is finished. ~h~Time: ~x~%d ms." time 3000 16@
  88. jump @CARRECORD_01
  89.  
  90. :CARRECORD_CANCEL
  91. wait 0
  92. if or
  93. 8AB0: NOT key_pressed 67 // C
  94. 8AB0: NOT key_pressed 82 // R
  95. jf @CARRECORD_CANCEL
  96. 018C: play_sound 13 at 0.0 0.0 0.0
  97. 0AD1: show_formatted_text_highpriority "Car Recording Script ~y~deactivated!" time 2000
  98. jump @CARRECORD_01
  99.  
  100. :CARRECORD_PLAY
  101. if
  102. 0AB0: key_pressed 80 // P
  103. jf @CARRECORD_03
  104.  
  105. :CARRECORD_PLAY_02
  106. wait 0
  107. if and
  108.    Player.Defined($PLAYER_CHAR)
  109. 00E0:   player $PLAYER_CHAR driving
  110. 8039:   NOT 0@ == -1
  111. 00DC:   player $PLAYER_CHAR driving 0@
  112. jf @CARRECORD_CANCEL
  113. if
  114. 8AB0: NOT key_pressed 80 // P
  115. jf @CARRECORD_PLAY_02
  116. if
  117. 0AAB: file_exists "cleo\carrec.cr"
  118. jf @CARRECORD_CANCEL
  119. //04C4: create_coordinate 1@ 2@ 3@ from_actor $PLAYER_ACTOR offset 0.0 0.0 2.0
  120. //012A: put_player $PLAYER_CHAR at 1@ 2@ 3@ and_remove_from_car
  121. //0464: put_actor $PLAYER_ACTOR into_turret_on_car 0@ at_car_offset 0.0 0.0 1.0 position 0 angle 0.0 with_weapon 0
  122. //wait 0
  123. 0AB1: call_scm_func @CARRECORD_READCR 0 2@ 1@
  124.  
  125. :CARRECORD_PLAY_START
  126. 0006: 3@ = 0x00 // allocated memory offset
  127. 018C: play_sound 16 at 0.0 0.0 0.0
  128. 0227: 14@ = car 0@ health
  129. 0006: 16@ = 0
  130. 046C: 15@ = car 0@ driver
  131. 0039:   15@ == -1
  132. jf @CARRECORD_PLAY_05
  133. 03A2: set_car_status 0@ to 3
  134.  
  135. :CARRECORD_PLAY_05
  136. 0AD1: show_formatted_text_highpriority "~p~RECORD PLAYBACK: %d ms ~h~Press ~p~P ~h~to finish playback." time 100 16@
  137. //Camera.OnPed($PLAYER_ACTOR, 0, 2)
  138. if and
  139.    Player.Defined($PLAYER_CHAR)
  140. //00E0:   player $PLAYER_CHAR driving
  141. 8039:   NOT 0@ == -1
  142. jf @CARRECORD_PLAY_END
  143. if// and
  144. //00DC:   player $PLAYER_CHAR driving 0@
  145. 8AB0: NOT key_pressed 80 // P
  146. jf @CARRECORD_PLAY_END
  147. 0AB1: call_scm_func @CARRECORD_RECORDPLAYBACK 4 0@ 2@ 3@ 16@ 3@
  148. wait 0
  149. 0224: set_car 0@ health_to 14@
  150. 0085: 15@ = 1@
  151. 0062: 15@ -= 3@
  152. 000E: 15@ -= 0x50 // 80 bytes
  153. 001B:   0 > 15@ // if playback is finished
  154. jf @CARRECORD_PLAY_05
  155. jump @CARRECORD_PLAY_START
  156.  
  157. :CARRECORD_PLAY_END
  158. 0AC9: free_allocated_memory 2@
  159. //0465: remove_actor $PLAYER_ACTOR from_turret_mode
  160. //Camera.Restore_WithJumpCut
  161. 018C: play_sound 10 at 0.0 0.0 0.0
  162. 0AD1: show_formatted_text_highpriority "Car record playback ~x~is finished. ~h~Time: ~x~%d ms." time 3000 16@
  163. jump @CARRECORD_01
  164.  
  165. :CARRECORD_RECORDING
  166. // Recording Time:
  167. 0085: 15@ = 1@
  168. 005A: 15@ += 2@
  169. 0A8C: write_memory 15@ size 4 value 3@ virtual_protect 1 // recording time
  170. 000A: 15@ += 0x04
  171. 0A97: 14@ = car 0@ struct
  172. // Recording Matrix:
  173. 0085: 13@ = 14@
  174. 000A: 13@ += 0x04 // right x
  175. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  176. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording right x
  177. 000A: 15@ += 0x04
  178. 000A: 13@ += 0x04 // right y
  179. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  180. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording right y
  181. 000A: 15@ += 0x04
  182. 000A: 13@ += 0x04 // right z
  183. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  184. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording right z
  185. 000A: 15@ += 0x04
  186. 000A: 13@ += 0x08 // up x
  187. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  188. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording up x
  189. 000A: 15@ += 0x04
  190. 000A: 13@ += 0x04 // up y
  191. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  192. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording up y
  193. 000A: 15@ += 0x04
  194. 000A: 13@ += 0x04 // up z
  195. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  196. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording up z
  197. 000A: 15@ += 0x04
  198. 000A: 13@ += 0x08 // at x
  199. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  200. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording at x
  201. 000A: 15@ += 0x04
  202. 000A: 13@ += 0x04 // at y
  203. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  204. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording at y
  205. 000A: 15@ += 0x04
  206. 000A: 13@ += 0x04 // at z
  207. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  208. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording at z
  209. 000A: 15@ += 0x04
  210. 000A: 13@ += 0x08 // position x
  211. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  212. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording position x
  213. 000A: 15@ += 0x04
  214. 000A: 13@ += 0x04 // position y
  215. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  216. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording position y
  217. 000A: 15@ += 0x04
  218. 000A: 13@ += 0x04 // position z
  219. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  220. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording position z
  221. 000A: 15@ += 0x04
  222. // Recording Movement Speed:
  223. 0085: 13@ = 14@
  224. 000A: 13@ += 0x70 // x push
  225. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  226. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording x push
  227. 000A: 15@ += 0x04
  228. 000A: 13@ += 0x04 // y push
  229. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  230. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording y push
  231. 000A: 15@ += 0x04
  232. 000A: 13@ += 0x04 // z push
  233. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  234. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording z push
  235. 000A: 15@ += 0x04
  236. // Recording Turn Speed:
  237. 000A: 13@ += 0x04 // x turn speed
  238. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  239. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording x turn speed
  240. 000A: 15@ += 0x04
  241. 000A: 13@ += 0x04 // y turn speed
  242. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  243. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording y turn speed
  244. 000A: 15@ += 0x04
  245. 000A: 13@ += 0x04 // z turn speed
  246. 0A8D: 12@ = read_memory 13@ size 4 virtual_protect 1
  247. 0A8C: write_memory 15@ size 4 value 12@ virtual_protect 1 // recording z turn speed
  248. 000A: 2@ += 0x50
  249.  
  250. :CARRECORD_RECORDING_RETURN
  251. 0AB2: ret 1 2@
  252.  
  253. :CARRECORD_RECORDTOCR
  254. 0AA7: call_function 0x48DF90 num_params 2 pop 2 "wb" "cleo\\carrec.cr" 15@ // FILE *file = CFileMgr::Open("cleo\carrec.cr", "wb");
  255. 0AC7: 13@ = var 14@ offset                                           // float *var_offset = &vars[3];
  256. 0006: 12@ = 0x00
  257.  
  258. :CARRECORD_RECORDTOCR_02
  259. if
  260. 001D:   1@ > 12@
  261. jf @CARRECORD_RECORDTOCR_RETURN
  262. 0085: 11@ = 0@
  263. 005A: 11@ += 12@
  264. 0A8D: 14@ = read_memory 11@ size 4 virtual_protect 1
  265. 0AA5: call 0x48DF30 num_params 3 pop 3 4 13@ 15@                 //     CFileMgr::Write(file, var_offset, 4);
  266. 000A: 12@ += 0x04
  267. jump @CARRECORD_RECORDTOCR_02
  268.  
  269. :CARRECORD_RECORDTOCR_RETURN
  270. 0AA5: call 0x48DEA0 num_params 1 pop 1 15@                          // CFileMgr::Close(file);
  271. 0AB2: ret 0
  272.  
  273. :CARRECORD_READCR
  274. 0AA7: call_function 0x48DF90 num_params 2 pop 2 "rb" "cleo\\carrec.cr" 15@ // file = CFileMgr::Open("cleo\carrec.cr", "rb");
  275. // Get file size to 14@:
  276. 0AA5: call 0x48DEE0 num_params 3 pop 3 2 0 15@                      // CFileMgr::Seek(file, 0, SEEK_END);
  277. 0AA7: call_function 0x652D50 num_params 1 pop 1 15@ 14@              // size = ftell(file);
  278. // Go to beginning of the file:
  279. 0AA5: call 0x48DEE0 num_params 3 pop 3 0 0 15@                      // CFileMgr::Seek(file, 0, SEEK_SET);
  280. // Now start reading:
  281. 0AC8: 13@ = allocate_memory_size 14@
  282. 0006: 12@ = 0x00
  283.  
  284. :CARRECORD_READCR_02
  285. if
  286. 801D:   NOT 12@ > 14@
  287. jf @CARRECORD_READCR_RETURN
  288. 0085: 11@ = 13@
  289. 005A: 11@ += 12@
  290. 0AA5: call 0x48DF50 num_params 3 pop 3 4 11@ 15@                 //     CFileMgr::Read(file, var_offset, 4);
  291. 000A: 12@ += 0x04    
  292. jump @CARRECORD_READCR_02
  293.  
  294. :CARRECORD_READCR_RETURN
  295. 0AA5: call 0x48DEA0 num_params 1 pop 1 15@                          // CFileMgr::Close(file);
  296. 0AB2: ret 2 13@ 14@
  297.  
  298. :CARRECORD_RECORDPLAYBACK
  299. // Check Time:
  300. 0085: 15@ = 1@
  301. 005A: 15@ += 2@
  302. 0A8D: 14@ = read_memory 15@ size 4 virtual_protect 1
  303. 001D:   3@ > 14@
  304. jf @CARRECORD_RECORDPLAYBACK_RETURN
  305.  
  306. :CARRECORD_RECORDPLAYBACK_2
  307. 000A: 2@ += 0x50
  308. 0085: 15@ = 1@
  309. 005A: 15@ += 2@
  310. 0A8D: 14@ = read_memory 15@ size 4 virtual_protect 1
  311. 801D:   NOT 3@ > 14@
  312. jf @CARRECORD_RECORDPLAYBACK_2
  313. 000E: 2@ -= 0x50
  314. 0085: 15@ = 1@
  315. 005A: 15@ += 2@
  316. 000A: 15@ += 0x04
  317. 0A97: 14@ = car 0@ struct
  318. // Playback Matrix:
  319. 0085: 13@ = 14@
  320. 000A: 13@ += 0x04 // right x
  321. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  322. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback right x
  323. 000A: 15@ += 0x04
  324. 000A: 13@ += 0x04 // right y
  325. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  326. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback right y
  327. 000A: 15@ += 0x04
  328. 000A: 13@ += 0x04 // right z
  329. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  330. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback right z
  331. 000A: 15@ += 0x04
  332. 000A: 13@ += 0x08 // up x
  333. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  334. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback up x
  335. 000A: 15@ += 0x04
  336. 000A: 13@ += 0x04 // up y
  337. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  338. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback up y
  339. 000A: 15@ += 0x04
  340. 000A: 13@ += 0x04 // up z
  341. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  342. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback up z
  343. 000A: 15@ += 0x04
  344. 000A: 13@ += 0x08 // at x
  345. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  346. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback at x
  347. 000A: 15@ += 0x04
  348. 000A: 13@ += 0x04 // at y
  349. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  350. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback at y
  351. 000A: 15@ += 0x04
  352. 000A: 13@ += 0x04 // at z
  353. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  354. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback at z
  355. 000A: 15@ += 0x04
  356. 000A: 13@ += 0x08 // position x
  357. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  358. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback position x
  359. 000A: 15@ += 0x04
  360. 000A: 13@ += 0x04 // position y
  361. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  362. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback position y
  363. 000A: 15@ += 0x04
  364. 000A: 13@ += 0x04 // position z
  365. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  366. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback position z
  367. 000A: 15@ += 0x04
  368. // Playback Movement Speed:
  369. 0085: 13@ = 14@
  370. 000A: 13@ += 0x70 // x push
  371. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  372. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback x push
  373. 000A: 15@ += 0x04
  374. 000A: 13@ += 0x04 // y push
  375. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  376. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback y push
  377. 000A: 15@ += 0x04
  378. 000A: 13@ += 0x04 // z push
  379. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  380. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback z push
  381. 000A: 15@ += 0x04
  382. // Playback Turn Speed:
  383. 000A: 13@ += 0x04 // x turn speed
  384. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  385. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback x turn speed
  386. 000A: 15@ += 0x04
  387. 000A: 13@ += 0x04 // y turn speed
  388. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  389. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback y turn speed
  390. 000A: 15@ += 0x04
  391. 000A: 13@ += 0x04 // z turn speed
  392. 0A8D: 12@ = read_memory 15@ size 4 virtual_protect 1
  393. 0A8C: write_memory 13@ size 4 value 12@ virtual_protect 1 // playback z turn speed
  394. 000A: 2@ += 0x50
  395.  
  396.  :CARRECORD_RECORDPLAYBACK_RETURN
  397. 0AB2: ret 1 2@

Скрипт пока сырой(пока записывается лишь самое-самое необходимое) и публикую я его потому, что хотел спросить у вас какие-нибудь идеи того, что можно записывать в такой файл помимо уже имеющегося(разумеется, будут добавлены все оставшиеся переменные из формата SA) и при этом не переборщить с нагрузкой.
Перемножать и конвертировать, как в SA, некоторые float для превращения их в INT16 или INT8 мне не охота(мне не лень, просто не очень хочется ставить производительность во главе угла в ущерб точности в года, когда иметь 2х-ядерник - моветон), а вот узнать, почему в SA версии поворот записывается в 6 адресов поворота, а их по-идее 9(насколько я понял), как в Вайсе - мне интересно.
Может, кто-нибудь на этом форуме знает, зачем вообще для поворота объекта 9 адресов?

Ну и вообще интересны ваши мысли и идеи по этому поводу  :)
« Последнее редактирование: Май 28, 2017, 01:48:19 am от Shagg_E »

Оффлайн xanser

  • Главный Модератор
  • Постоялец
  • *****
  • Сообщений: 599
  • Репутация: +92/-0
  • Есть такая профессия - на работе сидеть
    • Просмотр профиля
Re: CarRec
« Ответ #1 : Май 28, 2017, 07:23:48 am »
По поводу 9 адресов... Чтобы повернуть объект в 3-мерном пространстве xyz, нужно последовательно повернуть его в каждой из 2-мерных плоскостей xy, xz, yz. Для 2-мерной плоскости матрица поворота получается 2х2, для 3-мерного пространства - соответственно 3х3, но при этом внутри содержит ту же матрицу 2х2 + нули с единицей, обозначающих, что поворот происходит в 3d, но при этом в 2-мерной плоскости, одной из xy, xz, yz (по приведенной выше ссылке можно все посмотреть подробнее). Когда получен поворот в каждой из плоскостей 3-мерного пространства, то есть три матрицы поворота 3х3, остается их перемножить (по правилам перемножения матриц) и получится общая матрица поворота в 3d, отсюда и 9 адресов, каждый - это сумма/разность произведений синусов и косинусов от трех углов поворота. Примерно такое:
Код: C++
  1. void CMatrix::SetAngles(float x, float y, float z) {
  2.         this->right.x = cos(y)*cos(z);
  3.         this->right.y = cos(y)*sin(z);
  4.         this->right.z = -sin(y);
  5.         this->up.x = sin(x)*sin(y)*cos(z) - cos(x)*sin(z);
  6.         this->up.y = sin(x)*sin(y)*sin(z) + cos(x)*cos(z);
  7.         this->up.z = sin(x)*cos(y);
  8.         this->at.x = cos(x)*sin(y)*cos(z) + sin(x)*sin(z);
  9.         this->at.y = cos(x)*sin(y)*sin(z) - sin(x)*cos(z);
  10.         this->at.z = cos(x)*cos(y);
  11. }

Поскольку каждый объект уже повернут как-то, то он уже содержит матрицу поворота, для следующего поворота она умножается на следующие матрицы поворота. Как это сократили с 9 адресов до 6, как ты говоришь, я не знаю, если только там поворот осуществляется не на 3, а на 2 угла?

По поводу видео. Я не разбирал скрипт, как именно там реализовано воспроизведение, но пока заметно жуткое дерганье машины. Не уверен, нужны ли там вектора скорости, если координаты и углы полностью задаются матрицей. Я бы может быть наоборот порекомендовал каждый раз обнулять вектора скорости, чтобы машину не швыряло. Вот пример, я как-то делал телепорт машины, и когда она оказывалась в новых координатах, ее отбрасывало как мячик, пока я не обнулил вектор скорости, чтобы погасить импульс, как я предполагаю, при большой смене координат.

По поводу дерганья машины. Предполагаю, что сначала происходит рендер машины, потом изменение координат, это вызывает заметные рывки. Есть функция 0x589AD0 CAutomobile::PreRender(). Желательно сделать туда внедрение, и менять матрицу машины до ее рендера. Но это, если интересно, потом расскажу, и это надо делать на си, у меня на этом многие возможности машин реализованы.

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: CarRec
« Ответ #2 : Май 28, 2017, 12:35:18 pm »
Про 9 адресов теперь ясно, спасибо! Раз это синусы и косинусы, то тогда действительно стоит их перемножить на 127 и перевести в INT8 для оптимизации выходного файла.
Про дергания забыл упомянуть: видео с авто немного устарело, теперь авто дергается лишь при столкновениях с объектами, которых не было на пути авто при записи(это норма).
Вектора скорости нужны, чтобы "сгладить" положение авто между тактами. Если их убрать - машина станет реально дерганой. Тогда придется записывать и читать с частотой более 30 тактов в секунду, что невозможно при ограничителе кадров, да и не нужно.
Кроме того - скрипт построен так, что воспроизведение можно остановить в любую секунду и авто "направится" в нужную сторону, в соответствии со своими векторами скорости(например - если вертолет сбит, или машина взорвалась).
На C++ такое можно сделать, но смысл задумки абсолютно теряется - как потом использовать это скриптеру в миссиях?
« Последнее редактирование: Май 28, 2017, 12:41:48 pm от Shagg_E »

Оффлайн DK

  • Новичок
  • **
  • Сообщений: 234
  • Репутация: +328/-0
    • dk22pac
    • Просмотр профиля
Re: CarRec
« Ответ #3 : Май 28, 2017, 12:51:48 pm »
На C++ такое можно сделать, но смысл задумки абсолютно теряется - как потом использовать это скриптеру в миссиях?
Кастомные опкоды.
По сути, надо перенести опкоды, которые есть в SA, в VC  :P.

PS Не смотрел, как сделано в SA, но можно предположить, что третий вектор (at) "восстанавливается" из двух остальных.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk

Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: CarRec
« Ответ #4 : Май 28, 2017, 01:47:18 pm »
На C++ такое можно сделать, но смысл задумки абсолютно теряется - как потом использовать это скриптеру в миссиях?
Кастомные опкоды.
По сути, надо перенести опкоды, которые есть в SA, в VC  :P.
Всего-то ;D
Но вообще - была вначале задумка сделать структуру итогового файла полной копией САновского, но там нет силы вращения, плюс хочу сделать две версии(2 формата) файла на выбор: первый - SAновский минимум плюс сила вращения, второй - расширенный, в который добавлю доп. вещи типа угла поворота винта вертолета или колес авто(для некоторых задумок такое необходимо), статус повреждений, здоровье авто и пр(для отдельных задумок), хотя пока не уверен на счет этого.

PS Не смотрел, как сделано в SA, но можно предположить, что третий вектор (at) "восстанавливается" из двух остальных.
Да, только что проверил - можно обойтись и без третьей тройки векторов: никаких проблем не возникает!

Теперь, когда выяснилось, что переменные поворота можно действительно ужать до 1 байта каждую, а их кол-во сократилось до 6, то структура секции сократилась на 30 байт(почти половина от текущего размера секции)!

Оффлайн DK

  • Новичок
  • **
  • Сообщений: 234
  • Репутация: +328/-0
    • dk22pac
    • Просмотр профиля
Re: CarRec
« Ответ #5 : Май 28, 2017, 02:03:19 pm »
Ты спросил
Цитировать
как потом использовать это скриптеру в миссиях?
Я отвечаю - создать кастомные опкоды. CLEO тебе даёт возможность создавать свои опкоды.

Для скриптера тут 2 плюса:
-Не надо таскать дополнительные файлы с scm-функциями.
-Вызов опкодов, а не SCM-функций. А для опкода можно создать красивое название, и описать там же его параметры. При желании можно и создать класс с методами в SB.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk

Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: CarRec
« Ответ #6 : Май 28, 2017, 02:17:42 pm »
Ты спросил
Цитировать
как потом использовать это скриптеру в миссиях?
Я отвечаю - создать кастомные опкоды. CLEO тебе даёт возможность создавать свои опкоды.

Для скриптера тут 2 плюса:
-Не надо таскать дополнительные файлы с scm-функциями.
-Вызов опкодов, а не SCM-функций. А для опкода можно создать красивое название, и описать там же его параметры. При желании можно и создать класс с методами в SB.
У меня это опять растянется на год...  :D Нет уж - тут как-нибудь без меня. Я завершу начатое и постараюсь сделать максимально лаконичные клео-функции (что лично мне для моих задумок хватит за глаза), но не более(я не против, если у кого-то есть время превратить всё это в опкоды, но у меня 2 проекта по Вайсу + большая глобалка, которую я очень-очень хочу завершить, а я чет увлекся дабстеп-пушкой и этим CarRec - пора завязывать)

Оффлайн DK

  • Новичок
  • **
  • Сообщений: 234
  • Репутация: +328/-0
    • dk22pac
    • Просмотр профиля
Re: CarRec
« Ответ #7 : Май 28, 2017, 02:47:29 pm »
Мои комментарии и, так скажем, претензии к тебе следуют только из твоих запросов.

Допустим, я не умею работать в 3d-редакторе, и мне надо в файле 3d-модели пересунуть несколько вершин.
Ты мне скажешь - установи 3d-редактор, загрузи 3d-модель, выдели нужные вершины и передвинь их.

А я скажу - что-то много действий, ещё устанавливать что-то надо, и это - только чтобы передвинуть вершины? Нет, я лучше открою файл в текстовом редакторе, найду там вершины и отредактирую их. Да, это займёт какое-то время - надо будет методом отбрасывания найти нужные вершины. А что, если позже мне опять надо будет переместить вершины, но уже другие? Я опять потрачу кое-какое время на поиск. А потом - ещё. Зато никаких заморочек, и мозги не надо напрягать.
Plugin-SDK https://github.com/DK22Pac/plugin-sdk

Discord-сервер по plugin-sdk и программированию в GTA
RU https://discord.gg/QEesDGb
ENG https://discord.gg/zaVqFQv

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: CarRec
« Ответ #8 : Май 28, 2017, 03:46:38 pm »
DK>
Да я понимаю, просто реально нет времени на это дело.
Во мне борются две стороны: одна хочет углубиться в программирование и начать уже делать всё нормально, а не через задницу, но другая(и она несколько сильнее) хочет видеть результат прямо здесь и сейчас, т.е. делать не инструменты, а готовые вещи, ибо бесит, что некоторым моим наработкам уже несколько лет, а у меня тупо не хватает времени их завершить.
И я постоянно разрываюсь между первым и вторым.
Т.е. я сначала просто хотел реализовать возможность записи движения авто только для своего мода, но потом всё же решил доработать это до инструмента для других, но потом снова вспомнил, как хочу уже доделать тот самый мод, поэтому решил, что сделаю пусть и кривоватый, но готовый инструмент для того, чтобы другие не тратили время на это. И уже у этих "других" будет выбор - использовать мой кривой инструмент или переделать его в нормальный.
С "кривым" я конечно немного утрирую, поскольку считаю, что если результат не раздражает глаза(а текущая версия CarRec не "дергает" авто, как на первом видео), и в принципе удобоварим в использовании - значит всё ок  :D

Оффлайн Prographer

  • Прохожий
  • *
  • Сообщений: 102
  • Репутация: +9/-0
  • Говнокодим, грабим, убиваем
    • Просмотр профиля
Re: CarRec
« Ответ #9 : Май 30, 2017, 07:51:09 pm »
Решил я сделать "визуальный эквалайзер" для Dubstep-пушки(да простит меня Prographer за то что я влез и изнасиловал его идею)

Ничего страшного, для этого мы тут и собираемся, чтобы творить безумие  ;D

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: CarRec
« Ответ #10 : Июнь 03, 2017, 10:02:49 am »
Ничего страшного, для этого мы тут и собираемся, чтобы творить безумие  ;D
:D

К слову о безумии: сегодня целую ночь разбирал классы(или как там это называется) CWaterCannon, CWaterCannons и всё, что с ними связано( включая CAutomobile::FireTruckControl), но так и не смог "активировать" водяную пушку на пожарной машине.
Кто-нибудь знает, как это можно сделать(я даже пробовал просто "создать" струю воды, но тщетно...)? Регистрировать это дело(факт активации и направление струи) - не проблема, а с "воспроизведением" у меня беда...

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: CarRec
« Ответ #11 : Июнь 03, 2017, 02:35:13 pm »
Черт. Та же проблема с "воспроизведением" гудка автомобиля/байка. Регистрирую на отличненько, а вот когда хочу "побибикать" - какие функции ни вызываю(связанные с гудком) - ноль реакции...

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: CarRec
« Ответ #12 : Июнь 24, 2017, 09:26:02 pm »
Наконец, месяц спустя, я могу отпустить это в свободное плавание ;D
Попутно запилил ObjRec(смысл тот же - запись и воспроизведение "пути" движения, но уже для объектов).
Постарался сделать максимально лаконичные функции для использования в скриптах.
Хотел сделать еще PedRec(или ActRec - для актеров, короче), но не знаю, как "прочитать" текущую анимацию, которую "играет" актер.
Впрочем, это можно будет выложить и отдельно(если когда-нибудь удастся решить эту проблему).
Бета-тест на gtagarage успешно пройден(пока никто не жаловался), так что...
Релиз!

Оффлайн GeniusZ

  • Призрак
  • Сообщений: 29
  • Репутация: +0/-0
    • Просмотр профиля
Re: CarRec
« Ответ #13 : Июнь 25, 2017, 01:15:03 pm »
Хотел сделать еще PedRec(или ActRec - для актеров, короче), но не знаю, как "прочитать" текущую анимацию, которую "играет" актер.

Как-то раз пришлось побороться с этой проблемой:
Код: C++
  1. bool ReadAnim(RwObject* Clump, char *string)
  2. {
  3.         unsigned int* ClumpOffset = (unsigned int*)0x978798;
  4.         char* animation = (char*)(*(int*)((**(int**)((int)((int*)Clump) + *ClumpOffset)) + 0x10));
  5.  
  6.         if (!strcmp(string, animation))
  7.                 return true;
  8.         else
  9.                 return false;
  10. }
Простите за говнокод, когда писал эту функцию был неопытен. И еще она недоработанная, так как читает только одну анимацию из анимаций, проигрываемых педом в данный момент.

Оффлайн Shagg_E

  • Администратор
  • Постоялец
  • *****
  • Сообщений: 710
  • Репутация: +24/-4
  • Изобретательный Рукожопъ
    • Просмотр профиля
    • NewRockstar
Re: CarRec
« Ответ #14 : Июнь 27, 2017, 05:29:40 pm »
Как-то раз пришлось побороться с этой проблемой:
...
Спасибо, будет от чего отталкиваться. А про углы поворота костей(чтение и запись) случаем что-нибудь знаешь? Как ты реализовал в "First Person View" повороты рук при "выглядывании из окна" автомобиля?
Дело в том, что чтение/запись поворота костей было бы в сотни раз лучше, чем работать с анимациями. Можно было бы запилить эпичнейшие вещи...