Pol  Revision:cb584c9
skilladv.cpp
Go to the documentation of this file.
1 
7 #include "skilladv.h"
8 
9 namespace Pol
10 {
11 namespace Core
12 {
13 /* skill advancement:
14  (essentially, a base-2 logarithm..)
15  disp raw bits posn
16  10.0 2048 1000 0000 0000 11
17  20.0 4096 1 0000 0000 0000 12
18  30.0 8K 13
19  ...
20  70.0 128K 17
21  ...
22  100.0 1024K 20
23  200.0 1M ...
24  220.0 4M ...
25  We care about the high bit, and the next 8 bits of
26  lesser significance to it.
27  So, we want to normalize to: 1 bbbb bbbb (n removed)
28  "bbbb bbbb" is used to generate the "ones.decimal" part of
29  a "tens ones . decimal" skill value.
30 
31  2047 ( 111 1111 1111 )
32  shift 2 bits:
33  1 1111 1111
34  Not greater than 1FFh, so done
35  skill += (255 * 100) / 256
36  2048: (1000 0000 0000 )
37  shift 2 bits:
38  10 0000 0000
39  greater than 1FF, so skill += 100, raw >>= 1
40  1 0000 0000
41  not greater than 1FF, so stop
42 
43  Note, this function is faster for lower skill values than high ones.
44  */
45 unsigned short raw_to_base( unsigned int raw )
46 {
47  unsigned short skill = 0;
48 
49  // what we're really doing here is skipping up the power of two chain,
50  // accumulating tens.
51  while ( raw & 0xFFFFF000Lu )
52  {
53  raw >>= 1;
54  skill += 100; // go from 0.0 to 10.0, 10.0 to 20.0, and so forth
55  }
56 
57  if ( raw & 0x800 )
58  {
59  raw &= 0x7FF;
60  skill += 100;
61  }
62 
63  // now, what's left is the "1 bbbb bbbb" part.
64  // (or "0 bbbb bbbb" if less than 1 0000 0000)
65  // calculate (linearly) the ones digit and decimal point part, using 8 bits
66 
67  skill += static_cast<unsigned short>( raw ) * 100 / 2048;
68 
69  return skill;
70 }
71 
72 unsigned int base_to_raw( unsigned short base )
73 {
74  if ( base < 100 )
75  {
76  return base * 2048L / 100L;
77  }
78  else if ( base > 2100 )
79  {
80  base = 2100;
81  }
82 
83  unsigned int raw = 1024;
84  unsigned short tmpbase = base;
85  int rawadd = 10;
86  while ( tmpbase >= 100 )
87  {
88  tmpbase -= 100;
89  raw *= 2;
90  rawadd *= 2;
91  }
92  raw += ( tmpbase * raw / 100L );
93 
94  int diff;
95  while ( ( diff = base - raw_to_base( raw ) ) > 0 )
96  {
97  if ( diff > 1 )
98  --diff;
99  raw += rawadd * diff;
100  }
101 
102  return raw;
103 }
104 }
105 }
unsigned int base_to_raw(unsigned short base)
Definition: skilladv.cpp:72
unsigned short raw_to_base(unsigned int raw)
Definition: skilladv.cpp:45
Definition: berror.cpp:12