Разработка и ромхакинг > Ромхакинг и программирование
Как реализовать рандом на проце M68K?
(1/2) > >>
sergi:
Собственно в процессе кодинга игр возникла необходимость в мгновенном или не слишком медленном рандоме.
Вроде говорят что это дело цепляют за тактовую частоту процессора, ну может кто знает по этой теме что.

Я пока использовал инкремент который осуществляется каждое обновлени экрана т.е. 60 раз в секунду, но это медленно

получается только 60 цифр за секунду, мне бы побыстрее чего :?
HoRRoR:
Инкременируй и при каждом вызове функции, а потом бери какой-нибудь хеш.
sergi:
Цикл игры обычно зацеплен за обновление экрана

т.е. ждем прерывания по кадровому обновлению, при этом зачастую обычно вырубают преривания по строкам(наверно в пистолетах их только используют) и обновляем графику, палитры и опрашиваем джой, ну и инкрементирую я при этом

но проблема как раз в том что медленно, а отдельно процедура это всеравно по какомуто признаку должна быть не закономерная а реально рандомная :-\
HoRRoR:
Дык и инкрементируй при вызове функции - чем не изменение состояния? Ведь каждый раз при вызове функции будут разные значения, а разность рэндома решает уже не счётчик, а алгоритм взятия хеша и преобразования его в выходное значение в зависимости от требуемого типа и диапазона.
А лучше вместо счётчика менять при каждом удобном случае зерно - некий хеш, который меняется алгоритмом, дающим каждый непохожие результаты. А затем из этого зерна извлекать твой рэндом. На обновление экрана (да и вообще, куда не лень) тоже повесишь смену зерна - будет меньше закономерностей.
sergi:
Ну тогда следует уточнить что такое алгоритм взятия хэша - пример нужен, а то я не догоняю :-\
HoRRoR:
Алгоритм из ANSI-C:

--- Код: ---#define RAND_MAX 32767
 
unsigned long next=1;
 
int rand(void) {
 next=next*1103515245+12345;
 return((unsigned int)(next/65536)%32768);
}
 
void srand(unsigned int seed) {
 next=seed;
}
--- Конец кода ---

