Mercurial > touhou
comparison pytouhou/utils/random.pyx @ 509:292fea5c584e
Some more type optimisations.
author | Emmanuel Gil Peyrot <linkmauve@linkmauve.fr> |
---|---|
date | Mon, 25 Nov 2013 19:12:56 +0100 |
parents | pytouhou/utils/random.py@3c2a9e28198c |
children | 4ce3ef053a25 |
comparison
equal
deleted
inserted
replaced
508:1bc014f9d572 | 509:292fea5c584e |
---|---|
1 # -*- encoding: utf-8 -*- | |
2 ## | |
3 ## Copyright (C) 2011 Thibaut Girka <thib@sitedethib.com> | |
4 ## | |
5 ## This program is free software; you can redistribute it and/or modify | |
6 ## it under the terms of the GNU General Public License as published | |
7 ## by the Free Software Foundation; version 3 only. | |
8 ## | |
9 ## This program is distributed in the hope that it will be useful, | |
10 ## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
11 ## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
12 ## GNU General Public License for more details. | |
13 ## | |
14 | |
15 | |
16 """ | |
17 This file provides a pseudo-random number generator identical to the one used in | |
18 Touhou 6: The Embodiment of Scarlet Devil. | |
19 It is the only truly reverse-engineered piece of code of this project, | |
20 as it is needed in order to retain compatibility with replay files produced by | |
21 the offical game code. | |
22 | |
23 It has been reverse engineered from 102h.exe.""" | |
24 | |
25 | |
26 #TODO: maybe some post-processing is missing | |
27 | |
28 | |
29 from time import time | |
30 | |
31 cdef class Random: | |
32 def __init__(self, long seed=-1): | |
33 if seed < 0: | |
34 seed = time() | |
35 self.set_seed(<unsigned short>(seed & 65535)) | |
36 | |
37 | |
38 cdef void set_seed(self, unsigned short seed) nogil: | |
39 self.seed = seed | |
40 self.counter = 0 | |
41 | |
42 | |
43 cdef unsigned short rewind(self) nogil: | |
44 """Rewind the PRNG by 1 step. This is the reverse of rand_uint16. | |
45 Might be useful for debugging purposes. | |
46 """ | |
47 x = self.seed | |
48 x = (x >> 2) | ((x & 3) << 14) | |
49 self.seed = ((x + 0x6553) & 0xffff) ^ 0x9630 | |
50 self.counter -= 1 | |
51 return self.seed | |
52 | |
53 | |
54 cpdef unsigned short rand_uint16(self): | |
55 # 102h.exe@0x41e780 | |
56 x = ((self.seed ^ 0x9630) - 0x6553) & 0xffff | |
57 self.seed = (((x & 0xc000) >> 14) | (x << 2)) & 0xffff | |
58 self.counter += 1 | |
59 return self.seed | |
60 | |
61 | |
62 cpdef unsigned int rand_uint32(self): | |
63 # 102h.exe@0x41e7f0 | |
64 a = self.rand_uint16() << 16 | |
65 a |= self.rand_uint16() | |
66 return a | |
67 | |
68 | |
69 cpdef double rand_double(self): | |
70 # 102h.exe@0x41e820 | |
71 return self.rand_uint32() / <double>0x100000000 |