| Разработка и ромхакинг > Ромхакинг и программирование |
| Как реализовать рандом на проце 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 --- Конец кода --- |
| Навигация |
| Главная страница сообщений |
| Следующая страница |