Иногда в играх значения параметров хранятся в памяти не в целых, а в дробных величинах.
Программа ArtMoney в этом случае найдет значение типа DWORD (4 байта), которое при считывании пилотом из памяти выглядит как целое и совсем не похоже на нужное нам значение.
Скрипт был написан с целью помочь с решением проблемы в
этой теме, чтобы показать- как можно это "неправильное целое" преобразовать в нужное нам 4-хбайтовое вещественное число с плавающей запятой (SINGLE/FLOAT).
Данный скрипт оставляет только целую часть числа, отбрасывая дробную.
Теоретическая информация для алгоритма взята
отсюда.
З.Ы.: Протестировал не нескольких различных дробных числах - работает правильно.
Просьба при обнаружении в результатах работы скрипта ошибок - отписываться в теме, указывая целое число DWORD на входе скрипта, неверный результат на выходе, ожидаемое число (которое скрипт должен был вернуть).
Скрипт
Код
// (c) Zeleax
// В этом примере пилотом из памяти было считано DWORD равное 3305405440, которое подразумевает SINGLE(FLOAT) число -2119.75
// readmem #sdw_DWORD 0х12C30770 DWORD
set #sdw_DWORD 3305405440
gosub DWord2Single
// результат будет равен -2119
msg Целая часть дробного числа равна #sdw_result
end_script
// Процедура преобразует DWORD в соответствующее вещественное число, оставляя только целую часть
// Перед вызовом в #sdw_DWORD записываем исходные данные.
// Результат возвращается в #sdw_result
:DWord2Single
set linedelay 0 // Устанавливаем задержку между строк в 0
set #sdw_dww #sdw_DWORD // Исходное число DWORD считанное из памяти
if #sdw_dww = 0
set #sdw_result 0
return
end_if
set #sdw_dww_size 32 // разрядность числа, бит
set #sdw_dw #sdw_dww
if #sdw_dw < 0
set #sdw_dw #sdw_dw * (-1)
set #sdw_priznak -1 // придется далее инвертировать часть битов числа #sdw_dww
else
set #sdw_priznak 1
end_if
// Раскладываем число #sdw_dw на отдельные биты в массив %sdw_bit
set #sdw_i #sdw_dww_size
while #sdw_i > 0
set %sdw_bit[#sdw_i] #sdw_dw - #sdw_dw / 2 * 2 // bit № i (при нумерации битов слева направо с 1 по 32)
set #sdw_dw #sdw_dw / 2
set #sdw_i #sdw_i - 1
end_while
if #sdw_priznak < 0 // придется заморачиваться с частичной инверсией битов
// Ищем крайнюю правую "1"
set #sdw_i #sdw_dww_size
while #sdw_i > 1
if %sdw_bit[#sdw_i] = 1
break
end_if
set #sdw_i #sdw_i - 1
end_while
// всё что левее последней "1" - инвертируем
while #sdw_i > 2
set #sdw_i #sdw_i - 1
if %sdw_bit[#sdw_i] = 1
set %sdw_bit[#sdw_i] 0
else
set %sdw_bit[#sdw_i] 1
end_if
end_while
set %sdw_bit[1] 1 // устанавливаем старший бит, из-за которого и начался "сыр-бор" )
end_if
// *** Выделяем знак, порядок числа, мантиссу ***
// Знак числа
if %sdw_bit[1] = 0
set #sdw_znak 1 // +
else
set #sdw_znak -1 // -
end_if
// Порядок
set #sdw_por 0
for #sdw_i 2 9
set #sdw_por (#sdw_por * 2) + %sdw_bit[#sdw_i]
end_for
set #sdw_por #sdw_por - 127
// Выделяем целую часть числа
set #sdw_mant 1
set #sdw_j 10 + #sdw_por - 1
for #sdw_i 10 #sdw_j
set #sdw_mant (#sdw_mant * 2) + %sdw_bit[#sdw_i]
end_for
set #sdw_result #sdw_znak * #sdw_mant // Получаем результат
return