sr2lua/hud_msg.lua

  1. -- Has to match the enum in hud_message.h 
  2. HUD_REGION_DEBUG		= 0 
  3. HUD_REGION_HELP			= 1 
  4. HUD_REGION_DIVERSION	= 2 
  5. HUD_REGION_SUBTITLES	= 3 
  6. HUD_REGION_CUTSCENE_HELP	= 4 
  7. HUD_NUM_REGIONS			= 5 
  8.  
  9. HUD_MSG_DIR_UP			= 0 
  10. HUD_MSG_DIR_DOWN		= 1 
  11. HUD_MSG_DIR_CENTER		= 2 
  12.  
  13. Hud_msg_std_text 		= { scale = 0.6, wrap_width = 0 } 
  14. Hud_msg_help_text		= { scale = 0.7, wrap_width = 390 } 	 
  15. Hud_msg_subtitle_text	= { scale = 0.7, wrap_width = 0 }	-- Needs to match subtitles.cpp 
  16.  
  17. Hud_msg_regions = { 
  18. 	[HUD_REGION_DEBUG]		= { 
  19. 		text_fmt = Hud_msg_std_text, 
  20. 		direction = HUD_MSG_DIR_CENTER,	max_msgs = 10, 
  21. 		anchor = "msg_debug_anchor", 
  22. 		msgs = { num_msgs = 0 } 
  23. 	}, 
  24. 	 
  25. 	[HUD_REGION_HELP]		= { 
  26. 		text_fmt = Hud_msg_help_text, 
  27. 		direction = HUD_MSG_DIR_CENTER, 
  28. 		max_msgs = 3, 
  29. 		anchor = "msg_help_anchor", 
  30. 		msgs = { num_msgs = 0 } 
  31. 	}, 
  32. 	 
  33. 	[HUD_REGION_DIVERSION]	= { 
  34. 		text_fmt = Hud_msg_std_text, 
  35. 		direction = HUD_MSG_DIR_UP, 
  36. 		max_msgs = 7, 
  37. 		anchor = "msg_diversion_anchor", 
  38. 		msgs = { num_msgs = 0 } 
  39. 	}, 
  40.  
  41. 	[HUD_REGION_SUBTITLES]	= { 
  42. 		text_fmt = Hud_msg_subtitle_text, 
  43. 		direction = HUD_MSG_DIR_CENTER, 
  44. 		max_msgs = 3, 
  45. 		anchor = "msg_subtitle_anchor", 
  46. 		msgs = { num_msgs = 0 } 
  47. 	}, 
  48. 	 
  49. 	[HUD_REGION_CUTSCENE_HELP]	= { 
  50. 		text_fmt = Hud_msg_help_text, 
  51. 		direction = HUD_MSG_DIR_CENTER, 
  52. 		max_msgs = 2, 
  53. 		anchor = "cs_help_anchor", 
  54. 		msgs = { num_msgs = 0 } 
  55. 	}, 
  56. } 
  57.  
  58. -- all messages are stored here with the data item handle as index 
  59. Hud_msgs = { } 
  60.  
  61. function hud_msg_init() 
  62. 	-- resolve the anchors out to handles 
  63. 	for i, v in Hud_msg_regions do 
  64. 		v.anchor = vint_object_find(v.anchor) 
  65. 	end 
  66.  
  67. 	--Resize help region if we are in hd 
  68. 	if vint_hack_is_std_res() == false then 
  69. 		--HD mode 
  70. 		Hud_msg_help_text.wrap_width = 635 
  71. 	end 
  72. 	 
  73. 	vint_datagroup_add_subscription("hud_messages", "insert", "hud_msg_new_message") 
  74. 	vint_datagroup_add_subscription("hud_messages", "update", "hud_msg_update_message") 
  75. 	vint_datagroup_add_subscription("hud_messages", "remove", "hud_msg_remove_message") 
  76. end 
  77.  
  78. function hud_msg_process() 
  79. 	for i, region in Hud_msg_regions do 
  80. 		if region.is_dirty == true then 
  81. 			hud_msg_update_region(region) 
  82. 			region.is_dirty = false 
  83. 		end 
  84. 	end 
  85. end 
  86.  
  87. function hud_msg_update_region(region) 
  88. 	local pos_x, pos_y = 0, 0 
  89. 	local msgs_displayed = 0 
  90. 	 
  91. 	for msg_i = 0, region.msgs.num_msgs - 1 do 
  92. 		local msg = region.msgs[msg_i] 
  93. 		local o = msg.text_obj_h 
  94. 		 
  95. 		if msgs_displayed >= region.max_msgs then 
  96. 			if o ~= 0 then 
  97. 				vint_object_destroy(o) 
  98. 			end 
  99. 			msg.text_obj_h = 0 
  100. 		else 
  101.  
  102. 			-- create a text item if needed 
  103. 			if o == 0 then 
  104. 				o = vint_object_create("hud_msg", "text", region.anchor) 
  105. 				vint_set_property(o, "text_tag", msg.text) 
  106. 				vint_set_property(o, "font", "thin_overlay") 
  107. 				vint_set_property(o, "text_scale", region.text_fmt.scale, region.text_fmt.scale) 
  108. 				 
  109. 				local auto_offset, halign 
  110. 				if region.direction == HUD_MSG_DIR_CENTER then 
  111. 					auto_offset = "nw" 
  112. 					halign = "center" 
  113. 				elseif region.direction == HUD_MSG_DIR_UP then 
  114. 					auto_offset = "sw" 
  115. 					halign = "left" 
  116. 				else	-- HUD_MSG_DIR_DOWN 
  117. 					auto_offset = "nw" 
  118. 					halign = "left" 
  119. 				end 
  120. 				 
  121. 				if region.text_fmt.wrap_width > 0 then 
  122. 					vint_set_property(o, "word_wrap", true) 
  123. 					vint_set_property(o, "wrap_width", region.text_fmt.wrap_width) 
  124. 				end 
  125. 				 
  126. 				vint_set_property(o, "auto_offset", auto_offset) 
  127. 				vint_set_property(o, "horz_align", halign) 
  128. 				vint_set_property(o, "line_frame_enable", true) 
  129. 				vint_set_property(o, "line_frame_w", "ui_hud_hlp_bg_w") 
  130. 				vint_set_property(o, "line_frame_m", "ui_hud_hlp_bg_m") 
  131. 				vint_set_property(o, "line_frame_e", "ui_hud_hlp_bg_e") 
  132. 							 
  133. 				if msg.audio_id ~= -1 then 
  134. 					audio_play(msg.audio_id, msg.audio_type) 
  135. 				end 
  136. 			 
  137. 				msg.text_obj_h = o 
  138. 			end 
  139. 			 
  140. 			-- place the text 
  141. 			vint_set_property(o, "anchor", pos_x, pos_y) 
  142. 			 
  143. 			local w, h = vint_get_property(o, "unscaled_size") 
  144. 			 
  145. 			-- figure position of next element 
  146. 			if region.direction == HUD_MSG_DIR_UP then 
  147. 				pos_y = pos_y - h 
  148. 			else	-- HUD_MSG_DIR_DOWN or HUD_MSG_DIR_CENTER 
  149. 				pos_y = pos_y + h 
  150. 			end 
  151. 			 
  152. 		end 
  153. 		 
  154. 		msgs_displayed = msgs_displayed + 1 
  155. 	end 
  156. end 
  157.  
  158. function hud_msg_new_message(di_h) 
  159. 	local region_index, priority, text, fade_time, audio_type, audio_id = vint_dataitem_get(di_h) 
  160. 	local region = Hud_msg_regions[region_index] 
  161. 	 
  162. 	if region == nil then 
  163. 		debug_print("vint", "Message placed in invalid region, discarding\n") 
  164. 		return 
  165. 	end 
  166. 	 
  167. 	-- initialize message 
  168. 	local msg = { 
  169. 		di_h = di_h, 
  170. 		region_index = region_index, 
  171. 		priority = priority, 
  172. 		text = text, 
  173. 		audio_type = audio_type, 
  174. 		audio_id = audio_id, 
  175. 		text_obj_h = 0, 
  176. 	} 
  177. 	 
  178. 	-- insert in region list in priority order 
  179. 	local	insert_index = region.msgs.num_msgs 
  180. 	for i = 0, region.msgs.num_msgs - 1 do 
  181. 		local m = region.msgs[i] 
  182. 		if m.priority < priority then 
  183. 			insert_index = i 
  184. 			break 
  185. 		end 
  186. 	end 
  187.  
  188. 	-- shift the list down 
  189. 	for i = region.msgs.num_msgs, insert_index + 1, -1  do 
  190. 		region.msgs[i] = region.msgs[i - 1] 
  191. 	end 
  192. 	 
  193. 	-- insert new msg 
  194. 	region.msgs[insert_index] = msg 
  195. 	region.msgs.num_msgs = region.msgs.num_msgs + 1 
  196. 	Hud_msgs[di_h] = msg 
  197. 	region.is_dirty = true 
  198. 	 
  199. 	hud_msg_fade_process(msg, fade_time) 
  200. end 
  201.  
  202. function hud_msg_update_message(di_h) 
  203. 	local region_index, priority, text, fade_time = vint_dataitem_get(di_h) 
  204. 	local msg = Hud_msgs[di_h] 
  205. 	 
  206. 	if msg == nil then 
  207. 		-- we have no record of this data item 
  208. 		hud_msg_new_message(di_h) 
  209. 		return 
  210. 	end 
  211.  
  212. 	local region = Hud_msg_regions[msg.region_index] 
  213. 	 
  214. 	-- update the text item if it's changed 
  215. 	if msg.text ~= text then 
  216. 		msg.text = text 
  217. 		if msg.text_obj_h ~= 0 then 
  218. 			vint_set_property(msg.text_obj_h, "text_tag", text) 
  219. 		end 
  220. 	end 
  221. 	 
  222. 	hud_msg_fade_process(msg, fade_time) 
  223. 	 
  224. 	region.is_dirty = true 
  225. end 
  226.  
  227. function hud_msg_remove_message(di_h) 
  228. 	local msg = Hud_msgs[di_h] 
  229. 	 
  230. 	if msg ~= nil then 
  231. 		-- clean up any existing fade tween 
  232. 		if msg.fade_tween_h ~= nil then 
  233. 			vint_object_destroy(msg.fade_tween_h) 
  234. 		end 
  235.  
  236. 		-- destroy text object 
  237. 		if msg.text_obj_h ~= 0 then 
  238. 			vint_object_destroy(msg.text_obj_h) 
  239. 		end 
  240. 		 
  241. 		-- find msg in region 
  242. 		local region = Hud_msg_regions[msg.region_index] 
  243. 		local msg_index = -1 
  244. 		for i = 0, region.msgs.num_msgs - 1 do 
  245. 			if di_h == region.msgs[i].di_h then 
  246. 				msg_index = i 
  247. 				break 
  248. 			end 
  249. 		end 
  250. 		 
  251. 		-- remove it 
  252. 		if msg_index > -1 then 
  253. 			for i = msg_index + 1, region.msgs.num_msgs - 1 do 
  254. 				region.msgs[i - 1] = region.msgs[i] 
  255. 			end 
  256. 			 
  257. 			region.msgs.num_msgs = region.msgs.num_msgs - 1 
  258. 			region.is_dirty = true 
  259. 		end 
  260. 	end 
  261. 	 
  262. 	Hud_msgs[di_h] = nil 
  263. end 
  264.  
  265. function hud_msg_fade_process(msg, new_fade) 
  266. 	local is_fading = (msg.fade_time ~= nil and msg.fade_time ~= 0) 
  267. 	local should_be_fading = (new_fade > 0) 
  268. 	 
  269. 	if is_fading ~= should_be_fading then 
  270. 		-- clean up any existing tween 
  271. 		if msg.fade_tween_h ~= nil then 
  272. 			vint_object_destroy(msg.fade_tween_h) 
  273. 		end 
  274. 		 
  275. 		if should_be_fading == true then 
  276. 			-- start fading 
  277. 			local o = vint_object_create("msg_fade", "tween", vint_object_find("root_animation")) 
  278. 			vint_set_property(o, "target_handle", msg.text_obj_h) 
  279. 			vint_set_property(o, "target_property", "alpha") 
  280. 			vint_set_property(o, "duration", new_fade) 
  281. 			vint_set_property(o, "start_value", 1) 
  282. 			vint_set_property(o, "end_value", 0) 
  283. 			vint_set_property(o, "start_time", vint_get_time_index()) 
  284. 			msg.fade_tween_h = o 
  285. 		else 
  286. 			-- stop fading 
  287. 			vint_set_property(msg.text_obj_h, "alpha", 1) 
  288. 		end 
  289. 	end 
  290. 	 
  291. 	msg.fade_time = new_fade 
  292. end 
  293.  
  294. function hud_msg_hide_region(region, hide) 
  295. 	local region = Hud_msg_regions[region] 
  296. 	 
  297. 	if region ~= nil then 
  298. 		vint_set_property(region.anchor, "visible", hide == false) 
  299. 	end 
  300. end 
  301.