File: Utils.pas

package info (click to toggle)
cevomapgen 39-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 476 kB
  • sloc: pascal: 2,765; xml: 169; makefile: 50
file content (131 lines) | stat: -rw-r--r-- 2,868 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
unit Utils;

{***********************************************************

Project:    C-evo External Map Generator
Copyright:  1999-2023 P Blackman
License:    GPLv3+

General subroutines that don't belong anywhere else

***********************************************************}


interface


// Returns a value dependent on X, ranging from A to B,
//  scaled to be bewteen 0 and 1
function JumpStep(A, B, X: Double): Double;

// fast Bias & gain functions
//  scaled to work on input byte values with a percentage control
function Bias(TB, A: Integer): Integer;
function Gain(TB, A: Integer): Integer;

// Round to an integer with a probability of rounding up or down
//  that is dependent on how near the value is to the upper or lower bound
function BlendRound(X: Double): Integer;

// Round small numbers up, others down, so 0.1 etc shows as non zero
function MyRound(S: Double): Integer;

// Combine gain & bias
function GainBias(val, G, B: Integer): Integer;


implementation


function MyRound(S: Double): Integer;
begin
    if (S < 1) AND (S > 0.00001) then
        // Round very small values up to 1
        Result := 1
    else
    if S > 3 then
        Result := Trunc(S)
    else
        Result := Round(S);
end;

function BlendRound(X: Double): Integer;
var Base: Integer;
    Test: Double;
begin
    // Offset so 0 is a full band
    if X > 3.5 then
        Result := 3
    else
    begin
        X    := X - 0.5;
        Base := Trunc(X);
        Test := 0.5; //Random;

        if frac(X) > test then
            Inc(base);

        Result := base;
    end;
end;

function JumpStep(A, B, X: Double): Double;
begin
    if X < A then
        Result := 0
    else
    if X >= B then
        Result := 1
    else
        Result := (X - A) / (B - A);
end;

function Bias(TB, A: Integer): Integer;
var T: Double;
begin
    if A <= 0 then
        Result := 0
    else
    if A >= 100 then
        Result := High(Byte)
    else
    begin
        T      := TB / High(Byte);
        Result := Round(High(Byte) * T / ((100 / A - 2) * (1 - T) + 1));
    end;
end;

function Gain(TB, A: Integer): Integer;
var T: Double;
begin
    T := TB / High(Byte);
    A := 100 - A; // Function seems to invert expected results

    if A >= 100 then
        Result := High(Byte) DIV 2 // 50%
    else
    if T < 0.5 then
        if A <= 0 then
            Result := 0
        else
            Result := Round(High(Byte) * T / ((100 / A - 2) * (1 - 2 * T) + 1))
    else
    if A <= 0 then
        Result := High(Byte)
    else
        Result := Round(High(Byte) *
            ((100 / A - 2) * (1 - 2 * T) - T) / ((100 / A - 2) * (1 - 2 * T) - 1));
end;

function GainBias(val, G, B: Integer): Integer;
var temp1,
    temp2,
    Temp3: Integer;
begin
    temp1  := val;
    temp2  := Utils.Gain(temp1, G);
    temp3  := Utils.Bias(temp2, B);
    Result := temp3;
end;

end.