sdk-world v2026.11.05
PS2 SDK - world tier (copyleft-allowed, non-essential packages)
Loading...
Searching...
No Matches
aarender.c
1#include <stdio.h>
2#include <stdlib.h>
3#include <math.h>
4#include "aalib.h"
5#include "aamktabl.h"
6#include "config.h"
7aa_renderparams aa_defrenderparams =
8{0, 0, 1.0, AA_FLOYD_S, 0, 0};
9#define VAL (13) /*maximum distance good for fill tables */
10#define pos(i1,i2,i3,i4) (((int)(i1)<<12)+((int)(i2)<<8)+((int)(i3)<<4)+(int)(i4))
11char *aa_dithernames[] =
12{
13 "no dithering",
14 "error-distribution",
15 "floyd-steelberg dithering",
16 NULL
17};
18
19#define DO_CONTRAST(i,c) (i<c?0:(i>256-c)?255:(i-c)*255/(255-2*c))
20aa_renderparams *aa_getrenderparams(void)
21{
22 aa_renderparams *p = calloc(1, sizeof(*p));
23 if (p == NULL)
24 return NULL;
25 *p = aa_defrenderparams;
26 return (p);
27}
28#define MYLONG_MAX 0xffffffff /*this is enought for me. */
29#define myrand() (state = ((state * 1103515245) + 12345) & MYLONG_MAX)
30
31void aa_renderpalette(aa_context * c, aa_palette palette, aa_renderparams * p, int x1, int y1, int x2, int y2)
32{
33 static int state;
34 int x, y;
35 int val;
36 int wi = c->imgwidth;
37 int pos;
38 int i;
39 int pos1;
40 int i1, i2, i3, i4, esum;
41 int *errors[2];
42 int cur = 0;
43 int mval;
44 int gamma = p->gamma != 1.0;
45 aa_palette table;
46 if (x2 < 0 || y2 < 0 || x1 > aa_scrwidth(c) || y1 > aa_scrheight(c))
47 return;
48 if (x2 >= aa_scrwidth(c))
49 x2 = aa_scrwidth(c);
50 if (y2 >= aa_scrheight(c))
51 y2 = aa_scrheight(c);
52 if (x1 < 0)
53 x1 = 0;
54 if (y1 < 0)
55 y1 = 0;
56 if (c->table == NULL)
57 aa_mktable(c);
58 if (p->dither == AA_FLOYD_S) {
59 errors[0] = calloc(1, (x2 + 5) * sizeof(int));
60 if (errors[0] == NULL)
61 p->dither = AA_ERRORDISTRIB;
62 errors[0] += 3;
63 errors[1] = calloc(1, (x2 + 5) * sizeof(int));
64 if (errors[1] == NULL)
65 free(errors[0]), p->dither = AA_ERRORDISTRIB;
66 errors[1] += 3;
67 cur = 0;
68 }
69 for (i = 0; i < 256; i++) {
70 y = palette[i] + p->bright;
71 if (y > 255)
72 y = 255;
73 if (y < 0)
74 y = 0;
75 if (p->contrast)
76 y = DO_CONTRAST(y, p->contrast);
77 if (gamma) {
78 y = pow(y / 255.0, p->gamma) * 255 + 0.5;
79 }
80 if (p->inversion)
81 y = 255 - y;
82 if (y > 255)
83 y = 255;
84 else if (y < 0)
85 y = 0;
86 table[i] = y;
87 }
88 gamma = 0;
89 if (p->randomval)
90 gamma = p->randomval / 2;
91 mval = (c->parameters[c->filltable[255]].p[4]);
92 for (y = y1; y < y2; y++) {
93 pos = 2 * y * wi;
94 pos1 = y * aa_scrwidth(c);
95 esum = 0;
96 for (x = x1; x < x2; x++) {
97 i1 = table[((((int) c->imagebuffer[pos])))];
98 i2 = table[((((int) c->imagebuffer[pos + 1])))];
99 i3 = table[((((int) c->imagebuffer[pos + wi])))];
100 i4 = table[((((int) c->imagebuffer[pos + 1 + wi])))];
101 if (gamma) {
102 i = myrand();
103 i1 += (i) % p->randomval - gamma;
104 i2 += (i >> 8) % p->randomval - gamma;
105 i3 += (i >> 16) % p->randomval - gamma;
106 i4 += (i >> 24) % p->randomval - gamma;
107 if ((i1 | i2 | i3 | i4) & (~255)) {
108 if (i1 < 0)
109 i1 = 0;
110 else if (i1 > 255)
111 i1 = 255;
112 if (i2 < 0)
113 i2 = 0;
114 else if (i2 > 255)
115 i2 = 255;
116 if (i3 < 0)
117 i3 = 0;
118 else if (i3 > 255)
119 i3 = 255;
120 if (i4 < 0)
121 i4 = 0;
122 else if (i4 > 255)
123 i4 = 255;
124 }
125 }
126 switch (p->dither) {
127 case AA_ERRORDISTRIB:
128 esum = (esum + 2) >> 2;
129 i1 += esum;
130 i2 += esum;
131 i3 += esum;
132 i4 += esum;
133 break;
134 case AA_FLOYD_S:
135 if (i1 | i2 | i3 | i4) {
136 errors[cur][x - 2] += esum >> 4;
137 errors[cur][x - 1] += (5 * esum) >> 4;
138 errors[cur][x] = (3 * esum) >> 4;
139 esum = (7 * esum) >> 4;
140 esum += errors[cur ^ 1][x];
141 i1 += (esum + 1) >> 2;
142 i2 += (esum) >> 2;
143 i3 += (esum + 3) >> 2;
144 i4 += (esum + 2) >> 2;
145 }
146 break;
147 }
148 if (p->dither) {
149 esum = i1 + i2 + i3 + i4;
150 val = (esum) >> 2;
151 if ((abs(i1 - val) < VAL &&
152 abs(i2 - val) < VAL &&
153 abs(i3 - val) < VAL &&
154 abs(i4 - val) < VAL)) {
155 if (esum >= 4 * 256)
156 val = 255, esum = 4 * 256 - 1;
157 if (val < 0)
158 val = 0;
159 val = c->filltable[val];
160 } else {
161 if ((i1 | i2 | i3 | i4) & (~255)) {
162 if (i1 < 0)
163 i1 = 0;
164 else if (i1 > 255)
165 i1 = 255;
166 if (i2 < 0)
167 i2 = 0;
168 else if (i2 > 255)
169 i2 = 255;
170 if (i3 < 0)
171 i3 = 0;
172 else if (i3 > 255)
173 i3 = 255;
174 if (i4 < 0)
175 i4 = 0;
176 else if (i4 > 255)
177 i4 = 255;
178 }
179 esum = i1 + i2 + i3 + i4;
180 i1 >>= 4;
181 i2 >>= 4;
182 i3 >>= 4;
183 i4 >>= 4;
184 val = c->table[pos(i2, i1, i4, i3)];
185 }
186 esum = (esum - (c->parameters[val].p[4]) * 1020 / mval);
187 } else {
188 val = (i1 + i2 + i3 + i4) >> 2;
189 if ((abs(i1 - val) < VAL &&
190 abs(i2 - val) < VAL &&
191 abs(i3 - val) < VAL &&
192 abs(i4 - val) < VAL)) {
193 val = c->filltable[val];
194 } else {
195 i1 >>= 4;
196 i2 >>= 4;
197 i3 >>= 4;
198 i4 >>= 4;
199 val = c->table[pos(i2, i1, i4, i3)];
200 }
201 }
202 c->attrbuffer[pos1] = val >> 8;
203 c->textbuffer[pos1] = val & 0xff;
204 pos += 2;
205 pos1++;
206 }
207 if (p->dither == AA_FLOYD_S) {
208 if (x2 - 1 > x1)
209 errors[cur][x2 - 2] += (esum) >> 4;
210 if (x2 > x1)
211 errors[cur][x2 - 1] += (5 * esum) >> 4;
212 cur ^= 1;
213 errors[cur][x1] = 0;
214 errors[cur ^ 1][-1] = 0;
215 }
216 }
217 if (p->dither == AA_FLOYD_S) {
218 free(errors[0] - 3);
219 free(errors[1] - 3);
220 }
221}
222void aa_render(aa_context * c, aa_renderparams * p, int x1, int y1, int x2, int y2)
223{
224 int i;
225 static aa_palette table;
226 if (table[255] != 255)
227 for (i = 0; i < 256; i++) {
228 table[i] = i;
229 }
230 aa_renderpalette(c, table, p, x1, y1, x2, y2);
231}