При вызове srand() в качестве зерна можно выставлять какой-нибудь счётчик. Желательно при этом его увеличивать хотя бы на 1, чтобы быть увереным, что при каждом вызове его значение будет меняться.
sergi:
Ну возможно я не уточнил - мне нужно в ассемблере это дело а не в С, я на асме пишу
HoRRoR:
А есть разница? Алгоритм - он и в Африке алгоритм.
sergi:
unsigned int меня беспокоит :(

да и вообще хотелось бы за какую то величину физическую зацеплено чтобы было, там какой такт проца или комманды - вроде есть такое же, только я не знаю как достать :-\
HoRRoR:
 
--- Цитата: sergi от 19 Ноябрь 2009, 18:31:25 ---unsigned int меня беспокоит :(

--- Конец цитаты ---
о_О


--- Цитата: sergi от 19 Ноябрь 2009, 18:31:25 ---да и вообще хотелось бы за какую то величину физическую зацеплено чтобы было, там какой такт проца или комманды - вроде есть такое же, только я не знаю как достать :-\

--- Конец цитаты ---
Смысл?.. Как ни крути - закономерность будет всегда. Т.е. при одинаковых условиях будут выдаваться одинаковые значения.
Коль уж так хочется - реализуй вышеописанные функции, а в srand() в качестве параметра передавай какую-нибудь "физическую величину", если сможешь её раздобыть.
sergi:
Ну мне понятно что ты там делишь, умножаешь получается какоето число
но всеже если кто знает другой способ, то буду благодарен

то что можно умножать и делить я учту, может комбинированный вариант сделаю
HoRRoR:
А как иначе ты собрался делать рэндом? Какие-то неверные у тебя о нём представления.
Умножать/делить надо, чтобы получилось неожиданное значение. В этом и есть вся суть "случайности". Ты можешь подобрать любые другие аналоги, необязательно использовать именно эти операции. Можешь сделать xor с чем-нибудь, затем сдвиг влево на несколько разрядов, затем сложить с чем-нибудь.
evgeny:
Проще говоря, нужно брать любые переменные, которые часто меняются и проделать с ними математические операции, складывать, делить, прибавить значения опроса джойстика и другие прерывания и сохранить результат в новой переменной, которая и станет отвечать за рандом.
romanich:

--- Цитата: sergi от 19 Ноябрь 2009, 15:39:11 ---получается только 60 цифр за секунду, мне бы побыстрее чего :?

--- Конец цитаты ---

Заэнабли HBlank INT и будет ещё в 262 раза (NTSC) быстрее :)
sergi:
Заэнэбливание HBLank у меня ведет к тормозам, может чего не так конечно делаю, но лучше его не трогать пока

я думал все о номере исполняемой комманде - кто знает как его выцедить :?
ну там есть же статус регистр, а номер команды где хранится PC - программ каунтер т.е.
HoRRoR:
Представь себе картину: хочет человек просверлить в стене дырку. Он берёт железную руду, переплавляет, делает стальной сплав, вытачивает сверло, создаёт крутящий механизм, расчитывает всё до деталей, и в итоге просверливает дыру.
Раздаётся звонок в дверь - пришёл сосед, просит одолжить перфоратор. Человек идёт в кладовую, достаёт перфоратор, даёт соседу, попутно думая "вот у меня правильная дырка, а у него будет неправильная".
Вот у тебя примерно то же самое. Результат в любом случае будет один, а пути его достижения делятся на стандартно-логичный и феерически-спонтанный в вакууме.
sergi:
Так это же мечта человечества - стать богом и самому творить что хотеть, хочешь перфоратор, хочешь стенку с дыркой для разных нужд - все там будем :lol:
romanich:

--- Цитата: sergi от 20 Ноябрь 2009, 16:58:06 ---Заэнэбливание HBLank у меня ведет к тормозам, может чего не так конечно делаю, но лучше его не трогать пока

--- Конец цитаты ---

в своё время мне понравился такой генератор:


--- Код: ---u32 System_Seed=0; //Обязательно = 0 !!!!!

//Random Number Generator
u32 System_Random(u32 Modular)
{
 __asm
 {
  mov       eax,System_Seed
  mov       cx,0x21
  @1:
  add       eax,eax
  jnc       @2
  xor       al,0xC5
  @2:
  loop      @1
  mov       System_Seed,eax
 }
 if(Modular) return(System_Seed%Modular);
 return System_Seed;
}

--- Конец кода ---

беспроблемно переложится на м68к
sergi:
В общем я решил так сделать и сделал

Сначала добавляю какое то число находящееся в середине нужного диапазона к тому числу которое инкрементируется каждое обновление экрана

потом беру счетчик Program Counter - вроде он содержит адрес исполняемой комманды, ну не знаю его ли он точно содержит или чего другое, потом делю его на то число которое получилось после добавления к инкрементируемому каждый экран, а результат потом еще разделяю на 2 части по 4 бита, ну мне так нужнее и смотрю не вылетело ли каждое за указанные рамки, если вылетело то еще раз добавляю среднее число к тому результату который получился, а нижнее число (нижние 4 бита) если выбиваются из диапазона то тупо делю сдвигом вправо

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

в общем результатом доволен

но делю не сдвигом а именно делением в M68K это комманда divu.w

в принципе шустро делает, скоростью я доволен, да и рандомностью тоже

А вообще мне нужно было число от 0 до 100 :)
Ti_:

--- Цитата: sergi от 26 Ноябрь 2009, 11:24:56 ---но делю не сдвигом а именно делением в M68K это комманда divu.w

--- Конец цитаты ---
деление самое медленное у сеги.

вот рандом готовый мошт кому пригодится (думаю тема актуальна ещё, раз готового так никто и не выложил!)


--- Код: ---Rock n' Roll Racing :

ROM:00001328                 movem.l d1-d2,-(sp)
ROM:0000132C                 move.w  $51E6(a4),d0
ROM:00001330                 move.w  $51E8(a4),d1
ROM:00001334                 move.w  d1,d2
ROM:00001336                 mulu.w  #$43E5,d0
ROM:0000133A                 mulu.w  #$15A,d1
ROM:0000133E                 add.l   d1,d0
ROM:00001340                 swap    d0
ROM:00001342                 clr.w   d0
ROM:00001344                 mulu.w  #$43E5,d2
ROM:00001348                 add.l   d2,d0
ROM:0000134A                 addq.l  #1,d0
ROM:0000134C                 move.l  d0,$51E6(a4)
ROM:00001350                 swap    d0
ROM:00001352                 andi.w  #$7FFF,d0
ROM:00001356                 movem.l (sp)+,d1-d2
ROM:0000135A                 rts

Dune - The Battle for Arrakis :


ROM:00000E10                 move.l  #$349F285A,(random_value1).w

......

ROM:00000E42 sub_E42:                                ; CODE XREF: sub_C0C+8p
ROM:00000E42                                         ; sub_439Aj ...
ROM:00000E42                 lea     (random_value1).w,a0
ROM:00000E46                 moveq   #0,d0
ROM:00000E48                 move.b  3(a0),d0
ROM:00000E4C                 lsr.b   #2,d0
ROM:00000E4E                 move.b  1(a0),d1
ROM:00000E52                 roxl.b  #1,d1
ROM:00000E54                 move.b  d1,1(a0)
ROM:00000E58                 move.b  2(a0),d1
ROM:00000E5C                 roxl.b  #1,d1
ROM:00000E5E                 move.b  d1,2(a0)
ROM:00000E62                 eori    #$11,ccr
ROM:00000E66                 move.b  3(a0),d1
ROM:00000E6A                 subx.b  d1,d0
ROM:00000E6C                 lsr.b   #1,d0
ROM:00000E6E                 move.b  3(a0),d1
ROM:00000E72                 roxr.b  #1,d1
ROM:00000E74                 move.b  d1,3(a0)
ROM:00000E78                 move.b  3(a0),d0
ROM:00000E7C                 move.b  2(a0),d1
ROM:00000E80                 eor.b   d1,d0
ROM:00000E82                 rts

не использовано (? )

OM:00000E84 sub_E84:
ROM:00000E84                 movem.l d2-d3,-(sp)
ROM:00000E88                 move.b  (random_value4).w,d0
ROM:00000E8C                 move.b  (random_value3).w,d1
ROM:00000E90                 move.b  (random_value2).w,d2
ROM:00000E94                 move.b  d0,d3
ROM:00000E96                 lsr.b   #2,d0
ROM:00000E98                 roxl.b  #1,d2
ROM:00000E9A                 move.b  d2,(random_value2).w
ROM:00000E9E                 roxl.b  #1,d1
ROM:00000EA0
ROM:00000EA0 loc_EA0:
ROM:00000EA0                 move.b  d1,(random_value3).w
ROM:00000EA4                 eori    #$11,ccr
ROM:00000EA8                 subx.b  d3,d0
ROM:00000EAA                 lsr.b   #1,d0
ROM:00000EAC                 roxr.b  #1,d3
ROM:00000EAE                 move.b  d3,(random_value4).w
ROM:00000EB2                 move.b  d3,d0
ROM:00000EB4                 eor.b   d1,d0
ROM:00000EB6                 andi.w  #$FF,d0
ROM:00000EBA                 movem.l (sp)+,d2-d3
ROM:00000EBE                 rts

--- Конец кода ---





Навигация
Главная страница сообщений
Следующая страница

Перейти к полной версии